Skip to content

Commit 78d7a3b

Browse files
committed
reverse
1 parent eb9b94c commit 78d7a3b

File tree

2 files changed

+79
-19
lines changed

2 files changed

+79
-19
lines changed

ydb/core/tablet_flat/flat_part_charge_btree_index.h

+68-12
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ class TChargeBTreeIndex : public ICharge {
4848
ready &= TryLoadNode(meta.PageId, nextLevel);
4949
} else {
5050
for (ui32 i : xrange<ui32>(level.size())) {
51-
TRecIdx begin = 0, end = level[i].GetChildrenCount();
51+
TRecIdx from = 0, to = level[i].GetKeysCount();
5252
if (i == 0) {
53-
begin = level[i].Seek(row1);
53+
from = level[i].Seek(row1);
5454
}
5555
if (i + 1 == level.size() && row2 < meta.RowsCount) {
56-
end = level[i].Seek(row2) + 1;
56+
to = level[i].Seek(row2);
5757
}
58-
for (TRecIdx j : xrange(begin, end)) {
58+
for (TRecIdx j : xrange(from, to + 1)) {
5959
ready &= TryLoadNode(level[i].GetShortChild(j).PageId, nextLevel);
6060
}
6161
}
@@ -74,14 +74,14 @@ class TChargeBTreeIndex : public ICharge {
7474
ready &= HasDataPage(meta.PageId, { });
7575
} else {
7676
for (ui32 i : xrange<ui32>(level.size())) {
77-
TRecIdx begin = 0, end = level[i].GetChildrenCount();
77+
TRecIdx from = 0, to = level[i].GetKeysCount();
7878
if (i == 0) {
79-
begin = level[i].Seek(row1);
79+
from = level[i].Seek(row1);
8080
}
8181
if (i + 1 == level.size() && row2 < meta.RowsCount) {
82-
end = level[i].Seek(row2) + 1;
82+
to = level[i].Seek(row2);
8383
}
84-
for (TRecIdx j : xrange(begin, end)) {
84+
for (TRecIdx j : xrange(from, to + 1)) {
8585
ready &= HasDataPage(level[i].GetShortChild(j).PageId, { });
8686
}
8787
}
@@ -93,15 +93,71 @@ class TChargeBTreeIndex : public ICharge {
9393

9494
TResult DoReverse(const TCells key1, const TCells key2, TRowId row1, TRowId row2,
9595
const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override {
96-
// TODO: implement
96+
bool ready = true;
97+
9798
Y_UNUSED(key1);
9899
Y_UNUSED(key2);
99-
Y_UNUSED(row1);
100-
Y_UNUSED(row2);
101100
Y_UNUSED(keyDefaults);
102101
Y_UNUSED(itemsLimit);
103102
Y_UNUSED(bytesLimit);
104-
return {true, false};
103+
104+
auto& meta = Part->IndexPages.BTreeGroups[0];
105+
106+
if (Y_UNLIKELY(row1 >= meta.RowsCount)) {
107+
row1 = meta.RowsCount - 1; // start from the last row
108+
}
109+
if (Y_UNLIKELY(row1 < row2)) {
110+
row2 = row1; // will not go further than row1
111+
}
112+
113+
// level contains nodes in reverse order
114+
TVector<TBtreeIndexNode> level, nextLevel(Reserve(2));
115+
for (ui32 high = 0; high < meta.LevelsCount && ready; high++) {
116+
if (high == 0) {
117+
ready &= TryLoadNode(meta.PageId, nextLevel);
118+
} else {
119+
for (ui32 i : xrange<ui32>(level.size())) {
120+
TRecIdx from = level[i].GetKeysCount(), to = 0;
121+
if (i == 0) {
122+
from = level[i].Seek(row1);
123+
}
124+
if (i + 1 == level.size() && row2 < meta.RowsCount) {
125+
to = level[i].Seek(row2);
126+
}
127+
for (TRecIdx j = from + 1; j > to; j--) {
128+
ready &= TryLoadNode(level[i].GetShortChild(j - 1).PageId, nextLevel);
129+
}
130+
}
131+
}
132+
133+
level.swap(nextLevel);
134+
nextLevel.clear();
135+
}
136+
137+
if (!ready) {
138+
// some index pages are missing, do not continue
139+
return {false, false};
140+
}
141+
142+
if (meta.LevelsCount == 0) {
143+
ready &= HasDataPage(meta.PageId, { });
144+
} else {
145+
for (ui32 i : xrange<ui32>(level.size())) {
146+
TRecIdx from = level[i].GetKeysCount(), to = 0;
147+
if (i == 0) {
148+
from = level[i].Seek(row1);
149+
}
150+
if (i + 1 == level.size() && row2 < meta.RowsCount) {
151+
to = level[i].Seek(row2);
152+
}
153+
for (TRecIdx j = from + 1; j > to; j--) {
154+
ready &= HasDataPage(level[i].GetShortChild(j - 1).PageId, { });
155+
}
156+
}
157+
}
158+
159+
// TODO: overshot for keys search
160+
return {ready, false};
105161
}
106162

107163
private:

ydb/core/tablet_flat/ut/ut_btree_index.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -1161,9 +1161,12 @@ Y_UNIT_TEST_SUITE(TChargeBTreeIndex) {
11611161
}
11621162

11631163
void DoChargeRowId(ICharge& charge, IPages& env, const TRowId row1, const TRowId row2, ui64 itemsLimit, ui64 bytesLimit,
1164-
const TKeyCellDefaults &keyDefaults, const TString& message, ui32 failsAllowed = 10) {
1164+
bool reverse, const TKeyCellDefaults &keyDefaults, const TString& message, ui32 failsAllowed = 10) {
11651165
while (true) {
1166-
if (charge.Do(row1, row2, keyDefaults, itemsLimit, bytesLimit)) {
1166+
bool ready = reverse
1167+
? charge.DoReverse(row1, row2, keyDefaults, itemsLimit, bytesLimit)
1168+
: charge.Do(row1, row2, keyDefaults, itemsLimit, bytesLimit);
1169+
if (ready) {
11671170
return;
11681171
}
11691172
TTouchEnv::LoadTouched(env, false);
@@ -1172,16 +1175,16 @@ Y_UNIT_TEST_SUITE(TChargeBTreeIndex) {
11721175
Y_UNREACHABLE();
11731176
}
11741177

1175-
void CheckChargeRowId(const TPartStore& part, TTagsRef tags, const TKeyCellDefaults *keyDefaults) {
1178+
void CheckChargeRowId(const TPartStore& part, TTagsRef tags, const TKeyCellDefaults *keyDefaults, bool reverse) {
11761179
for (TRowId rowId1 : xrange(part.Stat.Rows + 1)) {
11771180
for (TRowId rowId2 : xrange(part.Stat.Rows + 1)) {
11781181
TTouchEnv bTreeEnv, flatEnv;
11791182
TChargeBTreeIndex bTree(&bTreeEnv, part, tags, true);
11801183
TCharge flat(&flatEnv, part, tags, true);
11811184

1182-
TString message = TStringBuilder() << "ChargeRowId " << rowId1 << " " << rowId2;
1183-
DoChargeRowId(bTree, bTreeEnv, rowId1, rowId2, 0, 0, *keyDefaults, message);
1184-
DoChargeRowId(flat, flatEnv, rowId1, rowId2, 0, 0, *keyDefaults, message);
1185+
TString message = TStringBuilder() << (reverse ? "ChargeRowIdReverse " : "ChargeRowId ") << rowId1 << " " << rowId2;
1186+
DoChargeRowId(bTree, bTreeEnv, rowId1, rowId2, 0, 0, reverse, *keyDefaults, message);
1187+
DoChargeRowId(flat, flatEnv, rowId1, rowId2, 0, 0, reverse, *keyDefaults, message);
11851188
AssertEqual(part, bTreeEnv, flatEnv, message);
11861189
}
11871190
}
@@ -1215,7 +1218,8 @@ Y_UNIT_TEST_SUITE(TChargeBTreeIndex) {
12151218
tags.push_back(c.Tag);
12161219
}
12171220

1218-
CheckChargeRowId(part, tags, eggs.Scheme->Keys.Get());
1221+
CheckChargeRowId(part, tags, eggs.Scheme->Keys.Get(), false);
1222+
CheckChargeRowId(part, tags, eggs.Scheme->Keys.Get(), true);
12191223
}
12201224

12211225
Y_UNIT_TEST(NoNodes) {

0 commit comments

Comments
 (0)