forked from alibaba/AliSQL
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfile_buffer.cpp
More file actions
125 lines (103 loc) · 3.44 KB
/
file_buffer.cpp
File metadata and controls
125 lines (103 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "duckdb/common/file_buffer.hpp"
#include "duckdb/common/allocator.hpp"
#include "duckdb/common/exception.hpp"
#include "duckdb/common/file_system.hpp"
#include "duckdb/common/helper.hpp"
#include "duckdb/storage/storage_info.hpp"
#include "duckdb/storage/block_manager.hpp"
#include <cstring>
namespace duckdb {
FileBuffer::FileBuffer(Allocator &allocator, FileBufferType type, uint64_t user_size, idx_t block_header_size)
: allocator(allocator), type(type) {
Init();
if (user_size) {
ResizeInternal(user_size, block_header_size);
}
}
FileBuffer::FileBuffer(Allocator &allocator, FileBufferType type, BlockManager &block_manager)
: allocator(allocator), type(type) {
Init();
Resize(block_manager);
}
void FileBuffer::Init() {
buffer = nullptr;
size = 0;
internal_buffer = nullptr;
internal_size = 0;
}
FileBuffer::FileBuffer(FileBuffer &source, FileBufferType type_p) : allocator(source.allocator), type(type_p) {
// take over the structures of the source buffer
buffer = source.buffer;
size = source.size;
internal_buffer = source.internal_buffer;
internal_size = source.internal_size;
source.Init();
}
FileBuffer::~FileBuffer() {
if (!internal_buffer) {
return;
}
allocator.FreeData(internal_buffer, internal_size);
}
void FileBuffer::ReallocBuffer(idx_t new_size) {
data_ptr_t new_buffer;
if (internal_buffer) {
new_buffer = allocator.ReallocateData(internal_buffer, internal_size, new_size);
} else {
new_buffer = allocator.AllocateData(new_size);
}
// FIXME: should we throw one of our exceptions here?
if (!new_buffer) {
throw std::bad_alloc();
}
internal_buffer = new_buffer;
internal_size = new_size;
// The caller must update these.
buffer = nullptr;
size = 0;
}
FileBuffer::MemoryRequirement FileBuffer::CalculateMemory(uint64_t user_size, uint64_t block_header_size) const {
FileBuffer::MemoryRequirement result;
if (type == FileBufferType::TINY_BUFFER) {
// We never do IO on tiny buffers, so there's no need to add a header or sector-align.
result.header_size = 0;
result.alloc_size = user_size;
} else {
result.header_size = block_header_size;
result.alloc_size = AlignValue<idx_t, Storage::SECTOR_SIZE>(result.header_size + user_size);
}
return result;
}
void FileBuffer::ResizeInternal(uint64_t new_size, uint64_t block_header_size) {
auto req = CalculateMemory(new_size, block_header_size);
ReallocBuffer(req.alloc_size);
if (new_size > 0) {
buffer = internal_buffer + req.header_size;
size = internal_size - req.header_size;
}
}
void FileBuffer::Resize(uint64_t new_size, BlockManager &block_manager) {
ResizeInternal(new_size, block_manager.GetBlockHeaderSize());
}
void FileBuffer::Resize(BlockManager &block_manager) {
ResizeInternal(block_manager.GetBlockSize(), block_manager.GetBlockHeaderSize());
}
void FileBuffer::Read(FileHandle &handle, uint64_t location) {
D_ASSERT(type != FileBufferType::TINY_BUFFER);
handle.Read(internal_buffer, internal_size, location);
}
void FileBuffer::Write(FileHandle &handle, uint64_t location) {
D_ASSERT(type != FileBufferType::TINY_BUFFER);
handle.Write(internal_buffer, internal_size, location);
}
void FileBuffer::Clear() {
memset(internal_buffer, 0, internal_size);
}
void FileBuffer::Initialize(DebugInitialize initialize) {
if (initialize == DebugInitialize::NO_INITIALIZE) {
return;
}
uint8_t value = initialize == DebugInitialize::DEBUG_ZERO_INITIALIZE ? 0 : 0xFF;
memset(internal_buffer, value, internal_size);
}
} // namespace duckdb