@@ -32,9 +32,6 @@ type twoLevelIterator[I any, PI indexBlockIterator[I], D any, PD dataBlockIterat
32
32
// false - any filtering happens at the top level.
33
33
useFilterBlock bool
34
34
lastBloomFilterMatched bool
35
-
36
- // Lazy loading flag for top-level index block
37
- topLevelIndexLoaded bool
38
35
}
39
36
40
37
var _ Iterator = (* twoLevelIteratorRowBlocks )(nil )
@@ -48,14 +45,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) loadSecondLevelIndexBlock(dir int8) loa
48
45
// the index fails.
49
46
PD (& i .secondLevel .data ).Invalidate ()
50
47
PI (& i .secondLevel .index ).Invalidate ()
51
-
52
- if ! i .topLevelIndexLoaded {
53
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
54
- i .secondLevel .err = err
55
- return loadBlockFailed
56
- }
57
- }
58
-
59
48
if ! PI (& i .topLevelIndex ).Valid () {
60
49
return loadBlockFailed
61
50
}
@@ -193,9 +182,14 @@ func newColumnBlockTwoLevelIterator(
193
182
objstorage .NoReadBefore , & i .secondLevel .vbRHPrealloc )
194
183
}
195
184
i .secondLevel .data .InitOnce (r .keySchema , r .Comparer , & i .secondLevel .internalValueConstructor )
196
-
197
- // Use lazy loading by default - top-level index will be loaded on first access
198
- i .topLevelIndexLoaded = false
185
+ topLevelIndexH , err := r .readTopLevelIndexBlock (ctx , i .secondLevel .readEnv .Block , i .secondLevel .indexFilterRH )
186
+ if err == nil {
187
+ err = i .topLevelIndex .InitHandle (r .Comparer , topLevelIndexH , opts .Transforms )
188
+ }
189
+ if err != nil {
190
+ _ = i .Close ()
191
+ return nil , err
192
+ }
199
193
return i , nil
200
194
}
201
195
@@ -242,8 +236,14 @@ func newRowBlockTwoLevelIterator(
242
236
i .secondLevel .data .SetHasValuePrefix (true )
243
237
}
244
238
245
- // Use lazy loading by default - top-level index will be loaded on first access
246
- i .topLevelIndexLoaded = false
239
+ topLevelIndexH , err := r .readTopLevelIndexBlock (ctx , i .secondLevel .readEnv .Block , i .secondLevel .indexFilterRH )
240
+ if err == nil {
241
+ err = i .topLevelIndex .InitHandle (r .Comparer , topLevelIndexH , opts .Transforms )
242
+ }
243
+ if err != nil {
244
+ _ = i .Close ()
245
+ return nil , err
246
+ }
247
247
return i , nil
248
248
}
249
249
@@ -286,13 +286,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) SeekGE(
286
286
return nil
287
287
}
288
288
289
- if ! i .topLevelIndexLoaded {
290
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
291
- i .secondLevel .err = err
292
- return nil
293
- }
294
- }
295
-
296
289
// SeekGE performs various step-instead-of-seeking optimizations: eg enabled
297
290
// by trySeekUsingNext, or by monotonically increasing bounds (i.boundsCmp).
298
291
@@ -471,13 +464,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) SeekPrefixGE(
471
464
// than the index block containing the sought key, resulting in a wasteful
472
465
// block load.
473
466
474
- if ! i .topLevelIndexLoaded {
475
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
476
- i .secondLevel .err = err
477
- return nil
478
- }
479
- }
480
-
481
467
var dontSeekWithinSingleLevelIter bool
482
468
if PI (& i .topLevelIndex ).IsDataInvalidated () || ! PI (& i .topLevelIndex ).Valid () || PI (& i .secondLevel .index ).IsDataInvalidated () || err != nil ||
483
469
(i .secondLevel .boundsCmp <= 0 && ! flags .TrySeekUsingNext ()) || PI (& i .topLevelIndex ).SeparatorLT (key ) {
@@ -637,13 +623,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) virtualLastSeekLE() *base.InternalKV {
637
623
func (i * twoLevelIterator [I , PI , D , PD ]) SeekLT (
638
624
key []byte , flags base.SeekLTFlags ,
639
625
) * base.InternalKV {
640
- if ! i .topLevelIndexLoaded {
641
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
642
- i .secondLevel .err = err
643
- return nil
644
- }
645
- }
646
-
647
626
if i .secondLevel .readEnv .Virtual != nil {
648
627
// Might have to fix upper bound since virtual sstable bounds are not
649
628
// known to callers of SeekLT.
@@ -725,12 +704,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) SeekLT(
725
704
// to ensure that key is greater than or equal to the lower bound (e.g. via a
726
705
// call to SeekGE(lower)).
727
706
func (i * twoLevelIterator [I , PI , D , PD ]) First () * base.InternalKV {
728
- if ! i .topLevelIndexLoaded {
729
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
730
- i .secondLevel .err = err
731
- return nil
732
- }
733
- }
734
707
// If we have a lower bound, use SeekGE. Note that in general this is not
735
708
// supported usage, except when the lower bound is there because the table is
736
709
// virtual.
@@ -776,13 +749,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) First() *base.InternalKV {
776
749
// to ensure that key is less than the upper bound (e.g. via a call to
777
750
// SeekLT(upper))
778
751
func (i * twoLevelIterator [I , PI , D , PD ]) Last () * base.InternalKV {
779
- if ! i .topLevelIndexLoaded {
780
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
781
- i .secondLevel .err = err
782
- return nil
783
- }
784
- }
785
-
786
752
if i .secondLevel .readEnv .Virtual != nil {
787
753
if i .secondLevel .endKeyInclusive {
788
754
return i .virtualLast ()
@@ -830,12 +796,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) Last() *base.InternalKV {
830
796
// Note: twoLevelCompactionIterator.Next mirrors the implementation of
831
797
// twoLevelIterator.Next due to performance. Keep the two in sync.
832
798
func (i * twoLevelIterator [I , PI , D , PD ]) Next () * base.InternalKV {
833
- if ! i .topLevelIndexLoaded {
834
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
835
- i .secondLevel .err = err
836
- return nil
837
- }
838
- }
839
799
// Seek optimization only applies until iterator is first positioned after SetBounds.
840
800
i .secondLevel .boundsCmp = 0
841
801
if i .secondLevel .err != nil {
@@ -854,13 +814,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) NextPrefix(succKey []byte) *base.Intern
854
814
if i .secondLevel .exhaustedBounds == + 1 {
855
815
panic ("Next called even though exhausted upper bound" )
856
816
}
857
-
858
- if ! i .topLevelIndexLoaded {
859
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
860
- i .secondLevel .err = err
861
- return nil
862
- }
863
- }
864
817
// Seek optimization only applies until iterator is first positioned after SetBounds.
865
818
i .secondLevel .boundsCmp = 0
866
819
if i .secondLevel .err != nil {
@@ -908,12 +861,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) NextPrefix(succKey []byte) *base.Intern
908
861
// Prev implements internalIterator.Prev, as documented in the pebble
909
862
// package.
910
863
func (i * twoLevelIterator [I , PI , D , PD ]) Prev () * base.InternalKV {
911
- if ! i .topLevelIndexLoaded {
912
- if err := i .ensureTopLevelIndexLoaded (); err != nil {
913
- i .secondLevel .err = err
914
- return nil
915
- }
916
- }
917
864
// Seek optimization only applies until iterator is first positioned after SetBounds.
918
865
i .secondLevel .boundsCmp = 0
919
866
if i .secondLevel .err != nil {
@@ -1073,27 +1020,8 @@ func (i *twoLevelIterator[I, PI, D, PD]) Close() error {
1073
1020
err = firstError (err , PI (& i .topLevelIndex ).Close ())
1074
1021
i .useFilterBlock = false
1075
1022
i .lastBloomFilterMatched = false
1076
- i .topLevelIndexLoaded = false
1077
1023
if pool != nil {
1078
1024
pool .Put (i )
1079
1025
}
1080
1026
return err
1081
1027
}
1082
-
1083
- func (i * twoLevelIterator [I , PI , D , PD ]) ensureTopLevelIndexLoaded () error {
1084
- if i .topLevelIndexLoaded {
1085
- return nil
1086
- }
1087
-
1088
- topLevelIndexH , err := i .secondLevel .reader .readTopLevelIndexBlock (i .secondLevel .ctx ,
1089
- i .secondLevel .readEnv .Block , i .secondLevel .indexFilterRH )
1090
- if err == nil {
1091
- err = PI (& i .topLevelIndex ).InitHandle (i .secondLevel .reader .Comparer ,
1092
- topLevelIndexH , i .secondLevel .transforms )
1093
- }
1094
- if err != nil {
1095
- return err
1096
- }
1097
- i .topLevelIndexLoaded = true
1098
- return nil
1099
- }
0 commit comments