diff --git a/data_test.go b/data_test.go index 2dd2cf686e..50bb16a640 100644 --- a/data_test.go +++ b/data_test.go @@ -1182,7 +1182,7 @@ func runSSTablePropertiesCmd(t *testing.T, td *datadriven.TestData, d *DB) strin var v sstable.VirtualReader props := r.Properties.String() if m != nil && m.Virtual { - v = sstable.MakeVirtualReader(r, m.VirtualMeta(), false /* isShared */) + v = sstable.MakeVirtualReader(r, m.VirtualMeta().VirtualReaderParams(false /* isShared */)) props = v.Properties.String() } if len(td.Input) == 0 { diff --git a/ingest.go b/ingest.go index 722b037f62..fda76be9cf 100644 --- a/ingest.go +++ b/ingest.go @@ -233,7 +233,7 @@ func ingestLoad1External( } if len(e.SyntheticPrefix) != 0 { - meta.PrefixReplacement = &manifest.PrefixReplacement{ + meta.PrefixReplacement = &sstable.PrefixReplacement{ ContentPrefix: e.ContentPrefix, SyntheticPrefix: e.SyntheticPrefix, } diff --git a/internal/manifest/version.go b/internal/manifest/version.go index a86eeaacc6..3becb44346 100644 --- a/internal/manifest/version.go +++ b/internal/manifest/version.go @@ -18,6 +18,7 @@ import ( "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/internal/invariants" + "github.com/cockroachdb/pebble/sstable" ) // Compare exports the base.Compare type. @@ -272,8 +273,9 @@ type FileMetadata struct { // PrefixReplacement is used for virtual files where the backing file has a // different prefix on its keys than the span in which it is being exposed. - PrefixReplacement *PrefixReplacement - SyntheticSuffix []byte + PrefixReplacement *sstable.PrefixReplacement + + SyntheticSuffix sstable.SyntheticSuffix } // InternalKeyBounds returns the set of overall table bounds. @@ -281,31 +283,6 @@ func (m *FileMetadata) InternalKeyBounds() (InternalKey, InternalKey) { return m.Smallest, m.Largest } -// PrefixReplacement represents a read-time replacement of a key prefix. -type PrefixReplacement struct { - ContentPrefix, SyntheticPrefix []byte -} - -// ReplaceArg replaces the new prefix in the argument with the original prefix. -func (p *PrefixReplacement) ReplaceArg(src []byte) []byte { - return p.replace(src, p.SyntheticPrefix, p.ContentPrefix) -} - -// ReplaceResult replaces the original prefix in the result with the new prefix. -func (p *PrefixReplacement) ReplaceResult(key []byte) []byte { - return p.replace(key, p.ContentPrefix, p.SyntheticPrefix) -} - -func (p *PrefixReplacement) replace(key, from, to []byte) []byte { - if !bytes.HasPrefix(key, from) { - panic(fmt.Sprintf("unexpected prefix in replace: %s", key)) - } - result := make([]byte, 0, len(to)+(len(key)-len(from))) - result = append(result, to...) - result = append(result, key[len(from):]...) - return result -} - // PhysicalFileMeta is used by functions which want a guarantee that their input // belongs to a physical sst and not a virtual sst. // @@ -351,6 +328,21 @@ type VirtualFileMeta struct { *FileMetadata } +// VirtualReaderParams fills in the parameters necessary to create a virtual +// sstable reader. +func (m VirtualFileMeta) VirtualReaderParams(isShared bool) sstable.VirtualReaderParams { + return sstable.VirtualReaderParams{ + Lower: m.Smallest, + Upper: m.Largest, + FileNum: m.FileNum, + IsShared: isShared, + Size: m.Size, + BackingSize: m.FileBacking.Size, + PrefixReplacement: m.PrefixReplacement, + SyntheticSuffix: m.SyntheticSuffix, + } +} + // PhysicalMeta should be the only source of creating the PhysicalFileMeta // wrapper type. func (m *FileMetadata) PhysicalMeta() PhysicalFileMeta { diff --git a/internal/manifest/version_edit.go b/internal/manifest/version_edit.go index 7dc9a87fc0..87763512a9 100644 --- a/internal/manifest/version_edit.go +++ b/internal/manifest/version_edit.go @@ -17,6 +17,7 @@ import ( "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/internal/invariants" + "github.com/cockroachdb/pebble/sstable" ) // TODO(peter): describe the MANIFEST file format, independently of the C++ @@ -340,7 +341,7 @@ func (v *VersionEdit) Decode(r io.Reader) error { virtual bool backingFileNum uint64 }{} - var virtualPrefix *PrefixReplacement + var virtualPrefix *sstable.PrefixReplacement var syntheticSuffix []byte if tag == tagNewFile4 || tag == tagNewFile5 { for { @@ -391,7 +392,7 @@ func (v *VersionEdit) Decode(r io.Reader) error { if err != nil { return err } - virtualPrefix = &PrefixReplacement{ + virtualPrefix = &sstable.PrefixReplacement{ ContentPrefix: content, SyntheticPrefix: synthetic, } diff --git a/internal/manifest/version_edit_test.go b/internal/manifest/version_edit_test.go index 599ef9ba31..8035d60b3d 100644 --- a/internal/manifest/version_edit_test.go +++ b/internal/manifest/version_edit_test.go @@ -19,6 +19,7 @@ import ( "github.com/cockroachdb/errors" "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/record" + "github.com/cockroachdb/pebble/sstable" "github.com/kr/pretty" "github.com/stretchr/testify/require" ) @@ -50,7 +51,7 @@ func TestVERoundTripAndAccumulate(t *testing.T) { CreationTime: 809060, SmallestSeqNum: 9, LargestSeqNum: 11, - PrefixReplacement: &PrefixReplacement{ + PrefixReplacement: &sstable.PrefixReplacement{ ContentPrefix: []byte("before"), SyntheticPrefix: []byte("after"), }, diff --git a/sstable/reader_iter.go b/sstable/reader_iter.go index 2b5a267a16..7fe9c7604b 100644 --- a/sstable/reader_iter.go +++ b/sstable/reader_iter.go @@ -5,6 +5,7 @@ package sstable import ( + "bytes" "fmt" "os" "sync" @@ -34,6 +35,35 @@ type Iterator interface { SetCloseHook(fn func(i Iterator) error) } +// PrefixReplacement represents a read-time replacement of a key prefix. +type PrefixReplacement struct { + // ContentPrefix is the existing prefix that each key is expected to have. + ContentPrefix []byte + // SyntheticPrefix replaces the ContentPrefix in all keys. If ContentPrefix is + // empty, we are just prepending the synthetic prefix. + SyntheticPrefix []byte +} + +// ReplaceArg replaces the new prefix in the argument with the original prefix. +func (p *PrefixReplacement) ReplaceArg(src []byte) []byte { + return p.replace(src, p.SyntheticPrefix, p.ContentPrefix) +} + +// ReplaceResult replaces the original prefix in the result with the new prefix. +func (p *PrefixReplacement) ReplaceResult(key []byte) []byte { + return p.replace(key, p.ContentPrefix, p.SyntheticPrefix) +} + +func (p *PrefixReplacement) replace(key, from, to []byte) []byte { + if !bytes.HasPrefix(key, from) { + panic(fmt.Sprintf("unexpected prefix in replace: %s", key)) + } + result := make([]byte, 0, len(to)+(len(key)-len(from))) + result = append(result, to...) + result = append(result, key[len(from):]...) + return result +} + // Iterator positioning optimizations and singleLevelIterator and // twoLevelIterator: // diff --git a/sstable/reader_test.go b/sstable/reader_test.go index 41658f543c..5caa3707d0 100644 --- a/sstable/reader_test.go +++ b/sstable/reader_test.go @@ -25,7 +25,6 @@ import ( "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/internal/cache" "github.com/cockroachdb/pebble/internal/humanize" - "github.com/cockroachdb/pebble/internal/manifest" "github.com/cockroachdb/pebble/internal/testkeys" "github.com/cockroachdb/pebble/objstorage" "github.com/cockroachdb/pebble/objstorage/objstorageprovider" @@ -187,12 +186,11 @@ func TestVirtualReader(t *testing.T) { // Set during the latest build command. var r *Reader - var meta manifest.PhysicalFileMeta + var wMeta *WriterMetadata var bp BufferPool // Set during the latest virtualize command. - var vMeta1 manifest.VirtualFileMeta - var v VirtualReader + var v *VirtualReader defer func() { if r != nil { @@ -201,32 +199,6 @@ func TestVirtualReader(t *testing.T) { } }() - createPhysicalMeta := func(w *WriterMetadata, r *Reader) (manifest.PhysicalFileMeta, error) { - meta := &manifest.FileMetadata{} - meta.FileNum = nextFileNum() - meta.CreationTime = time.Now().Unix() - meta.Size = w.Size - meta.SmallestSeqNum = w.SmallestSeqNum - meta.LargestSeqNum = w.LargestSeqNum - - if w.HasPointKeys { - meta.ExtendPointKeyBounds(r.Compare, w.SmallestPoint, w.LargestPoint) - } - if w.HasRangeDelKeys { - meta.ExtendPointKeyBounds(r.Compare, w.SmallestRangeDel, w.LargestRangeDel) - } - if w.HasRangeKeys { - meta.ExtendRangeKeyBounds(r.Compare, w.SmallestRangeKey, w.LargestRangeKey) - } - meta.InitPhysicalBacking() - - if err := meta.Validate(r.Compare, r.opts.Comparer.FormatKey); err != nil { - return manifest.PhysicalFileMeta{}, err - } - - return meta.PhysicalMeta(), nil - } - formatWMeta := func(m *WriterMetadata) string { var b bytes.Buffer if m.HasPointKeys { @@ -281,11 +253,8 @@ func TestVirtualReader(t *testing.T) { bp.Release() _ = r.Close() r = nil - meta.FileMetadata = nil - vMeta1.FileMetadata = nil - v = VirtualReader{} + v = nil } - var wMeta *WriterMetadata var err error writerOpts := &WriterOptions{ TableFormat: TableFormatMax, @@ -307,13 +276,6 @@ func TestVirtualReader(t *testing.T) { return err.Error() } bp.Init(5) - - // Create a fake filemetada using the writer meta. - meta, err = createPhysicalMeta(wMeta, r) - if err != nil { - return err.Error() - } - r.fileNum = meta.FileBacking.DiskFileNum return formatWMeta(wMeta) case "virtualize": @@ -323,49 +285,39 @@ func TestVirtualReader(t *testing.T) { // this command the bounds must be valid keys. In general, and for // this command, range key/range del spans must also not span across // virtual sstable bounds. - if meta.FileMetadata == nil { + if wMeta == nil { return "build must be called at least once before virtualize" } - if vMeta1.FileMetadata != nil { - vMeta1.FileMetadata = nil - v = VirtualReader{} - } + v = nil + var params VirtualReaderParams + + // Parse the virtualization bounds. + bounds := strings.Split(td.CmdArgs[0].String(), "-") + params.Lower = base.ParseInternalKey(bounds[0]) + params.Upper = base.ParseInternalKey(bounds[1]) - var syntheticSuffix []byte if td.HasArg("suffix") { var synthSuffixStr string td.ScanArgs(t, "suffix", &synthSuffixStr) - syntheticSuffix = []byte(synthSuffixStr) + params.SyntheticSuffix = []byte(synthSuffixStr) } - vMeta := &manifest.FileMetadata{ - FileBacking: meta.FileBacking, - SmallestSeqNum: meta.SmallestSeqNum, - LargestSeqNum: meta.LargestSeqNum, - Virtual: true, - SyntheticSuffix: syntheticSuffix, - } - // Parse the virtualization bounds. - bounds := strings.Split(td.CmdArgs[0].String(), "-") - vMeta.Smallest = base.ParseInternalKey(bounds[0]) - vMeta.Largest = base.ParseInternalKey(bounds[1]) - vMeta.FileNum = nextFileNum() + params.FileNum = nextFileNum() + params.BackingSize = wMeta.Size var err error - vMeta.Size, err = r.EstimateDiskUsage(vMeta.Smallest.UserKey, vMeta.Largest.UserKey) + params.Size, err = r.EstimateDiskUsage(params.Lower.UserKey, params.Upper.UserKey) if err != nil { return err.Error() } - vMeta.ValidateVirtual(meta.FileMetadata) - - vMeta1 = vMeta.VirtualMeta() - v = MakeVirtualReader(r, vMeta1, false /* isSharedIngested */) - return formatVirtualReader(&v) + vr := MakeVirtualReader(r, params) + v = &vr + return formatVirtualReader(v) case "citer": // Creates a compaction iterator from the virtual reader, and then // just scans the keyspace. Which is all a compaction iterator is // used for. This tests the First and Next calls. - if vMeta1.FileMetadata == nil { + if v == nil { return "virtualize must be called before creating compaction iters" } @@ -387,7 +339,7 @@ func TestVirtualReader(t *testing.T) { return buf.String() case "constrain": - if vMeta1.FileMetadata == nil { + if v == nil { return "virtualize must be called before constrain" } splits := strings.Split(td.CmdArgs[0].String(), ",") @@ -407,7 +359,7 @@ func TestVirtualReader(t *testing.T) { return buf.String() case "scan-range-del": - if vMeta1.FileMetadata == nil { + if v == nil { return "virtualize must be called before scan-range-del" } iter, err := v.NewRawRangeDelIter() @@ -430,7 +382,7 @@ func TestVirtualReader(t *testing.T) { return buf.String() case "scan-range-key": - if vMeta1.FileMetadata == nil { + if v == nil { return "virtualize must be called before scan-range-key" } iter, err := v.NewRawRangeKeyIter() @@ -453,7 +405,7 @@ func TestVirtualReader(t *testing.T) { return buf.String() case "iter": - if vMeta1.FileMetadata == nil { + if v == nil { return "virtualize must be called before iter" } var lower, upper []byte diff --git a/sstable/reader_virtual.go b/sstable/reader_virtual.go index 69c6242dd1..fdacde0bcf 100644 --- a/sstable/reader_virtual.go +++ b/sstable/reader_virtual.go @@ -9,7 +9,6 @@ import ( "github.com/cockroachdb/pebble/internal/base" "github.com/cockroachdb/pebble/internal/keyspan" - "github.com/cockroachdb/pebble/internal/manifest" "github.com/cockroachdb/pebble/internal/rangekey" ) @@ -33,50 +32,63 @@ type virtualState struct { fileNum base.FileNum Compare Compare isSharedIngested bool - prefixChange *manifest.PrefixReplacement + prefixChange *PrefixReplacement syntheticSuffix SyntheticSuffix } -func ceilDiv(a, b uint64) uint64 { - return (a + b - 1) / b +// VirtualReaderParams are the parameters necessary to create a VirtualReader. +type VirtualReaderParams struct { + Lower InternalKey + Upper InternalKey + FileNum base.FileNum + IsShared bool + // Size is an estimate of the size of the [Lower, Upper) section of the table. + Size uint64 + // BackingSize is the total size of the backing table. The ratio between Size + // and BackingSize is used to estimate statistics. + BackingSize uint64 + // TODO(radu): this should be passed just to iterators. + PrefixReplacement *PrefixReplacement + SyntheticSuffix SyntheticSuffix } // MakeVirtualReader is used to contruct a reader which can read from virtual // sstables. -func MakeVirtualReader(reader *Reader, meta manifest.VirtualFileMeta, isShared bool) VirtualReader { - if reader.fileNum != meta.FileBacking.DiskFileNum { - panic("pebble: invalid call to MakeVirtualReader") - } - +func MakeVirtualReader(reader *Reader, p VirtualReaderParams) VirtualReader { vState := virtualState{ - lower: meta.Smallest, - upper: meta.Largest, - fileNum: meta.FileNum, + lower: p.Lower, + upper: p.Upper, + fileNum: p.FileNum, Compare: reader.Compare, - isSharedIngested: isShared && reader.Properties.GlobalSeqNum != 0, - prefixChange: meta.PrefixReplacement, - syntheticSuffix: meta.SyntheticSuffix, + isSharedIngested: p.IsShared && reader.Properties.GlobalSeqNum != 0, + prefixChange: p.PrefixReplacement, + syntheticSuffix: p.SyntheticSuffix, } v := VirtualReader{ vState: vState, reader: reader, } - v.Properties.RawKeySize = ceilDiv(reader.Properties.RawKeySize*meta.Size, meta.FileBacking.Size) - v.Properties.RawValueSize = ceilDiv(reader.Properties.RawValueSize*meta.Size, meta.FileBacking.Size) - v.Properties.NumEntries = ceilDiv(reader.Properties.NumEntries*meta.Size, meta.FileBacking.Size) - v.Properties.NumDeletions = ceilDiv(reader.Properties.NumDeletions*meta.Size, meta.FileBacking.Size) - v.Properties.NumRangeDeletions = ceilDiv(reader.Properties.NumRangeDeletions*meta.Size, meta.FileBacking.Size) - v.Properties.NumRangeKeyDels = ceilDiv(reader.Properties.NumRangeKeyDels*meta.Size, meta.FileBacking.Size) + // Scales the given value by the (Size / BackingSize) ratio, rounding up. + scale := func(a uint64) uint64 { + return (a*p.Size + p.BackingSize - 1) / p.BackingSize + } + + v.Properties.RawKeySize = scale(reader.Properties.RawKeySize) + v.Properties.RawValueSize = scale(reader.Properties.RawValueSize) + v.Properties.NumEntries = scale(reader.Properties.NumEntries) + v.Properties.NumDeletions = scale(reader.Properties.NumDeletions) + v.Properties.NumRangeDeletions = scale(reader.Properties.NumRangeDeletions) + v.Properties.NumRangeKeyDels = scale(reader.Properties.NumRangeKeyDels) // Note that we rely on NumRangeKeySets for correctness. If the sstable may // contain range keys, then NumRangeKeySets must be > 0. ceilDiv works because // meta.Size will not be 0 for virtual sstables. - v.Properties.NumRangeKeySets = ceilDiv(reader.Properties.NumRangeKeySets*meta.Size, meta.FileBacking.Size) - v.Properties.ValueBlocksSize = ceilDiv(reader.Properties.ValueBlocksSize*meta.Size, meta.FileBacking.Size) - v.Properties.NumSizedDeletions = ceilDiv(reader.Properties.NumSizedDeletions*meta.Size, meta.FileBacking.Size) - v.Properties.RawPointTombstoneKeySize = ceilDiv(reader.Properties.RawPointTombstoneKeySize*meta.Size, meta.FileBacking.Size) - v.Properties.RawPointTombstoneValueSize = ceilDiv(reader.Properties.RawPointTombstoneValueSize*meta.Size, meta.FileBacking.Size) + v.Properties.NumRangeKeySets = scale(reader.Properties.NumRangeKeySets) + v.Properties.ValueBlocksSize = scale(reader.Properties.ValueBlocksSize) + v.Properties.NumSizedDeletions = scale(reader.Properties.NumSizedDeletions) + v.Properties.RawPointTombstoneKeySize = scale(reader.Properties.RawPointTombstoneKeySize) + v.Properties.RawPointTombstoneValueSize = scale(reader.Properties.RawPointTombstoneValueSize) return v } diff --git a/sstable/testdata/virtual_reader b/sstable/testdata/virtual_reader index 7f0ef064cd..69a1bdd756 100644 --- a/sstable/testdata/virtual_reader +++ b/sstable/testdata/virtual_reader @@ -19,7 +19,7 @@ seqnums: [1-1] virtualize b.SET.1-c.SET.1 ---- bounds: [b#1,1-c#1,1] -filenum: 000002 +filenum: 000001 props: NumEntries: 1, RawKeySize: 3, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 citer @@ -40,7 +40,7 @@ seqnums: [1-1] virtualize b.SET.1-c.SET.1 ---- bounds: [b#1,1-c#1,1] -filenum: 000004 +filenum: 000002 props: NumEntries: 1, RawKeySize: 2, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 citer @@ -128,7 +128,7 @@ seqnums: [1-12] virtualize a.SET.1-f.SET.1 ---- bounds: [a#1,1-f#1,1] -filenum: 000006 +filenum: 000003 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 1, ValueBlocksSize: 0 scan-range-del @@ -158,7 +158,7 @@ seqnums: [1-9] virtualize dd.SET.5-ddd.SET.6 ---- bounds: [dd#5,1-ddd#6,1] -filenum: 000008 +filenum: 000004 props: NumEntries: 1, RawKeySize: 10, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 # Check lower bound enforcement during SeekPrefixGE. @@ -189,7 +189,7 @@ seqnums: [1-9] virtualize c.SET.3-f.SET.6 ---- bounds: [c#3,1-f#6,1] -filenum: 000010 +filenum: 000005 props: NumEntries: 1, RawKeySize: 9, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 # Just test a basic iterator once virtual sstable bounds have been set. @@ -289,7 +289,7 @@ seqnums: [1-9] virtualize c.SET.3-f.SET.1:ff ---- bounds: [c#3,1-f#0,1] -filenum: 000012 +filenum: 000006 props: NumEntries: 2, RawKeySize: 11, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 3 iter @@ -342,7 +342,7 @@ last virtualize f.SET.6-h.SET.9 ---- bounds: [f#6,1-h#9,1] -filenum: 000013 +filenum: 000007 props: NumEntries: 2, RawKeySize: 11, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 3 iter @@ -381,7 +381,7 @@ seqnums: [1-9] virtualize dd.SET.5-ddd.SET.6 ---- bounds: [dd#5,1-ddd#6,1] -filenum: 000015 +filenum: 000008 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 # Check lower bound enforcement during SeekPrefixGE. @@ -412,7 +412,7 @@ seqnums: [1-9] virtualize c.SET.3-f.SET.6 ---- bounds: [c#3,1-f#6,1] -filenum: 000017 +filenum: 000009 props: NumEntries: 1, RawKeySize: 7, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 # Just test a basic iterator once virtual sstable bounds have been set. @@ -512,7 +512,7 @@ seqnums: [1-9] virtualize c.SET.3-f.SET.1:ff ---- bounds: [c#3,1-f#0,1] -filenum: 000019 +filenum: 000010 props: NumEntries: 1, RawKeySize: 7, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 2 iter @@ -565,7 +565,7 @@ last virtualize f.SET.6-h.SET.9 ---- bounds: [f#6,1-h#9,1] -filenum: 000020 +filenum: 000011 props: NumEntries: 1, RawKeySize: 7, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 2 iter @@ -604,7 +604,7 @@ seqnums: [1-5] virtualize a.SET.1-e.RANGEDEL.72057594037927935 ---- bounds: [a#1,1-e#72057594037927935,15] -filenum: 000022 +filenum: 000012 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 iter @@ -643,7 +643,7 @@ seqnums: [1-5] virtualize a.SET.1-e.RANGEDEL.72057594037927935 ---- bounds: [a#1,1-e#72057594037927935,15] -filenum: 000024 +filenum: 000013 props: NumEntries: 1, RawKeySize: 4, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 iter @@ -688,7 +688,7 @@ seqnums: [1-12] virtualize a.SET.1-b.SET.5 ---- bounds: [a#1,1-b#5,1] -filenum: 000026 +filenum: 000014 props: NumEntries: 1, RawKeySize: 3, RawValueSize: 1, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 1, NumRangeDeletions: 1, NumRangeKeyDels: 0, NumRangeKeySets: 1, ValueBlocksSize: 0 # Test that a virtual reader with a suffix replacement rule replaces the @@ -712,7 +712,7 @@ seqnums: [1-9] virtualize c@7.SET.3-f@4.SET.8 suffix=@8 ---- bounds: [c@7#3,1-f@4#8,1] -filenum: 000028 +filenum: 000015 props: NumEntries: 2, RawKeySize: 13, RawValueSize: 2, RawPointTombstoneKeySize: 0, RawPointTombstoneValueSize: 0, NumSizedDeletions: 0, NumDeletions: 0, NumRangeDeletions: 0, NumRangeKeyDels: 0, NumRangeKeySets: 0, ValueBlocksSize: 0 # Just test a basic iterator once virtual sstable bounds have been set. diff --git a/table_cache.go b/table_cache.go index a7a012d04e..1c9f554cc2 100644 --- a/table_cache.go +++ b/table_cache.go @@ -276,7 +276,7 @@ func createCommonReader(v *tableCacheValue, file *fileMetadata) sstable.CommonRe var cr sstable.CommonReader = v.reader if file.Virtual { virtualReader := sstable.MakeVirtualReader( - v.reader, file.VirtualMeta(), v.isShared, + v.reader, file.VirtualMeta().VirtualReaderParams(v.isShared), ) cr = &virtualReader } @@ -320,7 +320,7 @@ func (c *tableCacheContainer) withVirtualReader( if err != nil { return err } - return fn(sstable.MakeVirtualReader(v.reader, meta, objMeta.IsShared())) + return fn(sstable.MakeVirtualReader(v.reader, meta.VirtualReaderParams(objMeta.IsShared()))) } func (c *tableCacheContainer) iterCount() int64 {