diff --git a/pkg/kv/kvserver/spanset/batch.go b/pkg/kv/kvserver/spanset/batch.go index 704023e1fd54..805fef2bcd8d 100644 --- a/pkg/kv/kvserver/spanset/batch.go +++ b/pkg/kv/kvserver/spanset/batch.go @@ -18,7 +18,6 @@ import ( "github.com/cockroachdb/cockroach/pkg/keys" "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage" - "github.com/cockroachdb/cockroach/pkg/storage/pebbleiter" "github.com/cockroachdb/cockroach/pkg/util/hlc" "github.com/cockroachdb/cockroach/pkg/util/protoutil" "github.com/cockroachdb/cockroach/pkg/util/uuid" @@ -421,9 +420,9 @@ func (i *EngineIterator) UnsafeRawEngineKey() []byte { return i.i.UnsafeRawEngineKey() } -// GetRawIter is part of the storage.EngineIterator interface. -func (i *EngineIterator) GetRawIter() pebbleiter.Iterator { - return i.i.GetRawIter() +// CloneContext is part of the storage.EngineIterator interface. +func (i *EngineIterator) CloneContext() storage.CloneContext { + return i.i.CloneContext() } // Stats is part of the storage.EngineIterator interface. diff --git a/pkg/storage/engine.go b/pkg/storage/engine.go index 464b1103191c..d83866b18fc8 100644 --- a/pkg/storage/engine.go +++ b/pkg/storage/engine.go @@ -361,9 +361,9 @@ type EngineIterator interface { // Value returns the current value as a byte slice. // REQUIRES: latest positioning function returned valid=true. Value() ([]byte, error) - // GetRawIter is a low-level method only for use in the storage package, - // that returns the underlying pebble Iterator. - GetRawIter() pebbleiter.Iterator + // CloneContext is a low-level method only for use in the storage package, + // that provides sufficient context that the iterator may be cloned. + CloneContext() CloneContext // SeekEngineKeyGEWithLimit is similar to SeekEngineKeyGE, but takes an // additional exclusive upper limit parameter. The limit is semantically // best-effort, and is an optimization to avoid O(n^2) iteration behavior in @@ -388,6 +388,12 @@ type EngineIterator interface { Stats() IteratorStats } +// CloneContext is an opaque type encapsulating sufficient context to construct +// a clone of an existing iterator. +type CloneContext struct { + rawIter pebbleiter.Iterator +} + // IterOptions contains options used to create an {MVCC,Engine}Iterator. // // For performance, every {MVCC,Engine}Iterator must specify either Prefix or diff --git a/pkg/storage/intent_interleaving_iter.go b/pkg/storage/intent_interleaving_iter.go index f2c31525b0c6..ecc6511800ff 100644 --- a/pkg/storage/intent_interleaving_iter.go +++ b/pkg/storage/intent_interleaving_iter.go @@ -267,7 +267,8 @@ func newIntentInterleavingIterator(reader Reader, opts IterOptions) MVCCIterator if reader.ConsistentIterators() { iter = maybeUnwrapUnsafeIter(reader.NewMVCCIterator(MVCCKeyIterKind, opts)).(*pebbleIterator) } else { - iter = newPebbleIteratorByCloning(intentIter.GetRawIter(), opts, StandardDurability) + cloneCtx := intentIter.CloneContext() + iter = newPebbleIteratorByCloning(cloneCtx.rawIter, opts, StandardDurability) } *iiIter = intentInterleavingIter{ diff --git a/pkg/storage/mvcc.go b/pkg/storage/mvcc.go index bf324a0f482c..a5a3955d37ae 100644 --- a/pkg/storage/mvcc.go +++ b/pkg/storage/mvcc.go @@ -5052,7 +5052,8 @@ func MVCCResolveWriteIntentRange( mvccIter = rw.NewMVCCIterator(MVCCKeyIterKind, iterOpts) } else { // For correctness, we need mvccIter to be consistent with engineIter. - mvccIter = newPebbleIteratorByCloning(engineIter.GetRawIter(), iterOpts, StandardDurability) + cloneCtx := engineIter.CloneContext() + mvccIter = newPebbleIteratorByCloning(cloneCtx.rawIter, iterOpts, StandardDurability) } iterAndBuf := GetBufUsingIter(mvccIter) defer func() { diff --git a/pkg/storage/pebble_iterator.go b/pkg/storage/pebble_iterator.go index 95ef7ec31845..36a914c8f453 100644 --- a/pkg/storage/pebble_iterator.go +++ b/pkg/storage/pebble_iterator.go @@ -887,9 +887,9 @@ func (p *pebbleIterator) IsPrefix() bool { return p.prefix } -// GetRawIter is part of the EngineIterator interface. -func (p *pebbleIterator) GetRawIter() pebbleiter.Iterator { - return p.iter +// CloneContext is part of the EngineIterator interface. +func (p *pebbleIterator) CloneContext() CloneContext { + return CloneContext{rawIter: p.iter} } func (p *pebbleIterator) getBlockPropertyFilterMask() pebble.BlockPropertyFilterMask {