Skip to content

Commit f535156

Browse files
committed
Revert "sstable: lazy load the index block in two level iterator"
This reverts commit fe43e7b.
1 parent 46650aa commit f535156

File tree

2 files changed

+18
-95
lines changed

2 files changed

+18
-95
lines changed

sstable/reader_iter_test.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,13 @@ func TestIteratorErrorOnInit(t *testing.T) {
6868
require.Error(t, iter.Error())
6969
iter.Close()
7070
} else {
71-
iter, err := newRowBlockTwoLevelIterator(context.Background(), r, IterOptions{
71+
_, err := newRowBlockTwoLevelIterator(context.Background(), r, IterOptions{
7272
Transforms: NoTransforms,
7373
FilterBlockSizeLimit: NeverUseFilterBlock,
7474
Env: ReadEnv{Block: block.ReadEnv{Stats: &stats, BufferPool: &pool}},
7575
ReaderProvider: MakeTrivialReaderProvider(r),
7676
})
77-
// Two-level iterators use lazy loading - creation succeeds but first access fails
78-
require.NoError(t, err)
79-
// Error should surface when trying to use the iterator
80-
_ = iter.First()
81-
require.Error(t, iter.Error())
82-
iter.Close()
77+
require.Error(t, err)
8378
}
8479
}
8580
}

sstable/reader_iter_two_lvl.go

Lines changed: 16 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ type twoLevelIterator[I any, PI indexBlockIterator[I], D any, PD dataBlockIterat
3232
// false - any filtering happens at the top level.
3333
useFilterBlock bool
3434
lastBloomFilterMatched bool
35-
36-
// Lazy loading flag for top-level index block
37-
topLevelIndexLoaded bool
3835
}
3936

4037
var _ Iterator = (*twoLevelIteratorRowBlocks)(nil)
@@ -48,14 +45,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) loadSecondLevelIndexBlock(dir int8) loa
4845
// the index fails.
4946
PD(&i.secondLevel.data).Invalidate()
5047
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-
5948
if !PI(&i.topLevelIndex).Valid() {
6049
return loadBlockFailed
6150
}
@@ -193,9 +182,14 @@ func newColumnBlockTwoLevelIterator(
193182
objstorage.NoReadBefore, &i.secondLevel.vbRHPrealloc)
194183
}
195184
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+
}
199193
return i, nil
200194
}
201195

@@ -242,8 +236,14 @@ func newRowBlockTwoLevelIterator(
242236
i.secondLevel.data.SetHasValuePrefix(true)
243237
}
244238

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+
}
247247
return i, nil
248248
}
249249

@@ -286,13 +286,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) SeekGE(
286286
return nil
287287
}
288288

289-
if !i.topLevelIndexLoaded {
290-
if err := i.ensureTopLevelIndexLoaded(); err != nil {
291-
i.secondLevel.err = err
292-
return nil
293-
}
294-
}
295-
296289
// SeekGE performs various step-instead-of-seeking optimizations: eg enabled
297290
// by trySeekUsingNext, or by monotonically increasing bounds (i.boundsCmp).
298291

@@ -471,13 +464,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) SeekPrefixGE(
471464
// than the index block containing the sought key, resulting in a wasteful
472465
// block load.
473466

474-
if !i.topLevelIndexLoaded {
475-
if err := i.ensureTopLevelIndexLoaded(); err != nil {
476-
i.secondLevel.err = err
477-
return nil
478-
}
479-
}
480-
481467
var dontSeekWithinSingleLevelIter bool
482468
if PI(&i.topLevelIndex).IsDataInvalidated() || !PI(&i.topLevelIndex).Valid() || PI(&i.secondLevel.index).IsDataInvalidated() || err != nil ||
483469
(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 {
637623
func (i *twoLevelIterator[I, PI, D, PD]) SeekLT(
638624
key []byte, flags base.SeekLTFlags,
639625
) *base.InternalKV {
640-
if !i.topLevelIndexLoaded {
641-
if err := i.ensureTopLevelIndexLoaded(); err != nil {
642-
i.secondLevel.err = err
643-
return nil
644-
}
645-
}
646-
647626
if i.secondLevel.readEnv.Virtual != nil {
648627
// Might have to fix upper bound since virtual sstable bounds are not
649628
// known to callers of SeekLT.
@@ -725,12 +704,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) SeekLT(
725704
// to ensure that key is greater than or equal to the lower bound (e.g. via a
726705
// call to SeekGE(lower)).
727706
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-
}
734707
// If we have a lower bound, use SeekGE. Note that in general this is not
735708
// supported usage, except when the lower bound is there because the table is
736709
// virtual.
@@ -776,13 +749,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) First() *base.InternalKV {
776749
// to ensure that key is less than the upper bound (e.g. via a call to
777750
// SeekLT(upper))
778751
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-
786752
if i.secondLevel.readEnv.Virtual != nil {
787753
if i.secondLevel.endKeyInclusive {
788754
return i.virtualLast()
@@ -830,12 +796,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) Last() *base.InternalKV {
830796
// Note: twoLevelCompactionIterator.Next mirrors the implementation of
831797
// twoLevelIterator.Next due to performance. Keep the two in sync.
832798
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-
}
839799
// Seek optimization only applies until iterator is first positioned after SetBounds.
840800
i.secondLevel.boundsCmp = 0
841801
if i.secondLevel.err != nil {
@@ -854,13 +814,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) NextPrefix(succKey []byte) *base.Intern
854814
if i.secondLevel.exhaustedBounds == +1 {
855815
panic("Next called even though exhausted upper bound")
856816
}
857-
858-
if !i.topLevelIndexLoaded {
859-
if err := i.ensureTopLevelIndexLoaded(); err != nil {
860-
i.secondLevel.err = err
861-
return nil
862-
}
863-
}
864817
// Seek optimization only applies until iterator is first positioned after SetBounds.
865818
i.secondLevel.boundsCmp = 0
866819
if i.secondLevel.err != nil {
@@ -908,12 +861,6 @@ func (i *twoLevelIterator[I, PI, D, PD]) NextPrefix(succKey []byte) *base.Intern
908861
// Prev implements internalIterator.Prev, as documented in the pebble
909862
// package.
910863
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-
}
917864
// Seek optimization only applies until iterator is first positioned after SetBounds.
918865
i.secondLevel.boundsCmp = 0
919866
if i.secondLevel.err != nil {
@@ -1073,27 +1020,8 @@ func (i *twoLevelIterator[I, PI, D, PD]) Close() error {
10731020
err = firstError(err, PI(&i.topLevelIndex).Close())
10741021
i.useFilterBlock = false
10751022
i.lastBloomFilterMatched = false
1076-
i.topLevelIndexLoaded = false
10771023
if pool != nil {
10781024
pool.Put(i)
10791025
}
10801026
return err
10811027
}
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

Comments
 (0)