//===----------------------------------------------------------------------===// // DuckDB // // resizable_buffer.hpp // // //===----------------------------------------------------------------------===// #pragma once #include "duckdb.hpp" #include "duckdb/common/allocator.hpp" #include namespace duckdb { class ByteBuffer { // on to the 10 thousandth impl public: ByteBuffer() {}; ByteBuffer(data_ptr_t ptr, uint64_t len) : ptr(ptr), len(len) {}; data_ptr_t ptr = nullptr; uint64_t len = 0; public: void inc(const uint64_t increment) { available(increment); unsafe_inc(increment); } void unsafe_inc(const uint64_t increment) { len -= increment; ptr += increment; } template T read() { available(sizeof(T)); return unsafe_read(); } template T unsafe_read() { T val = unsafe_get(); unsafe_inc(sizeof(T)); return val; } template T get() { available(sizeof(T)); return unsafe_get(); } template T unsafe_get() { return Load(ptr); } void copy_to(char *dest, const uint64_t len) const { available(len); unsafe_copy_to(dest, len); } void unsafe_copy_to(char *dest, const uint64_t len) const { std::memcpy(dest, ptr, len); } void zero() const { std::memset(ptr, 0, len); } void available(const uint64_t req_len) const { if (!check_available(req_len)) { throw std::runtime_error("Out of buffer"); } } bool check_available(const uint64_t req_len) const { return req_len <= len; } }; class ResizeableBuffer : public ByteBuffer { public: ResizeableBuffer() { } ResizeableBuffer(Allocator &allocator, const uint64_t new_size) { resize(allocator, new_size); } void resize(Allocator &allocator, const uint64_t new_size) { len = new_size; if (new_size == 0) { return; } if (new_size > alloc_len) { alloc_len = NextPowerOfTwo(new_size); allocated_data.Reset(); // Have to reset before allocating new buffer (otherwise we use ~2x the memory) allocated_data = allocator.Allocate(alloc_len); ptr = allocated_data.get(); } } void reset() { ptr = allocated_data.get(); len = alloc_len; } private: AllocatedData allocated_data; idx_t alloc_len = 0; }; } // namespace duckdb