/* * include/framework/structure/BufferView.h * * Copyright (C) 2023 Douglas B. Rumbaugh * * Distributed under the Modified BSD License. * */ #pragma once #include #include #include #include #include "psu-util/alignment.h" #include "psu-ds/BloomFilter.h" #include "framework/interface/Record.h" namespace de { typedef std::_Bind ReleaseFunction; template class BufferView { public: BufferView() = default; /* * the BufferView's lifetime is tightly linked to buffer versioning, and so * copying and assignment are disabled. */ BufferView(const BufferView&) = delete; BufferView &operator=(BufferView &) = delete; BufferView(BufferView &&other) : m_data(std::exchange(other.m_data, nullptr)) , m_release(std::move(other.m_release)) , m_head(std::exchange(other.m_head, 0)) , m_tail(std::exchange(other.m_tail, 0)) , m_cap(std::exchange(other.m_cap, 0)) , m_approx_ts_cnt(std::exchange(other.m_approx_ts_cnt, 0)) , m_tombstone_filter(std::exchange(other.m_tombstone_filter, nullptr)) , m_active(std::exchange(other.m_active, false)) {} BufferView &operator=(BufferView &&other) = delete; BufferView(Wrapped *buffer, size_t cap, size_t head, size_t tail, size_t tombstone_cnt, psudb::BloomFilter *filter, ReleaseFunction release) : m_data(buffer) , m_release(release) , m_head(head) , m_tail(tail) , m_cap(cap) , m_approx_ts_cnt(tombstone_cnt) , m_tombstone_filter(filter) , m_active(true) {} ~BufferView() { if (m_active) { m_release(); } } bool check_tombstone(const R& rec) { if (m_tombstone_filter && !m_tombstone_filter->lookup(rec)) return false; for (size_t i=0; i *get(size_t i) { assert(i < get_record_count()); return m_data + to_idx(i); } void copy_to_buffer(psudb::byte *buffer) { /* check if the region to be copied circles back to start. If so, do it in two steps */ if ((m_head % m_cap) + get_record_count() > m_cap) { size_t split_idx = m_cap - (m_head % m_cap); memcpy(buffer, (std::byte*) (m_data + (m_head % m_cap)), split_idx* sizeof(Wrapped)); memcpy(buffer + split_idx, (std::byte*) m_data, (get_record_count() - split_idx) * sizeof(Wrapped)); } else { memcpy(buffer, (std::byte*) (m_data + (m_head % m_cap)), get_record_count() * sizeof(Wrapped)); } } size_t get_tail() { return m_tail; } size_t get_head() { return m_head; } private: Wrapped* m_data; ReleaseFunction m_release; size_t m_head; size_t m_tail; size_t m_cap; size_t m_approx_ts_cnt; psudb::BloomFilter *m_tombstone_filter; bool m_active; size_t to_idx(size_t i) { return (m_head + i) % m_cap; } }; }