| 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 |