Upgrade versions of vendored libs
This commit is contained in:
407
vendor/github.com/cockroachdb/pebble/scan_internal.go
generated
vendored
407
vendor/github.com/cockroachdb/pebble/scan_internal.go
generated
vendored
@@ -7,12 +7,15 @@ package pebble
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
"github.com/cockroachdb/pebble/internal/base"
|
||||
"github.com/cockroachdb/pebble/internal/invariants"
|
||||
"github.com/cockroachdb/pebble/internal/keyspan"
|
||||
"github.com/cockroachdb/pebble/internal/manifest"
|
||||
"github.com/cockroachdb/pebble/objstorage"
|
||||
"github.com/cockroachdb/pebble/sstable"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -92,8 +95,41 @@ type pcIterPos int
|
||||
const (
|
||||
pcIterPosCur pcIterPos = iota
|
||||
pcIterPosNext
|
||||
pcIterPosPrev
|
||||
)
|
||||
|
||||
// pointCollapsingSSTIterator implements sstable.Iterator while composing
|
||||
// pointCollapsingIterator.
|
||||
type pointCollapsingSSTIterator struct {
|
||||
pointCollapsingIterator
|
||||
childIter sstable.Iterator
|
||||
}
|
||||
|
||||
var pcSSTIterPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &pointCollapsingSSTIterator{}
|
||||
},
|
||||
}
|
||||
|
||||
// MaybeFilteredKeys implements the sstable.Iterator interface.
|
||||
func (p *pointCollapsingSSTIterator) MaybeFilteredKeys() bool {
|
||||
return p.childIter.MaybeFilteredKeys()
|
||||
}
|
||||
|
||||
// SetCloseHook implements the sstable.Iterator interface.
|
||||
func (p *pointCollapsingSSTIterator) SetCloseHook(fn func(i sstable.Iterator) error) {
|
||||
p.childIter.SetCloseHook(fn)
|
||||
}
|
||||
|
||||
// Close implements the sstable.Iterator interface.
|
||||
func (p *pointCollapsingSSTIterator) Close() error {
|
||||
err := p.pointCollapsingIterator.Close()
|
||||
p.pointCollapsingIterator = pointCollapsingIterator{}
|
||||
p.childIter = nil
|
||||
pcSSTIterPool.Put(p)
|
||||
return err
|
||||
}
|
||||
|
||||
// pointCollapsingIterator is an internalIterator that collapses point keys and
|
||||
// returns at most one point internal key for each user key. Merges are merged,
|
||||
// sets are emitted as-is, and SingleDeletes are collapsed with the next point
|
||||
@@ -112,32 +148,52 @@ type pointCollapsingIterator struct {
|
||||
merge base.Merge
|
||||
err error
|
||||
seqNum uint64
|
||||
// The current position of `iter`. Could be backed by savedKey (i.e. iterKey ==
|
||||
// &savedKey) or could be owned by `iter`. findNextEntry and similar methods
|
||||
// are expected to save the current value of this to savedKey if they're
|
||||
// iterating away from the current key but still need to retain it. See
|
||||
// comments in findNextEntry on how this field is used.
|
||||
// The current position of `iter`. Always owned by the underlying iter.
|
||||
iterKey *InternalKey
|
||||
// The last saved key. findNextEntry and similar methods are expected to save
|
||||
// the current value of iterKey to savedKey if they're iterating away from the
|
||||
// current key but still need to retain it. See comments in findNextEntry on
|
||||
// how this field is used.
|
||||
//
|
||||
// At the end of a positioning call:
|
||||
// - if pos == pcIterPosNext, iterKey is pointing to the next user key owned
|
||||
// by `iter` while savedKey is holding a copy to our current key.
|
||||
// - If pos == pcIterPosCur, iterKey is pointing to either a savedKey-backed
|
||||
// copy of the current key, or an `iter`-owned current key in which case
|
||||
// the value of savedKey is undefined.
|
||||
iterKey *InternalKey
|
||||
savedKey InternalKey
|
||||
// - If pos == pcIterPosCur, iterKey is pointing to an `iter`-owned current
|
||||
// key, and savedKey is either undefined or pointing to a version of the
|
||||
// current key owned by this iterator (i.e. backed by savedKeyBuf).
|
||||
// - if pos == pcIterPosPrev, iterKey is pointing to the key before
|
||||
// p.savedKey. p.savedKey is treated as the current key and is owned by
|
||||
// this iterator, while p.iterKey is the previous key that is the current
|
||||
// position of the child iterator.
|
||||
savedKey InternalKey
|
||||
savedKeyBuf []byte
|
||||
// elideRangeDeletes ignores range deletes returned by the interleaving
|
||||
// iterator if true.
|
||||
elideRangeDeletes bool
|
||||
// Value at the current iterator position, at iterKey.
|
||||
value base.LazyValue
|
||||
iterValue base.LazyValue
|
||||
// Saved value backed by valueBuf, if set. Used in reverse iteration, and
|
||||
// for merges.
|
||||
savedValue base.LazyValue
|
||||
// Used for Merge keys only.
|
||||
valueMerger ValueMerger
|
||||
valueBuf []byte
|
||||
// If fixedSeqNum is non-zero, all emitted points are verified to have this
|
||||
// fixed sequence number.
|
||||
fixedSeqNum uint64
|
||||
}
|
||||
|
||||
// SeekPrefixGE implements the InternalIterator interface.
|
||||
func (p *pointCollapsingIterator) SeekPrefixGE(
|
||||
prefix, key []byte, flags base.SeekGEFlags,
|
||||
) (*base.InternalKey, base.LazyValue) {
|
||||
panic("unimplemented")
|
||||
p.resetKey()
|
||||
p.iterKey, p.iterValue = p.iter.SeekPrefixGE(prefix, key, flags)
|
||||
p.pos = pcIterPosCur
|
||||
if p.iterKey == nil {
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
return p.findNextEntry()
|
||||
}
|
||||
|
||||
// SeekGE implements the InternalIterator interface.
|
||||
@@ -145,7 +201,7 @@ func (p *pointCollapsingIterator) SeekGE(
|
||||
key []byte, flags base.SeekGEFlags,
|
||||
) (*base.InternalKey, base.LazyValue) {
|
||||
p.resetKey()
|
||||
p.iterKey, p.value = p.iter.SeekGE(key, flags)
|
||||
p.iterKey, p.iterValue = p.iter.SeekGE(key, flags)
|
||||
p.pos = pcIterPosCur
|
||||
if p.iterKey == nil {
|
||||
return nil, base.LazyValue{}
|
||||
@@ -157,11 +213,17 @@ func (p *pointCollapsingIterator) SeekGE(
|
||||
func (p *pointCollapsingIterator) SeekLT(
|
||||
key []byte, flags base.SeekLTFlags,
|
||||
) (*base.InternalKey, base.LazyValue) {
|
||||
panic("unimplemented")
|
||||
p.resetKey()
|
||||
p.iterKey, p.iterValue = p.iter.SeekLT(key, flags)
|
||||
p.pos = pcIterPosCur
|
||||
if p.iterKey == nil {
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
return p.findPrevEntry()
|
||||
}
|
||||
|
||||
func (p *pointCollapsingIterator) resetKey() {
|
||||
p.savedKey.UserKey = p.savedKey.UserKey[:0]
|
||||
p.savedKey.UserKey = p.savedKeyBuf[:0]
|
||||
p.savedKey.Trailer = 0
|
||||
p.valueMerger = nil
|
||||
p.valueBuf = p.valueBuf[:0]
|
||||
@@ -169,59 +231,73 @@ func (p *pointCollapsingIterator) resetKey() {
|
||||
p.pos = pcIterPosCur
|
||||
}
|
||||
|
||||
// findNextEntry is called to return the next key. p.iter must be positioned at
|
||||
// the start of the first user key we are interested in.
|
||||
func (p *pointCollapsingIterator) findNextEntry() (*base.InternalKey, base.LazyValue) {
|
||||
finishAndReturnMerge := func() (*base.InternalKey, base.LazyValue) {
|
||||
value, closer, err := p.valueMerger.Finish(true /* includesBase */)
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
p.valueBuf = append(p.valueBuf[:0], value...)
|
||||
if closer != nil {
|
||||
_ = closer.Close()
|
||||
}
|
||||
p.valueMerger = nil
|
||||
newValue := base.MakeInPlaceValue(value)
|
||||
return &p.savedKey, newValue
|
||||
func (p *pointCollapsingIterator) verifySeqNum(key *base.InternalKey) *base.InternalKey {
|
||||
if !invariants.Enabled {
|
||||
return key
|
||||
}
|
||||
if p.fixedSeqNum == 0 || key == nil || key.Kind() == InternalKeyKindRangeDelete {
|
||||
return key
|
||||
}
|
||||
if key.SeqNum() != p.fixedSeqNum {
|
||||
panic(fmt.Sprintf("expected foreign point key to have seqnum %d, got %d", p.fixedSeqNum, key.SeqNum()))
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
// saveKey sets p.iterKey (if not-nil) to &p.savedKey. We can use this equality
|
||||
// as a proxy to determine if we're at the first internal key for a user key.
|
||||
// finishAndReturnMerge finishes off the valueMerger and returns the saved key.
|
||||
func (p *pointCollapsingIterator) finishAndReturnMerge() (*base.InternalKey, base.LazyValue) {
|
||||
value, closer, err := p.valueMerger.Finish(true /* includesBase */)
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
p.valueBuf = append(p.valueBuf[:0], value...)
|
||||
if closer != nil {
|
||||
_ = closer.Close()
|
||||
}
|
||||
p.valueMerger = nil
|
||||
val := base.MakeInPlaceValue(p.valueBuf)
|
||||
return p.verifySeqNum(&p.savedKey), val
|
||||
}
|
||||
|
||||
// findNextEntry is called to return the next key. p.iter must be positioned at the
|
||||
// start of the first user key we are interested in.
|
||||
func (p *pointCollapsingIterator) findNextEntry() (*base.InternalKey, base.LazyValue) {
|
||||
p.saveKey()
|
||||
// Saves a comparison in the fast path
|
||||
firstIteration := true
|
||||
for p.iterKey != nil {
|
||||
// NB: p.savedKey is either the current key (iff p.iterKey == &p.savedKey),
|
||||
// NB: p.savedKey is either the current key (iff p.iterKey == firstKey),
|
||||
// or the previous key.
|
||||
if p.iterKey != &p.savedKey && !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) {
|
||||
if !firstIteration && !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) {
|
||||
if p.valueMerger != nil {
|
||||
if p.savedKey.Kind() != InternalKeyKindMerge {
|
||||
panic(fmt.Sprintf("expected key %s to have MERGE kind", p.iterKey))
|
||||
}
|
||||
p.pos = pcIterPosNext
|
||||
return finishAndReturnMerge()
|
||||
return p.finishAndReturnMerge()
|
||||
}
|
||||
p.saveKey()
|
||||
continue
|
||||
}
|
||||
firstIteration = false
|
||||
if s := p.iter.Span(); s != nil && s.CoversAt(p.seqNum, p.iterKey.SeqNum()) {
|
||||
// All future keys for this user key must be deleted.
|
||||
if p.valueMerger != nil {
|
||||
return finishAndReturnMerge()
|
||||
return p.finishAndReturnMerge()
|
||||
} else if p.savedKey.Kind() == InternalKeyKindSingleDelete {
|
||||
panic("cannot process singledel key in point collapsing iterator")
|
||||
}
|
||||
// Fast forward to the next user key.
|
||||
p.saveKey()
|
||||
p.iterKey, p.value = p.iter.Next()
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
for p.iterKey != nil && p.savedKey.SeqNum() >= p.iterKey.SeqNum() && p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) {
|
||||
p.iterKey, p.value = p.iter.Next()
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
}
|
||||
continue
|
||||
}
|
||||
switch p.savedKey.Kind() {
|
||||
case InternalKeyKindSet, InternalKeyKindDelete, InternalKeyKindSetWithDelete:
|
||||
p.saveKey()
|
||||
case InternalKeyKindSet, InternalKeyKindDelete, InternalKeyKindSetWithDelete, InternalKeyKindDeleteSized:
|
||||
// Note that we return SETs directly, even if they would otherwise get
|
||||
// compacted into a Del to turn into a SetWithDelete. This is a fast
|
||||
// path optimization that can break SINGLEDEL determinism. To lead to
|
||||
@@ -240,14 +316,14 @@ func (p *pointCollapsingIterator) findNextEntry() (*base.InternalKey, base.LazyV
|
||||
// of blocks and can determine user key changes without doing key saves
|
||||
// or comparisons.
|
||||
p.pos = pcIterPosCur
|
||||
return p.iterKey, p.value
|
||||
return p.verifySeqNum(p.iterKey), p.iterValue
|
||||
case InternalKeyKindSingleDelete:
|
||||
// Panic, as this iterator is not expected to observe single deletes.
|
||||
panic("cannot process singledel key in point collapsing iterator")
|
||||
case InternalKeyKindMerge:
|
||||
if p.valueMerger == nil {
|
||||
// Set up merger. This is the first Merge key encountered.
|
||||
value, callerOwned, err := p.value.Value(p.valueBuf[:0])
|
||||
value, callerOwned, err := p.iterValue.Value(p.valueBuf[:0])
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return nil, base.LazyValue{}
|
||||
@@ -263,13 +339,13 @@ func (p *pointCollapsingIterator) findNextEntry() (*base.InternalKey, base.LazyV
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
p.saveKey()
|
||||
p.iterKey, p.value = p.iter.Next()
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
continue
|
||||
}
|
||||
switch p.iterKey.Kind() {
|
||||
case InternalKeyKindSet, InternalKeyKindMerge, InternalKeyKindSetWithDelete:
|
||||
// Merge into key.
|
||||
value, callerOwned, err := p.value.Value(p.valueBuf[:0])
|
||||
value, callerOwned, err := p.iterValue.Value(p.valueBuf[:0])
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return nil, base.LazyValue{}
|
||||
@@ -287,31 +363,144 @@ func (p *pointCollapsingIterator) findNextEntry() (*base.InternalKey, base.LazyV
|
||||
if p.iterKey.Kind() != InternalKeyKindMerge {
|
||||
p.savedKey.SetKind(p.iterKey.Kind())
|
||||
p.pos = pcIterPosCur
|
||||
return finishAndReturnMerge()
|
||||
return p.finishAndReturnMerge()
|
||||
}
|
||||
p.iterKey, p.value = p.iter.Next()
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
case InternalKeyKindRangeDelete:
|
||||
if p.elideRangeDeletes {
|
||||
// Skip this range delete, and process any point after it.
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
p.saveKey()
|
||||
continue
|
||||
}
|
||||
// These are interleaved by the interleaving iterator ahead of all points.
|
||||
// We should pass them as-is, but also account for any points ahead of
|
||||
// them.
|
||||
p.pos = pcIterPosCur
|
||||
return p.iterKey, p.value
|
||||
return p.verifySeqNum(p.iterKey), p.iterValue
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected kind: %d", p.iterKey.Kind()))
|
||||
}
|
||||
}
|
||||
if p.valueMerger != nil {
|
||||
p.pos = pcIterPosNext
|
||||
return finishAndReturnMerge()
|
||||
return p.finishAndReturnMerge()
|
||||
}
|
||||
p.resetKey()
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
|
||||
// findPrevEntry finds the relevant point key to return for the previous user key
|
||||
// (i.e. in reverse iteration). Requires that the iterator is already positioned
|
||||
// at the first-in-reverse (i.e. rightmost / largest) internal key encountered
|
||||
// for that user key.
|
||||
func (p *pointCollapsingIterator) findPrevEntry() (*base.InternalKey, base.LazyValue) {
|
||||
if p.iterKey == nil {
|
||||
p.pos = pcIterPosCur
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
|
||||
p.saveKey()
|
||||
firstIteration := true
|
||||
for p.iterKey != nil {
|
||||
if !firstIteration && !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) {
|
||||
p.pos = pcIterPosPrev
|
||||
return p.verifySeqNum(&p.savedKey), p.savedValue
|
||||
}
|
||||
firstIteration = false
|
||||
if s := p.iter.Span(); s != nil && s.CoversAt(p.seqNum, p.iterKey.SeqNum()) {
|
||||
// Skip this key.
|
||||
p.iterKey, p.iterValue = p.iter.Prev()
|
||||
p.saveKey()
|
||||
continue
|
||||
}
|
||||
switch p.iterKey.Kind() {
|
||||
case InternalKeyKindSet, InternalKeyKindDelete, InternalKeyKindSetWithDelete:
|
||||
// Instead of calling saveKey(), we take advantage of the invariant that
|
||||
// p.savedKey.UserKey == p.iterKey.UserKey (otherwise we'd have gone into
|
||||
// the !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) case at
|
||||
// the top of this for loop). That allows us to just save the trailer
|
||||
// and move on.
|
||||
if invariants.Enabled && !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) {
|
||||
panic("unexpected inequality between p.iterKey and p.savedKey")
|
||||
}
|
||||
p.savedKey.Trailer = p.iterKey.Trailer
|
||||
// Copy value into p.savedValue.
|
||||
value, callerOwned, err := p.iterValue.Value(p.valueBuf[:0])
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
if !callerOwned {
|
||||
p.valueBuf = append(p.valueBuf[:0], value...)
|
||||
} else {
|
||||
p.valueBuf = value
|
||||
}
|
||||
p.valueMerger = nil
|
||||
p.savedValue = base.MakeInPlaceValue(p.valueBuf)
|
||||
p.iterKey, p.iterValue = p.iter.Prev()
|
||||
continue
|
||||
case InternalKeyKindSingleDelete:
|
||||
// Panic, as this iterator is not expected to observe single deletes.
|
||||
panic("cannot process singledel key in point collapsing iterator")
|
||||
case InternalKeyKindMerge:
|
||||
panic("cannot process merge key in point collapsing iterator in reverse iteration")
|
||||
case InternalKeyKindRangeDelete:
|
||||
if p.elideRangeDeletes {
|
||||
// Skip this range delete, and process any point before it.
|
||||
p.iterKey, p.iterValue = p.iter.Prev()
|
||||
continue
|
||||
}
|
||||
// These are interleaved by the interleaving iterator behind all points.
|
||||
if p.savedKey.Kind() != InternalKeyKindRangeDelete {
|
||||
// If the previous key was not a rangedel, we need to return it. Pretend that we're at the
|
||||
// previous user key (i.e. with p.pos = pcIterPosPrev) even if we're not, so on the next
|
||||
// Prev() we encounter and return this rangedel. For now return the point ahead of
|
||||
// this range del (if any).
|
||||
p.pos = pcIterPosPrev
|
||||
return p.verifySeqNum(&p.savedKey), p.savedValue
|
||||
}
|
||||
// We take advantage of the fact that a Prev() *on* a RangeDel iterKey
|
||||
// always takes us to a different user key, so on the next iteration
|
||||
// we will fall into the !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey)
|
||||
// case.
|
||||
//
|
||||
// Instead of calling saveKey(), we take advantage of the invariant that
|
||||
// p.savedKey.UserKey == p.iterKey.UserKey (otherwise we'd have gone into
|
||||
// the !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) case at
|
||||
// the top of this for loop). That allows us to just save the trailer
|
||||
// and move on.
|
||||
if invariants.Enabled && !p.comparer.Equal(p.iterKey.UserKey, p.savedKey.UserKey) {
|
||||
panic("unexpected inequality between p.iterKey and p.savedKey")
|
||||
}
|
||||
p.savedKey.Trailer = p.iterKey.Trailer
|
||||
// Copy value into p.savedValue.
|
||||
value, callerOwned, err := p.iterValue.Value(p.valueBuf[:0])
|
||||
if err != nil {
|
||||
p.err = err
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
if !callerOwned {
|
||||
p.valueBuf = append(p.valueBuf[:0], value...)
|
||||
} else {
|
||||
p.valueBuf = value
|
||||
}
|
||||
p.valueMerger = nil
|
||||
p.savedValue = base.MakeInPlaceValue(p.valueBuf)
|
||||
p.iterKey, p.iterValue = p.iter.Prev()
|
||||
continue
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected kind: %d", p.iterKey.Kind()))
|
||||
}
|
||||
}
|
||||
p.pos = pcIterPosPrev
|
||||
return p.verifySeqNum(&p.savedKey), p.savedValue
|
||||
}
|
||||
|
||||
// First implements the InternalIterator interface.
|
||||
func (p *pointCollapsingIterator) First() (*base.InternalKey, base.LazyValue) {
|
||||
p.resetKey()
|
||||
p.iterKey, p.value = p.iter.First()
|
||||
p.iterKey, p.iterValue = p.iter.First()
|
||||
p.pos = pcIterPosCur
|
||||
if p.iterKey == nil {
|
||||
return nil, base.LazyValue{}
|
||||
@@ -321,41 +510,67 @@ func (p *pointCollapsingIterator) First() (*base.InternalKey, base.LazyValue) {
|
||||
|
||||
// Last implements the InternalIterator interface.
|
||||
func (p *pointCollapsingIterator) Last() (*base.InternalKey, base.LazyValue) {
|
||||
panic("unimplemented")
|
||||
p.resetKey()
|
||||
p.iterKey, p.iterValue = p.iter.Last()
|
||||
p.pos = pcIterPosCur
|
||||
if p.iterKey == nil {
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
return p.findPrevEntry()
|
||||
}
|
||||
|
||||
func (p *pointCollapsingIterator) saveKey() {
|
||||
if p.iterKey == nil {
|
||||
p.savedKey = InternalKey{UserKey: p.savedKey.UserKey[:0]}
|
||||
return
|
||||
} else if p.iterKey == &p.savedKey {
|
||||
// Do nothing.
|
||||
p.savedKey = InternalKey{UserKey: p.savedKeyBuf[:0]}
|
||||
return
|
||||
}
|
||||
p.savedKey.CopyFrom(*p.iterKey)
|
||||
p.iterKey = &p.savedKey
|
||||
p.savedKeyBuf = append(p.savedKeyBuf[:0], p.iterKey.UserKey...)
|
||||
p.savedKey = InternalKey{UserKey: p.savedKeyBuf, Trailer: p.iterKey.Trailer}
|
||||
}
|
||||
|
||||
// Next implements the InternalIterator interface.
|
||||
func (p *pointCollapsingIterator) Next() (*base.InternalKey, base.LazyValue) {
|
||||
switch p.pos {
|
||||
case pcIterPosPrev:
|
||||
p.saveKey()
|
||||
if p.iterKey != nil && p.iterKey.Kind() == InternalKeyKindRangeDelete && !p.elideRangeDeletes {
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
p.pos = pcIterPosCur
|
||||
} else {
|
||||
// Fast forward to the next user key.
|
||||
key, val := p.iter.Next()
|
||||
// p.iterKey.SeqNum() >= key.SeqNum() is an optimization that allows us to
|
||||
// use p.iterKey.SeqNum() < key.SeqNum() as a sign that the user key has
|
||||
// changed, without needing to do the full key comparison.
|
||||
for key != nil && p.savedKey.SeqNum() >= key.SeqNum() &&
|
||||
p.comparer.Equal(p.savedKey.UserKey, key.UserKey) {
|
||||
key, val = p.iter.Next()
|
||||
}
|
||||
if key == nil {
|
||||
// There are no keys to return.
|
||||
p.resetKey()
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
p.iterKey, p.iterValue = key, val
|
||||
p.pos = pcIterPosCur
|
||||
}
|
||||
fallthrough
|
||||
case pcIterPosCur:
|
||||
p.saveKey()
|
||||
if p.iterKey != nil && p.iterKey.Kind() == InternalKeyKindRangeDelete {
|
||||
if p.iterKey != nil && p.iterKey.Kind() == InternalKeyKindRangeDelete && !p.elideRangeDeletes {
|
||||
// Step over the interleaved range delete and process the very next
|
||||
// internal key, even if it's at the same user key. This is because a
|
||||
// point for that user key has not been returned yet.
|
||||
p.iterKey, p.value = p.iter.Next()
|
||||
p.iterKey, p.iterValue = p.iter.Next()
|
||||
break
|
||||
}
|
||||
// Fast forward to the next user key. p.iterKey stayed at p.savedKey for
|
||||
// this loop.
|
||||
// Fast forward to the next user key.
|
||||
key, val := p.iter.Next()
|
||||
// p.iterKey.SeqNum() >= key.SeqNum() is an optimization that allows us to
|
||||
// use p.iterKey.SeqNum() < key.SeqNum() as a sign that the user key has
|
||||
// changed, without needing to do the full key comparison.
|
||||
for p.iterKey != nil && key != nil && p.iterKey.SeqNum() >= key.SeqNum() &&
|
||||
p.comparer.Equal(p.iterKey.UserKey, key.UserKey) {
|
||||
for key != nil && p.savedKey.SeqNum() >= key.SeqNum() &&
|
||||
p.comparer.Equal(p.savedKey.UserKey, key.UserKey) {
|
||||
key, val = p.iter.Next()
|
||||
}
|
||||
if key == nil {
|
||||
@@ -363,7 +578,7 @@ func (p *pointCollapsingIterator) Next() (*base.InternalKey, base.LazyValue) {
|
||||
p.resetKey()
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
p.iterKey, p.value = key, val
|
||||
p.iterKey, p.iterValue = key, val
|
||||
case pcIterPosNext:
|
||||
p.pos = pcIterPosCur
|
||||
}
|
||||
@@ -376,12 +591,56 @@ func (p *pointCollapsingIterator) Next() (*base.InternalKey, base.LazyValue) {
|
||||
|
||||
// NextPrefix implements the InternalIterator interface.
|
||||
func (p *pointCollapsingIterator) NextPrefix(succKey []byte) (*base.InternalKey, base.LazyValue) {
|
||||
// TODO(bilal): Implement this. It'll be similar to SeekGE, except we'll call
|
||||
// the child iterator's NextPrefix, and have some special logic in case pos
|
||||
// is pcIterPosNext.
|
||||
panic("unimplemented")
|
||||
}
|
||||
|
||||
// Prev implements the InternalIterator interface.
|
||||
func (p *pointCollapsingIterator) Prev() (*base.InternalKey, base.LazyValue) {
|
||||
panic("unimplemented")
|
||||
switch p.pos {
|
||||
case pcIterPosNext:
|
||||
// Rewind backwards to the previous iter key.
|
||||
p.saveKey()
|
||||
key, val := p.iter.Prev()
|
||||
for key != nil && p.savedKey.SeqNum() <= key.SeqNum() &&
|
||||
p.comparer.Equal(p.savedKey.UserKey, key.UserKey) {
|
||||
if key.Kind() == InternalKeyKindRangeDelete && !p.elideRangeDeletes {
|
||||
// We need to pause at this range delete and return it as-is, as "cur"
|
||||
// is referencing the point key after it, not the range delete.
|
||||
break
|
||||
}
|
||||
key, val = p.iter.Prev()
|
||||
}
|
||||
p.iterKey = key
|
||||
p.iterValue = val
|
||||
p.pos = pcIterPosCur
|
||||
fallthrough
|
||||
case pcIterPosCur:
|
||||
p.saveKey()
|
||||
key, val := p.iter.Prev()
|
||||
for key != nil && p.savedKey.SeqNum() <= key.SeqNum() &&
|
||||
p.comparer.Equal(p.savedKey.UserKey, key.UserKey) {
|
||||
if key.Kind() == InternalKeyKindRangeDelete && !p.elideRangeDeletes {
|
||||
// We need to pause at this range delete and return it as-is, as "cur"
|
||||
// is referencing the point key after it, not the range delete.
|
||||
break
|
||||
}
|
||||
key, val = p.iter.Prev()
|
||||
}
|
||||
p.iterKey = key
|
||||
p.iterValue = val
|
||||
p.pos = pcIterPosCur
|
||||
case pcIterPosPrev:
|
||||
// Do nothing.
|
||||
p.pos = pcIterPosCur
|
||||
}
|
||||
if p.iterKey == nil {
|
||||
p.resetKey()
|
||||
return nil, base.LazyValue{}
|
||||
}
|
||||
return p.findPrevEntry()
|
||||
}
|
||||
|
||||
// Error implements the InternalIterator interface.
|
||||
@@ -477,10 +736,6 @@ func (d *DB) truncateSharedFile(
|
||||
|
||||
// We will need to truncate file bounds in at least one direction. Open all
|
||||
// relevant iterators.
|
||||
//
|
||||
// TODO(bilal): Once virtual sstables go in, verify that the constraining of
|
||||
// bounds to virtual sstable bounds happens below this method, so we aren't
|
||||
// unintentionally exposing keys we shouldn't be exposing.
|
||||
iter, rangeDelIter, err := d.newIters(ctx, file, &IterOptions{
|
||||
LowerBound: lower,
|
||||
UpperBound: upper,
|
||||
@@ -497,7 +752,7 @@ func (d *DB) truncateSharedFile(
|
||||
)
|
||||
defer rangeDelIter.Close()
|
||||
}
|
||||
rangeKeyIter, err := d.tableNewRangeKeyIter(file, nil /* spanIterOptions */)
|
||||
rangeKeyIter, err := d.tableNewRangeKeyIter(file, keyspan.SpanIterOptions{Level: manifest.Level(level)})
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
@@ -584,6 +839,10 @@ func (d *DB) truncateSharedFile(
|
||||
if len(sst.Smallest.UserKey) == 0 {
|
||||
return nil, true, nil
|
||||
}
|
||||
sst.Size, err = d.tableCache.estimateSize(file, sst.Smallest.UserKey, sst.Largest.UserKey)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return sst, false, nil
|
||||
}
|
||||
|
||||
@@ -616,7 +875,7 @@ func scanInternalImpl(
|
||||
for f := files.SeekGE(cmp, lower); f != nil && cmp(f.Smallest.UserKey, upper) < 0; f = files.Next() {
|
||||
var objMeta objstorage.ObjectMetadata
|
||||
var err error
|
||||
objMeta, err = provider.Lookup(fileTypeTable, f.FileNum.DiskFileNum())
|
||||
objMeta, err = provider.Lookup(fileTypeTable, f.FileBacking.DiskFileNum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -718,6 +977,7 @@ func (i *scanInternalIterator) constructPointIter(memtables flushableList, buf *
|
||||
mlevels = mlevels[:numMergingLevels]
|
||||
levels = levels[:numLevelIters]
|
||||
rangeDelLevels = rangeDelLevels[:numLevelIters]
|
||||
i.opts.IterOptions.snapshotForHideObsoletePoints = i.seqNum
|
||||
addLevelIterForFiles := func(files manifest.LevelIterator, level manifest.Level) {
|
||||
li := &levels[levelsIndex]
|
||||
rli := &rangeDelLevels[levelsIndex]
|
||||
@@ -804,8 +1064,7 @@ func (i *scanInternalIterator) constructRangeKeyIter() {
|
||||
// around Key Trailer order.
|
||||
iter := current.RangeKeyLevels[0].Iter()
|
||||
for f := iter.Last(); f != nil; f = iter.Prev() {
|
||||
spanIterOpts := &keyspan.SpanIterOptions{RangeKeyFilters: i.opts.RangeKeyFilters}
|
||||
spanIter, err := i.newIterRangeKey(f, spanIterOpts)
|
||||
spanIter, err := i.newIterRangeKey(f, i.opts.SpanIterOptions(manifest.Level(0)))
|
||||
if err != nil {
|
||||
i.rangeKey.iterConfig.AddLevel(&errorKeyspanIter{err: err})
|
||||
continue
|
||||
@@ -822,7 +1081,7 @@ func (i *scanInternalIterator) constructRangeKeyIter() {
|
||||
continue
|
||||
}
|
||||
li := i.rangeKey.iterConfig.NewLevelIter()
|
||||
spanIterOpts := keyspan.SpanIterOptions{RangeKeyFilters: i.opts.RangeKeyFilters}
|
||||
spanIterOpts := i.opts.SpanIterOptions(manifest.Level(level))
|
||||
li.Init(spanIterOpts, i.comparer.Compare, i.newIterRangeKey, current.RangeKeyLevels[level].Iter(),
|
||||
manifest.Level(level), manifest.KeyTypeRange)
|
||||
i.rangeKey.iterConfig.AddLevel(li)
|
||||
|
||||
Reference in New Issue
Block a user