Update dependencies
This commit is contained in:
211
vendor/github.com/cockroachdb/pebble/table_cache.go
generated
vendored
211
vendor/github.com/cockroachdb/pebble/table_cache.go
generated
vendored
@@ -9,7 +9,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
@@ -22,7 +21,6 @@ import (
|
||||
"github.com/cockroachdb/pebble/internal/keyspan"
|
||||
"github.com/cockroachdb/pebble/internal/manifest"
|
||||
"github.com/cockroachdb/pebble/internal/private"
|
||||
"github.com/cockroachdb/pebble/internal/rangekey"
|
||||
"github.com/cockroachdb/pebble/objstorage"
|
||||
"github.com/cockroachdb/pebble/objstorage/objstorageprovider/objiotracing"
|
||||
"github.com/cockroachdb/pebble/sstable"
|
||||
@@ -196,6 +194,40 @@ func (c *tableCacheContainer) estimateSize(
|
||||
return size, nil
|
||||
}
|
||||
|
||||
// createCommonReader creates a Reader for this file. isForeign, if true for
|
||||
// virtual sstables, is passed into the vSSTable reader so its iterators can
|
||||
// collapse obsolete points accordingly.
|
||||
func createCommonReader(
|
||||
v *tableCacheValue, file *fileMetadata, isForeign bool,
|
||||
) sstable.CommonReader {
|
||||
// TODO(bananabrick): We suffer an allocation if file is a virtual sstable.
|
||||
var cr sstable.CommonReader = v.reader
|
||||
if file.Virtual {
|
||||
virtualReader := sstable.MakeVirtualReader(
|
||||
v.reader, file.VirtualMeta(), isForeign,
|
||||
)
|
||||
cr = &virtualReader
|
||||
}
|
||||
return cr
|
||||
}
|
||||
|
||||
func (c *tableCacheContainer) withCommonReader(
|
||||
meta *fileMetadata, fn func(sstable.CommonReader) error,
|
||||
) error {
|
||||
s := c.tableCache.getShard(meta.FileBacking.DiskFileNum)
|
||||
v := s.findNode(meta, &c.dbOpts)
|
||||
defer s.unrefValue(v)
|
||||
if v.err != nil {
|
||||
return v.err
|
||||
}
|
||||
provider := c.dbOpts.objProvider
|
||||
objMeta, err := provider.Lookup(fileTypeTable, meta.FileBacking.DiskFileNum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fn(createCommonReader(v, meta, provider.IsSharedForeign(objMeta)))
|
||||
}
|
||||
|
||||
func (c *tableCacheContainer) withReader(meta physicalMeta, fn func(*sstable.Reader) error) error {
|
||||
s := c.tableCache.getShard(meta.FileBacking.DiskFileNum)
|
||||
v := s.findNode(meta.FileMetadata, &c.dbOpts)
|
||||
@@ -216,7 +248,12 @@ func (c *tableCacheContainer) withVirtualReader(
|
||||
if v.err != nil {
|
||||
return v.err
|
||||
}
|
||||
return fn(sstable.MakeVirtualReader(v.reader, meta))
|
||||
provider := c.dbOpts.objProvider
|
||||
objMeta, err := provider.Lookup(fileTypeTable, meta.FileBacking.DiskFileNum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return fn(sstable.MakeVirtualReader(v.reader, meta, provider.IsSharedForeign(objMeta)))
|
||||
}
|
||||
|
||||
func (c *tableCacheContainer) iterCount() int64 {
|
||||
@@ -402,6 +439,7 @@ func (c *tableCacheShard) newIters(
|
||||
}
|
||||
|
||||
hideObsoletePoints := false
|
||||
var pointKeyFilters []BlockPropertyFilter
|
||||
if opts != nil {
|
||||
// This code is appending (at most one filter) in-place to
|
||||
// opts.PointKeyFilters even though the slice is shared for iterators in
|
||||
@@ -417,7 +455,7 @@ func (c *tableCacheShard) newIters(
|
||||
//
|
||||
// An alternative would be to have different slices for different sstable
|
||||
// iterators, but that requires more work to avoid allocations.
|
||||
hideObsoletePoints, opts.PointKeyFilters =
|
||||
hideObsoletePoints, pointKeyFilters =
|
||||
v.reader.TryAddBlockPropertyFilterForHideObsoletePoints(
|
||||
opts.snapshotForHideObsoletePoints, file.LargestSeqNum, opts.PointKeyFilters)
|
||||
}
|
||||
@@ -426,31 +464,13 @@ func (c *tableCacheShard) newIters(
|
||||
var err error
|
||||
if opts != nil {
|
||||
ok, filterer, err = c.checkAndIntersectFilters(v, opts.TableFilter,
|
||||
opts.PointKeyFilters, internalOpts.boundLimitedFilter)
|
||||
pointKeyFilters, internalOpts.boundLimitedFilter)
|
||||
}
|
||||
if err != nil {
|
||||
c.unrefValue(v)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
type iterCreator interface {
|
||||
NewRawRangeDelIter() (keyspan.FragmentIterator, error)
|
||||
NewIterWithBlockPropertyFiltersAndContextEtc(ctx context.Context, lower, upper []byte, filterer *sstable.BlockPropertiesFilterer, hideObsoletePoints, useFilterBlock bool, stats *base.InternalIteratorStats, rp sstable.ReaderProvider) (sstable.Iterator, error)
|
||||
NewCompactionIter(
|
||||
bytesIterated *uint64,
|
||||
rp sstable.ReaderProvider,
|
||||
) (sstable.Iterator, error)
|
||||
}
|
||||
|
||||
// TODO(bananabrick): We suffer an allocation if file is a virtual sstable.
|
||||
var ic iterCreator = v.reader
|
||||
if file.Virtual {
|
||||
virtualReader := sstable.MakeVirtualReader(
|
||||
v.reader, file.VirtualMeta(),
|
||||
)
|
||||
ic = &virtualReader
|
||||
}
|
||||
|
||||
provider := dbOpts.objProvider
|
||||
// Check if this file is a foreign file.
|
||||
objMeta, err := provider.Lookup(fileTypeTable, file.FileBacking.DiskFileNum)
|
||||
@@ -458,31 +478,12 @@ func (c *tableCacheShard) newIters(
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Note: This suffers an allocation for virtual sstables.
|
||||
cr := createCommonReader(v, file, provider.IsSharedForeign(objMeta))
|
||||
|
||||
// NB: range-del iterator does not maintain a reference to the table, nor
|
||||
// does it need to read from it after creation.
|
||||
var rangeDelIter keyspan.FragmentIterator
|
||||
if provider.IsForeign(objMeta) {
|
||||
if opts == nil {
|
||||
panic("unexpected nil opts when reading foreign file")
|
||||
}
|
||||
if !file.Virtual {
|
||||
// Foreign sstables must be virtual by definition.
|
||||
panic(fmt.Sprintf("sstable is foreign but not virtual: %s", file.FileNum))
|
||||
}
|
||||
switch manifest.LevelToInt(opts.level) {
|
||||
case 5:
|
||||
rangeDelIter, err = ic.NewRawRangeDelIter()
|
||||
case 6:
|
||||
// Let rangeDelIter remain nil. We don't need to return rangedels from
|
||||
// this file as they will not apply to any other files. For the purpose
|
||||
// of collapsing rangedels within this file, we create another rangeDelIter
|
||||
// below for use with the interleaving iter.
|
||||
default:
|
||||
panic(fmt.Sprintf("unexpected level for foreign sstable: %d", manifest.LevelToInt(opts.level)))
|
||||
}
|
||||
} else {
|
||||
rangeDelIter, err = ic.NewRawRangeDelIter()
|
||||
}
|
||||
rangeDelIter, err := cr.NewRawRangeDelIter()
|
||||
if err != nil {
|
||||
c.unrefValue(v)
|
||||
return nil, nil, err
|
||||
@@ -519,10 +520,16 @@ func (c *tableCacheShard) newIters(
|
||||
rp = &tableCacheShardReaderProvider{c: c, file: file, dbOpts: dbOpts}
|
||||
}
|
||||
|
||||
if provider.IsSharedForeign(objMeta) {
|
||||
if tableFormat < sstable.TableFormatPebblev4 {
|
||||
return nil, nil, errors.New("pebble: shared foreign sstable has a lower table format than expected")
|
||||
}
|
||||
hideObsoletePoints = true
|
||||
}
|
||||
if internalOpts.bytesIterated != nil {
|
||||
iter, err = ic.NewCompactionIter(internalOpts.bytesIterated, rp)
|
||||
iter, err = cr.NewCompactionIter(internalOpts.bytesIterated, rp, internalOpts.bufferPool)
|
||||
} else {
|
||||
iter, err = ic.NewIterWithBlockPropertyFiltersAndContextEtc(
|
||||
iter, err = cr.NewIterWithBlockPropertyFiltersAndContextEtc(
|
||||
ctx, opts.GetLowerBound(), opts.GetUpperBound(), filterer, hideObsoletePoints, useFilter,
|
||||
internalOpts.stats, rp)
|
||||
}
|
||||
@@ -536,35 +543,6 @@ func (c *tableCacheShard) newIters(
|
||||
// NB: v.closeHook takes responsibility for calling unrefValue(v) here. Take
|
||||
// care to avoid introducing an allocation here by adding a closure.
|
||||
iter.SetCloseHook(v.closeHook)
|
||||
if provider.IsForeign(objMeta) {
|
||||
// NB: IsForeign() guarantees IsShared, so opts must not be nil as we've
|
||||
// already panicked on the nil case above.
|
||||
pointKeySeqNum := base.SeqNumForLevel(manifest.LevelToInt(opts.level))
|
||||
pcIter := pointCollapsingIterator{
|
||||
comparer: dbOpts.opts.Comparer,
|
||||
merge: dbOpts.opts.Merge,
|
||||
seqNum: math.MaxUint64,
|
||||
elideRangeDeletes: true,
|
||||
fixedSeqNum: pointKeySeqNum,
|
||||
}
|
||||
// Open a second rangedel iter. This is solely for the interleaving iter to
|
||||
// be able to efficiently delete covered range deletes. We don't need to fix
|
||||
// the sequence number in this iter, as these range deletes will not be
|
||||
// exposed to anything other than the interleaving iter and
|
||||
// pointCollapsingIter.
|
||||
rangeDelIter, err := v.reader.NewRawRangeDelIter()
|
||||
if err != nil {
|
||||
c.unrefValue(v)
|
||||
return nil, nil, err
|
||||
}
|
||||
if rangeDelIter == nil {
|
||||
rangeDelIter = emptyKeyspanIter
|
||||
}
|
||||
pcIter.iter.Init(dbOpts.opts.Comparer, iter, rangeDelIter, nil /* mask */, opts.LowerBound, opts.UpperBound)
|
||||
pcSSTIter := pcSSTIterPool.Get().(*pointCollapsingSSTIterator)
|
||||
*pcSSTIter = pointCollapsingSSTIterator{pointCollapsingIterator: pcIter, childIter: iter}
|
||||
iter = pcSSTIter
|
||||
}
|
||||
|
||||
c.iterCount.Add(1)
|
||||
dbOpts.iterCount.Add(1)
|
||||
@@ -612,10 +590,15 @@ func (c *tableCacheShard) newRangeKeyIter(
|
||||
|
||||
var iter keyspan.FragmentIterator
|
||||
if file.Virtual {
|
||||
virtualReader := sstable.MakeVirtualReader(
|
||||
v.reader, file.VirtualMeta(),
|
||||
)
|
||||
iter, err = virtualReader.NewRawRangeKeyIter()
|
||||
provider := dbOpts.objProvider
|
||||
var objMeta objstorage.ObjectMetadata
|
||||
objMeta, err = provider.Lookup(fileTypeTable, file.FileBacking.DiskFileNum)
|
||||
if err == nil {
|
||||
virtualReader := sstable.MakeVirtualReader(
|
||||
v.reader, file.VirtualMeta(), provider.IsSharedForeign(objMeta),
|
||||
)
|
||||
iter, err = virtualReader.NewRawRangeKeyIter()
|
||||
}
|
||||
} else {
|
||||
iter, err = v.reader.NewRawRangeKeyIter()
|
||||
}
|
||||
@@ -634,29 +617,6 @@ func (c *tableCacheShard) newRangeKeyIter(
|
||||
return emptyKeyspanIter, nil
|
||||
}
|
||||
|
||||
objMeta, err := dbOpts.objProvider.Lookup(fileTypeTable, file.FileBacking.DiskFileNum)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if dbOpts.objProvider.IsForeign(objMeta) {
|
||||
if opts.Level == 0 {
|
||||
panic("unexpected zero level when reading foreign file")
|
||||
}
|
||||
transform := &rangekey.ForeignSSTTransformer{
|
||||
Comparer: dbOpts.opts.Comparer,
|
||||
Level: manifest.LevelToInt(opts.Level),
|
||||
}
|
||||
if iter == nil {
|
||||
iter = emptyKeyspanIter
|
||||
}
|
||||
transformIter := &keyspan.TransformerIter{
|
||||
FragmentIterator: iter,
|
||||
Transformer: transform,
|
||||
Compare: dbOpts.opts.Comparer.Compare,
|
||||
}
|
||||
return transformIter, nil
|
||||
}
|
||||
|
||||
return iter, nil
|
||||
}
|
||||
|
||||
@@ -783,6 +743,29 @@ func (c *tableCacheShard) unrefValue(v *tableCacheValue) {
|
||||
// that node if it didn't already exist. The caller is responsible for
|
||||
// decrementing the returned node's refCount.
|
||||
func (c *tableCacheShard) findNode(meta *fileMetadata, dbOpts *tableCacheOpts) *tableCacheValue {
|
||||
v := c.findNodeInternal(meta, dbOpts)
|
||||
|
||||
// Loading a file before its global sequence number is known (eg,
|
||||
// during ingest before entering the commit pipeline) can pollute
|
||||
// the cache with incorrect state. In invariant builds, verify
|
||||
// that the global sequence number of the returned reader matches.
|
||||
if invariants.Enabled {
|
||||
if v.reader != nil && meta.LargestSeqNum == meta.SmallestSeqNum &&
|
||||
v.reader.Properties.GlobalSeqNum != meta.SmallestSeqNum {
|
||||
panic(errors.AssertionFailedf("file %s loaded from table cache with the wrong global sequence number %d",
|
||||
meta, v.reader.Properties.GlobalSeqNum))
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func (c *tableCacheShard) findNodeInternal(
|
||||
meta *fileMetadata, dbOpts *tableCacheOpts,
|
||||
) *tableCacheValue {
|
||||
if refs := meta.Refs(); refs <= 0 {
|
||||
panic(errors.AssertionFailedf("attempting to load file %s with refs=%d from table cache",
|
||||
meta, refs))
|
||||
}
|
||||
// Fast-path for a hit in the cache.
|
||||
c.mu.RLock()
|
||||
key := tableCacheKey{dbOpts.cacheID, meta.FileBacking.DiskFileNum}
|
||||
@@ -1108,20 +1091,16 @@ func (v *tableCacheValue) load(loadInfo loadInfo, c *tableCacheShard, dbOpts *ta
|
||||
f, err = dbOpts.objProvider.OpenForReading(
|
||||
context.TODO(), fileTypeTable, loadInfo.backingFileNum, objstorage.OpenOptions{MustExist: true},
|
||||
)
|
||||
if err != nil {
|
||||
v.err = errors.Wrap(
|
||||
err,
|
||||
fmt.Sprintf("pebble: could not open backing file %s", errors.Safe(loadInfo.backingFileNum.FileNum())),
|
||||
)
|
||||
}
|
||||
if v.err == nil {
|
||||
if err == nil {
|
||||
cacheOpts := private.SSTableCacheOpts(dbOpts.cacheID, loadInfo.backingFileNum).(sstable.ReaderOption)
|
||||
v.reader, v.err = sstable.NewReader(f, dbOpts.opts, cacheOpts, dbOpts.filterMetrics)
|
||||
v.reader, err = sstable.NewReader(f, dbOpts.opts, cacheOpts, dbOpts.filterMetrics)
|
||||
}
|
||||
if v.err == nil {
|
||||
if loadInfo.smallestSeqNum == loadInfo.largestSeqNum {
|
||||
v.reader.Properties.GlobalSeqNum = loadInfo.largestSeqNum
|
||||
}
|
||||
if err != nil {
|
||||
v.err = errors.Wrapf(
|
||||
err, "pebble: backing file %s error", errors.Safe(loadInfo.backingFileNum.FileNum()))
|
||||
}
|
||||
if v.err == nil && loadInfo.smallestSeqNum == loadInfo.largestSeqNum {
|
||||
v.reader.Properties.GlobalSeqNum = loadInfo.largestSeqNum
|
||||
}
|
||||
if v.err != nil {
|
||||
c.mu.Lock()
|
||||
|
||||
Reference in New Issue
Block a user