@@ -13,22 +13,27 @@ class TChargeBTreeIndex : public ICharge {
13
13
using TGroupId = NPage::TGroupId;
14
14
using TChild = TBtreeIndexNode::TChild;
15
15
16
- // TODO: store PageId only instead of TChild?
17
- struct TChildState : TChild {
16
+ // TODO: store PageId only?
17
+ struct TChildState {
18
+ TPageId PageId;
18
19
TRowId BeginRowId;
19
20
TRowId EndRowId;
21
+ TRowId RowCount;
22
+ ui64 DataSize;
20
23
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 )
23
26
, BeginRowId(beginRowId)
24
27
, EndRowId(endRowId)
28
+ , RowCount(rowCount)
29
+ , DataSize(dataSize)
25
30
{
26
31
}
27
32
};
28
33
29
34
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 )
32
37
, TBtreeIndexNode(data)
33
38
{
34
39
}
@@ -62,14 +67,15 @@ class TChargeBTreeIndex : public ICharge {
62
67
63
68
public:
64
69
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 {
66
71
endRowId++; // current interface accepts inclusive row2 bound
67
72
Y_ABORT_UNLESS (beginRowId < endRowId);
68
73
69
74
bool ready = true , overshot = true ;
70
75
bool chargeGroups = bool (Groups); // false value means that beginRowId, endRowId are invalid and shouldn't be used
76
+ ui64 rowCount = 0 , dataSize = 0 ;
71
77
72
- Y_UNUSED (bytesLimit );
78
+ Y_UNUSED (rowCountLimit, dataSizeLimit, rowCount, dataSize );
73
79
74
80
const auto & meta = Part->IndexPages .BTreeGroups [0 ];
75
81
Y_ABORT_UNLESS (endRowId <= meta.RowCount );
@@ -80,10 +86,6 @@ class TChargeBTreeIndex : public ICharge {
80
86
chargeGroups = false ;
81
87
}
82
88
83
- if (!key1) {
84
- ApplyItemsLimit (beginRowId, endRowId, itemsLimit, overshot);
85
- }
86
-
87
89
TVector<TNodeState> level, nextLevel (::Reserve (3 ));
88
90
TPageId key1PageId = key1 ? meta.PageId : Max<TPageId>();
89
91
TPageId key2PageId = key2 ? meta.PageId : Max<TPageId>();
@@ -106,16 +108,22 @@ class TChargeBTreeIndex : public ICharge {
106
108
}
107
109
for (TRecIdx pos : xrange (from, to)) {
108
110
auto child = node.GetChild (pos);
109
- TRowId beginRowId = pos ? node.GetChild (pos - 1 ).RowCount : node.BeginRowId ;
110
- TRowId endRowId = child.RowCount ;
111
- 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
+ }
112
121
}
113
122
}
114
123
};
115
124
116
- const auto skipUnloadedRows = [&](TChildState child) {
125
+ const auto skipUnloadedRows = [&](const TChildState& child) {
117
126
if (child.PageId == key1PageId) {
118
- ApplyItemsLimit (Max (beginRowId, child.BeginRowId ), endRowId, itemsLimit, overshot);
119
127
beginRowId = Max (beginRowId, child.EndRowId );
120
128
}
121
129
if (child.PageId == key2PageId) {
@@ -133,7 +141,6 @@ class TChargeBTreeIndex : public ICharge {
133
141
if (pos) {
134
142
beginRowId = Max (beginRowId, node.GetShortChild (pos - 1 ).RowCount ); // move beginRowId to the first key >= key1
135
143
}
136
- ApplyItemsLimit (node.GetShortChild (pos).RowCount , endRowId, itemsLimit, overshot);
137
144
}
138
145
if (child.PageId == key2PageId) {
139
146
TRecIdx pos = node.Seek (ESeek::Lower, key2, Scheme.Groups [0 ].ColsKeyIdx , &keyDefaults);
@@ -161,7 +168,6 @@ class TChargeBTreeIndex : public ICharge {
161
168
if (child.PageId == key1PageId) {
162
169
TRowId key1RowId = data.BaseRow () + data.LookupKey (key1, Scheme.Groups [0 ], ESeek::Lower, &keyDefaults).Off ();
163
170
beginRowId = Max (beginRowId, key1RowId);
164
- ApplyItemsLimit (beginRowId, endRowId, itemsLimit, overshot);
165
171
}
166
172
if (child.PageId == key2PageId) {
167
173
TRowId key2RowId = data.BaseRow () + data.LookupKey (key2, Scheme.Groups [0 ], ESeek::Upper, &keyDefaults).Off ();
@@ -173,16 +179,13 @@ class TChargeBTreeIndex : public ICharge {
173
179
return false ;
174
180
}
175
181
} else {
176
- if (child.PageId == key1PageId) {
177
- ApplyItemsLimit (child.EndRowId , endRowId, itemsLimit, overshot);
178
- }
179
182
return HasDataPage (child.PageId , { });
180
183
}
181
184
};
182
185
183
186
for (ui32 height = 0 ; height < meta.LevelCount && ready; height++) {
184
187
if (height == 0 ) {
185
- ready &= tryHandleNode (TChildState (meta, 0 , meta.RowCount ));
188
+ ready &= tryHandleNode (TChildState (meta. PageId , 0 , meta.RowCount , meta. GetNonErasedRowCount (), meta. DataSize ));
186
189
} else {
187
190
iterateLevel (tryHandleNode);
188
191
}
@@ -200,7 +203,7 @@ class TChargeBTreeIndex : public ICharge {
200
203
overshot &= endRowId == sliceEndRowId;
201
204
202
205
if (meta.LevelCount == 0 ) {
203
- ready &= tryHandleDataPage (TChildState (meta, 0 , meta.RowCount ));
206
+ ready &= tryHandleDataPage (TChildState (meta. PageId , 0 , meta.RowCount , meta. GetNonErasedRowCount (), meta. DataSize ));
204
207
} else {
205
208
iterateLevel (tryHandleDataPage);
206
209
}
@@ -211,15 +214,15 @@ class TChargeBTreeIndex : public ICharge {
211
214
}
212
215
213
216
TResult DoReverse (TCells key1, TCells key2, TRowId endRowId, TRowId beginRowId,
214
- const TKeyCellDefaults &keyDefaults, ui64 itemsLimit , ui64 bytesLimit ) const noexcept override {
217
+ const TKeyCellDefaults &keyDefaults, ui64 rowCountLimit , ui64 dataSizeLimit ) const noexcept override {
215
218
endRowId++; // current interface accepts inclusive row1 bound
216
219
Y_ABORT_UNLESS (beginRowId < endRowId);
217
220
218
221
bool ready = true , overshot = true ;
219
222
bool chargeGroups = bool (Groups); // false value means that beginRowId, endRowId are invalid and shouldn't be used
223
+ ui64 rowCount = 0 , dataSize = 0 ;
220
224
221
- Y_UNUSED (itemsLimit);
222
- Y_UNUSED (bytesLimit);
225
+ Y_UNUSED (rowCountLimit, dataSizeLimit, rowCount, dataSize);
223
226
224
227
const auto & meta = Part->IndexPages .BTreeGroups [0 ];
225
228
Y_ABORT_UNLESS (endRowId <= meta.RowCount );
@@ -230,10 +233,6 @@ class TChargeBTreeIndex : public ICharge {
230
233
chargeGroups = false ;
231
234
}
232
235
233
- if (!key1) {
234
- ApplyItemsLimitReverse (beginRowId, endRowId, itemsLimit, overshot);
235
- }
236
-
237
236
TVector<TNodeState> level, nextLevel (::Reserve (3 ));
238
237
TPageId key1PageId = key1 ? meta.PageId : Max<TPageId>();
239
238
TPageId key2PageId = key2 ? meta.PageId : Max<TPageId>();
@@ -256,16 +255,22 @@ class TChargeBTreeIndex : public ICharge {
256
255
}
257
256
for (TRecIdx pos : xrange (from, to)) {
258
257
auto child = node.GetChild (pos);
259
- TRowId beginRowId = pos ? node.GetChild (pos - 1 ).RowCount : node.BeginRowId ;
260
- TRowId endRowId = child.RowCount ;
261
- 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
+ }
262
268
}
263
269
}
264
270
};
265
271
266
272
const auto skipUnloadedRows = [&](TChildState child) {
267
273
if (child.PageId == key1PageId) {
268
- ApplyItemsLimitReverse (beginRowId, Min (endRowId, child.EndRowId ), itemsLimit, overshot);
269
274
endRowId = Min (endRowId, child.BeginRowId );
270
275
}
271
276
if (child.PageId == key2PageId) {
@@ -281,9 +286,6 @@ class TChargeBTreeIndex : public ICharge {
281
286
TRecIdx pos = node.SeekReverse (ESeek::Lower, key1, Scheme.Groups [0 ].ColsKeyIdx , &keyDefaults);
282
287
key1PageId = node.GetShortChild (pos).PageId ;
283
288
endRowId = Min (endRowId, node.GetShortChild (pos).RowCount ); // move endRowId - 1 to the last key <= key1
284
- if (pos) {
285
- ApplyItemsLimitReverse (beginRowId, node.GetShortChild (pos - 1 ).RowCount , itemsLimit, overshot);
286
- }
287
289
}
288
290
if (child.PageId == key2PageId) {
289
291
TRecIdx pos = node.Seek (ESeek::Lower, key2, Scheme.Groups [0 ].ColsKeyIdx , &keyDefaults);
@@ -318,7 +320,6 @@ class TChargeBTreeIndex : public ICharge {
318
320
} else {
319
321
endRowId = Min (endRowId, child.BeginRowId );
320
322
}
321
- ApplyItemsLimitReverse (beginRowId, endRowId, itemsLimit, overshot);
322
323
}
323
324
if (child.PageId == key2PageId) {
324
325
auto iter = data.LookupKeyReverse (key2, Scheme.Groups [0 ], ESeek::Upper, &keyDefaults);
@@ -335,16 +336,13 @@ class TChargeBTreeIndex : public ICharge {
335
336
return false ;
336
337
}
337
338
} else {
338
- if (child.PageId == key1PageId) {
339
- ApplyItemsLimitReverse (beginRowId, child.BeginRowId , itemsLimit, overshot);
340
- }
341
339
return HasDataPage (child.PageId , { });
342
340
}
343
341
};
344
342
345
343
for (ui32 height = 0 ; height < meta.LevelCount && ready; height++) {
346
344
if (height == 0 ) {
347
- ready &= tryHandleNode (TChildState (meta, 0 , meta.RowCount ));
345
+ ready &= tryHandleNode (TChildState (meta. PageId , 0 , meta.RowCount , meta. GetNonErasedRowCount (), meta. DataSize ));
348
346
} else {
349
347
iterateLevel (tryHandleNode);
350
348
}
@@ -362,7 +360,7 @@ class TChargeBTreeIndex : public ICharge {
362
360
overshot &= beginRowId == sliceBeginRowId;
363
361
364
362
if (meta.LevelCount == 0 ) {
365
- ready &= tryHandleDataPage (TChildState (meta, 0 , meta.RowCount ));
363
+ ready &= tryHandleDataPage (TChildState (meta. PageId , 0 , meta.RowCount , meta. GetNonErasedRowCount (), meta. DataSize ));
366
364
} else {
367
365
iterateLevel (tryHandleDataPage);
368
366
}
@@ -403,9 +401,16 @@ class TChargeBTreeIndex : public ICharge {
403
401
}
404
402
for (TRecIdx pos : xrange (from, to)) {
405
403
auto child = node.GetChild (pos);
406
- TRowId beginRowId = pos ? node.GetChild (pos - 1 ).RowCount : node.BeginRowId ;
407
- TRowId endRowId = child.RowCount ;
408
- 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
+ }
409
414
}
410
415
}
411
416
};
@@ -420,7 +425,7 @@ class TChargeBTreeIndex : public ICharge {
420
425
421
426
for (ui32 height = 0 ; height < meta.LevelCount && ready; height++) {
422
427
if (height == 0 ) {
423
- ready &= tryHandleNode (TChildState (meta, 0 , meta.RowCount ));
428
+ ready &= tryHandleNode (TChildState (meta. PageId , 0 , meta.RowCount , meta. RowCount , meta. DataSize ));
424
429
} else {
425
430
iterateLevel (tryHandleNode);
426
431
}
@@ -433,7 +438,7 @@ class TChargeBTreeIndex : public ICharge {
433
438
}
434
439
435
440
if (meta.LevelCount == 0 ) {
436
- ready &= tryHandleDataPage (TChildState (meta, 0 , meta.RowCount ));
441
+ ready &= tryHandleDataPage (TChildState (meta. PageId , 0 , meta.RowCount , meta. RowCount , meta. DataSize ));
437
442
} else {
438
443
iterateLevel (tryHandleDataPage);
439
444
}
@@ -442,20 +447,6 @@ class TChargeBTreeIndex : public ICharge {
442
447
}
443
448
444
449
private:
445
- void ApplyItemsLimit (TRowId beginRowId, TRowId &endRowId, ui64 itemsLimit, bool &overshot) const noexcept {
446
- if (itemsLimit && endRowId > beginRowId && endRowId - beginRowId - 1 >= itemsLimit) {
447
- endRowId = beginRowId + itemsLimit + 1 ;
448
- overshot = false ;
449
- }
450
- }
451
-
452
- void ApplyItemsLimitReverse (TRowId& beginRowId, TRowId endRowId, ui64 itemsLimit, bool &overshot) const noexcept {
453
- if (itemsLimit && endRowId > beginRowId && endRowId - beginRowId - 1 >= itemsLimit) {
454
- beginRowId = endRowId - itemsLimit - 1 ;
455
- overshot = false ;
456
- }
457
- }
458
-
459
450
const TSharedData* TryGetDataPage (TPageId pageId, TGroupId groupId) const noexcept {
460
451
return Env->TryGetPage (Part, pageId, groupId);
461
452
};
@@ -474,7 +465,7 @@ class TChargeBTreeIndex : public ICharge {
474
465
return true ;
475
466
}
476
467
477
- int Compare (TCells left, TCells right, const TKeyCellDefaults & keyDefaults) const noexcept
468
+ int Compare (TCells left, TCells right, const TKeyCellDefaults& keyDefaults) const noexcept
478
469
{
479
470
Y_DEBUG_ABORT_UNLESS (left, " Empty keys should be handled separately" );
480
471
Y_DEBUG_ABORT_UNLESS (right, " Empty keys should be handled separately" );
0 commit comments