1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/storage/arena_allocator.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/allocator.hpp"
12#include "duckdb/common/common.hpp"
13
14namespace duckdb {
15
16struct ArenaChunk {
17 ArenaChunk(Allocator &allocator, idx_t size);
18 ~ArenaChunk();
19
20 AllocatedData data;
21 idx_t current_position;
22 idx_t maximum_size;
23 unsafe_unique_ptr<ArenaChunk> next;
24 ArenaChunk *prev;
25};
26
27class ArenaAllocator {
28 static constexpr const idx_t ARENA_ALLOCATOR_INITIAL_CAPACITY = 2048;
29
30public:
31 DUCKDB_API ArenaAllocator(Allocator &allocator, idx_t initial_capacity = ARENA_ALLOCATOR_INITIAL_CAPACITY);
32 DUCKDB_API ~ArenaAllocator();
33
34 DUCKDB_API data_ptr_t Allocate(idx_t size);
35 DUCKDB_API data_ptr_t Reallocate(data_ptr_t pointer, idx_t old_size, idx_t size);
36
37 DUCKDB_API data_ptr_t AllocateAligned(idx_t size);
38 DUCKDB_API data_ptr_t ReallocateAligned(data_ptr_t pointer, idx_t old_size, idx_t size);
39
40 //! Resets the current head and destroys all previous arena chunks
41 DUCKDB_API void Reset();
42 DUCKDB_API void Destroy();
43 DUCKDB_API void Move(ArenaAllocator &allocator);
44
45 DUCKDB_API ArenaChunk *GetHead();
46 DUCKDB_API ArenaChunk *GetTail();
47
48 DUCKDB_API bool IsEmpty();
49
50 //! Returns an "Allocator" wrapper for this arena allocator
51 Allocator &GetAllocator() {
52 return arena_allocator;
53 }
54
55private:
56 //! Internal allocator that is used by the arena allocator
57 Allocator &allocator;
58 idx_t current_capacity;
59 unsafe_unique_ptr<ArenaChunk> head;
60 ArenaChunk *tail;
61 //! An allocator wrapper using this arena allocator
62 Allocator arena_allocator;
63};
64
65} // namespace duckdb
66