From 13c7fad86956beef5c25e72f497fba8b84ccd3b8 Mon Sep 17 00:00:00 2001 From: Tishj Date: Tue, 7 Jan 2025 10:19:51 +0100 Subject: [PATCH] remove const casts, replaced with duplicated function bodies | lesser of two evils?? --- .../duckdb/storage/table/segment_tree.hpp | 43 ++++++++++++++++--- src/storage/table/row_group.cpp | 34 +++++++++++++-- 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/src/include/duckdb/storage/table/segment_tree.hpp b/src/include/duckdb/storage/table/segment_tree.hpp index 51bcdad7149e..e7ee72e2bb09 100644 --- a/src/include/duckdb/storage/table/segment_tree.hpp +++ b/src/include/duckdb/storage/table/segment_tree.hpp @@ -125,18 +125,49 @@ class SegmentTree { auto l = Lock(); return GetSegmentByIndex(l, index); } + const T *GetSegmentByIndex(SegmentLock &l, int64_t index) const { - auto &non_const_this = (SegmentTree &)(*this); // NOLINT - auto res = non_const_this.GetSegmentByIndex(l, index); - return (const T *)(res); // NOLINT + if (index < 0) { + // load all segments + LoadAllSegments(l); + index += nodes.size(); + if (index < 0) { + return nullptr; + } + return nodes[UnsafeNumericCast(index)].node.get(); + } else { + // lazily load segments until we reach the specific segment + while (idx_t(index) >= nodes.size() && LoadNextSegment(l)) { + } + if (idx_t(index) >= nodes.size()) { + return nullptr; + } + return nodes[UnsafeNumericCast(index)].node.get(); + } } //! Gets the next segment T *GetNextSegment(T *segment) { - auto &const_this = (const SegmentTree &)(*this); // NOLINT - auto res = const_this.GetNextSegment(segment); - return (T *)(res); // NOLINT + if (!SUPPORTS_LAZY_LOADING) { + return segment->Next(); + } + if (finished_loading) { + return segment->Next(); + } + auto l = Lock(); + return GetNextSegment(l, segment); + } + + T *GetNextSegment(SegmentLock &l, T *segment) { + if (!segment) { + return nullptr; + } +#ifdef DEBUG + D_ASSERT(nodes[segment->index].node.get() == segment); +#endif + return GetSegmentByIndex(l, UnsafeNumericCast(segment->index + 1)); } + const T *GetNextSegment(const T *segment) const { if (!SUPPORTS_LAZY_LOADING) { return segment->Next(); diff --git a/src/storage/table/row_group.cpp b/src/storage/table/row_group.cpp index a3451742634a..973191639aee 100644 --- a/src/storage/table/row_group.cpp +++ b/src/storage/table/row_group.cpp @@ -107,9 +107,37 @@ ColumnData &RowGroup::GetColumn(const StorageIndex &c) { } ColumnData &RowGroup::GetColumn(storage_t c) { - auto &const_this = (const RowGroup &)*this; // NOLINT - auto &res = const_this.GetColumn(c); - return (ColumnData &)res; // NOLINT + D_ASSERT(c < columns.size()); + if (!is_loaded) { + // not being lazy loaded + D_ASSERT(columns[c]); + return *columns[c]; + } + if (is_loaded[c]) { + D_ASSERT(columns[c]); + return *columns[c]; + } + lock_guard l(row_group_lock); + if (columns[c]) { + D_ASSERT(is_loaded[c]); + return *columns[c]; + } + if (column_pointers.size() != columns.size()) { + throw InternalException("Lazy loading a column but the pointer was not set"); + } + auto &metadata_manager = GetCollection().GetMetadataManager(); + auto &types = GetCollection().GetTypes(); + auto &block_pointer = column_pointers[c]; + MetadataReader column_data_reader(metadata_manager, block_pointer); + this->columns[c] = + ColumnData::Deserialize(GetBlockManager(), GetTableInfo(), c, start, column_data_reader, types[c]); + is_loaded[c] = true; + if (this->columns[c]->count != this->count) { + throw InternalException("Corrupted database - loaded column with index %llu at row start %llu, count %llu did " + "not match count of row group %llu", + c, start, this->columns[c]->count.load(), this->count.load()); + } + return *columns[c]; } const ColumnData &RowGroup::GetColumn(storage_t c) const {