diff --git a/sstable/block/kv.go b/sstable/block/kv.go index 1165e9e9fd..d27dd80dd9 100644 --- a/sstable/block/kv.go +++ b/sstable/block/kv.go @@ -68,3 +68,9 @@ func InPlaceValuePrefix(setHasSameKeyPrefix bool) ValuePrefix { } return prefix } + +// GetLazyValueForPrefixAndValueHandler is an interface for getting a LazyValue +// from a value prefix and value. +type GetLazyValueForPrefixAndValueHandler interface { + GetLazyValueForPrefixAndValueHandle(handle []byte) base.LazyValue +} diff --git a/sstable/reader_iter_single_lvl.go b/sstable/reader_iter_single_lvl.go index 61d9c55d86..0ced62e45c 100644 --- a/sstable/reader_iter_single_lvl.go +++ b/sstable/reader_iter_single_lvl.go @@ -269,7 +269,7 @@ func (i *singleLevelIterator) init( vbih: r.valueBIH, stats: stats, } - i.data.SetGetLazyValue(i.vbReader.getLazyValueForPrefixAndValueHandle) + i.data.SetGetLazyValuer(i.vbReader) i.vbRH = objstorageprovider.UsePreallocatedReadHandle(r.readable, objstorage.NoReadBefore, &i.vbRHPrealloc) } i.data.SetHasValuePrefix(true) diff --git a/sstable/reader_test.go b/sstable/reader_test.go index 550f4ca426..85805c5739 100644 --- a/sstable/reader_test.go +++ b/sstable/reader_test.go @@ -2153,7 +2153,7 @@ func BenchmarkIteratorScanManyVersions(b *testing.B) { require.NoError(b, err) return r } - for _, format := range []TableFormat{TableFormatPebblev2, TableFormatPebblev3} { + for _, format := range []TableFormat{TableFormatPebblev2, TableFormatPebblev3, TableFormatPebblev4} { b.Run(fmt.Sprintf("format=%s", format.String()), func(b *testing.B) { // 150MiB results in a high cache hit rate for both formats. 20MiB // results in a high cache hit rate for the data blocks in @@ -2165,6 +2165,13 @@ func BenchmarkIteratorScanManyVersions(b *testing.B) { defer func() { require.NoError(b, r.Close()) }() + b.Run("NewIter", func(b *testing.B) { + for i := 0; i < b.N; i++ { + iter, err := r.NewIter(NoTransforms, nil, nil) + require.NoError(b, err) + require.NoError(b, iter.Close()) + } + }) for _, readValue := range []bool{false, true} { b.Run(fmt.Sprintf("read-value=%t", readValue), func(b *testing.B) { iter, err := r.NewIter(NoTransforms, nil, nil) diff --git a/sstable/rowblk/rowblk_iter.go b/sstable/rowblk/rowblk_iter.go index e846db13ab..70d48d3bb2 100644 --- a/sstable/rowblk/rowblk_iter.go +++ b/sstable/rowblk/rowblk_iter.go @@ -187,7 +187,7 @@ type Iter struct { // for block iteration for already loaded blocks. firstUserKey []byte lazyValueHandling struct { - getLazyValue func([]byte) base.LazyValue + getValue block.GetLazyValueForPrefixAndValueHandler hasValuePrefix bool } synthSuffixBuf []byte @@ -271,10 +271,11 @@ func (i *Iter) SetHasValuePrefix(hasValuePrefix bool) { i.lazyValueHandling.hasValuePrefix = hasValuePrefix } -// SetGetLazyValue sets the function the iterator should use to get lazy values -// when the value encodes a value prefix. -func (i *Iter) SetGetLazyValue(fn func([]byte) base.LazyValue) { - i.lazyValueHandling.getLazyValue = fn +// SetGetLazyValuer sets the value block reader the iterator should use to get +// lazy values when the value encodes a value prefix. +func (i *Iter) SetGetLazyValuer(g block.GetLazyValueForPrefixAndValueHandler) { + i.lazyValueHandling.getValue = g + } // Handle returns the underlying block buffer handle, if the iterator was @@ -683,10 +684,10 @@ func (i *Iter) SeekGE(key []byte, flags base.SeekGEFlags) *base.InternalKV { if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -967,10 +968,10 @@ func (i *Iter) SeekLT(key []byte, flags base.SeekLTFlags) *base.InternalKV { if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -996,10 +997,10 @@ func (i *Iter) First() *base.InternalKV { if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -1042,10 +1043,10 @@ func (i *Iter) Last() *base.InternalKV { if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -1101,10 +1102,10 @@ start: if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -1392,10 +1393,10 @@ func (i *Iter) nextPrefixV3(succKey []byte) *base.InternalKV { } if i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -1450,10 +1451,10 @@ start: if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -1531,10 +1532,10 @@ start: if !i.lazyValueHandling.hasValuePrefix || i.ikv.K.Kind() != base.InternalKeyKindSet { i.ikv.V = base.MakeInPlaceValue(i.val) - } else if i.lazyValueHandling.getLazyValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { + } else if i.lazyValueHandling.getValue == nil || !block.ValuePrefix(i.val[0]).IsValueHandle() { i.ikv.V = base.MakeInPlaceValue(i.val[1:]) } else { - i.ikv.V = i.lazyValueHandling.getLazyValue(i.val) + i.ikv.V = i.lazyValueHandling.getValue.GetLazyValueForPrefixAndValueHandle(i.val) } return &i.ikv } @@ -1567,7 +1568,7 @@ func (i *Iter) Close() error { i.handle = block.BufferHandle{} i.val = nil i.ikv = base.InternalKV{} - i.lazyValueHandling.getLazyValue = nil + i.lazyValueHandling.getValue = nil return nil } diff --git a/sstable/value_block.go b/sstable/value_block.go index 777ce3d454..69f963783d 100644 --- a/sstable/value_block.go +++ b/sstable/value_block.go @@ -751,7 +751,7 @@ type valueBlockReader struct { bufToMangle []byte } -func (r *valueBlockReader) getLazyValueForPrefixAndValueHandle(handle []byte) base.LazyValue { +func (r *valueBlockReader) GetLazyValueForPrefixAndValueHandle(handle []byte) base.LazyValue { fetcher := &r.lazyFetcher valLen, h := decodeLenFromValueHandle(handle[1:]) *fetcher = base.LazyFetcher{ diff --git a/sstable/writer_test.go b/sstable/writer_test.go index 735efe9c1e..fcbcb61f33 100644 --- a/sstable/writer_test.go +++ b/sstable/writer_test.go @@ -333,7 +333,7 @@ func TestWriterWithValueBlocks(t *testing.T) { } forceIgnoreValueBlocks := func(i *singleLevelIterator) { i.vbReader = nil - i.data.SetGetLazyValue(nil) + i.data.SetGetLazyValuer(nil) i.data.SetHasValuePrefix(false) } switch i := origIter.(type) {