Skip to content

Commit 1d68b01

Browse files
committed
internal/manifest: add BlobReferences type
Define a BlobReferences type for a slice of blob references, and use it on the TableMetadata for its BlobReferences field. When yielding an InternalValue backed by a blob value handle to higher levels, an iterator will need to map the blob handle's file reference index to the file number. This type will implement the interface to perform this mapping.
1 parent d5443f6 commit 1d68b01

File tree

9 files changed

+60
-39
lines changed

9 files changed

+60
-39
lines changed

internal/blobtest/handles.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ func (bv *Values) ParseInlineHandle(
190190
}
191191
return blob.InlineHandle{
192192
InlineHandlePreface: blob.InlineHandlePreface{
193-
ReferenceIndex: references.MapToReferenceIndex(fullHandle.FileNum),
194-
ValueLen: fullHandle.ValueLen,
193+
ReferenceID: references.MapToReferenceID(fullHandle.FileNum),
194+
ValueLen: fullHandle.ValueLen,
195195
},
196196
HandleSuffix: blob.HandleSuffix{
197197
BlockNum: fullHandle.BlockNum,
@@ -261,14 +261,14 @@ type References struct {
261261
fileNums []base.DiskFileNum
262262
}
263263

264-
// MapToReferenceIndex maps the given file number to a reference index.
265-
func (b *References) MapToReferenceIndex(fileNum base.DiskFileNum) uint32 {
264+
// MapToReferenceID maps the given file number to a reference ID.
265+
func (b *References) MapToReferenceID(fileNum base.DiskFileNum) blob.ReferenceID {
266266
for i, fn := range b.fileNums {
267267
if fn == fileNum {
268-
return uint32(i)
268+
return blob.ReferenceID(i)
269269
}
270270
}
271271
i := uint32(len(b.fileNums))
272272
b.fileNums = append(b.fileNums, fileNum)
273-
return i
273+
return blob.ReferenceID(i)
274274
}

internal/compact/run.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ type OutputTable struct {
4848
// failure (see Result), WriterMeta might not be set.
4949
WriterMeta sstable.WriterMetadata
5050
// BlobReferences is the list of blob references for the table.
51-
BlobReferences []manifest.BlobReference
51+
BlobReferences manifest.BlobReferences
5252
// BlobReferenceDepth is the depth of the blob references for the table.
5353
BlobReferenceDepth manifest.BlobReferenceDepth
5454
}
@@ -138,7 +138,7 @@ type ValueSeparation interface {
138138
// ValueSeparationMetadata describes metadata about a table's blob references,
139139
// and optionally a newly constructed blob file.
140140
type ValueSeparationMetadata struct {
141-
BlobReferences []manifest.BlobReference
141+
BlobReferences manifest.BlobReferences
142142
BlobReferenceSize uint64
143143
BlobReferenceDepth manifest.BlobReferenceDepth
144144

internal/manifest/blob_metadata.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/cockroachdb/pebble/internal/humanize"
1313
"github.com/cockroachdb/pebble/internal/invariants"
1414
"github.com/cockroachdb/pebble/internal/strparse"
15+
"github.com/cockroachdb/pebble/sstable/blob"
1516
"github.com/cockroachdb/redact"
1617
)
1718

@@ -216,3 +217,26 @@ func ParseBlobFileMetadataDebug(s string) (_ *BlobFileMetadata, err error) {
216217
// is actually better than in this analysis because more of the keys will be
217218
// from the lower level.
218219
type BlobReferenceDepth int
220+
221+
// BlobReferences is a slice of BlobReference. The order of the slice is
222+
// significant and should be maintained. In practice, a sstable's BlobReferences
223+
// are ordered by earliest appearance within the sstable. The ordering is
224+
// persisted to the manifest.
225+
type BlobReferences []BlobReference
226+
227+
// FileNumByID returns the FileNum for the identified BlobReference.
228+
func (br BlobReferences) FileNumByID(i blob.ReferenceID) base.DiskFileNum {
229+
return br[i].FileNum
230+
}
231+
232+
// IDByFileNum returns the reference ID for the given FileNum. If the file
233+
// number is not found, the second return value is false. IDByFileNum is linear
234+
// in the length of the BlobReferences slice.
235+
func (br BlobReferences) IDByFileNum(fileNum base.DiskFileNum) (blob.ReferenceID, bool) {
236+
for i, ref := range br {
237+
if ref.FileNum == fileNum {
238+
return blob.ReferenceID(i), true
239+
}
240+
}
241+
return blob.ReferenceID(len(br)), false
242+
}

internal/manifest/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ type TableMetadata struct {
238238
Largest InternalKey
239239
// BlobReferences is a list of blob files containing values that are
240240
// referenced by this sstable.
241-
BlobReferences []BlobReference
241+
BlobReferences BlobReferences
242242
// BlobReferenceDepth is the stack depth of blob files referenced by this
243243
// sstable. See the comment on the BlobReferenceDepth type for more details.
244244
//

internal/manifest/version_edit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ func (v *VersionEdit) Decode(r io.Reader) error {
357357
}{}
358358
var syntheticPrefix sstable.SyntheticPrefix
359359
var syntheticSuffix sstable.SyntheticSuffix
360-
var blobReferences []BlobReference
360+
var blobReferences BlobReferences
361361
var blobReferenceDepth BlobReferenceDepth
362362
if tag == tagNewFile4 || tag == tagNewFile5 {
363363
for {

sstable/blob/blob_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ func TestHandleRoundtrip(t *testing.T) {
8787
handles := []InlineHandle{
8888
{
8989
InlineHandlePreface: InlineHandlePreface{
90-
ReferenceIndex: 0,
91-
ValueLen: 29357353,
90+
ReferenceID: 0,
91+
ValueLen: 29357353,
9292
},
9393
HandleSuffix: HandleSuffix{
9494
BlockNum: 194,
@@ -97,8 +97,8 @@ func TestHandleRoundtrip(t *testing.T) {
9797
},
9898
{
9999
InlineHandlePreface: InlineHandlePreface{
100-
ReferenceIndex: 129,
101-
ValueLen: 205,
100+
ReferenceID: 129,
101+
ValueLen: 205,
102102
},
103103
HandleSuffix: HandleSuffix{
104104
BlockNum: 2,

sstable/blob/handle.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,16 @@ type InlineHandle struct {
5454
HandleSuffix
5555
}
5656

57+
// ReferenceID identifies a particular blob reference within a table. It's
58+
// implemented as an index into the slice of the BlobReferences recorded in the
59+
// manifest.
60+
type ReferenceID uint32
61+
5762
// InlineHandlePreface is the prefix of an inline handle. It's eagerly decoded
5863
// when returning an InternalValue to higher layers.
5964
type InlineHandlePreface struct {
60-
ReferenceIndex uint32
61-
ValueLen uint32
65+
ReferenceID ReferenceID
66+
ValueLen uint32
6267
}
6368

6469
// HandleSuffix is the suffix of an inline handle. It's decoded only when the
@@ -85,14 +90,14 @@ func (h InlineHandle) String() string {
8590
// SafeFormat implements redact.SafeFormatter.
8691
func (h InlineHandle) SafeFormat(w redact.SafePrinter, _ rune) {
8792
w.Printf("(f%d,blk%d[%d:%d])",
88-
h.ReferenceIndex, h.BlockNum, h.OffsetInBlock, h.OffsetInBlock+h.ValueLen)
93+
h.ReferenceID, h.BlockNum, h.OffsetInBlock, h.OffsetInBlock+h.ValueLen)
8994
}
9095

9196
// Encode encodes the inline handle into the provided buffer, returning the
9297
// number of bytes encoded.
9398
func (h InlineHandle) Encode(b []byte) int {
9499
n := 0
95-
n += binary.PutUvarint(b[n:], uint64(h.ReferenceIndex))
100+
n += binary.PutUvarint(b[n:], uint64(h.ReferenceID))
96101
n += valblk.EncodeHandle(b[n:], valblk.Handle{
97102
BlockNum: h.BlockNum,
98103
OffsetInBlock: h.OffsetInBlock,
@@ -145,8 +150,8 @@ func DecodeInlineHandlePrefix(src []byte) (InlineHandlePreface, []byte) {
145150
}
146151

147152
return InlineHandlePreface{
148-
ReferenceIndex: refIdx,
149-
ValueLen: valueLen,
153+
ReferenceID: ReferenceID(refIdx),
154+
ValueLen: valueLen,
150155
}, src
151156
}
152157

sstable/data_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ func decodeBlobInlineHandleAndAttribute(
204204
}
205205
return blob.InlineHandle{
206206
InlineHandlePreface: blob.InlineHandlePreface{
207-
ReferenceIndex: uint32(refIdx),
208-
ValueLen: uint32(valLen),
207+
ReferenceID: blob.ReferenceID(refIdx),
208+
ValueLen: uint32(valLen),
209209
},
210210
HandleSuffix: blob.HandleSuffix{
211211
BlockNum: uint32(blockNum),

value_separation.go

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ func (vs *writeNewBlobFiles) Add(
143143
// between sstables and blob files, the reference index is always 0
144144
// here. Only compactions that don't rewrite blob files will produce
145145
// handles with nonzero reference indices.
146-
ReferenceIndex: 0,
147-
ValueLen: handle.ValueLen,
146+
ReferenceID: 0,
147+
ValueLen: handle.ValueLen,
148148
},
149149
HandleSuffix: blob.HandleSuffix{
150150
BlockNum: handle.BlockNum,
@@ -166,7 +166,7 @@ func (vs *writeNewBlobFiles) FinishOutput() (compact.ValueSeparationMetadata, er
166166
}
167167
vs.writer = nil
168168
return compact.ValueSeparationMetadata{
169-
BlobReferences: []manifest.BlobReference{{
169+
BlobReferences: manifest.BlobReferences{{
170170
FileNum: vs.objMeta.DiskFileNum,
171171
ValueSize: stats.UncompressedValueBytes,
172172
}},
@@ -197,7 +197,7 @@ type preserveBlobReferences struct {
197197

198198
// state
199199
buf []byte
200-
currReferences []manifest.BlobReference
200+
currReferences manifest.BlobReferences
201201
// totalValueSize is the sum of the sizes of all ValueSizes in currReferences.
202202
totalValueSize uint64
203203
}
@@ -250,24 +250,16 @@ func (vs *preserveBlobReferences) Add(
250250
// sstable, taking note of the reference for the table metadata.
251251
lv := kv.V.LazyValue()
252252
fn := lv.Fetcher.BlobFileNum
253-
var found bool
254-
refIdx := 0
255-
for refIdx = range vs.currReferences {
256-
if vs.currReferences[refIdx].FileNum == fn {
257-
// This sstable contains an existing reference to this blob file.
258-
// Record the reference.
259-
found = true
260-
break
261-
}
262-
}
253+
254+
refIdx, found := vs.currReferences.IDByFileNum(fn)
263255
if !found {
264256
// This is the first time we're seeing this blob file for this sstable.
265257
// Find the blob file metadata for this file among the input metadatas.
266258
idx, found := vs.findInputBlobMetadata(fn)
267259
if !found {
268260
return errors.AssertionFailedf("pebble: blob file %s not found among input sstables", fn)
269261
}
270-
refIdx = len(vs.currReferences)
262+
refIdx = blob.ReferenceID(len(vs.currReferences))
271263
vs.currReferences = append(vs.currReferences, manifest.BlobReference{
272264
FileNum: fn,
273265
Metadata: vs.inputBlobMetadatas[idx],
@@ -281,8 +273,8 @@ func (vs *preserveBlobReferences) Add(
281273
handleSuffix := blob.DecodeHandleSuffix(lv.ValueOrHandle)
282274
inlineHandle := blob.InlineHandle{
283275
InlineHandlePreface: blob.InlineHandlePreface{
284-
ReferenceIndex: uint32(refIdx),
285-
ValueLen: lv.Fetcher.Attribute.ValueLen,
276+
ReferenceID: refIdx,
277+
ValueLen: lv.Fetcher.Attribute.ValueLen,
286278
},
287279
HandleSuffix: handleSuffix,
288280
}

0 commit comments

Comments
 (0)