Skip to content

Commit

Permalink
sstable: introduce RawColumnWriter
Browse files Browse the repository at this point in the history
Introduce a new RawWriter implementation that writes sstables using
columnar-oriented blocks. This commit lays down the initial stencil of the
writer. The new table format is currently excluded from unit tests, in part
because the sstable reader does not yet know how to read the new table format.
  • Loading branch information
jbowens committed Sep 13, 2024
1 parent 0665a3e commit d5fd992
Show file tree
Hide file tree
Showing 13 changed files with 2,313 additions and 25 deletions.
8 changes: 8 additions & 0 deletions internal/aligned/aligned.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ func ByteSlice(n int) []byte {
}
return b
}

// Copy copies the provided byte slice into an aligned byte slice of the same
// length.
func Copy(s []byte) []byte {
dst := ByteSlice(len(s))
copy(dst, s)
return dst
}
42 changes: 42 additions & 0 deletions internal/binfmt/binfmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,36 @@ func (f *Formatter) HexBytesln(n int, format string, args ...interface{}) int {
return n
}

// HexTextln formats the next n bytes in hexadecimal format, appending a comment
// to each line showing the ASCII equivalent characters for each byte for bytes
// that are human-readable.
func (f *Formatter) HexTextln(n int) int {
printLine := func() {
bytesInLine := min(f.lineWidth/2, n)
if f.buf.Len() == 0 {
f.printOffsets(bytesInLine)
}
f.printf("x %0"+strconv.Itoa(bytesInLine*2)+"x", f.data[f.off:f.off+bytesInLine])
commentLine := asciiChars(f.data[f.off : f.off+bytesInLine])
f.newline(f.buf.String(), commentLine)
f.off += bytesInLine
n -= bytesInLine
}
printLine()
for n > 0 {
printLine()
}
return n
}

// Uvarint decodes the bytes at the current offset as a uvarint, formatting them
// in hexadecimal and prefixing the comment with the encoded decimal value.
func (f *Formatter) Uvarint(format string, args ...interface{}) {
comment := fmt.Sprintf(format, args...)
v, n := binary.Uvarint(f.data[f.off:])
f.HexBytesln(n, "uvarint(%d): %s", v, comment)
}

// Line prepares a single line of formatted output that will consume n bytes,
// but formatting those n bytes in multiple ways. The line will be prefixed with
// the offsets for the line's entire data.
Expand Down Expand Up @@ -241,3 +271,15 @@ func (l Line) Done(format string, args ...interface{}) int {
l.f.off += l.n
return l.n
}

func asciiChars(b []byte) string {
s := make([]byte, len(b))
for i := range b {
if b[i] >= 32 && b[i] <= 126 {
s[i] = b[i]
} else {
s[i] = '.'
}
}
return string(s)
}
11 changes: 8 additions & 3 deletions internal/cache/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ package cache
import "unsafe"

// ValueMetadataSize denotes the number of bytes of metadata allocated for a
// cache entry. Note that for builds with cgo disabled no metadata is allocated,
// however, we keep the value constant to reduce friction for writing tests.
const ValueMetadataSize = int(unsafe.Sizeof(Value{}))
// cache entry. Note that builds with cgo disabled allocate no metadata, and
// 32-bit builds allocate less for a cache.Value. However, we keep the value
// constant to reduce friction for writing tests.
const ValueMetadataSize = 32

// Assert that the size of a Value{} is less than or equal to the
// ValueMetadataSize.
var _ uint = ValueMetadataSize - uint(unsafe.Sizeof(Value{}))

// Value holds a reference counted immutable value.
type Value struct {
Expand Down
7 changes: 7 additions & 0 deletions sstable/block/compression.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ func (b *PhysicalBlock) CloneWithByteAlloc(a *bytealloc.A) PhysicalBlock {
}
}

// Clone returns a deep copy of the block.
func (b PhysicalBlock) Clone() PhysicalBlock {
data := make([]byte, len(b.data))
copy(data, b.data)
return PhysicalBlock{data: data, trailer: b.trailer}
}

// IsCompressed returns true if the block is compressed.
func (b *PhysicalBlock) IsCompressed() bool {
return CompressionIndicator(b.trailer[0]) != NoCompressionIndicator
Expand Down
Loading

0 comments on commit d5fd992

Please sign in to comment.