0

Initial commit

This commit is contained in:
eleksir
2022-09-04 02:34:54 +03:00
commit d9de157ad8
1017 changed files with 407553 additions and 0 deletions

View File

@@ -0,0 +1,284 @@
// Copyright 2021 The LevelDB-Go and Pebble Authors. All rights reserved. Use
// of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
package rangekey
import (
"bytes"
"sort"
"github.com/cockroachdb/pebble/internal/base"
"github.com/cockroachdb/pebble/internal/invariants"
"github.com/cockroachdb/pebble/internal/keyspan"
"github.com/cockroachdb/pebble/internal/manifest"
)
// UserIteratorConfig holds state for constructing the range key iterator stack
// for user iteration.
type UserIteratorConfig struct {
snapshot uint64
miter keyspan.MergingIter
diter keyspan.DefragmentingIter
liters [manifest.NumLevels]keyspan.LevelIter
litersUsed int
defragBufA keysBySuffix
defragBufB keysBySuffix
// defragBufAlloc defines two arrays used to preallocate defragBuf{A,B} keys
// slices to prevent additional allocations during iteration. Each array
// preallocates up to two keys.
defragBufAlloc [2][2]keyspan.Key
}
// Init initializes the range key iterator stack for user iteration. The
// resulting fragment iterator applies range key semantics, defragments spans
// according to their user-observable state and removes all Keys other than
// RangeKeySets describing the current state of range keys.
//
// The snapshot sequence number parameter determines which keys are visible. Any
// keys not visible at the provided snapshot are ignored.
func (ui *UserIteratorConfig) Init(
cmp base.Compare, snapshot uint64, iters ...keyspan.FragmentIterator,
) keyspan.FragmentIterator {
ui.snapshot = snapshot
ui.defragBufA.keys = ui.defragBufAlloc[0][:0]
ui.defragBufB.keys = ui.defragBufAlloc[1][:0]
ui.miter.Init(cmp, ui, iters...)
ui.diter.Init(cmp, &ui.miter, ui, keyspan.StaticDefragmentReducer)
ui.litersUsed = 0
return &ui.diter
}
// AddLevel adds a new level to the bottom of the iterator stack. AddLevel
// must be called after Init and before any other method on the iterator.
func (ui *UserIteratorConfig) AddLevel(iter keyspan.FragmentIterator) {
ui.miter.AddLevel(iter)
}
// NewLevelIter returns a pointer to a newly allocated or reused
// keyspan.LevelIter. The caller is responsible for calling Init() on this
// instance.
func (ui *UserIteratorConfig) NewLevelIter() *keyspan.LevelIter {
if ui.litersUsed >= len(ui.liters) {
return &keyspan.LevelIter{}
}
ui.litersUsed++
return &ui.liters[ui.litersUsed-1]
}
// Transform implements the keyspan.Transformer interface for use with a
// keyspan.MergingIter. It transforms spans by resolving range keys at the
// provided snapshot sequence number. Shadowing of keys is resolved (eg, removal
// of unset keys, removal of keys overwritten by a set at the same suffix, etc)
// and then non-RangeKeySet keys are removed. The resulting transformed spans
// only contain RangeKeySets describing the state visible at the provided
// sequence number.
func (ui *UserIteratorConfig) Transform(cmp base.Compare, s keyspan.Span, dst *keyspan.Span) error {
// Apply shadowing of keys.
dst.Start = s.Start
dst.End = s.End
if err := Coalesce(cmp, s.Visible(ui.snapshot).Keys, &dst.Keys); err != nil {
return err
}
// During user iteration over range keys, unsets and deletes don't
// matter. Remove them. This step helps logical defragmentation during
// iteration.
keys := dst.Keys
dst.Keys = dst.Keys[:0]
for i := range keys {
switch keys[i].Kind() {
case base.InternalKeyKindRangeKeySet:
dst.Keys = append(dst.Keys, keys[i])
case base.InternalKeyKindRangeKeyUnset:
// Skip.
continue
case base.InternalKeyKindRangeKeyDelete:
// Skip.
continue
default:
return base.CorruptionErrorf("pebble: unrecognized range key kind %s", keys[i].Kind())
}
}
return nil
}
// ShouldDefragment implements the DefragmentMethod interface and configures a
// DefragmentingIter to defragment spans of range keys if their user-visible
// state is identical. This defragmenting method assumes the provided spans have
// already been transformed through (UserIterationConfig).Transform, so all
// RangeKeySets are user-visible sets. This defragmenter checks for equality
// between set suffixes and values (ignoring sequence numbers). It's intended
// for use during user iteration, when the wrapped keyspan iterator is merging
// spans across all levels of the LSM.
//
// This implementation is stateful, and must not be used on multiple
// DefragmentingIters concurrently.
func (ui *UserIteratorConfig) ShouldDefragment(cmp base.Compare, a, b *keyspan.Span) bool {
// This implementation must only be used on spans that have transformed by
// ui.Transform. The transform applies shadowing and removes all keys
// besides the resulting Sets. Since shadowing has been applied, each Set
// must set a unique suffix. If the two spans are equivalent, they must have
// the same number of range key sets.
if len(a.Keys) != len(b.Keys) || len(a.Keys) == 0 {
return false
}
// The keys in both spans must be all sets. In order to be equivalent
// during user iteration, they must set identical suffix-value mappings.
// They do not need to have the same sequence number.
//
// Currently, the Keys are sorted by Trailer (as per the keyspan.Span
// and keyspan.FragmentIterator interfaces). Collect all the keys in
// both spans into buffers and sort them by suffix for comparison.
ui.defragBufA.cmp = cmp
ui.defragBufA.keys = append(ui.defragBufA.keys[:0], a.Keys...)
sort.Sort(&ui.defragBufA)
ui.defragBufB.cmp = cmp
ui.defragBufB.keys = append(ui.defragBufB.keys[:0], b.Keys...)
sort.Sort(&ui.defragBufB)
for i := range ui.defragBufA.keys {
if ui.defragBufA.keys[i].Kind() != base.InternalKeyKindRangeKeySet ||
ui.defragBufB.keys[i].Kind() != base.InternalKeyKindRangeKeySet {
panic("pebble: unexpected non-RangeKeySet during defragmentation")
}
if cmp(ui.defragBufA.keys[i].Suffix, ui.defragBufB.keys[i].Suffix) != 0 {
return false
}
if !bytes.Equal(ui.defragBufA.keys[i].Value, ui.defragBufB.keys[i].Value) {
return false
}
}
return true
}
// Coalesce imposes range key semantics and coalesces range keys with the same
// bounds. Coalesce drops any keys shadowed by more recent sets, unsets or
// deletes. Coalesce modifies the provided span's Keys slice, reslicing the
// slice to remove dropped keys.
//
// Coalescence has subtle behavior with respect to sequence numbers. Coalesce
// depends on a keyspan.Span's Keys being sorted in sequence number descending
// order. The first key has the largest sequence number. The returned coalesced
// span includes only the largest sequence number. All other sequence numbers
// are forgotten. When a compaction constructs output range keys from a
// coalesced span, it produces at most one RANGEKEYSET, one RANGEKEYUNSET and
// one RANGEKEYDEL. Each one of these keys adopt the largest sequence number.
//
// This has the potentially surprising effect of 'promoting' a key to a higher
// sequence number. This is okay, because:
// - There are no other overlapping keys within the coalesced span of
// sequence numbers (otherwise they would be in the compaction, due to
// the LSM invariant).
// - Range key sequence numbers are never compared to point key sequence
// numbers. Range keys and point keys have parallel existences.
// - Compactions only coalesce within snapshot stripes.
//
// Additionally, internal range keys at the same sequence number have subtle
// mechanics:
// * RANGEKEYSETs shadow RANGEKEYUNSETs of the same suffix.
// * RANGEKEYDELs only apply to keys at lower sequence numbers.
// This is required for ingestion. Ingested sstables are assigned a single
// sequence number for the file, at which all of the file's keys are visible.
// The RANGEKEYSET, RANGEKEYUNSET and RANGEKEYDEL key kinds are ordered such
// that among keys with equal sequence numbers (thus ordered by their kinds) the
// keys do not affect one another. Ingested sstables are expected to be
// consistent with respect to the set/unset suffixes: A given suffix should be
// set or unset but not both.
func Coalesce(cmp base.Compare, keys []keyspan.Key, dst *[]keyspan.Key) error {
// TODO(jackson): Currently, Coalesce doesn't actually perform the sequence
// number promotion described in the comment above.
keysBySuffix := keysBySuffix{
cmp: cmp,
keys: (*dst)[:0],
}
var deleted bool
for i := 0; i < len(keys) && !deleted; i++ {
k := keys[i]
if invariants.Enabled && i > 0 && k.Trailer > keys[i-1].Trailer {
panic("pebble: invariant violation: span keys unordered")
}
// NB: Within a given sequence number, keys are ordered as:
// RangeKeySet > RangeKeyUnset > RangeKeyDelete
// This is significant, because this ensures that none of the range keys
// sharing a sequence number shadow each other.
switch k.Kind() {
case base.InternalKeyKindRangeKeySet:
n := len(keysBySuffix.keys)
if keysBySuffix.get(n, k.Suffix) < n {
// This suffix is already set or unset at a higher sequence
// number. Skip.
continue
}
keysBySuffix.keys = append(keysBySuffix.keys, k)
sort.Sort(&keysBySuffix)
case base.InternalKeyKindRangeKeyUnset:
n := len(keysBySuffix.keys)
if keysBySuffix.get(n, k.Suffix) < n {
// This suffix is already set or unset at a higher sequence
// number. Skip.
continue
}
keysBySuffix.keys = append(keysBySuffix.keys, k)
sort.Sort(&keysBySuffix)
case base.InternalKeyKindRangeKeyDelete:
// All remaining range keys in this span have been deleted by this
// RangeKeyDelete. There's no need to continue looping, because all
// the remaining keys are shadowed by this one. The for loop
// condition will terminate when it sees the last key is a
// range key deletion.
keysBySuffix.keys = append(keysBySuffix.keys, k)
deleted = true
default:
return base.CorruptionErrorf("pebble: unexpected range key kind %s", k.Kind())
}
}
// Update the span with the (potentially reduced) keys slice, and re-sort it
// by Trailer.
*dst = keysBySuffix.keys
keyspan.SortKeys(dst)
return nil
}
// SortBySuffix sorts the provided keys by suffix.
func SortBySuffix(cmp base.Compare, keys []keyspan.Key) {
bySuffix := keysBySuffix{
cmp: cmp,
keys: keys,
}
sort.Sort(&bySuffix)
}
type keysBySuffix struct {
cmp base.Compare
keys []keyspan.Key
}
// get searches for suffix among the first n keys in keys. If the suffix is
// found, it returns the index of the item with the suffix. If the suffix is not
// found, it returns n.
func (s *keysBySuffix) get(n int, suffix []byte) (i int) {
// Binary search for the suffix to see if there's an existing key with the
// suffix. Only binary search among the first n items. get is called while
// appending new keys with suffixes that may sort before existing keys.
// The n parameter indicates what portion of the keys slice is sorted and
// may contain relevant keys.
i = sort.Search(n, func(i int) bool {
return s.cmp(s.keys[i].Suffix, suffix) >= 0
})
if i < n && s.cmp(s.keys[i].Suffix, suffix) == 0 {
return i
}
return n
}
func (s *keysBySuffix) Len() int { return len(s.keys) }
func (s *keysBySuffix) Less(i, j int) bool { return s.cmp(s.keys[i].Suffix, s.keys[j].Suffix) < 0 }
func (s *keysBySuffix) Swap(i, j int) { s.keys[i], s.keys[j] = s.keys[j], s.keys[i] }

