115 lines
2.2 KiB
C++
115 lines
2.2 KiB
C++
//===----------------------------------------------------------------------===//
|
|
// DuckDB
|
|
//
|
|
// resizable_buffer.hpp
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#pragma once
|
|
|
|
#include "duckdb.hpp"
|
|
#include "duckdb/common/allocator.hpp"
|
|
|
|
#include <exception>
|
|
|
|
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 <class T>
|
|
T read() {
|
|
available(sizeof(T));
|
|
return unsafe_read<T>();
|
|
}
|
|
|
|
template <class T>
|
|
T unsafe_read() {
|
|
T val = unsafe_get<T>();
|
|
unsafe_inc(sizeof(T));
|
|
return val;
|
|
}
|
|
|
|
template <class T>
|
|
T get() {
|
|
available(sizeof(T));
|
|
return unsafe_get<T>();
|
|
}
|
|
|
|
template <class T>
|
|
T unsafe_get() {
|
|
return Load<T>(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
|