1 | #include "duckdb/storage/meta_block_writer.hpp" |
---|---|
2 | |
3 | #include <cstring> |
4 | |
5 | using namespace duckdb; |
6 | using namespace std; |
7 | |
8 | MetaBlockWriter::MetaBlockWriter(BlockManager &manager) : manager(manager) { |
9 | block = manager.CreateBlock(); |
10 | offset = sizeof(block_id_t); |
11 | } |
12 | |
13 | MetaBlockWriter::~MetaBlockWriter() { |
14 | Flush(); |
15 | } |
16 | |
17 | void MetaBlockWriter::Flush() { |
18 | if (offset > sizeof(block_id_t)) { |
19 | manager.Write(*block); |
20 | offset = sizeof(block_id_t); |
21 | } |
22 | } |
23 | |
24 | void MetaBlockWriter::WriteData(const_data_ptr_t buffer, idx_t write_size) { |
25 | while (offset + write_size > block->size) { |
26 | // we need to make a new block |
27 | // first copy what we can |
28 | assert(offset <= block->size); |
29 | idx_t copy_amount = block->size - offset; |
30 | if (copy_amount > 0) { |
31 | memcpy(block->buffer + offset, buffer, copy_amount); |
32 | buffer += copy_amount; |
33 | offset += copy_amount; |
34 | write_size -= copy_amount; |
35 | } |
36 | // now we need to get a new block id |
37 | block_id_t new_block_id = manager.GetFreeBlockId(); |
38 | // write the block id of the new block to the start of the current block |
39 | *((block_id_t *)block->buffer) = new_block_id; |
40 | // first flush the old block |
41 | Flush(); |
42 | // now update the block id of the lbock |
43 | block->id = new_block_id; |
44 | } |
45 | memcpy(block->buffer + offset, buffer, write_size); |
46 | offset += write_size; |
47 | } |
48 |