@@ -48,14 +48,14 @@ class TChargeBTreeIndex : public ICharge {
48
48
ready &= TryLoadNode (meta.PageId , nextLevel);
49
49
} else {
50
50
for (ui32 i : xrange<ui32>(level.size ())) {
51
- TRecIdx begin = 0 , end = level[i].GetChildrenCount ();
51
+ TRecIdx from = 0 , to = level[i].GetKeysCount ();
52
52
if (i == 0 ) {
53
- begin = level[i].Seek (row1);
53
+ from = level[i].Seek (row1);
54
54
}
55
55
if (i + 1 == level.size () && row2 < meta.RowsCount ) {
56
- end = level[i].Seek (row2) + 1 ;
56
+ to = level[i].Seek (row2);
57
57
}
58
- for (TRecIdx j : xrange (begin, end )) {
58
+ for (TRecIdx j : xrange (from, to + 1 )) {
59
59
ready &= TryLoadNode (level[i].GetShortChild (j).PageId , nextLevel);
60
60
}
61
61
}
@@ -74,14 +74,14 @@ class TChargeBTreeIndex : public ICharge {
74
74
ready &= HasDataPage (meta.PageId , { });
75
75
} else {
76
76
for (ui32 i : xrange<ui32>(level.size ())) {
77
- TRecIdx begin = 0 , end = level[i].GetChildrenCount ();
77
+ TRecIdx from = 0 , to = level[i].GetKeysCount ();
78
78
if (i == 0 ) {
79
- begin = level[i].Seek (row1);
79
+ from = level[i].Seek (row1);
80
80
}
81
81
if (i + 1 == level.size () && row2 < meta.RowsCount ) {
82
- end = level[i].Seek (row2) + 1 ;
82
+ to = level[i].Seek (row2);
83
83
}
84
- for (TRecIdx j : xrange (begin, end )) {
84
+ for (TRecIdx j : xrange (from, to + 1 )) {
85
85
ready &= HasDataPage (level[i].GetShortChild (j).PageId , { });
86
86
}
87
87
}
@@ -93,15 +93,71 @@ class TChargeBTreeIndex : public ICharge {
93
93
94
94
TResult DoReverse (const TCells key1, const TCells key2, TRowId row1, TRowId row2,
95
95
const TKeyCellDefaults &keyDefaults, ui64 itemsLimit, ui64 bytesLimit) const noexcept override {
96
- // TODO: implement
96
+ bool ready = true ;
97
+
97
98
Y_UNUSED (key1);
98
99
Y_UNUSED (key2);
99
- Y_UNUSED (row1);
100
- Y_UNUSED (row2);
101
100
Y_UNUSED (keyDefaults);
102
101
Y_UNUSED (itemsLimit);
103
102
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 };
105
161
}
106
162
107
163
private:
0 commit comments