/src/duckdb/extension/parquet/include/resizable_buffer.hpp
Line | Count | Source |
1 | | //===----------------------------------------------------------------------===// |
2 | | // DuckDB |
3 | | // |
4 | | // resizable_buffer.hpp |
5 | | // |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | |
9 | | #pragma once |
10 | | |
11 | | #include "duckdb.hpp" |
12 | | #include "duckdb/common/allocator.hpp" |
13 | | |
14 | | #include <exception> |
15 | | |
16 | | namespace duckdb { |
17 | | |
18 | | class ByteBuffer { // on to the 10 thousandth impl |
19 | | public: |
20 | 0 | ByteBuffer() {}; |
21 | 0 | ByteBuffer(data_ptr_t ptr, uint64_t len) : ptr(ptr), len(len) {}; |
22 | | |
23 | | data_ptr_t ptr = nullptr; |
24 | | uint64_t len = 0; |
25 | | |
26 | | public: |
27 | 0 | void inc(const uint64_t increment) { |
28 | 0 | available(increment); |
29 | 0 | unsafe_inc(increment); |
30 | 0 | } |
31 | | |
32 | 0 | void unsafe_inc(const uint64_t increment) { |
33 | 0 | len -= increment; |
34 | 0 | ptr += increment; |
35 | 0 | } |
36 | | |
37 | | template <class T> |
38 | 0 | T read() { |
39 | 0 | available(sizeof(T)); |
40 | 0 | return unsafe_read<T>(); |
41 | 0 | } Unexecuted instantiation: unsigned char duckdb::ByteBuffer::read<unsigned char>() Unexecuted instantiation: unsigned int duckdb::ByteBuffer::read<unsigned int>() Unexecuted instantiation: unsigned long duckdb::ByteBuffer::read<unsigned long>() Unexecuted instantiation: int duckdb::ByteBuffer::read<int>() Unexecuted instantiation: long duckdb::ByteBuffer::read<long>() Unexecuted instantiation: unsigned short duckdb::ByteBuffer::read<unsigned short>() Unexecuted instantiation: float duckdb::ByteBuffer::read<float>() Unexecuted instantiation: double duckdb::ByteBuffer::read<double>() Unexecuted instantiation: duckdb::Int96 duckdb::ByteBuffer::read<duckdb::Int96>() Unexecuted instantiation: bool duckdb::ByteBuffer::read<bool>() |
42 | | |
43 | | template <class T> |
44 | 0 | T unsafe_read() { |
45 | 0 | T val = unsafe_get<T>(); |
46 | 0 | unsafe_inc(sizeof(T)); |
47 | 0 | return val; |
48 | 0 | } Unexecuted instantiation: unsigned char duckdb::ByteBuffer::unsafe_read<unsigned char>() Unexecuted instantiation: unsigned int duckdb::ByteBuffer::unsafe_read<unsigned int>() Unexecuted instantiation: unsigned long duckdb::ByteBuffer::unsafe_read<unsigned long>() Unexecuted instantiation: int duckdb::ByteBuffer::unsafe_read<int>() Unexecuted instantiation: long duckdb::ByteBuffer::unsafe_read<long>() Unexecuted instantiation: unsigned short duckdb::ByteBuffer::unsafe_read<unsigned short>() Unexecuted instantiation: float duckdb::ByteBuffer::unsafe_read<float>() Unexecuted instantiation: double duckdb::ByteBuffer::unsafe_read<double>() Unexecuted instantiation: duckdb::Int96 duckdb::ByteBuffer::unsafe_read<duckdb::Int96>() Unexecuted instantiation: bool duckdb::ByteBuffer::unsafe_read<bool>() |
49 | | |
50 | | template <class T> |
51 | | T get() { |
52 | | available(sizeof(T)); |
53 | | return unsafe_get<T>(); |
54 | | } |
55 | | |
56 | | template <class T> |
57 | 0 | T unsafe_get() { |
58 | 0 | return Load<T>(ptr); |
59 | 0 | } Unexecuted instantiation: unsigned char duckdb::ByteBuffer::unsafe_get<unsigned char>() Unexecuted instantiation: unsigned int duckdb::ByteBuffer::unsafe_get<unsigned int>() Unexecuted instantiation: unsigned long duckdb::ByteBuffer::unsafe_get<unsigned long>() Unexecuted instantiation: int duckdb::ByteBuffer::unsafe_get<int>() Unexecuted instantiation: long duckdb::ByteBuffer::unsafe_get<long>() Unexecuted instantiation: unsigned short duckdb::ByteBuffer::unsafe_get<unsigned short>() Unexecuted instantiation: float duckdb::ByteBuffer::unsafe_get<float>() Unexecuted instantiation: double duckdb::ByteBuffer::unsafe_get<double>() Unexecuted instantiation: duckdb::Int96 duckdb::ByteBuffer::unsafe_get<duckdb::Int96>() Unexecuted instantiation: bool duckdb::ByteBuffer::unsafe_get<bool>() |
60 | | |
61 | 0 | void copy_to(char *dest, const uint64_t len) const { |
62 | 0 | available(len); |
63 | 0 | unsafe_copy_to(dest, len); |
64 | 0 | } |
65 | | |
66 | 0 | void unsafe_copy_to(char *dest, const uint64_t len) const { |
67 | 0 | std::memcpy(dest, ptr, len); |
68 | 0 | } |
69 | | |
70 | 0 | void zero() const { |
71 | 0 | std::memset(ptr, 0, len); |
72 | 0 | } |
73 | | |
74 | 0 | void available(const uint64_t req_len) const { |
75 | 0 | if (!check_available(req_len)) { |
76 | 0 | throw std::runtime_error("Out of buffer"); |
77 | 0 | } |
78 | 0 | } |
79 | | |
80 | 0 | bool check_available(const uint64_t req_len) const { |
81 | 0 | return req_len <= len; |
82 | 0 | } |
83 | | }; |
84 | | |
85 | | class ResizeableBuffer : public ByteBuffer { |
86 | | public: |
87 | 0 | ResizeableBuffer() { |
88 | 0 | } |
89 | 0 | ResizeableBuffer(Allocator &allocator, const uint64_t new_size) { |
90 | 0 | resize(allocator, new_size); |
91 | 0 | } |
92 | 0 | void resize(Allocator &allocator, const uint64_t new_size) { |
93 | 0 | len = new_size; |
94 | 0 | if (new_size == 0) { |
95 | 0 | return; |
96 | 0 | } |
97 | 0 | if (new_size > alloc_len) { |
98 | 0 | alloc_len = NextPowerOfTwo(new_size); |
99 | 0 | allocated_data.Reset(); // Have to reset before allocating new buffer (otherwise we use ~2x the memory) |
100 | 0 | allocated_data = allocator.Allocate(alloc_len); |
101 | 0 | ptr = allocated_data.get(); |
102 | 0 | } |
103 | 0 | } |
104 | 0 | void reset() { |
105 | 0 | ptr = allocated_data.get(); |
106 | 0 | len = alloc_len; |
107 | 0 | } |
108 | | |
109 | | private: |
110 | | AllocatedData allocated_data; |
111 | | idx_t alloc_len = 0; |
112 | | }; |
113 | | |
114 | | } // namespace duckdb |