Upgrade versions of vendored libs
This commit is contained in:
141
vendor/github.com/cockroachdb/pebble/table_cache.go
generated
vendored
141
vendor/github.com/cockroachdb/pebble/table_cache.go
generated
vendored
@@ -28,6 +28,25 @@ import (
|
||||
var emptyIter = &errorIter{err: nil}
|
||||
var emptyKeyspanIter = &errorKeyspanIter{err: nil}
|
||||
|
||||
// filteredAll is a singleton internalIterator implementation used when an
|
||||
// sstable does contain point keys, but all the keys are filtered by the active
|
||||
// PointKeyFilters set in the iterator's IterOptions.
|
||||
//
|
||||
// filteredAll implements filteredIter, ensuring the level iterator recognizes
|
||||
// when it may need to return file boundaries to keep the rangeDelIter open
|
||||
// during mergingIter operation.
|
||||
var filteredAll = &filteredAllKeysIter{errorIter: errorIter{err: nil}}
|
||||
|
||||
var _ filteredIter = filteredAll
|
||||
|
||||
type filteredAllKeysIter struct {
|
||||
errorIter
|
||||
}
|
||||
|
||||
func (s *filteredAllKeysIter) MaybeFilteredKeys() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
var tableCacheLabels = pprof.Labels("pebble", "table-cache")
|
||||
|
||||
// tableCacheOpts contains the db specific fields
|
||||
@@ -114,9 +133,9 @@ func (c *tableCacheContainer) close() error {
|
||||
}
|
||||
|
||||
func (c *tableCacheContainer) newIters(
|
||||
file *manifest.FileMetadata, opts *IterOptions, bytesIterated *uint64,
|
||||
file *manifest.FileMetadata, opts *IterOptions, internalOpts internalIterOpts,
|
||||
) (internalIterator, keyspan.FragmentIterator, error) {
|
||||
return c.tableCache.getShard(file.FileNum).newIters(file, opts, bytesIterated, &c.dbOpts)
|
||||
return c.tableCache.getShard(file.FileNum).newIters(file, opts, internalOpts, &c.dbOpts)
|
||||
}
|
||||
|
||||
func (c *tableCacheContainer) newRangeKeyIter(
|
||||
@@ -280,8 +299,9 @@ type tableCacheShard struct {
|
||||
sizeCold int
|
||||
sizeTest int
|
||||
}
|
||||
releasing sync.WaitGroup
|
||||
releasingCh chan *tableCacheValue
|
||||
releasing sync.WaitGroup
|
||||
releasingCh chan *tableCacheValue
|
||||
releaseLoopExit sync.WaitGroup
|
||||
}
|
||||
|
||||
func (c *tableCacheShard) init(size int) {
|
||||
@@ -290,6 +310,7 @@ func (c *tableCacheShard) init(size int) {
|
||||
c.mu.nodes = make(map[tableCacheKey]*tableCacheNode)
|
||||
c.mu.coldTarget = size
|
||||
c.releasingCh = make(chan *tableCacheValue, 100)
|
||||
c.releaseLoopExit.Add(1)
|
||||
go c.releaseLoop()
|
||||
|
||||
if invariants.RaceEnabled {
|
||||
@@ -299,6 +320,7 @@ func (c *tableCacheShard) init(size int) {
|
||||
|
||||
func (c *tableCacheShard) releaseLoop() {
|
||||
pprof.Do(context.Background(), tableCacheLabels, func(context.Context) {
|
||||
defer c.releaseLoopExit.Done()
|
||||
for v := range c.releasingCh {
|
||||
v.release(c)
|
||||
}
|
||||
@@ -312,14 +334,15 @@ func (c *tableCacheShard) checkAndIntersectFilters(
|
||||
v *tableCacheValue,
|
||||
tableFilter func(userProps map[string]string) bool,
|
||||
blockPropertyFilters []BlockPropertyFilter,
|
||||
boundLimitedFilter sstable.BoundLimitedBlockPropertyFilter,
|
||||
) (ok bool, filterer *sstable.BlockPropertiesFilterer, err error) {
|
||||
if tableFilter != nil &&
|
||||
!tableFilter(v.reader.Properties.UserProperties) {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
if len(blockPropertyFilters) > 0 {
|
||||
filterer = sstable.NewBlockPropertiesFilterer(blockPropertyFilters)
|
||||
if boundLimitedFilter != nil || len(blockPropertyFilters) > 0 {
|
||||
filterer = sstable.NewBlockPropertiesFilterer(blockPropertyFilters, boundLimitedFilter)
|
||||
intersects, err :=
|
||||
filterer.IntersectsUserPropsAndFinishInit(v.reader.Properties.UserProperties)
|
||||
if err != nil {
|
||||
@@ -333,7 +356,10 @@ func (c *tableCacheShard) checkAndIntersectFilters(
|
||||
}
|
||||
|
||||
func (c *tableCacheShard) newIters(
|
||||
file *manifest.FileMetadata, opts *IterOptions, bytesIterated *uint64, dbOpts *tableCacheOpts,
|
||||
file *manifest.FileMetadata,
|
||||
opts *IterOptions,
|
||||
internalOpts internalIterOpts,
|
||||
dbOpts *tableCacheOpts,
|
||||
) (internalIterator, keyspan.FragmentIterator, error) {
|
||||
// Calling findNode gives us the responsibility of decrementing v's
|
||||
// refCount. If opening the underlying table resulted in error, then we
|
||||
@@ -350,17 +376,36 @@ func (c *tableCacheShard) newIters(
|
||||
var filterer *sstable.BlockPropertiesFilterer
|
||||
var err error
|
||||
if opts != nil {
|
||||
ok, filterer, err = c.checkAndIntersectFilters(v, opts.TableFilter, opts.PointKeyFilters)
|
||||
ok, filterer, err = c.checkAndIntersectFilters(v, opts.TableFilter,
|
||||
opts.PointKeyFilters, internalOpts.boundLimitedFilter)
|
||||
}
|
||||
if err != nil {
|
||||
c.unrefValue(v)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// NB: range-del iterator does not maintain a reference to the table, nor
|
||||
// does it need to read from it after creation.
|
||||
rangeDelIter, err := v.reader.NewRawRangeDelIter()
|
||||
if err != nil {
|
||||
c.unrefValue(v)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if !ok {
|
||||
c.unrefValue(v)
|
||||
// Return the empty iterator. This iterator has no mutable state, so
|
||||
// Return an empty iterator. This iterator has no mutable state, so
|
||||
// using a singleton is fine.
|
||||
return emptyIter, nil, err
|
||||
// NB: We still return the potentially non-empty rangeDelIter. This
|
||||
// ensures the iterator observes the file's range deletions even if the
|
||||
// block property filters exclude all the file's point keys. The range
|
||||
// deletions may still delete keys lower in the LSM in files that DO
|
||||
// match the active filters.
|
||||
//
|
||||
// The point iterator returned must implement the filteredIter
|
||||
// interface, so that the level iterator surfaces file boundaries when
|
||||
// range deletions are present.
|
||||
return filteredAll, rangeDelIter, err
|
||||
}
|
||||
|
||||
var iter sstable.Iterator
|
||||
@@ -368,20 +413,22 @@ func (c *tableCacheShard) newIters(
|
||||
if opts != nil {
|
||||
useFilter = manifest.LevelToInt(opts.level) != 6 || opts.UseL6Filters
|
||||
}
|
||||
if bytesIterated != nil {
|
||||
iter, err = v.reader.NewCompactionIter(bytesIterated)
|
||||
if internalOpts.bytesIterated != nil {
|
||||
iter, err = v.reader.NewCompactionIter(internalOpts.bytesIterated)
|
||||
} else {
|
||||
iter, err = v.reader.NewIterWithBlockPropertyFilters(
|
||||
opts.GetLowerBound(), opts.GetUpperBound(), filterer, useFilter)
|
||||
opts.GetLowerBound(), opts.GetUpperBound(), filterer, useFilter, internalOpts.stats)
|
||||
}
|
||||
if err != nil {
|
||||
if rangeDelIter != nil {
|
||||
_ = rangeDelIter.Close()
|
||||
}
|
||||
c.unrefValue(v)
|
||||
return nil, nil, err
|
||||
}
|
||||
// NB: v.closeHook takes responsibility for calling unrefValue(v) here.
|
||||
iter.SetCloseHook(func(i sstable.Iterator) error {
|
||||
return v.closeHook(i)
|
||||
})
|
||||
// NB: v.closeHook takes responsibility for calling unrefValue(v) here. Take
|
||||
// care to avoid introduceingan allocation here by adding a closure.
|
||||
iter.SetCloseHook(v.closeHook)
|
||||
|
||||
atomic.AddInt32(&c.atomic.iterCount, 1)
|
||||
atomic.AddInt32(dbOpts.atomic.iterCount, 1)
|
||||
@@ -390,19 +437,7 @@ func (c *tableCacheShard) newIters(
|
||||
c.mu.iters[iter] = debug.Stack()
|
||||
c.mu.Unlock()
|
||||
}
|
||||
|
||||
// NB: range-del iterator does not maintain a reference to the table, nor
|
||||
// does it need to read from it after creation.
|
||||
rangeDelIter, err := v.reader.NewRawRangeDelIter()
|
||||
if err != nil {
|
||||
_ = iter.Close()
|
||||
return nil, nil, err
|
||||
}
|
||||
if rangeDelIter != nil {
|
||||
return iter, rangeDelIter, nil
|
||||
}
|
||||
// NB: Translate a nil range-del iterator into a nil interface.
|
||||
return iter, nil, nil
|
||||
return iter, rangeDelIter, nil
|
||||
}
|
||||
|
||||
func (c *tableCacheShard) newRangeKeyIter(
|
||||
@@ -421,8 +456,13 @@ func (c *tableCacheShard) newRangeKeyIter(
|
||||
|
||||
ok := true
|
||||
var err error
|
||||
if opts != nil {
|
||||
ok, _, err = c.checkAndIntersectFilters(v, nil, opts.RangeKeyFilters)
|
||||
// Don't filter a table's range keys if the file contains RANGEKEYDELs.
|
||||
// The RANGEKEYDELs may delete range keys in other levels. Skipping the
|
||||
// file's range key blocks may surface deleted range keys below. This is
|
||||
// done here, rather than deferring to the block-property collector in order
|
||||
// to maintain parity with point keys and the treatment of RANGEDELs.
|
||||
if opts != nil && v.reader.Properties.NumRangeKeyDels == 0 {
|
||||
ok, _, err = c.checkAndIntersectFilters(v, nil, opts.RangeKeyFilters, nil)
|
||||
}
|
||||
if err != nil {
|
||||
c.unrefValue(v)
|
||||
@@ -435,27 +475,14 @@ func (c *tableCacheShard) newRangeKeyIter(
|
||||
return emptyKeyspanIter, err
|
||||
}
|
||||
|
||||
var iter sstable.FragmentIterator
|
||||
// TODO(bilal): We are currently passing through the raw blockIter for range
|
||||
// keys. This iter does not support bounds (eg. SetBounds will panic).
|
||||
// Any future users of the iter returned by this function need to make any
|
||||
// bounds-specific optimizations themselves.
|
||||
var iter keyspan.FragmentIterator
|
||||
iter, err = v.reader.NewRawRangeKeyIter()
|
||||
if err != nil || iter == nil {
|
||||
c.unrefValue(v)
|
||||
return nil, err
|
||||
}
|
||||
// NB: v.closeHook takes responsibility for calling unrefValue(v) here.
|
||||
iter.SetCloseHook(func(i keyspan.FragmentIterator) error {
|
||||
return v.closeHook(i)
|
||||
})
|
||||
// iter is a block iter that holds the entire value of the block in memory.
|
||||
// No need to hold onto a ref of the cache value.
|
||||
c.unrefValue(v)
|
||||
|
||||
atomic.AddInt32(&c.atomic.iterCount, 1)
|
||||
atomic.AddInt32(dbOpts.atomic.iterCount, 1)
|
||||
if invariants.RaceEnabled {
|
||||
c.mu.Lock()
|
||||
c.mu.iters[iter] = debug.Stack()
|
||||
c.mu.Unlock()
|
||||
if err != nil || iter == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return iter, nil
|
||||
@@ -607,7 +634,7 @@ func (c *tableCacheShard) findNode(meta *fileMetadata, dbOpts *tableCacheOpts) *
|
||||
}
|
||||
// Cache the closure invoked when an iterator is closed. This avoids an
|
||||
// allocation on every call to newIters.
|
||||
v.closeHook = func(i io.Closer) error {
|
||||
v.closeHook = func(i sstable.Iterator) error {
|
||||
if invariants.RaceEnabled {
|
||||
c.mu.Lock()
|
||||
delete(c.mu.iters, i)
|
||||
@@ -829,15 +856,19 @@ func (c *tableCacheShard) Close() error {
|
||||
// complete. This behavior is used by iterator leak tests. Leaking the
|
||||
// goroutine for these tests is less bad not closing the iterator which
|
||||
// triggers other warnings about block cache handles not being released.
|
||||
if err == nil {
|
||||
close(c.releasingCh)
|
||||
if err != nil {
|
||||
c.releasing.Wait()
|
||||
return err
|
||||
}
|
||||
|
||||
close(c.releasingCh)
|
||||
c.releasing.Wait()
|
||||
c.releaseLoopExit.Wait()
|
||||
return err
|
||||
}
|
||||
|
||||
type tableCacheValue struct {
|
||||
closeHook func(i io.Closer) error
|
||||
closeHook func(i sstable.Iterator) error
|
||||
reader *sstable.Reader
|
||||
filename string
|
||||
err error
|
||||
|
||||
Reference in New Issue
Block a user