View File

@@ -0,0 +1,411 @@
// Copyright 2021 The LevelDB-Go and Pebble Authors. All rights reserved. Use
// of this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
// Package rangekey provides facilities for encoding, decoding and merging range
// keys.
//
// Range keys map a span of keyspan `[start, end)`, at an optional suffix, to a
// value.
//
// # Encoding
//
// Unlike other Pebble keys, range keys encode several fields of information:
// start key, end key, suffix and value. Internally within Pebble and its
// sstables, all keys including range keys are represented as a key-value tuple.
// Range keys map to internal key-value tuples by mapping the start key to the
// key and encoding the remainder of the fields in the value.
//
// ## `RANGEKEYSET`
//
// A `RANGEKEYSET` represents one more range keys set over a single region of
// user key space. Each represented range key must have a unique suffix. A
// `RANGEKEYSET` encapsulates a start key, an end key and a set of SuffixValue
// pairs.
//
// A `RANGEKEYSET` key's user key holds the start key. Its value is a varstring
// end key, followed by a set of SuffixValue pairs. A `RANGEKEYSET` may have
// multiple SuffixValue pairs if the keyspan was set at multiple unique suffix
// values.
//
// ## `RANGEKEYUNSET`
//
// A `RANGEKEYUNSET` represents the removal of range keys at specific suffixes
// over a single region of user key space. A `RANGEKEYUNSET` encapsulates a
// start key, an end key and a set of suffixes.
//
// A `RANGEKEYUNSET` key's user key holds the start key. Its value is a
// varstring end key, followed by a set of suffixes. A `RANGEKEYUNSET` may have
// multiple suffixes if the keyspan was unset at multiple unique suffixes.
//
// ## `RANGEKEYDEL`
//
// A `RANGEKEYDEL` represents the removal of all range keys over a single region
// of user key space, regardless of suffix. A `RANGEKEYDEL` encapsulates a
// start key and an end key. The end key is stored in the value, without any
// varstring length prefixing.
package rangekey
// TODO(jackson): Document the encoding of RANGEKEYSET and RANGEKEYUNSET values
// once we're confident they're stable.
import (
"encoding/binary"
"github.com/cockroachdb/errors"
"github.com/cockroachdb/pebble/internal/base"
"github.com/cockroachdb/pebble/internal/keyspan"
)
// Encode takes a Span containing only range keys. It invokes the provided
// closure with the encoded internal keys that represent the Span's state. The
// keys and values passed to emit are only valid until the closure returns.
// If emit returns an error, Encode stops and returns the error.
func Encode(s *keyspan.Span, emit func(k base.InternalKey, v []byte) error) error {
enc := Encoder{Emit: emit}
return enc.Encode(s)
}
// An Encoder encodes range keys into their on-disk InternalKey format. An
// Encoder holds internal buffers, reused between Emit calls.
type Encoder struct {
Emit func(base.InternalKey, []byte) error
buf []byte
unsets [][]byte
sets []SuffixValue
}
// Encode takes a Span containing only range keys. It invokes the Encoder's Emit
// closure with the encoded internal keys that represent the Span's state. The
// keys and values passed to emit are only valid until the closure returns. If
// Emit returns an error, Encode stops and returns the error.
//
// The encoded key-value pair passed to Emit is only valid until the closure
// completes.
func (e *Encoder) Encode(s *keyspan.Span) error {
if s.Empty() {
return nil
}
// This for loop iterates through the span's keys, which are sorted by
// sequence number descending, grouping them into sequence numbers. All keys
// with identical sequence numbers are flushed together.
var del bool
var seqNum uint64
for i := range s.Keys {
if i == 0 || s.Keys[i].SeqNum() != seqNum {
if i > 0 {
// Flush all the existing internal keys that exist at seqNum.
if err := e.flush(s, seqNum, del); err != nil {
return err
}
}
// Reset sets, unsets, del.
seqNum = s.Keys[i].SeqNum()
del = false
e.sets = e.sets[:0]
e.unsets = e.unsets[:0]
}
switch s.Keys[i].Kind() {
case base.InternalKeyKindRangeKeySet:
e.sets = append(e.sets, SuffixValue{
Suffix: s.Keys[i].Suffix,
Value: s.Keys[i].Value,
})
case base.InternalKeyKindRangeKeyUnset:
e.unsets = append(e.unsets, s.Keys[i].Suffix)
case base.InternalKeyKindRangeKeyDelete:
del = true
default:
return base.CorruptionErrorf("pebble: %s key kind is not a range key", s.Keys[i].Kind())
}
}
return e.flush(s, seqNum, del)
}
// flush constructs internal keys for accumulated key state, and emits the
// internal keys.
func (e *Encoder) flush(s *keyspan.Span, seqNum uint64, del bool) error {
if len(e.sets) > 0 {
ik := base.MakeInternalKey(s.Start, seqNum, base.InternalKeyKindRangeKeySet)
l := EncodedSetValueLen(s.End, e.sets)
if l > cap(e.buf) {
e.buf = make([]byte, l)
}
EncodeSetValue(e.buf[:l], s.End, e.sets)
if err := e.Emit(ik, e.buf[:l]); err != nil {
return err
}
}
if len(e.unsets) > 0 {
ik := base.MakeInternalKey(s.Start, seqNum, base.InternalKeyKindRangeKeyUnset)
l := EncodedUnsetValueLen(s.End, e.unsets)
if l > cap(e.buf) {
e.buf = make([]byte, l)
}
EncodeUnsetValue(e.buf[:l], s.End, e.unsets)
if err := e.Emit(ik, e.buf[:l]); err != nil {
return err
}
}
if del {
ik := base.MakeInternalKey(s.Start, seqNum, base.InternalKeyKindRangeKeyDelete)
// s.End is stored directly in the value for RangeKeyDeletes.
if err := e.Emit(ik, s.End); err != nil {
return err
}
}
return nil
}
// Decode takes an internal key pair encoding range key(s) and returns a decoded
// keyspan containing the keys. If keysDst is provided, keys will be appended to
// keysDst.
func Decode(ik base.InternalKey, v []byte, keysDst []keyspan.Key) (keyspan.Span, error) {
var s keyspan.Span
// Hydrate the user key bounds.
s.Start = ik.UserKey
var ok bool
s.End, v, ok = DecodeEndKey(ik.Kind(), v)
if !ok {
return keyspan.Span{}, base.CorruptionErrorf("pebble: unable to decode range key end from %s", ik.Kind())
}
s.Keys = keysDst
// Hydrate the contents of the range key(s).
switch ik.Kind() {
case base.InternalKeyKindRangeKeySet:
for len(v) > 0 {
var sv SuffixValue
sv, v, ok = decodeSuffixValue(v)
if !ok {
return keyspan.Span{}, base.CorruptionErrorf("pebble: unable to decode range key suffix-value tuple")
}
s.Keys = append(s.Keys, keyspan.Key{
Trailer: ik.Trailer,
Suffix: sv.Suffix,
Value: sv.Value,
})
}
case base.InternalKeyKindRangeKeyUnset:
for len(v) > 0 {
var suffix []byte
suffix, v, ok = decodeSuffix(v)
if !ok {
return keyspan.Span{}, base.CorruptionErrorf("pebble: unable to decode range key unset suffix")
}
s.Keys = append(s.Keys, keyspan.Key{
Trailer: ik.Trailer,
Suffix: suffix,
})
}
case base.InternalKeyKindRangeKeyDelete:
if len(v) > 0 {
return keyspan.Span{}, base.CorruptionErrorf("pebble: RANGEKEYDELs must not contain additional data")
}
s.Keys = append(s.Keys, keyspan.Key{Trailer: ik.Trailer})
default:
return keyspan.Span{}, base.CorruptionErrorf("pebble: %s is not a range key", ik.Kind())
}
return s, nil
}
// SuffixValue represents a tuple of a suffix and a corresponding value. A
// physical RANGEKEYSET key may contain many logical RangeKeySets, each
// represented with a separate SuffixValue tuple.
type SuffixValue struct {
Suffix []byte
Value []byte
}
// encodedSetSuffixValuesLen precomputes the length of the given slice of
// SuffixValues, when encoded for a RangeKeySet. It may be used to construct a
// buffer of the appropriate size before encoding.
func encodedSetSuffixValuesLen(suffixValues []SuffixValue) int {
var n int
for i := 0; i < len(suffixValues); i++ {
n += lenVarint(len(suffixValues[i].Suffix))
n += len(suffixValues[i].Suffix)
n += lenVarint(len(suffixValues[i].Value))
n += len(suffixValues[i].Value)
}
return n
}
// encodeSetSuffixValues encodes a slice of SuffixValues for a RangeKeySet into
// dst. The length of dst must be greater than or equal to
// encodedSetSuffixValuesLen. encodeSetSuffixValues returns the number of bytes
// written, which should always equal the EncodedSetValueLen with the same
// arguments.
func encodeSetSuffixValues(dst []byte, suffixValues []SuffixValue) int {
// Encode the list of (suffix, value-len) tuples.
var n int
for i := 0; i < len(suffixValues); i++ {
// Encode the length of the suffix.
n += binary.PutUvarint(dst[n:], uint64(len(suffixValues[i].Suffix)))
// Encode the suffix itself.
n += copy(dst[n:], suffixValues[i].Suffix)
// Encode the value length.
n += binary.PutUvarint(dst[n:], uint64(len(suffixValues[i].Value)))
// Encode the value itself.
n += copy(dst[n:], suffixValues[i].Value)
}
return n
}
// EncodedSetValueLen precomputes the length of a RangeKeySet's value when
// encoded. It may be used to construct a buffer of the appropriate size before
// encoding.
func EncodedSetValueLen(endKey []byte, suffixValues []SuffixValue) int {
n := lenVarint(len(endKey))
n += len(endKey)
n += encodedSetSuffixValuesLen(suffixValues)
return n
}
// EncodeSetValue encodes a RangeKeySet's value into dst. The length of dst must
// be greater than or equal to EncodedSetValueLen. EncodeSetValue returns the
// number of bytes written, which should always equal the EncodedSetValueLen
// with the same arguments.
func EncodeSetValue(dst []byte, endKey []byte, suffixValues []SuffixValue) int {
// First encode the end key as a varstring.
n := binary.PutUvarint(dst, uint64(len(endKey)))
n += copy(dst[n:], endKey)
n += encodeSetSuffixValues(dst[n:], suffixValues)
return n
}
// DecodeEndKey reads the end key from the beginning of a range key (RANGEKEYSET,
// RANGEKEYUNSET or RANGEKEYDEL)'s physical encoded value. Both sets and unsets
// encode the range key, plus additional data in the value.
func DecodeEndKey(kind base.InternalKeyKind, data []byte) (endKey, value []byte, ok bool) {
switch kind {
case base.InternalKeyKindRangeKeyDelete:
// No splitting is necessary for range key deletes. The value is the end
// key, and there is no additional associated value.
return data, nil, true
case base.InternalKeyKindRangeKeySet, base.InternalKeyKindRangeKeyUnset:
v, n := binary.Uvarint(data)
if n <= 0 || uint64(n)+v >= uint64(len(data)) {
return nil, nil, false
}
endKey, value = data[n:n+int(v)], data[n+int(v):]
return endKey, value, true
default:
panic(errors.Newf("key kind %s is not a range key kind", kind))
}
}
// decodeSuffixValue decodes a single encoded SuffixValue from a RangeKeySet's
// split value. The end key must have already been stripped from the
// RangeKeySet's value (see DecodeEndKey).
func decodeSuffixValue(data []byte) (sv SuffixValue, rest []byte, ok bool) {
// Decode the suffix.
sv.Suffix, data, ok = decodeVarstring(data)
if !ok {
return SuffixValue{}, nil, false
}
// Decode the value.
sv.Value, data, ok = decodeVarstring(data)
if !ok {
return SuffixValue{}, nil, false
}
return sv, data, true
}
// encodedUnsetSuffixesLen precomputes the length of the given slice of
// suffixes, when encoded for a RangeKeyUnset. It may be used to construct a
// buffer of the appropriate size before encoding.
func encodedUnsetSuffixesLen(suffixes [][]byte) int {
var n int
for i := 0; i < len(suffixes); i++ {
n += lenVarint(len(suffixes[i]))
n += len(suffixes[i])
}
return n
}
// encodeUnsetSuffixes encodes a slice of suffixes for a RangeKeyUnset into dst.
// The length of dst must be greater than or equal to EncodedUnsetSuffixesLen.
// EncodeUnsetSuffixes returns the number of bytes written, which should always
// equal the EncodedUnsetSuffixesLen with the same arguments.
func encodeUnsetSuffixes(dst []byte, suffixes [][]byte) int {
// Encode the list of (suffix, value-len) tuples.
var n int
for i := 0; i < len(suffixes); i++ {
// Encode the length of the suffix.
n += binary.PutUvarint(dst[n:], uint64(len(suffixes[i])))
// Encode the suffix itself.
n += copy(dst[n:], suffixes[i])
}
return n
}
// EncodedUnsetValueLen precomputes the length of a RangeKeyUnset's value when
// encoded. It may be used to construct a buffer of the appropriate size before
// encoding.
func EncodedUnsetValueLen(endKey []byte, suffixes [][]byte) int {
n := lenVarint(len(endKey))
n += len(endKey)
n += encodedUnsetSuffixesLen(suffixes)
return n
}
// EncodeUnsetValue encodes a RangeKeyUnset's value into dst. The length of dst
// must be greater than or equal to EncodedUnsetValueLen. EncodeUnsetValue
// returns the number of bytes written, which should always equal the
// EncodedUnsetValueLen with the same arguments.
func EncodeUnsetValue(dst []byte, endKey []byte, suffixes [][]byte) int {
// First encode the end key as a varstring.
n := binary.PutUvarint(dst, uint64(len(endKey)))
n += copy(dst[n:], endKey)
n += encodeUnsetSuffixes(dst[n:], suffixes)
return n
}
// decodeSuffix decodes a single suffix from the beginning of data. If decoding
// suffixes from a RangeKeyUnset's value, the end key must have already been
// stripped from the RangeKeyUnset's value (see DecodeEndKey).
func decodeSuffix(data []byte) (suffix, rest []byte, ok bool) {
return decodeVarstring(data)
}
func decodeVarstring(data []byte) (v, rest []byte, ok bool) {
// Decode the length of the string.
l, n := binary.Uvarint(data)
if n <= 0 {
return nil, nil, ok
}
// Extract the string itself.
return data[n : n+int(l)], data[n+int(l):], true
}
// IsRangeKey returns true if the given key kind is one of the range key kinds.
func IsRangeKey(kind base.InternalKeyKind) bool {
switch kind {
case base.InternalKeyKindRangeKeyDelete,
base.InternalKeyKindRangeKeyUnset,
base.InternalKeyKindRangeKeySet:
return true
default:
return false
}
}
func lenVarint(v int) (n int) {
x := uint32(v)
n++
for x >= 0x80 {
x >>= 7
n++
}
return n
}