Skip to content

Commit

Permalink
colblk: add IndexBlockWriter.UnsafeSeparator
Browse files Browse the repository at this point in the history
Add an API for retrieving a separator contained in an entry written to a
pending index block. This will be used by the sstable writer when finishing an
index block in a sstable with a two-level index.
  • Loading branch information
jbowens committed Aug 30, 2024
1 parent 5a00241 commit bb1c2c4
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 7 deletions.
6 changes: 4 additions & 2 deletions sstable/colblk/data_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ func (w *defaultKeyWriter) ComparePrev(key []byte) KeyComparison {
// CommonPrefixLen, it would sort after [key].)
if cmpv.CommonPrefixLen == cmpv.PrefixLen {
// The keys share the same MVCC prefix. Compare the suffixes.
cmpv.UserKeyComparison = int32(w.comparer.CompareSuffixes(key[cmpv.PrefixLen:], w.suffixes.LastSlice()))
cmpv.UserKeyComparison = int32(w.comparer.CompareSuffixes(key[cmpv.PrefixLen:],
w.suffixes.UnsafeGet(w.suffixes.rows-1)))
if invariants.Enabled {
if !w.comparer.Equal(lp, key[:cmpv.PrefixLen]) {
panic(errors.AssertionFailedf("keys have different logical prefixes: %q != %q", lp, key[:cmpv.PrefixLen]))
Expand All @@ -206,7 +207,8 @@ func (w *defaultKeyWriter) ComparePrev(key []byte) KeyComparison {
// so the UserKeyComparison should be equal to the result of comparing
// the prefixes and nonzero.
if cmpv.UserKeyComparison == 0 {
panic(errors.AssertionFailedf("user keys should not be equal: %q+%q, %q", lp, w.suffixes.LastSlice(), key))
panic(errors.AssertionFailedf("user keys should not be equal: %q+%q, %q",
lp, w.suffixes.UnsafeGet(w.suffixes.rows-1), key))
}
if v := w.comparer.Compare(key, lp); v != int(cmpv.UserKeyComparison) {
panic(errors.AssertionFailedf("user key comparison mismatch: Compare(%q, %q) = %d ≠ %d",
Expand Down
10 changes: 10 additions & 0 deletions sstable/colblk/index_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ func (w *IndexBlockWriter) Reset() {
w.enc.reset()
}

// Rows returns the number of entries in the index block so far.
func (w *IndexBlockWriter) Rows() int {
return w.rows
}

// AddBlockHandle adds a new separator and end offset of a data block to the
// index block. Add returns the index of the row.
//
Expand All @@ -85,6 +90,11 @@ func (w *IndexBlockWriter) AddBlockHandle(
return idx
}

// UnsafeSeparator returns the separator of the i'th entry.
func (w *IndexBlockWriter) UnsafeSeparator(i int) []byte {
return w.separators.UnsafeGet(i)
}

// Size returns the size of the pending index block.
func (w *IndexBlockWriter) Size() int {
off := blockHeaderSize(indexBlockColumnCount, indexBlockCustomHeaderSize)
Expand Down
4 changes: 3 additions & 1 deletion sstable/colblk/index_block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ func TestIndexBlock(t *testing.T) {
}
w.AddBlockHandle([]byte(fields[0]), h, bp)
}
fmt.Fprintf(&buf, "UnsafeSeparator(Rows()-1) = %q\n", w.UnsafeSeparator(w.Rows()-1))
data := w.Finish()
r.Init(data)
return r.DebugString()
fmt.Fprint(&buf, r.DebugString())
return buf.String()
case "iter":
var it IndexIter
it.Init(&r)
Expand Down
11 changes: 8 additions & 3 deletions sstable/colblk/raw_bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,18 @@ func (b *RawBytesBuilder) PutConcat(s1, s2 []byte) {
b.offsets.Set(b.rows, uint64(len(b.data)))
}

// LastSlice returns the last slice added to the builder. The returned slice is
// Rows returns the count of slices that have been added to the builder.
func (b *RawBytesBuilder) Rows() int {
return b.rows
}

// UnsafeGet returns the i'th slice added to the builder. The returned slice is
// owned by the builder and must not be mutated.
func (b *RawBytesBuilder) LastSlice() []byte {
func (b *RawBytesBuilder) UnsafeGet(i int) []byte {
if b.rows == 0 {
return nil
}
return b.data[b.offsets.array.elems.At(b.rows-1):b.offsets.array.elems.At(b.rows)]
return b.data[b.offsets.array.elems.At(i):b.offsets.array.elems.At(i+1)]
}

// Finish writes the serialized byte slices to buf starting at offset. The buf
Expand Down
2 changes: 2 additions & 0 deletions sstable/colblk/testdata/index_block
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ bacitracin 412 212
banana 632 215 bp5
bonifide 963 326 bp6
----
UnsafeSeparator(Rows()-1) = "bonifide"
# index block header
# columnar block header
000-001: x 01 # version 1
Expand Down Expand Up @@ -130,6 +131,7 @@ catatonic 102422 20442
cephalopod 122864 9104 bp4
coat 293128 32104
----
UnsafeSeparator(Rows()-1) = "coat"
# index block header
# columnar block header
000-001: x 01 # version 1
Expand Down
2 changes: 1 addition & 1 deletion sstable/colblk/unsafe_slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ var _ Array[uint64] = UnsafeUints{}
func DecodeUnsafeUints(b []byte, off uint32, rows int) (_ UnsafeUints, endOffset uint32) {
encoding := UintEncoding(b[off])
if !encoding.IsValid() {
panic(errors.AssertionFailedf("invalid encoding 0x%x", b))
panic(errors.AssertionFailedf("invalid encoding 0x%x", b[off:off+1]))
}
off++
var base uint64
Expand Down

0 comments on commit bb1c2c4

Please sign in to comment.