aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkungasc <kungasc@ydb.tech>2023-12-14 12:56:56 +0300
committerkungasc <kungasc@ydb.tech>2023-12-14 14:54:47 +0300
commite7f64cc383ca087378ff3edb8b833360561445a7 (patch)
tree62271dc2eefe8fa395ac4808afc5ce6999eb7784
parent897ada7941ae63332514c27e676d2f70edc3c13b (diff)
downloadydb-e7f64cc383ca087378ff3edb8b833360561445a7.tar.gz
KIKIMR-19521 BTreeIndex Charge Interface
-rw-r--r--ydb/core/tablet_flat/CMakeLists.darwin-arm64.txt2
-rw-r--r--ydb/core/tablet_flat/CMakeLists.darwin-x86_64.txt2
-rw-r--r--ydb/core/tablet_flat/CMakeLists.linux-aarch64.txt2
-rw-r--r--ydb/core/tablet_flat/CMakeLists.linux-x86_64.txt2
-rw-r--r--ydb/core/tablet_flat/CMakeLists.windows-x86_64.txt2
-rw-r--r--ydb/core/tablet_flat/benchmark/b_charge.cpp8
-rw-r--r--ydb/core/tablet_flat/flat_part_charge.h153
-rw-r--r--ydb/core/tablet_flat/flat_part_charge_btree_index.h69
-rw-r--r--ydb/core/tablet_flat/flat_part_charge_create.cpp15
-rw-r--r--ydb/core/tablet_flat/flat_part_charge_create.h10
-rw-r--r--ydb/core/tablet_flat/flat_part_charge_iface.h48
-rw-r--r--ydb/core/tablet_flat/flat_part_charge_range.cpp124
-rw-r--r--ydb/core/tablet_flat/flat_part_charge_range.h20
-rw-r--r--ydb/core/tablet_flat/flat_table.cpp12
-rw-r--r--ydb/core/tablet_flat/ut/ut_charge.cpp15
-rw-r--r--ydb/core/tablet_flat/ut/ut_part.cpp6
-rw-r--r--ydb/core/tablet_flat/ya.make2
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