From 38e5fe4f5526e06d88e75aa6f0ac464c9902cf08 Mon Sep 17 00:00:00 2001 From: Jackson Owens Date: Fri, 3 May 2024 10:02:28 -0400 Subject: [PATCH] db: avoid keyspanimpl.TableNewSpanIter closure allocation The tableNewIters func requires a context, but the keyspanimpl.TableNewSpanIter func used by keyspan.LevelIter did not take one. This required iterator construction to close over the context and the tableNewIters to create an keyspanimpl.TableNewSpanIter, forcing an allocation. This commit refactors the keyspanimpl.LevelIter to embed a context, like the point iterator's levelIter, and propagate the context into TableNewSpanIter through an argument. --- compaction.go | 13 +++--- compaction_test.go | 2 +- db.go | 32 ++++++-------- flushable.go | 36 +++++----------- flushable_test.go | 2 +- ingest.go | 2 +- internal/keyspan/keyspanimpl/level_iter.go | 15 +++++-- .../keyspan/keyspanimpl/level_iter_test.go | 7 +++- iterator.go | 3 -- open.go | 1 - overlap.go | 10 ++--- range_keys.go | 11 ++--- scan_internal.go | 42 +++++++++---------- table_cache.go | 41 ++++++++---------- 14 files changed, 99 insertions(+), 118 deletions(-) diff --git a/compaction.go b/compaction.go index f74227b177..b2aa070fb1 100644 --- a/compaction.go +++ b/compaction.go @@ -706,7 +706,7 @@ func (c *compaction) allowZeroSeqNum() bool { // newInputIters returns an iterator over all the input tables in a compaction. func (c *compaction) newInputIters( - newIters tableNewIters, newRangeKeyIter keyspanimpl.TableNewSpanIter, + newIters tableNewIters, ) ( pointIter internalIterator, rangeDelIter, rangeKeyIter keyspan.FragmentIterator, @@ -778,6 +778,7 @@ func (c *compaction) newInputIters( } } }() + ctx := context.Background() iterOpts := IterOptions{ CategoryAndQoS: sstable.CategoryAndQoS{ Category: "pebble-compaction", @@ -809,7 +810,7 @@ func (c *compaction) newInputIters( // initRangeDel, the levelIter will close and forget the range // deletion iterator when it steps on to a new file. Surfacing range // deletions to compactions are handled below. - iters = append(iters, newLevelIter(context.Background(), + iters = append(iters, newLevelIter(ctx, iterOpts, c.comparer, newIters, level.files.Iter(), l, internalIterOpts{ compaction: true, bufferPool: &c.bufferPool, @@ -875,8 +876,8 @@ func (c *compaction) newInputIters( } if hasRangeKeys { li := &keyspanimpl.LevelIter{} - newRangeKeyIterWrapper := func(file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { - iter, err := newRangeKeyIter(file, iterOptions) + newRangeKeyIterWrapper := func(ctx context.Context, file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { + iter, err := newIters.NewRangeKeyIter(ctx, file, iterOptions) if err != nil { return nil, err } else if iter == nil { @@ -896,7 +897,7 @@ func (c *compaction) newInputIters( // in this sstable must wholly lie within the file's bounds. return iter, err } - li.Init(keyspan.SpanIterOptions{}, c.cmp, newRangeKeyIterWrapper, level.files.Iter(), l, manifest.KeyTypeRange) + li.Init(ctx, keyspan.SpanIterOptions{}, c.cmp, newRangeKeyIterWrapper, level.files.Iter(), l, manifest.KeyTypeRange) rangeKeyIters = append(rangeKeyIters, li) } return nil @@ -2556,7 +2557,7 @@ func (d *DB) runCompaction( c.bufferPool.Init(12) defer c.bufferPool.Release() - pointIter, rangeDelIter, rangeKeyIter, err := c.newInputIters(d.newIters, d.tableNewRangeKeyIter) + pointIter, rangeDelIter, rangeKeyIter, err := c.newInputIters(d.newIters) if err != nil { return nil, pendingOutputs, stats, err } diff --git a/compaction_test.go b/compaction_test.go index a8eead7e5d..536574f389 100644 --- a/compaction_test.go +++ b/compaction_test.go @@ -2460,7 +2460,7 @@ func TestCompactionCheckOrdering(t *testing.T) { return iterSet{point: &errorIter{}}, nil } result := "OK" - _, _, _, err := c.newInputIters(newIters, nil) + _, _, _, err := c.newInputIters(newIters) if err != nil { result = fmt.Sprint(err) } diff --git a/db.go b/db.go index b4b9acd0a4..2aa7b5aee9 100644 --- a/db.go +++ b/db.go @@ -20,7 +20,6 @@ import ( "github.com/cockroachdb/pebble/internal/invalidating" "github.com/cockroachdb/pebble/internal/invariants" "github.com/cockroachdb/pebble/internal/keyspan" - "github.com/cockroachdb/pebble/internal/keyspan/keyspanimpl" "github.com/cockroachdb/pebble/internal/manifest" "github.com/cockroachdb/pebble/internal/manual" "github.com/cockroachdb/pebble/objstorage" @@ -297,9 +296,8 @@ type DB struct { fileLock *Lock dataDir vfs.File - tableCache *tableCacheContainer - newIters tableNewIters - tableNewRangeKeyIter keyspanimpl.TableNewSpanIter + tableCache *tableCacheContainer + newIters tableNewIters commit *commitPipeline @@ -1043,7 +1041,6 @@ func (d *DB) newIter( } var readState *readState var newIters tableNewIters - var newIterRangeKey keyspanimpl.TableNewSpanIter if !internalOpts.batch.batchOnly { // Grab and reference the current readState. This prevents the underlying // files in the associated version from being deleted if there is a current @@ -1067,7 +1064,6 @@ func (d *DB) newIter( seqNum = d.mu.versions.visibleSeqNum.Load() } newIters = d.newIters - newIterRangeKey = d.tableNewRangeKeyIter } // Bundle various structures under a single umbrella in order to allocate @@ -1086,7 +1082,6 @@ func (d *DB) newIter( boundsBuf: buf.boundsBuf, batch: batch, newIters: newIters, - newIterRangeKey: newIterRangeKey, seqNum: seqNum, batchOnlyIter: internalOpts.batch.batchOnly, } @@ -1184,7 +1179,7 @@ func finishInitializingIter(ctx context.Context, buf *iterAlloc) *Iterator { if dbi.rangeKey == nil { dbi.rangeKey = iterRangeKeyStateAllocPool.Get().(*iteratorRangeKeyState) dbi.rangeKey.init(dbi.comparer.Compare, dbi.comparer.Split, &dbi.opts) - dbi.constructRangeKeyIter() + dbi.constructRangeKeyIter(ctx) } else { dbi.rangeKey.iterConfig.SetBounds(dbi.opts.LowerBound, dbi.opts.UpperBound) } @@ -1309,17 +1304,16 @@ func (d *DB) newInternalIter( // them together. buf := iterAllocPool.Get().(*iterAlloc) dbi := &scanInternalIterator{ - ctx: ctx, - db: d, - comparer: d.opts.Comparer, - merge: d.opts.Merger.Merge, - readState: readState, - version: sOpts.vers, - alloc: buf, - newIters: d.newIters, - newIterRangeKey: d.tableNewRangeKeyIter, - seqNum: seqNum, - mergingIter: &buf.merging, + ctx: ctx, + db: d, + comparer: d.opts.Comparer, + merge: d.opts.Merger.Merge, + readState: readState, + version: sOpts.vers, + alloc: buf, + newIters: d.newIters, + seqNum: seqNum, + mergingIter: &buf.merging, } dbi.opts = *o dbi.opts.logger = d.opts.Logger diff --git a/flushable.go b/flushable.go index ce3b74fbb8..56eee97686 100644 --- a/flushable.go +++ b/flushable.go @@ -152,10 +152,9 @@ type flushableList []*flushableEntry // ingesting sstables which are added to the flushable list. type ingestedFlushable struct { // files are non-overlapping and ordered (according to their bounds). - files []physicalMeta - comparer *Comparer - newIters tableNewIters - newRangeKeyIters keyspanimpl.TableNewSpanIter + files []physicalMeta + comparer *Comparer + newIters tableNewIters // Since the level slice is immutable, we construct and set it once. It // should be safe to read from slice in future reads. @@ -168,11 +167,7 @@ type ingestedFlushable struct { } func newIngestedFlushable( - files []*fileMetadata, - comparer *Comparer, - newIters tableNewIters, - newRangeKeyIters keyspanimpl.TableNewSpanIter, - exciseSpan KeyRange, + files []*fileMetadata, comparer *Comparer, newIters tableNewIters, exciseSpan KeyRange, ) *ingestedFlushable { if invariants.Enabled { for i := 1; i < len(files); i++ { @@ -193,10 +188,9 @@ func newIngestedFlushable( } ret := &ingestedFlushable{ - files: physicalFiles, - comparer: comparer, - newIters: newIters, - newRangeKeyIters: newRangeKeyIters, + files: physicalFiles, + comparer: comparer, + newIters: newIters, // slice is immutable and can be set once and used many times. slice: manifest.NewLevelSliceKeySorted(comparer.Compare, files), hasRangeKeys: hasRangeKeys, @@ -233,16 +227,6 @@ func (s *ingestedFlushable) newFlushIter(*IterOptions) internalIterator { panic("pebble: not implemented") } -func (s *ingestedFlushable) constructRangeDelIter( - file *manifest.FileMetadata, _ keyspan.SpanIterOptions, -) (keyspan.FragmentIterator, error) { - iters, err := s.newIters(context.Background(), file, nil, internalIterOpts{}, iterRangeDeletions) - // Note that the keyspan level iter expects a non-nil iterator to be - // returned even if there is an error. So, we return iters.RangeDeletion() - // regardless of the value of err. - return iters.RangeDeletion(), err -} - // newRangeDelIter is part of the flushable interface. // TODO(bananabrick): Using a level iter instead of a keyspan level iter to // surface range deletes is more efficient. @@ -251,8 +235,9 @@ func (s *ingestedFlushable) constructRangeDelIter( // the point iterator in constructRangeDeIter is not tracked. func (s *ingestedFlushable) newRangeDelIter(_ *IterOptions) keyspan.FragmentIterator { return keyspanimpl.NewLevelIter( + context.Background(), keyspan.SpanIterOptions{}, s.comparer.Compare, - s.constructRangeDelIter, s.slice.Iter(), manifest.Level(0), + s.newIters.NewRangeDelIter, s.slice.Iter(), manifest.Level(0), manifest.KeyTypePoint, ) } @@ -264,7 +249,8 @@ func (s *ingestedFlushable) newRangeKeyIter(o *IterOptions) keyspan.FragmentIter } return keyspanimpl.NewLevelIter( - keyspan.SpanIterOptions{}, s.comparer.Compare, s.newRangeKeyIters, + context.Background(), + keyspan.SpanIterOptions{}, s.comparer.Compare, s.newIters.NewRangeKeyIter, s.slice.Iter(), manifest.Level(0), manifest.KeyTypeRange, ) } diff --git a/flushable_test.go b/flushable_test.go index 50b7420dbe..5a0f584a34 100644 --- a/flushable_test.go +++ b/flushable_test.go @@ -118,7 +118,7 @@ func TestIngestedSSTFlushableAPI(t *testing.T) { } meta := loadFileMeta(paths) - flushable = newIngestedFlushable(meta, d.opts.Comparer, d.newIters, d.tableNewRangeKeyIter, KeyRange{}) + flushable = newIngestedFlushable(meta, d.opts.Comparer, d.newIters, KeyRange{}) return "" case "iter": iter := flushable.newIter(nil) diff --git a/ingest.go b/ingest.go index 63cc45230f..f837311a5e 100644 --- a/ingest.go +++ b/ingest.go @@ -1271,7 +1271,7 @@ func (d *DB) newIngestedFlushableEntry( } } - f := newIngestedFlushable(meta, d.opts.Comparer, d.newIters, d.tableNewRangeKeyIter, exciseSpan) + f := newIngestedFlushable(meta, d.opts.Comparer, d.newIters, exciseSpan) // NB: The logNum/seqNum are the WAL number which we're writing this entry // to and the sequence number within the WAL which we'll write this entry diff --git a/internal/keyspan/keyspanimpl/level_iter.go b/internal/keyspan/keyspanimpl/level_iter.go index 352beaeff1..cefd7d5b92 100644 --- a/internal/keyspan/keyspanimpl/level_iter.go +++ b/internal/keyspan/keyspanimpl/level_iter.go @@ -5,6 +5,7 @@ package keyspanimpl import ( + "context" "fmt" "github.com/cockroachdb/errors" @@ -17,13 +18,18 @@ import ( // TableNewSpanIter creates a new iterator for range key spans for the given // file. type TableNewSpanIter func( - file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions, + ctx context.Context, file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions, ) (keyspan.FragmentIterator, error) // LevelIter provides a merged view of spans from sstables in a level. // It takes advantage of level invariants to only have one sstable span block // open at one time, opened using the newIter function passed in. type LevelIter struct { + // The context is stored here since (a) iterators are expected to be + // short-lived (since they pin sstables), (b) plumbing a context into every + // method is very painful, (c) they do not (yet) respect context + // cancellation and are only used for tracing. + ctx context.Context cmp base.Compare // Denotes the kind of key the level iterator should read. If the key type // is KeyTypePoint, the level iterator will read range tombstones (which @@ -84,6 +90,7 @@ var _ keyspan.FragmentIterator = (*LevelIter)(nil) // NewLevelIter returns a LevelIter. func NewLevelIter( + ctx context.Context, opts keyspan.SpanIterOptions, cmp base.Compare, newIter TableNewSpanIter, @@ -92,12 +99,13 @@ func NewLevelIter( keyType manifest.KeyType, ) *LevelIter { l := &LevelIter{} - l.Init(opts, cmp, newIter, files, level, keyType) + l.Init(ctx, opts, cmp, newIter, files, level, keyType) return l } // Init initializes a LevelIter. func (l *LevelIter) Init( + ctx context.Context, opts keyspan.SpanIterOptions, cmp base.Compare, newIter TableNewSpanIter, @@ -105,6 +113,7 @@ func (l *LevelIter) Init( level manifest.Level, keyType manifest.KeyType, ) { + l.ctx = ctx l.err = nil l.level = level l.tableOpts = opts @@ -159,7 +168,7 @@ func (l *LevelIter) loadFile(file *manifest.FileMetadata, dir int) loadFileRetur return noFileLoaded } if indicator != fileAlreadyLoaded { - l.iter, l.err = l.newIter(file, l.tableOpts) + l.iter, l.err = l.newIter(l.ctx, file, l.tableOpts) if l.wrapFn != nil { l.iter = l.wrapFn(l.iter) } diff --git a/internal/keyspan/keyspanimpl/level_iter_test.go b/internal/keyspan/keyspanimpl/level_iter_test.go index 0d98eb220e..97068b8958 100644 --- a/internal/keyspan/keyspanimpl/level_iter_test.go +++ b/internal/keyspan/keyspanimpl/level_iter_test.go @@ -5,6 +5,7 @@ package keyspanimpl import ( + "context" "fmt" "strings" "testing" @@ -301,7 +302,7 @@ func TestLevelIterEquivalence(t *testing.T) { metas = append(metas, meta) } - tableNewIters := func(file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { + tableNewIters := func(_ context.Context, file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { return keyspan.NewIter(base.DefaultComparer.Compare, tc.levels[j][file.FileNum-1]), nil } // Add all the fileMetadatas to L6. @@ -314,6 +315,7 @@ func TestLevelIterEquivalence(t *testing.T) { v, err := b.Apply(nil, base.DefaultComparer, 0, 0) require.NoError(t, err) levelIter.Init( + context.Background(), keyspan.SpanIterOptions{}, base.DefaultComparer.Compare, tableNewIters, v.Levels[6].Iter(), 0, manifest.KeyTypeRange, ) @@ -440,7 +442,7 @@ func TestLevelIter(t *testing.T) { } if iter == nil { var lastFileNum base.FileNum - tableNewIters := func(file *manifest.FileMetadata, _ keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { + tableNewIters := func(_ context.Context, file *manifest.FileMetadata, _ keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { keyType := keyType spans := level[file.FileNum-1] if keyType == manifest.KeyTypePoint { @@ -458,6 +460,7 @@ func TestLevelIter(t *testing.T) { v, err := b.Apply(nil, base.DefaultComparer, 0, 0) require.NoError(t, err) iter = NewLevelIter( + context.Background(), keyspan.SpanIterOptions{}, base.DefaultComparer.Compare, tableNewIters, v.Levels[6].Iter(), 6, keyType, ) diff --git a/iterator.go b/iterator.go index b92118fbd1..d0aa406cb3 100644 --- a/iterator.go +++ b/iterator.go @@ -18,7 +18,6 @@ import ( "github.com/cockroachdb/pebble/internal/humanize" "github.com/cockroachdb/pebble/internal/invariants" "github.com/cockroachdb/pebble/internal/keyspan" - "github.com/cockroachdb/pebble/internal/keyspan/keyspanimpl" "github.com/cockroachdb/pebble/internal/manifest" "github.com/cockroachdb/pebble/internal/rangekeystack" "github.com/cockroachdb/pebble/sstable" @@ -233,7 +232,6 @@ type Iterator struct { // Non-nil if this Iterator includes a Batch. batch *Batch newIters tableNewIters - newIterRangeKey keyspanimpl.TableNewSpanIter lazyCombinedIter lazyCombinedIter seqNum uint64 // batchSeqNum is used by Iterators over indexed batches to detect when the @@ -2822,7 +2820,6 @@ func (i *Iterator) CloneWithContext(ctx context.Context, opts CloneOptions) (*It batch: i.batch, batchSeqNum: i.batchSeqNum, newIters: i.newIters, - newIterRangeKey: i.newIterRangeKey, seqNum: i.seqNum, } dbi.processBounds(dbi.opts.LowerBound, dbi.opts.UpperBound) diff --git a/open.go b/open.go index 4c6139dbe9..9f5d4e78ea 100644 --- a/open.go +++ b/open.go @@ -400,7 +400,6 @@ func Open(dirname string, opts *Options) (db *DB, err error) { opts.TableCache, d.cacheID, d.objProvider, d.opts, tableCacheSize, &sstable.CategoryStatsCollector{}) d.newIters = d.tableCache.newIters - d.tableNewRangeKeyIter = tableNewRangeKeyIter(context.TODO(), d.newIters) var previousOptionsFileNum base.DiskFileNum var previousOptionsFilename string diff --git a/overlap.go b/overlap.go index 7c8cf6ba2c..51b9e6636b 100644 --- a/overlap.go +++ b/overlap.go @@ -97,9 +97,8 @@ func (c *overlapChecker) determinePointKeyOverlapInLevel( // Check for overlapping range deletions. { c.keyspanLevelIter.Init( - keyspan.SpanIterOptions{}, c.comparer.Compare, tableNewRangeDelIter(ctx, c.newIters), - metadataIter, level, manifest.KeyTypePoint, - ) + ctx, keyspan.SpanIterOptions{}, c.comparer.Compare, + c.newIters.NewRangeDelIter, metadataIter, level, manifest.KeyTypePoint) rangeDeletionOverlap, err := determineOverlapKeyspanIterator(c.comparer.Compare, bounds, &c.keyspanLevelIter) err = errors.CombineErrors(err, c.keyspanLevelIter.Close()) if rangeDeletionOverlap || err != nil { @@ -117,9 +116,8 @@ func (c *overlapChecker) determineRangeKeyOverlapInLevel( ) (bool, error) { // Check for overlapping range keys. c.keyspanLevelIter.Init( - keyspan.SpanIterOptions{}, c.comparer.Compare, tableNewRangeKeyIter(ctx, c.newIters), - metadataIter, level, manifest.KeyTypeRange, - ) + ctx, keyspan.SpanIterOptions{}, c.comparer.Compare, + c.newIters.NewRangeKeyIter, metadataIter, level, manifest.KeyTypeRange) rangeKeyOverlap, err := determineOverlapKeyspanIterator(c.comparer.Compare, bounds, &c.keyspanLevelIter) return rangeKeyOverlap, errors.CombineErrors(err, c.keyspanLevelIter.Close()) } diff --git a/range_keys.go b/range_keys.go index 121a489440..367044a9ac 100644 --- a/range_keys.go +++ b/range_keys.go @@ -17,7 +17,7 @@ import ( // constructRangeKeyIter constructs the range-key iterator stack, populating // i.rangeKey.rangeKeyIter with the resulting iterator. -func (i *Iterator) constructRangeKeyIter() { +func (i *Iterator) constructRangeKeyIter(ctx context.Context) { i.rangeKey.rangeKeyIter = i.rangeKey.iterConfig.Init( &i.comparer, i.seqNum, i.opts.LowerBound, i.opts.UpperBound, &i.hasPrefix, &i.prefixOrFullSeekKey, false /* internalKeys */, &i.rangeKey.rangeKeyBuffers.internal) @@ -91,9 +91,10 @@ func (i *Iterator) constructRangeKeyIter() { li := i.rangeKey.iterConfig.NewLevelIter() li.Init( + ctx, i.opts.SpanIterOptions(), i.cmp, - i.newIterRangeKey, + i.newIters.NewRangeKeyIter, iter.Filter(manifest.KeyTypeRange), manifest.L0Sublevel(j), manifest.KeyTypeRange, @@ -109,8 +110,8 @@ func (i *Iterator) constructRangeKeyIter() { } li := i.rangeKey.iterConfig.NewLevelIter() spanIterOpts := i.opts.SpanIterOptions() - li.Init(spanIterOpts, i.cmp, i.newIterRangeKey, current.RangeKeyLevels[level].Iter(), - manifest.Level(level), manifest.KeyTypeRange) + li.Init(ctx, spanIterOpts, i.cmp, i.newIters.NewRangeKeyIter, + current.RangeKeyLevels[level].Iter(), manifest.Level(level), manifest.KeyTypeRange) i.rangeKey.iterConfig.AddLevel(li) } } @@ -555,7 +556,7 @@ func (i *lazyCombinedIter) initCombinedIteration( // be performing combined iteration. i.parent.rangeKey = iterRangeKeyStateAllocPool.Get().(*iteratorRangeKeyState) i.parent.rangeKey.init(i.parent.comparer.Compare, i.parent.comparer.Split, &i.parent.opts) - i.parent.constructRangeKeyIter() + i.parent.constructRangeKeyIter(i.parent.ctx) // Initialize the Iterator's interleaving iterator. i.parent.rangeKey.iiter.Init( diff --git a/scan_internal.go b/scan_internal.go index d6ee26618f..d24b6d3467 100644 --- a/scan_internal.go +++ b/scan_internal.go @@ -409,23 +409,22 @@ type IteratorLevel struct { // *must* return the range delete as well as the range key unset/delete that did // the shadowing. type scanInternalIterator struct { - ctx context.Context - db *DB - opts scanInternalOptions - comparer *base.Comparer - merge Merge - iter internalIterator - readState *readState - version *version - rangeKey *iteratorRangeKeyState - pointKeyIter internalIterator - iterKV *base.InternalKV - alloc *iterAlloc - newIters tableNewIters - newIterRangeKey keyspanimpl.TableNewSpanIter - seqNum uint64 - iterLevels []IteratorLevel - mergingIter *mergingIter + ctx context.Context + db *DB + opts scanInternalOptions + comparer *base.Comparer + merge Merge + iter internalIterator + readState *readState + version *version + rangeKey *iteratorRangeKeyState + pointKeyIter internalIterator + iterKV *base.InternalKV + alloc *iterAlloc + newIters tableNewIters + seqNum uint64 + iterLevels []IteratorLevel + mergingIter *mergingIter // boundsBuf holds two buffers used to store the lower and upper bounds. // Whenever the InternalIterator's bounds change, the new bounds are copied @@ -901,9 +900,8 @@ func (i *scanInternalIterator) constructPointIter( i.ctx, i.opts.IterOptions, i.comparer, i.newIters, files, level, internalIterOpts{}) mlevels[mlevelsIndex].iter = li - rli.Init(keyspan.SpanIterOptions{RangeKeyFilters: i.opts.RangeKeyFilters}, - i.comparer.Compare, tableNewRangeDelIter(i.ctx, i.newIters), files, level, - manifest.KeyTypePoint) + rli.Init(i.ctx, keyspan.SpanIterOptions{RangeKeyFilters: i.opts.RangeKeyFilters}, + i.comparer.Compare, i.newIters.NewRangeDelIter, files, level, manifest.KeyTypePoint) rangeDelIters = append(rangeDelIters, rli) levelsIndex++ @@ -1023,7 +1021,7 @@ func (i *scanInternalIterator) constructRangeKeyIter() error { // around Key Trailer order. iter := current.RangeKeyLevels[0].Iter() for f := iter.Last(); f != nil; f = iter.Prev() { - spanIter, err := i.newIterRangeKey(f, i.opts.SpanIterOptions()) + spanIter, err := i.newIters.NewRangeKeyIter(i.ctx, f, i.opts.SpanIterOptions()) if err != nil { return err } @@ -1058,7 +1056,7 @@ func (i *scanInternalIterator) constructRangeKeyIter() error { levSlice := manifest.NewLevelSliceKeySorted(i.db.cmp, nonRemoteFiles) levIter = levSlice.Iter() } - li.Init(spanIterOpts, i.comparer.Compare, i.newIterRangeKey, levIter, + li.Init(i.ctx, spanIterOpts, i.comparer.Compare, i.newIters.NewRangeKeyIter, levIter, manifest.Level(level), manifest.KeyTypeRange) i.rangeKey.iterConfig.AddLevel(li) } diff --git a/table_cache.go b/table_cache.go index a8f9154b95..4e0de38c87 100644 --- a/table_cache.go +++ b/table_cache.go @@ -19,7 +19,6 @@ import ( "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/internal/invariants" "github.com/cockroachdb/pebble/internal/keyspan" - "github.com/cockroachdb/pebble/internal/keyspan/keyspanimpl" "github.com/cockroachdb/pebble/internal/manifest" "github.com/cockroachdb/pebble/internal/private" "github.com/cockroachdb/pebble/objstorage" @@ -59,32 +58,28 @@ type tableNewIters func( kinds iterKinds, ) (iterSet, error) -// tableNewRangeDelIter takes a tableNewIters and returns a TableNewSpanIter -// for the rangedel iterator returned by tableNewIters. -func tableNewRangeDelIter( - ctx context.Context, newIters tableNewIters, -) keyspanimpl.TableNewSpanIter { - return func(file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { - iters, err := newIters(ctx, file, nil, internalIterOpts{}, iterRangeDeletions) - if err != nil { - return nil, err - } - return iters.RangeDeletion(), nil +// NewRangeDelIter is a TableNewSpanIter that returns a range deletion iterator +// constructed through f. +func (f tableNewIters) NewRangeDelIter( + ctx context.Context, file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions, +) (keyspan.FragmentIterator, error) { + iters, err := f(ctx, file, nil, internalIterOpts{}, iterRangeDeletions) + if err != nil { + return nil, err } + return iters.RangeDeletion(), nil } -// tableNewRangeKeyIter takes a tableNewIters and returns a TableNewSpanIter -// for the range key iterator returned by tableNewIters. -func tableNewRangeKeyIter( - ctx context.Context, newIters tableNewIters, -) keyspanimpl.TableNewSpanIter { - return func(file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions) (keyspan.FragmentIterator, error) { - iters, err := newIters(ctx, file, nil, internalIterOpts{}, iterRangeKeys) - if err != nil { - return nil, err - } - return iters.RangeKey(), nil +// NewRangeKeyIter is a TableNewSpanIter that returns a range key iterator +// constructed through f. +func (f tableNewIters) NewRangeKeyIter( + ctx context.Context, file *manifest.FileMetadata, iterOptions keyspan.SpanIterOptions, +) (keyspan.FragmentIterator, error) { + iters, err := f(ctx, file, nil, internalIterOpts{}, iterRangeKeys) + if err != nil { + return nil, err } + return iters.RangeKey(), nil } var tableCacheLabels = pprof.Labels("pebble", "table-cache")