Skip to content

Commit cc1fc5b

Browse files
authored
Merge f5eda6d into 11534d6
2 parents 11534d6 + f5eda6d commit cc1fc5b

File tree

3 files changed

+184
-135
lines changed

3 files changed

+184
-135
lines changed

ydb/core/tablet_flat/flat_page_btree_index.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,13 @@ namespace NKikimr::NTable::NPage {
101101

102102
auto operator<=>(const TChild&) const = default;
103103

104-
TString ToString() const noexcept
105-
{
104+
TString ToString() const noexcept {
106105
return TStringBuilder() << "PageId: " << PageId << " RowCount: " << RowCount << " DataSize: " << DataSize << " ErasedRowCount: " << ErasedRowCount;
107106
}
107+
108+
TRowId GetNonErasedRowCount() const noexcept {
109+
return RowCount - ErasedRowCount;
110+
}
108111
} Y_PACKED;
109112

110113
static_assert(sizeof(TChild) == 28, "Invalid TBtreeIndexNode TChild size");

ydb/core/tablet_flat/flat_part_charge_btree_index.h

+88-64
Original file line numberDiff line numberDiff line change
@@ -13,22 +13,27 @@ class TChargeBTreeIndex : public ICharge {
1313
using TGroupId = NPage::TGroupId;
1414
using TChild = TBtreeIndexNode::TChild;
1515

16-
// TODO: store PageId only instead of TChild?
17-
struct TChildState : TChild {
16+
// TODO: store PageId only?
17+
struct TChildState {
18+
TPageId PageId;
1819
TRowId BeginRowId;
1920
TRowId EndRowId;
21+
TRowId RowCount;
22+
ui64 DataSize;
2023

21-
TChildState(TChild meta, TRowId beginRowId, TRowId endRowId)
22-
: TChild(meta)
24+
TChildState(TPageId pageId, TRowId beginRowId, TRowId endRowId, TRowId rowCount, ui64 dataSize)
25+
: PageId(pageId)
2326
, BeginRowId(beginRowId)
2427
, EndRowId(endRowId)
28+
, RowCount(rowCount)
29+
, DataSize(dataSize)
2530
{
2631
}
2732
};
2833

2934
struct TNodeState : TChildState, TBtreeIndexNode {
30-
TNodeState(TSharedData data, TChild meta, TRowId beginRowId, TRowId endRowId)
31-
: TChildState(meta, beginRowId, endRowId)
35+
TNodeState(TSharedData data, TPageId pageId, TRowId beginRowId, TRowId endRowId, TRowId rowCount, ui64 dataSize)
36+
: TChildState(pageId, beginRowId, endRowId, rowCount, dataSize)
3237
, TBtreeIndexNode(data)
3338
{
3439
}
@@ -62,15 +67,15 @@ class TChargeBTreeIndex : public ICharge {
6267

6368
public:
6469
TResult Do(TCells key1, TCells key2, TRowId beginRowId, TRowId endRowId,
65-
const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override {
70+
const TKeyCellDefaults &keyDefaults, ui64 rowCountLimit, ui64 dataSizeLimit) const noexcept override {
6671
endRowId++; // current interface accepts inclusive row2 bound
6772
Y_ABORT_UNLESS(beginRowId < endRowId);
6873

69-
bool ready = true;
74+
bool ready = true, overshot = true;
7075
bool chargeGroups = bool(Groups); // false value means that beginRowId, endRowId are invalid and shouldn't be used
76+
ui64 rowCount = 0, dataSize = 0;
7177

72-
Y_UNUSED(itemsLimit);
73-
Y_UNUSED(bytesLimit);
78+
Y_UNUSED(rowCountLimit, dataSizeLimit, rowCount, dataSize);
7479

7580
const auto& meta = Part->IndexPages.BTreeGroups[0];
7681
Y_ABORT_UNLESS(endRowId <= meta.RowCount);
@@ -103,16 +108,32 @@ class TChargeBTreeIndex : public ICharge {
103108
}
104109
for (TRecIdx pos : xrange(from, to)) {
105110
auto child = node.GetChild(pos);
106-
TRowId beginRowId = pos ? node.GetChild(pos - 1).RowCount : node.BeginRowId;
107-
TRowId endRowId = child.RowCount;
108-
ready &= tryHandleChild(TChildState(child, beginRowId, endRowId));
111+
if (pos) {
112+
auto prev = node.GetChild(pos - 1);
113+
ready &= tryHandleChild(TChildState(child.PageId, prev.RowCount, child.RowCount,
114+
child.GetNonErasedRowCount() - prev.GetNonErasedRowCount(),
115+
child.DataSize - prev.DataSize));
116+
} else {
117+
ready &= tryHandleChild(TChildState(child.PageId, 0, child.RowCount,
118+
child.GetNonErasedRowCount(),
119+
child.DataSize));
120+
}
109121
}
110122
}
111123
};
112124

125+
const auto skipUnloadedRows = [&](const TChildState& child) {
126+
if (child.PageId == key1PageId) {
127+
beginRowId = Max(beginRowId, child.EndRowId);
128+
}
129+
if (child.PageId == key2PageId) {
130+
endRowId = Min(endRowId, child.BeginRowId);
131+
}
132+
};
133+
113134
const auto tryHandleNode = [&](TChildState child) -> bool {
114135
if (child.PageId == key1PageId || child.PageId == key2PageId) {
115-
if (TryLoadNode(child, nextLevel)) { // update beginRowId, endRowId
136+
if (TryLoadNode(child, nextLevel)) {
116137
const auto& node = nextLevel.back();
117138
if (child.PageId == key1PageId) {
118139
TRecIdx pos = node.Seek(ESeek::Lower, key1, Scheme.Groups[0].ColsKeyIdx, &keyDefaults);
@@ -130,13 +151,8 @@ class TChargeBTreeIndex : public ICharge {
130151
}
131152
}
132153
return true;
133-
} else { // skip unloaded page rows
134-
if (child.PageId == key1PageId) {
135-
beginRowId = Max(beginRowId, child.EndRowId);
136-
}
137-
if (child.PageId == key2PageId) {
138-
endRowId = Min(endRowId, child.BeginRowId);
139-
}
154+
} else {
155+
skipUnloadedRows(child);
140156
return false;
141157
}
142158
} else {
@@ -147,7 +163,7 @@ class TChargeBTreeIndex : public ICharge {
147163
const auto tryHandleDataPage = [&](TChildState child) -> bool {
148164
if (chargeGroups && (child.PageId == key1PageId || child.PageId == key2PageId)) {
149165
const auto page = TryGetDataPage(child.PageId, { });
150-
if (page) { // update beginRowId, endRowId
166+
if (page) {
151167
auto data = NPage::TDataPage(page);
152168
if (child.PageId == key1PageId) {
153169
TRowId key1RowId = data.BaseRow() + data.LookupKey(key1, Scheme.Groups[0], ESeek::Lower, &keyDefaults).Off();
@@ -158,13 +174,8 @@ class TChargeBTreeIndex : public ICharge {
158174
endRowId = Min(endRowId, key2RowId);
159175
}
160176
return true;
161-
} else { // skip unloaded page rows
162-
if (child.PageId == key1PageId) {
163-
beginRowId = Max(beginRowId, child.EndRowId);
164-
}
165-
if (child.PageId == key2PageId) {
166-
endRowId = Min(endRowId, child.BeginRowId);
167-
}
177+
} else {
178+
skipUnloadedRows(child);
168179
return false;
169180
}
170181
} else {
@@ -174,7 +185,7 @@ class TChargeBTreeIndex : public ICharge {
174185

175186
for (ui32 height = 0; height < meta.LevelCount && ready; height++) {
176187
if (height == 0) {
177-
ready &= tryHandleNode(TChildState(meta, 0, meta.RowCount));
188+
ready &= tryHandleNode(TChildState(meta.PageId, 0, meta.RowCount, meta.GetNonErasedRowCount(), meta.DataSize));
178189
} else {
179190
iterateLevel(tryHandleNode);
180191
}
@@ -189,10 +200,10 @@ class TChargeBTreeIndex : public ICharge {
189200

190201
// flat index doesn't treat key placement within data page, so let's do the same
191202
// TODO: remove it later
192-
bool overshot = endRowId == sliceEndRowId;
203+
overshot &= endRowId == sliceEndRowId;
193204

194205
if (meta.LevelCount == 0) {
195-
ready &= tryHandleDataPage(TChildState(meta, 0, meta.RowCount));
206+
ready &= tryHandleDataPage(TChildState(meta.PageId, 0, meta.RowCount, meta.GetNonErasedRowCount(), meta.DataSize));
196207
} else {
197208
iterateLevel(tryHandleDataPage);
198209
}
@@ -203,15 +214,15 @@ class TChargeBTreeIndex : public ICharge {
203214
}
204215

205216
TResult DoReverse(TCells key1, TCells key2, TRowId endRowId, TRowId beginRowId,
206-
const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override {
217+
const TKeyCellDefaults &keyDefaults, ui64 rowCountLimit, ui64 dataSizeLimit) const noexcept override {
207218
endRowId++; // current interface accepts inclusive row1 bound
208219
Y_ABORT_UNLESS(beginRowId < endRowId);
209220

210-
bool ready = true;
221+
bool ready = true, overshot = true;
211222
bool chargeGroups = bool(Groups); // false value means that beginRowId, endRowId are invalid and shouldn't be used
223+
ui64 rowCount = 0, dataSize = 0;
212224

213-
Y_UNUSED(itemsLimit);
214-
Y_UNUSED(bytesLimit);
225+
Y_UNUSED(rowCountLimit, dataSizeLimit, rowCount, dataSize);
215226

216227
const auto& meta = Part->IndexPages.BTreeGroups[0];
217228
Y_ABORT_UNLESS(endRowId <= meta.RowCount);
@@ -244,16 +255,32 @@ class TChargeBTreeIndex : public ICharge {
244255
}
245256
for (TRecIdx pos : xrange(from, to)) {
246257
auto child = node.GetChild(pos);
247-
TRowId beginRowId = pos ? node.GetChild(pos - 1).RowCount : node.BeginRowId;
248-
TRowId endRowId = child.RowCount;
249-
ready &= tryHandleChild(TChildState(child, beginRowId, endRowId));
258+
if (pos) {
259+
auto prev = node.GetChild(pos - 1);
260+
ready &= tryHandleChild(TChildState(child.PageId, prev.RowCount, child.RowCount,
261+
child.GetNonErasedRowCount() - prev.GetNonErasedRowCount(),
262+
child.DataSize - prev.DataSize));
263+
} else {
264+
ready &= tryHandleChild(TChildState(child.PageId, 0, child.RowCount,
265+
child.GetNonErasedRowCount(),
266+
child.DataSize));
267+
}
250268
}
251269
}
252270
};
253271

272+
const auto skipUnloadedRows = [&](TChildState child) {
273+
if (child.PageId == key1PageId) {
274+
endRowId = Min(endRowId, child.BeginRowId);
275+
}
276+
if (child.PageId == key2PageId) {
277+
beginRowId = Max(beginRowId, child.EndRowId);
278+
}
279+
};
280+
254281
const auto tryHandleNode = [&](TChildState child) -> bool {
255282
if (child.PageId == key1PageId || child.PageId == key2PageId) {
256-
if (TryLoadNode(child, nextLevel)) { // update beginRowId, endRowId
283+
if (TryLoadNode(child, nextLevel)) {
257284
const auto& node = nextLevel.back();
258285
if (child.PageId == key1PageId) {
259286
TRecIdx pos = node.SeekReverse(ESeek::Lower, key1, Scheme.Groups[0].ColsKeyIdx, &keyDefaults);
@@ -271,13 +298,8 @@ class TChargeBTreeIndex : public ICharge {
271298
}
272299
}
273300
return true;
274-
} else { // skip unloaded page rows
275-
if (child.PageId == key1PageId) {
276-
endRowId = Min(endRowId, child.BeginRowId);
277-
}
278-
if (child.PageId == key2PageId) {
279-
beginRowId = Max(beginRowId, child.EndRowId);
280-
}
301+
} else {
302+
skipUnloadedRows(child);
281303
return false;
282304
}
283305
} else {
@@ -288,7 +310,7 @@ class TChargeBTreeIndex : public ICharge {
288310
const auto tryHandleDataPage = [&](TChildState child) -> bool {
289311
if (chargeGroups && (child.PageId == key1PageId || child.PageId == key2PageId)) {
290312
const auto page = TryGetDataPage(child.PageId, { });
291-
if (page) { // update beginRowId, endRowId
313+
if (page) {
292314
auto data = NPage::TDataPage(page);
293315
if (child.PageId == key1PageId) {
294316
auto iter = data.LookupKeyReverse(key1, Scheme.Groups[0], ESeek::Lower, &keyDefaults);
@@ -309,13 +331,8 @@ class TChargeBTreeIndex : public ICharge {
309331
}
310332
}
311333
return true;
312-
} else { // skip unloaded page rows
313-
if (child.PageId == key1PageId) {
314-
endRowId = Min(endRowId, child.BeginRowId);
315-
}
316-
if (child.PageId == key2PageId) {
317-
beginRowId = Max(beginRowId, child.EndRowId);
318-
}
334+
} else {
335+
skipUnloadedRows(child);
319336
return false;
320337
}
321338
} else {
@@ -325,7 +342,7 @@ class TChargeBTreeIndex : public ICharge {
325342

326343
for (ui32 height = 0; height < meta.LevelCount && ready; height++) {
327344
if (height == 0) {
328-
ready &= tryHandleNode(TChildState(meta, 0, meta.RowCount));
345+
ready &= tryHandleNode(TChildState(meta.PageId, 0, meta.RowCount, meta.GetNonErasedRowCount(), meta.DataSize));
329346
} else {
330347
iterateLevel(tryHandleNode);
331348
}
@@ -340,10 +357,10 @@ class TChargeBTreeIndex : public ICharge {
340357

341358
// flat index doesn't treat key placement within data page, so let's do the same
342359
// TODO: remove it later
343-
bool overshot = beginRowId == sliceBeginRowId;
360+
overshot &= beginRowId == sliceBeginRowId;
344361

345362
if (meta.LevelCount == 0) {
346-
ready &= tryHandleDataPage(TChildState(meta, 0, meta.RowCount));
363+
ready &= tryHandleDataPage(TChildState(meta.PageId, 0, meta.RowCount, meta.GetNonErasedRowCount(), meta.DataSize));
347364
} else {
348365
iterateLevel(tryHandleDataPage);
349366
}
@@ -384,9 +401,16 @@ class TChargeBTreeIndex : public ICharge {
384401
}
385402
for (TRecIdx pos : xrange(from, to)) {
386403
auto child = node.GetChild(pos);
387-
TRowId beginRowId = pos ? node.GetChild(pos - 1).RowCount : node.BeginRowId;
388-
TRowId endRowId = child.RowCount;
389-
ready &= tryHandleChild(TChildState(child, beginRowId, endRowId));
404+
if (pos) {
405+
auto prev = node.GetChild(pos - 1);
406+
ready &= tryHandleChild(TChildState(child.PageId, prev.RowCount, child.RowCount,
407+
child.GetNonErasedRowCount() - prev.GetNonErasedRowCount(),
408+
child.DataSize - prev.DataSize));
409+
} else {
410+
ready &= tryHandleChild(TChildState(child.PageId, 0, child.RowCount,
411+
child.GetNonErasedRowCount(),
412+
child.DataSize));
413+
}
390414
}
391415
}
392416
};
@@ -401,7 +425,7 @@ class TChargeBTreeIndex : public ICharge {
401425

402426
for (ui32 height = 0; height < meta.LevelCount && ready; height++) {
403427
if (height == 0) {
404-
ready &= tryHandleNode(TChildState(meta, 0, meta.RowCount));
428+
ready &= tryHandleNode(TChildState(meta.PageId, 0, meta.RowCount, meta.RowCount, meta.DataSize));
405429
} else {
406430
iterateLevel(tryHandleNode);
407431
}
@@ -414,7 +438,7 @@ class TChargeBTreeIndex : public ICharge {
414438
}
415439

416440
if (meta.LevelCount == 0) {
417-
ready &= tryHandleDataPage(TChildState(meta, 0, meta.RowCount));
441+
ready &= tryHandleDataPage(TChildState(meta.PageId, 0, meta.RowCount, meta.RowCount, meta.DataSize));
418442
} else {
419443
iterateLevel(tryHandleDataPage);
420444
}
@@ -441,7 +465,7 @@ class TChargeBTreeIndex : public ICharge {
441465
return true;
442466
}
443467

444-
int Compare(TCells left, TCells right, const TKeyCellDefaults &keyDefaults) const noexcept
468+
int Compare(TCells left, TCells right, const TKeyCellDefaults& keyDefaults) const noexcept
445469
{
446470
Y_DEBUG_ABORT_UNLESS(left, "Empty keys should be handled separately");
447471
Y_DEBUG_ABORT_UNLESS(right, "Empty keys should be handled separately");

0 commit comments

Comments
 (0)