diff options
author | kungasc <kungasc@ydb.tech> | 2023-12-14 12:56:56 +0300 |
---|---|---|
committer | kungasc <kungasc@ydb.tech> | 2023-12-14 14:54:47 +0300 |
commit | e7f64cc383ca087378ff3edb8b833360561445a7 (patch) | |
tree | 62271dc2eefe8fa395ac4808afc5ce6999eb7784 | |
parent | 897ada7941ae63332514c27e676d2f70edc3c13b (diff) | |
download | ydb-e7f64cc383ca087378ff3edb8b833360561445a7.tar.gz |
KIKIMR-19521 BTreeIndex Charge Interface
-rw-r--r-- | ydb/core/tablet_flat/CMakeLists.darwin-arm64.txt | 2 | ||||
-rw-r--r-- | ydb/core/tablet_flat/CMakeLists.darwin-x86_64.txt | 2 | ||||
-rw-r--r-- | ydb/core/tablet_flat/CMakeLists.linux-aarch64.txt | 2 | ||||
-rw-r--r-- | ydb/core/tablet_flat/CMakeLists.linux-x86_64.txt | 2 | ||||
-rw-r--r-- | ydb/core/tablet_flat/CMakeLists.windows-x86_64.txt | 2 | ||||
-rw-r--r-- | ydb/core/tablet_flat/benchmark/b_charge.cpp | 8 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge.h | 153 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge_btree_index.h | 69 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge_create.cpp | 15 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge_create.h | 10 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge_iface.h | 48 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge_range.cpp | 124 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_part_charge_range.h | 20 | ||||
-rw-r--r-- | ydb/core/tablet_flat/flat_table.cpp | 12 | ||||
-rw-r--r-- | ydb/core/tablet_flat/ut/ut_charge.cpp | 15 | ||||
-rw-r--r-- | ydb/core/tablet_flat/ut/ut_part.cpp | 6 | ||||
-rw-r--r-- | ydb/core/tablet_flat/ya.make | 2 |
17 files changed, 325 insertions, 167 deletions
diff --git a/ydb/core/tablet_flat/CMakeLists.darwin-arm64.txt b/ydb/core/tablet_flat/CMakeLists.darwin-arm64.txt index dcc93ab95c..c6d0640e5f 100644 --- a/ydb/core/tablet_flat/CMakeLists.darwin-arm64.txt +++ b/ydb/core/tablet_flat/CMakeLists.darwin-arm64.txt @@ -107,6 +107,8 @@ target_sources(ydb-core-tablet_flat PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_mem_warm.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausagecache.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausage_meta.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_create.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_range.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_page_label.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_dump.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_iter_multi.cpp diff --git a/ydb/core/tablet_flat/CMakeLists.darwin-x86_64.txt b/ydb/core/tablet_flat/CMakeLists.darwin-x86_64.txt index dcc93ab95c..c6d0640e5f 100644 --- a/ydb/core/tablet_flat/CMakeLists.darwin-x86_64.txt +++ b/ydb/core/tablet_flat/CMakeLists.darwin-x86_64.txt @@ -107,6 +107,8 @@ target_sources(ydb-core-tablet_flat PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_mem_warm.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausagecache.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausage_meta.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_create.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_range.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_page_label.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_dump.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_iter_multi.cpp diff --git a/ydb/core/tablet_flat/CMakeLists.linux-aarch64.txt b/ydb/core/tablet_flat/CMakeLists.linux-aarch64.txt index 0f0cc8999b..8dd469d197 100644 --- a/ydb/core/tablet_flat/CMakeLists.linux-aarch64.txt +++ b/ydb/core/tablet_flat/CMakeLists.linux-aarch64.txt @@ -108,6 +108,8 @@ target_sources(ydb-core-tablet_flat PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_mem_warm.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausagecache.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausage_meta.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_create.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_range.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_page_label.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_dump.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_iter_multi.cpp diff --git a/ydb/core/tablet_flat/CMakeLists.linux-x86_64.txt b/ydb/core/tablet_flat/CMakeLists.linux-x86_64.txt index 0f0cc8999b..8dd469d197 100644 --- a/ydb/core/tablet_flat/CMakeLists.linux-x86_64.txt +++ b/ydb/core/tablet_flat/CMakeLists.linux-x86_64.txt @@ -108,6 +108,8 @@ target_sources(ydb-core-tablet_flat PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_mem_warm.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausagecache.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausage_meta.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_create.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_range.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_page_label.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_dump.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_iter_multi.cpp diff --git a/ydb/core/tablet_flat/CMakeLists.windows-x86_64.txt b/ydb/core/tablet_flat/CMakeLists.windows-x86_64.txt index dcc93ab95c..c6d0640e5f 100644 --- a/ydb/core/tablet_flat/CMakeLists.windows-x86_64.txt +++ b/ydb/core/tablet_flat/CMakeLists.windows-x86_64.txt @@ -107,6 +107,8 @@ target_sources(ydb-core-tablet_flat PRIVATE ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_mem_warm.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausagecache.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_sausage_meta.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_create.cpp + ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_charge_range.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_page_label.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_dump.cpp ${CMAKE_SOURCE_DIR}/ydb/core/tablet_flat/flat_part_iter_multi.cpp diff --git a/ydb/core/tablet_flat/benchmark/b_charge.cpp b/ydb/core/tablet_flat/benchmark/b_charge.cpp index 3e862785b9..ece5e52034 100644 --- a/ydb/core/tablet_flat/benchmark/b_charge.cpp +++ b/ydb/core/tablet_flat/benchmark/b_charge.cpp @@ -1,8 +1,8 @@ #include <benchmark/benchmark.h> -#include <random> #include <ydb/core/tablet_flat/flat_row_celled.h> -#include <ydb/core/tablet_flat/flat_part_charge.h> +#include <ydb/core/tablet_flat/flat_part_charge_range.h> +#include <ydb/core/tablet_flat/flat_part_charge_create.h> #include <ydb/core/tablet_flat/test/libs/rows/cook.h> #include <ydb/core/tablet_flat/test/libs/rows/tool.h> #include <ydb/core/tablet_flat/test/libs/table/model/large.h> @@ -138,7 +138,7 @@ BENCHMARK_DEFINE_F(TModel, PrechargeByKeys)(benchmark::State& state) { const auto from = Tool.KeyCells(Mass.Saved[lower]); const auto to = Tool.KeyCells(Mass.Saved[upper]); - TCharge::Range(Env.Get(), from, to, *Run.Get(), keyDefaults, Tags, items, Max<ui64>()); + ChargeRange(Env.Get(), from, to, *Run.Get(), keyDefaults, Tags, items, Max<ui64>()); } state.counters["Touched"] = benchmark::Counter(Env->TouchedCount, benchmark::Counter::kAvgIterations); @@ -154,7 +154,7 @@ BENCHMARK_DEFINE_F(TModel, PrechargeByRows)(benchmark::State& state) { ui32 lower = ++it % 50; ui32 upper = lower + items; - TCharge(Env.Get(), *(Run.Get())->begin()->Part, Tags, false).Do(lower, upper, keyDefaults, items, Max<ui64>()); + CreateCharge(Env.Get(), *(Run.Get())->begin()->Part, Tags, false)->Do(lower, upper, keyDefaults, items, Max<ui64>()); } state.counters["Touched"] = Env->TouchedCount / it; diff --git a/ydb/core/tablet_flat/flat_part_charge.h b/ydb/core/tablet_flat/flat_part_charge.h index 499e04c3ee..6e2531eec4 100644 --- a/ydb/core/tablet_flat/flat_part_charge.h +++ b/ydb/core/tablet_flat/flat_part_charge.h @@ -1,27 +1,20 @@ #pragma once -#include "defs.h" #include "flat_table_part.h" #include "flat_part_iface.h" -#include "flat_part_slice.h" #include "flat_part_index_iter.h" +#include "flat_part_charge_iface.h" #include <util/generic/bitmap.h> namespace NKikimr { namespace NTable { - class TCharge { + class TCharge : public ICharge { public: - using TCells = NPage::TCells; using TIter = NPage::TIndex::TIter; using TDataPage = NPage::TDataPage; using TGroupId = NPage::TGroupId; - - struct TResult { - bool Ready; /* All required pages are already in memory */ - bool Overshot; /* Search may start outside of bounds */ - }; TCharge(IPages *env, const TPart &part, TTagsRef tags, bool includeHistory = false) : Env(env) @@ -49,131 +42,8 @@ namespace NTable { } } - static bool Range(IPages *env, const TCells key1, const TCells key2, - const TRun &run, const TKeyCellDefaults &keyDefaults, TTagsRef tags, - ui64 items, ui64 bytes, bool includeHistory = false) noexcept - { - if (run.size() == 1) { - auto pos = run.begin(); - TRowId row1 = pos->Slice.BeginRowId(); - TRowId row2 = pos->Slice.EndRowId() - 1; - return TCharge(env, *pos->Part, tags, includeHistory).Do(key1, key2, row1, row2, keyDefaults, items, bytes).Ready; - } - - bool ready = true; - auto pos = run.LowerBound(key1); - - if (pos == run.end()) - return true; - - bool fromStart = TSlice::CompareSearchKeyFirstKey(key1, pos->Slice, keyDefaults) <= 0; - - while (pos != run.end()) { - TRowId row1 = pos->Slice.BeginRowId(); - TRowId row2 = pos->Slice.EndRowId() - 1; - - const int cmp = TSlice::CompareLastKeySearchKey(pos->Slice, key2, keyDefaults); - - TArrayRef<const TCell> key1r; - if (!fromStart) { - key1r = key1; - } - TArrayRef<const TCell> key2r; - if (cmp > 0 /* slice->LastKey > key2 */) { - key2r = key2; - } - - auto r = TCharge(env, *pos->Part, tags, includeHistory).Do(key1r, key2r, row1, row2, keyDefaults, items, bytes); - ready &= r.Ready; - - if (cmp >= 0 /* slice->LastKey >= key2 */) { - if (r.Overshot && ++pos != run.end()) { - // Unfortunately key > key2 might be at the start of the next slice - TRowId firstRow = pos->Slice.BeginRowId(); - // Precharge the first row on the next slice - TCharge(env, *pos->Part, tags, includeHistory).Do(firstRow, firstRow, keyDefaults, items, bytes); - } - - break; - } - - // Will consume this slice before encountering key2 - fromStart = true; - ++pos; - } - - return ready; - } - - static bool RangeReverse(IPages *env, const TCells key1, const TCells key2, - const TRun &run, const TKeyCellDefaults &keyDefaults, TTagsRef tags, - ui64 items, ui64 bytes, bool includeHistory = false) noexcept - { - if (run.size() == 1) { - auto pos = run.begin(); - TRowId row1 = pos->Slice.EndRowId() - 1; - TRowId row2 = pos->Slice.BeginRowId(); - return TCharge(env, *pos->Part, tags, includeHistory).DoReverse(key1, key2, row1, row2, keyDefaults, items, bytes).Ready; - } - - bool ready = true; - auto pos = run.LowerBoundReverse(key1); - - if (pos == run.end()) - return true; - - bool fromEnd = TSlice::CompareLastKeySearchKey(pos->Slice, key1, keyDefaults) <= 0; - - for (;;) { - TRowId row1 = pos->Slice.EndRowId() - 1; - TRowId row2 = pos->Slice.BeginRowId(); - - // N.B. empty key2 is like -inf during reverse iteration - const int cmp = key2 ? TSlice::CompareSearchKeyFirstKey(key2, pos->Slice, keyDefaults) : -1; - - TArrayRef<const TCell> key1r; - if (!fromEnd) { - key1r = key1; - } - TArrayRef<const TCell> key2r; - if (cmp > 0 /* key2 > slice->FirstKey */) { - key2r = key2; - } - - auto r = TCharge(env, *pos->Part, tags, includeHistory).DoReverse(key1r, key2r, row1, row2, keyDefaults, items, bytes); - ready &= r.Ready; - - if (pos == run.begin()) { - break; - } - - if (cmp >= 0 /* key2 >= slice->FirstKey */) { - if (r.Overshot) { - --pos; - // Unfortunately key <= key2 might be at the end of the previous slice - TRowId lastRow = pos->Slice.EndRowId() - 1; - // Precharge the last row on the previous slice - TCharge(env, *pos->Part, tags, includeHistory).DoReverse(lastRow, lastRow, keyDefaults, items, bytes); - } - - break; - } - - // Will consume this slice before encountering key2 - fromEnd = true; - --pos; - } - - return ready; - } - - /** - * Precharges data for rows between row1 and row2 inclusive - * - * Important caveat: assumes iteration won't touch any row > row2 - */ bool Do(const TRowId row1, const TRowId row2, - const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept + const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override { auto index = Index.TryLoadRaw(); if (!index) { @@ -199,13 +69,8 @@ namespace NTable { return DoPrecharge(TCells{}, TCells{}, TIter{}, TIter{}, first, last, startRow, endRow, keyDefaults, itemsLimit, bytesLimit); } - /** - * Precharges data for rows between row1 and row2 inclusive in reverse - * - * Important caveat: assumes iteration won't touch any row > row2 - */ bool DoReverse(const TRowId row1, const TRowId row2, - const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept + const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override { auto index = Index.TryLoadRaw(); if (!index) { @@ -236,12 +101,9 @@ namespace NTable { return DoPrechargeReverse(TCells{}, TCells{}, TIter{}, TIter{}, first, last, startRow, endRow, keyDefaults, itemsLimit, bytesLimit); } - /** - * Precharges data for rows between max(key1, row1) and min(key2, row2) inclusive - */ TResult Do(const TCells key1, const TCells key2, const TRowId row1, const TRowId row2, const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, - ui64 bytesLimit) const noexcept + ui64 bytesLimit) const noexcept override { auto index = Index.TryLoadRaw(); if (!index) { @@ -307,12 +169,9 @@ namespace NTable { return { ready, overshot }; } - /** - * Precharges data for rows between min(key1, row1) and max(key2, row2) inclusive in reverse - */ TResult DoReverse(const TCells key1, const TCells key2, const TRowId row1, const TRowId row2, const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, - ui64 bytesLimit) const noexcept + ui64 bytesLimit) const noexcept override { auto index = Index.TryLoadRaw(); if (!index) { diff --git a/ydb/core/tablet_flat/flat_part_charge_btree_index.h b/ydb/core/tablet_flat/flat_part_charge_btree_index.h new file mode 100644 index 0000000000..6a10a57cab --- /dev/null +++ b/ydb/core/tablet_flat/flat_part_charge_btree_index.h @@ -0,0 +1,69 @@ +#pragma once + +#include "flat_table_part.h" +#include "flat_part_iface.h" +#include "flat_part_charge_iface.h" + +namespace NKikimr::NTable { + + class TChargeBTreeIndex : public ICharge { + public: + TChargeBTreeIndex(IPages *env, const TPart &part, TTagsRef tags, bool includeHistory = false) { + Y_UNUSED(env); + Y_UNUSED(part); + Y_UNUSED(tags); + Y_UNUSED(includeHistory); + } + + virtual bool Do(const TRowId row1, const TRowId row2, + const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override { + // TODO: implement + Y_UNUSED(row1); + Y_UNUSED(row2); + Y_UNUSED(keyDefaults); + Y_UNUSED(itemsLimit); + Y_UNUSED(bytesLimit); + return true; + } + + virtual bool DoReverse(const TRowId row1, const TRowId row2, + const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override { + // TODO: implement + Y_UNUSED(row1); + Y_UNUSED(row2); + Y_UNUSED(keyDefaults); + Y_UNUSED(itemsLimit); + Y_UNUSED(bytesLimit); + return true; + } + + virtual TResult Do(const TCells key1, const TCells key2, const TRowId row1, + const TRowId row2, const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, + ui64 bytesLimit) const noexcept override { + // TODO: implement + Y_UNUSED(key1); + Y_UNUSED(key2); + Y_UNUSED(row1); + Y_UNUSED(row2); + Y_UNUSED(keyDefaults); + Y_UNUSED(itemsLimit); + Y_UNUSED(bytesLimit); + return {true, false}; + } + + virtual TResult DoReverse(const TCells key1, const TCells key2, const TRowId row1, + const TRowId row2, const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, + ui64 bytesLimit) const noexcept override { + // TODO: implement + Y_UNUSED(key1); + Y_UNUSED(key2); + Y_UNUSED(row1); + Y_UNUSED(row2); + Y_UNUSED(keyDefaults); + Y_UNUSED(itemsLimit); + Y_UNUSED(bytesLimit); + return {true, false}; + } +}; + +} diff --git a/ydb/core/tablet_flat/flat_part_charge_create.cpp b/ydb/core/tablet_flat/flat_part_charge_create.cpp new file mode 100644 index 0000000000..30b9a52547 --- /dev/null +++ b/ydb/core/tablet_flat/flat_part_charge_create.cpp @@ -0,0 +1,15 @@ +#include "flat_part_charge_create.h" +#include "flat_part_charge.h" +#include "flat_part_charge_btree_index.h" + +namespace NKikimr::NTable { + +THolder<ICharge> CreateCharge(IPages *env, const TPart &part, TTagsRef tags, bool includeHistory) { + if (part.IndexPages.BTreeGroups) { + return MakeHolder<TChargeBTreeIndex>(env, part, tags, includeHistory); + } else { + return MakeHolder<TCharge>(env, part, tags, includeHistory); + } +} + +} diff --git a/ydb/core/tablet_flat/flat_part_charge_create.h b/ydb/core/tablet_flat/flat_part_charge_create.h new file mode 100644 index 0000000000..40249e631f --- /dev/null +++ b/ydb/core/tablet_flat/flat_part_charge_create.h @@ -0,0 +1,10 @@ +#pragma once + +#include "flat_part_charge_iface.h" +#include "flat_part_iface.h" + +namespace NKikimr::NTable { + +THolder<ICharge> CreateCharge(IPages *env, const TPart &part, TTagsRef tags, bool includeHistory = false); + +} diff --git a/ydb/core/tablet_flat/flat_part_charge_iface.h b/ydb/core/tablet_flat/flat_part_charge_iface.h new file mode 100644 index 0000000000..698e927262 --- /dev/null +++ b/ydb/core/tablet_flat/flat_part_charge_iface.h @@ -0,0 +1,48 @@ +#pragma once + +#include "flat_page_base.h" + +namespace NKikimr::NTable { + + struct ICharge { + using TCells = NPage::TCells; + + struct TResult { + bool Ready; /* All required pages are already in memory */ + bool Overshot; /* Search may start outside of bounds */ + }; + + /** + * Precharges data for rows between row1 and row2 inclusive + * + * Important caveat: assumes iteration won't touch any row > row2 + */ + virtual bool Do(const TRowId row1, const TRowId row2, + const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept = 0; + + /** + * Precharges data for rows between row1 and row2 inclusive in reverse + * + * Important caveat: assumes iteration won't touch any row > row2 + */ + virtual bool DoReverse(const TRowId row1, const TRowId row2, + const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept = 0; + + /** + * Precharges data for rows between max(key1, row1) and min(key2, row2) inclusive + */ + virtual TResult Do(const TCells key1, const TCells key2, const TRowId row1, + const TRowId row2, const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, + ui64 bytesLimit) const noexcept = 0; + + /** + * Precharges data for rows between min(key1, row1) and max(key2, row2) inclusive in reverse + */ + virtual TResult DoReverse(const TCells key1, const TCells key2, const TRowId row1, + const TRowId row2, const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, + ui64 bytesLimit) const noexcept = 0; + + virtual ~ICharge() = default; +}; + +} diff --git a/ydb/core/tablet_flat/flat_part_charge_range.cpp b/ydb/core/tablet_flat/flat_part_charge_range.cpp new file mode 100644 index 0000000000..3ba7325fca --- /dev/null +++ b/ydb/core/tablet_flat/flat_part_charge_range.cpp @@ -0,0 +1,124 @@ +#include "flat_part_charge_range.h" +#include "flat_part_charge_create.h" + +namespace NKikimr::NTable { + +bool ChargeRange(IPages *env, const TCells key1, const TCells key2, + const TRun &run, const TKeyCellDefaults &keyDefaults, TTagsRef tags, + ui64 items, ui64 bytes, bool includeHistory) noexcept +{ + if (run.size() == 1) { + auto pos = run.begin(); + TRowId row1 = pos->Slice.BeginRowId(); + TRowId row2 = pos->Slice.EndRowId() - 1; + return CreateCharge(env, *pos->Part, tags, includeHistory)->Do(key1, key2, row1, row2, keyDefaults, items, bytes).Ready; + } + + bool ready = true; + auto pos = run.LowerBound(key1); + + if (pos == run.end()) + return true; + + bool fromStart = TSlice::CompareSearchKeyFirstKey(key1, pos->Slice, keyDefaults) <= 0; + + while (pos != run.end()) { + TRowId row1 = pos->Slice.BeginRowId(); + TRowId row2 = pos->Slice.EndRowId() - 1; + + const int cmp = TSlice::CompareLastKeySearchKey(pos->Slice, key2, keyDefaults); + + TArrayRef<const TCell> key1r; + if (!fromStart) { + key1r = key1; + } + TArrayRef<const TCell> key2r; + if (cmp > 0 /* slice->LastKey > key2 */) { + key2r = key2; + } + + auto r = CreateCharge(env, *pos->Part, tags, includeHistory)->Do(key1r, key2r, row1, row2, keyDefaults, items, bytes); + ready &= r.Ready; + + if (cmp >= 0 /* slice->LastKey >= key2 */) { + if (r.Overshot && ++pos != run.end()) { + // Unfortunately key > key2 might be at the start of the next slice + TRowId firstRow = pos->Slice.BeginRowId(); + // Precharge the first row on the next slice + CreateCharge(env, *pos->Part, tags, includeHistory)->Do(firstRow, firstRow, keyDefaults, items, bytes); + } + + break; + } + + // Will consume this slice before encountering key2 + fromStart = true; + ++pos; + } + + return ready; +} + +bool ChargeRangeReverse(IPages *env, const TCells key1, const TCells key2, + const TRun &run, const TKeyCellDefaults &keyDefaults, TTagsRef tags, + ui64 items, ui64 bytes, bool includeHistory) noexcept +{ + if (run.size() == 1) { + auto pos = run.begin(); + TRowId row1 = pos->Slice.EndRowId() - 1; + TRowId row2 = pos->Slice.BeginRowId(); + return CreateCharge(env, *pos->Part, tags, includeHistory)->DoReverse(key1, key2, row1, row2, keyDefaults, items, bytes).Ready; + } + + bool ready = true; + auto pos = run.LowerBoundReverse(key1); + + if (pos == run.end()) + return true; + + bool fromEnd = TSlice::CompareLastKeySearchKey(pos->Slice, key1, keyDefaults) <= 0; + + for (;;) { + TRowId row1 = pos->Slice.EndRowId() - 1; + TRowId row2 = pos->Slice.BeginRowId(); + + // N.B. empty key2 is like -inf during reverse iteration + const int cmp = key2 ? TSlice::CompareSearchKeyFirstKey(key2, pos->Slice, keyDefaults) : -1; + + TArrayRef<const TCell> key1r; + if (!fromEnd) { + key1r = key1; + } + TArrayRef<const TCell> key2r; + if (cmp > 0 /* key2 > slice->FirstKey */) { + key2r = key2; + } + + auto r = CreateCharge(env, *pos->Part, tags, includeHistory)->DoReverse(key1r, key2r, row1, row2, keyDefaults, items, bytes); + ready &= r.Ready; + + if (pos == run.begin()) { + break; + } + + if (cmp >= 0 /* key2 >= slice->FirstKey */) { + if (r.Overshot) { + --pos; + // Unfortunately key <= key2 might be at the end of the previous slice + TRowId lastRow = pos->Slice.EndRowId() - 1; + // Precharge the last row on the previous slice + CreateCharge(env, *pos->Part, tags, includeHistory)->DoReverse(lastRow, lastRow, keyDefaults, items, bytes); + } + + break; + } + + // Will consume this slice before encountering key2 + fromEnd = true; + --pos; + } + + return ready; +} + +} diff --git a/ydb/core/tablet_flat/flat_part_charge_range.h b/ydb/core/tablet_flat/flat_part_charge_range.h new file mode 100644 index 0000000000..88b921fc00 --- /dev/null +++ b/ydb/core/tablet_flat/flat_part_charge_range.h @@ -0,0 +1,20 @@ +#pragma once + +#include "flat_part_iface.h" +#include "flat_part_slice.h" + +namespace NKikimr::NTable { + +namespace { + using TCells = NPage::TCells; +} + +bool ChargeRange(IPages *env, const TCells key1, const TCells key2, + const TRun &run, const TKeyCellDefaults &keyDefaults, TTagsRef tags, + ui64 items, ui64 bytes, bool includeHistory = false) noexcept; + +bool ChargeRangeReverse(IPages *env, const TCells key1, const TCells key2, + const TRun &run, const TKeyCellDefaults &keyDefaults, TTagsRef tags, + ui64 items, ui64 bytes, bool includeHistory = false) noexcept; + +} diff --git a/ydb/core/tablet_flat/flat_table.cpp b/ydb/core/tablet_flat/flat_table.cpp index 66fcbecea3..e3feb7e3ea 100644 --- a/ydb/core/tablet_flat/flat_table.cpp +++ b/ydb/core/tablet_flat/flat_table.cpp @@ -4,8 +4,8 @@ #include "flat_bloom_hash.h" #include "flat_part_iter_multi.h" #include "flat_part_laid.h" -#include "flat_part_shrink.h" -#include "flat_part_charge.h" +#include "flat_part_charge_range.h" +#include "flat_part_charge_create.h" #include "flat_part_dump.h" #include "flat_range_cache.h" #include "flat_util_misc.h" @@ -789,8 +789,8 @@ EReady TTable::Precharge(TRawVals minKey_, TRawVals maxKey_, TTagsRef tags, { TRowId row1 = pos->Slice.BeginRowId(); TRowId row2 = pos->Slice.EndRowId() - 1; - ready &= TCharge(env, *pos->Part, tags, includeHistory) - .Do(key, key, row1, row2, *Scheme->Keys, items, bytes) + ready &= CreateCharge(env, *pos->Part, tags, includeHistory) + ->Do(key, key, row1, row2, *Scheme->Keys, items, bytes) .Ready; ++stats.Sieved; } else { @@ -805,10 +805,10 @@ EReady TTable::Precharge(TRawVals minKey_, TRawVals maxKey_, TTagsRef tags, for (const auto& run : GetLevels()) { switch (direction) { case EDirection::Forward: - ready &= TCharge::Range(env, minKey, maxKey, run, *Scheme->Keys, tags, items, bytes, includeHistory); + ready &= ChargeRange(env, minKey, maxKey, run, *Scheme->Keys, tags, items, bytes, includeHistory); break; case EDirection::Reverse: - ready &= TCharge::RangeReverse(env, maxKey, minKey, run, *Scheme->Keys, tags, items, bytes, includeHistory); + ready &= ChargeRangeReverse(env, maxKey, minKey, run, *Scheme->Keys, tags, items, bytes, includeHistory); break; } } diff --git a/ydb/core/tablet_flat/ut/ut_charge.cpp b/ydb/core/tablet_flat/ut/ut_charge.cpp index aea20ce174..195577ffc7 100644 --- a/ydb/core/tablet_flat/ut/ut_charge.cpp +++ b/ydb/core/tablet_flat/ut/ut_charge.cpp @@ -1,5 +1,6 @@ #include <ydb/core/tablet_flat/flat_row_celled.h> -#include <ydb/core/tablet_flat/flat_part_charge.h> +#include <ydb/core/tablet_flat/flat_part_charge_range.h> +#include <ydb/core/tablet_flat/flat_part_charge_create.h> #include <ydb/core/tablet_flat/test/libs/rows/cook.h> #include <ydb/core/tablet_flat/test/libs/rows/tool.h> #include <ydb/core/tablet_flat/test/libs/table/model/large.h> @@ -196,10 +197,10 @@ namespace { } bool ready = !reverse - ? TCharge::Range(&env, from, to, run, keyDefaults, tags, items, Max<ui64>(), true) - : TCharge::RangeReverse(&env, from, to, run, keyDefaults, tags, items, Max<ui64>(), true); + ? ChargeRange(&env, from, to, run, keyDefaults, tags, items, Max<ui64>(), true) + : ChargeRangeReverse(&env, from, to, run, keyDefaults, tags, items, Max<ui64>(), true); - UNIT_ASSERT_VALUES_EQUAL_C(!fail || env.ToLoad.empty(), ready, AssertMesage(fail)); + UNIT_ASSERT_VALUES_EQUAL_C(!fail || env.ToLoad.empty(), ready, AssertMessage(fail)); CheckPrecharged(env.Touched, shouldPrecharge, sticky, flags); } @@ -226,8 +227,8 @@ namespace { UNIT_ASSERT_VALUES_EQUAL_C( !fail, - TCharge(&env, *run.begin()->Part, tags, false).Do(row1, row2, keyDefaults, items, Max<ui64>()), - AssertMesage(fail)); + CreateCharge(&env, *run.begin()->Part, tags, false)->Do(row1, row2, keyDefaults, items, Max<ui64>()), + AssertMessage(fail)); CheckPrecharged(env.Touched, shouldPrecharge, sticky, fail ? TPageIdFlags::IfFail : TPageIdFlags::IfNoFail); } @@ -361,7 +362,7 @@ namespace { } } - std::string AssertMesage(bool fail) const { + std::string AssertMessage(bool fail) const { return "Seq: " + std::to_string(CurrentStep()) + " Fail: " + (fail ? "Yes" : "No"); diff --git a/ydb/core/tablet_flat/ut/ut_part.cpp b/ydb/core/tablet_flat/ut/ut_part.cpp index 3de1b3e3d9..9be2c73329 100644 --- a/ydb/core/tablet_flat/ut/ut_part.cpp +++ b/ydb/core/tablet_flat/ut/ut_part.cpp @@ -1,5 +1,5 @@ -#include "flat_part_charge.h" #include <ydb/core/tablet_flat/flat_part_dump.h> +#include "ydb/core/tablet_flat/flat_part_charge_range.h" #include <ydb/core/tablet_flat/test/libs/rows/cook.h> #include <ydb/core/tablet_flat/test/libs/rows/layout.h> #include <ydb/core/tablet_flat/test/libs/table/model/large.h> @@ -97,9 +97,9 @@ namespace { } if constexpr (Direction == EDirection::Forward) { - TCharge::Range(env, from, to, run, *keyDefaults, tags, 0, 0, true); + ChargeRange(env, from, to, run, *keyDefaults, tags, 0, 0, true); } else { - TCharge::RangeReverse(env, from, to, run, *keyDefaults, tags, 0, 0, true); + ChargeRangeReverse(env, from, to, run, *keyDefaults, tags, 0, 0, true); } env->PrechargePhase = false; diff --git a/ydb/core/tablet_flat/ya.make b/ydb/core/tablet_flat/ya.make index bb186aa53e..8a6604935e 100644 --- a/ydb/core/tablet_flat/ya.make +++ b/ydb/core/tablet_flat/ya.make @@ -41,6 +41,8 @@ SRCS( flat_sausagecache.cpp flat_sausagecache.h flat_sausage_meta.cpp + flat_part_charge_create.cpp + flat_part_charge_range.cpp flat_page_label.cpp flat_part_dump.cpp flat_part_iter_multi.cpp |