1#include "duckdb/storage/checkpoint/table_data_writer.hpp"
2
3#include "duckdb/catalog/catalog_entry/duck_table_entry.hpp"
4#include "duckdb/catalog/catalog_entry/table_catalog_entry.hpp"
5#include "duckdb/common/vector_operations/vector_operations.hpp"
6#include "duckdb/common/serializer/buffered_serializer.hpp"
7#include "duckdb/storage/table/column_checkpoint_state.hpp"
8#include "duckdb/storage/table/table_statistics.hpp"
9
10namespace duckdb {
11
12TableDataWriter::TableDataWriter(TableCatalogEntry &table_p) : table(table_p.Cast<DuckTableEntry>()) {
13 D_ASSERT(table_p.IsDuckTable());
14}
15
16TableDataWriter::~TableDataWriter() {
17}
18
19void TableDataWriter::WriteTableData() {
20 // start scanning the table and append the data to the uncompressed segments
21 table.GetStorage().Checkpoint(writer&: *this);
22}
23
24CompressionType TableDataWriter::GetColumnCompressionType(idx_t i) {
25 return table.GetColumn(idx: LogicalIndex(i)).CompressionType();
26}
27
28void TableDataWriter::AddRowGroup(RowGroupPointer &&row_group_pointer, unique_ptr<RowGroupWriter> &&writer) {
29 row_group_pointers.push_back(x: std::move(row_group_pointer));
30 writer.reset();
31}
32
33SingleFileTableDataWriter::SingleFileTableDataWriter(SingleFileCheckpointWriter &checkpoint_manager,
34 TableCatalogEntry &table, MetaBlockWriter &table_data_writer,
35 MetaBlockWriter &meta_data_writer)
36 : TableDataWriter(table), checkpoint_manager(checkpoint_manager), table_data_writer(table_data_writer),
37 meta_data_writer(meta_data_writer) {
38}
39
40unique_ptr<RowGroupWriter> SingleFileTableDataWriter::GetRowGroupWriter(RowGroup &row_group) {
41 return make_uniq<SingleFileRowGroupWriter>(args&: table, args&: checkpoint_manager.partial_block_manager, args&: table_data_writer);
42}
43
44void SingleFileTableDataWriter::FinalizeTable(TableStatistics &&global_stats, DataTableInfo *info) {
45 // store the current position in the metadata writer
46 // this is where the row groups for this table start
47 auto pointer = table_data_writer.GetBlockPointer();
48
49 global_stats.Serialize(serializer&: table_data_writer);
50
51 // now start writing the row group pointers to disk
52 table_data_writer.Write<uint64_t>(element: row_group_pointers.size());
53 idx_t total_rows = 0;
54 for (auto &row_group_pointer : row_group_pointers) {
55 auto row_group_count = row_group_pointer.row_start + row_group_pointer.tuple_count;
56 if (row_group_count > total_rows) {
57 total_rows = row_group_count;
58 }
59 RowGroup::Serialize(pointer&: row_group_pointer, serializer&: table_data_writer);
60 }
61
62 // Pointer to the table itself goes to the metadata stream.
63 meta_data_writer.Write<block_id_t>(element: pointer.block_id);
64 meta_data_writer.Write<uint64_t>(element: pointer.offset);
65 meta_data_writer.Write<idx_t>(element: total_rows);
66
67 // Now we serialize indexes in the table_metadata_writer
68 vector<BlockPointer> index_pointers = info->indexes.SerializeIndexes(writer&: table_data_writer);
69
70 // Write-off to metadata block ids and offsets of indexes
71 meta_data_writer.Write<idx_t>(element: index_pointers.size());
72 for (auto &block_info : index_pointers) {
73 meta_data_writer.Write<idx_t>(element: block_info.block_id);
74 meta_data_writer.Write<idx_t>(element: block_info.offset);
75 }
76}
77
78} // namespace duckdb
79