Initial commit
This commit is contained in:
380
vendor/github.com/cockroachdb/pebble/internal/rangekey/coalesce.go
generated
vendored
Normal file
380
vendor/github.com/cockroachdb/pebble/internal/rangekey/coalesce.go
generated
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
// 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"
|
||||
"math"
|
||||
"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. The range key iterator must merge range key spans across
|
||||
// the levels of the LSM. This merging is performed by a keyspan.MergingIter
|
||||
// on-the-fly. The UserIteratorConfig implements keyspan.Transformer, evaluating
|
||||
// range-key semantics and shadowing, so the spans returned by a MergingIter are
|
||||
// fully resolved.
|
||||
//
|
||||
// The MergingIter is wrapped by a BoundedIter, which elides spans that are
|
||||
// outside the iterator bounds (or the current prefix's bounds, during prefix
|
||||
// iteration mode).
|
||||
//
|
||||
// To provide determinisim during iteration, the BoundedIter is wrapped by a
|
||||
// DefragmentingIter that defragments abutting spans with identical
|
||||
// user-observable state.
|
||||
//
|
||||
// At the top-level an InterleavingIter interleaves range keys with point keys
|
||||
// and performs truncation to iterator bounds.
|
||||
//
|
||||
// Below is an abbreviated diagram illustrating the mechanics of a SeekGE.
|
||||
//
|
||||
// InterleavingIter.SeekGE
|
||||
// │
|
||||
// DefragmentingIter.SeekGE
|
||||
// │
|
||||
// BoundedIter.SeekGE
|
||||
// │
|
||||
// ╭────────────────┴───────────────╮
|
||||
// │ ├── defragmentBwd*
|
||||
// MergingIter.SeekGE │
|
||||
// │ ╰── defragmentFwd
|
||||
// ╰─╶╶ per level╶╶ ─╮
|
||||
// │
|
||||
// │
|
||||
// ├── <?>.SeekLT
|
||||
// │
|
||||
// ╰── <?>.Next
|
||||
type UserIteratorConfig struct {
|
||||
snapshot uint64
|
||||
comparer *base.Comparer
|
||||
miter keyspan.MergingIter
|
||||
biter keyspan.BoundedIter
|
||||
diter keyspan.DefragmentingIter
|
||||
liters [manifest.NumLevels]keyspan.LevelIter
|
||||
litersUsed int
|
||||
internalKeys bool
|
||||
bufs *Buffers
|
||||
}
|
||||
|
||||
// Buffers holds various buffers used for range key iteration. They're exposed
|
||||
// so that they may be pooled and reused between iterators.
|
||||
type Buffers struct {
|
||||
merging keyspan.MergingBuffers
|
||||
defragmenting keyspan.DefragmentingBuffers
|
||||
sortBuf keyspan.KeysBySuffix
|
||||
}
|
||||
|
||||
// PrepareForReuse discards any excessively large buffers.
|
||||
func (bufs *Buffers) PrepareForReuse() {
|
||||
bufs.merging.PrepareForReuse()
|
||||
bufs.defragmenting.PrepareForReuse()
|
||||
}
|
||||
|
||||
// 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, if !internalKeys, removes all
|
||||
// Keys other than RangeKeySets describing the current state of range keys. The
|
||||
// resulting spans contain Keys sorted by suffix (unless internalKeys is true,
|
||||
// in which case they remain sorted by trailer descending).
|
||||
//
|
||||
// The snapshot sequence number parameter determines which keys are visible. Any
|
||||
// keys not visible at the provided snapshot are ignored.
|
||||
func (ui *UserIteratorConfig) Init(
|
||||
comparer *base.Comparer,
|
||||
snapshot uint64,
|
||||
lower, upper []byte,
|
||||
hasPrefix *bool,
|
||||
prefix *[]byte,
|
||||
internalKeys bool,
|
||||
bufs *Buffers,
|
||||
iters ...keyspan.FragmentIterator,
|
||||
) keyspan.FragmentIterator {
|
||||
ui.snapshot = snapshot
|
||||
ui.comparer = comparer
|
||||
ui.internalKeys = internalKeys
|
||||
ui.miter.Init(comparer.Compare, ui, &bufs.merging, iters...)
|
||||
ui.biter.Init(comparer.Compare, comparer.Split, &ui.miter, lower, upper, hasPrefix, prefix)
|
||||
if internalKeys {
|
||||
ui.diter.Init(comparer, &ui.biter, keyspan.DefragmentInternal, keyspan.StaticDefragmentReducer, &bufs.defragmenting)
|
||||
} else {
|
||||
ui.diter.Init(comparer, &ui.biter, ui, keyspan.StaticDefragmentReducer, &bufs.defragmenting)
|
||||
}
|
||||
ui.litersUsed = 0
|
||||
ui.bufs = bufs
|
||||
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]
|
||||
}
|
||||
|
||||
// SetBounds propagates bounds to the iterator stack. The fragment iterator
|
||||
// interface ordinarily doesn't enforce bounds, so this is exposed as an
|
||||
// explicit method on the user iterator config.
|
||||
func (ui *UserIteratorConfig) SetBounds(lower, upper []byte) {
|
||||
ui.biter.SetBounds(lower, upper)
|
||||
}
|
||||
|
||||
// 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, and hold their Keys sorted by Suffix (except if internalKeys
|
||||
// is true, then keys remain sorted by trailer.
|
||||
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
|
||||
ui.bufs.sortBuf = keyspan.KeysBySuffix{
|
||||
Cmp: cmp,
|
||||
Keys: ui.bufs.sortBuf.Keys[:0],
|
||||
}
|
||||
if err := coalesce(ui.comparer.Equal, &ui.bufs.sortBuf, ui.snapshot, s.Keys); err != nil {
|
||||
return err
|
||||
}
|
||||
if ui.internalKeys {
|
||||
if s.KeysOrder != keyspan.ByTrailerDesc {
|
||||
panic("unexpected key ordering in UserIteratorTransform with internalKeys = true")
|
||||
}
|
||||
dst.Keys = ui.bufs.sortBuf.Keys
|
||||
keyspan.SortKeysByTrailer(&dst.Keys)
|
||||
return nil
|
||||
}
|
||||
// During user iteration over range keys, unsets and deletes don't matter. This
|
||||
// step helps logical defragmentation during iteration.
|
||||
keys := ui.bufs.sortBuf.Keys
|
||||
dst.Keys = dst.Keys[:0]
|
||||
for i := range keys {
|
||||
switch keys[i].Kind() {
|
||||
case base.InternalKeyKindRangeKeySet:
|
||||
if invariants.Enabled && len(dst.Keys) > 0 && cmp(dst.Keys[len(dst.Keys)-1].Suffix, keys[i].Suffix) > 0 {
|
||||
panic("pebble: keys unexpectedly not in ascending suffix order")
|
||||
}
|
||||
dst.Keys = append(dst.Keys, keys[i])
|
||||
case base.InternalKeyKindRangeKeyUnset:
|
||||
if invariants.Enabled && len(dst.Keys) > 0 && cmp(dst.Keys[len(dst.Keys)-1].Suffix, keys[i].Suffix) > 0 {
|
||||
panic("pebble: keys unexpectedly not in ascending suffix order")
|
||||
}
|
||||
// Skip.
|
||||
continue
|
||||
case base.InternalKeyKindRangeKeyDelete:
|
||||
// Skip.
|
||||
continue
|
||||
default:
|
||||
return base.CorruptionErrorf("pebble: unrecognized range key kind %s", keys[i].Kind())
|
||||
}
|
||||
}
|
||||
// coalesce results in dst.Keys being sorted by Suffix.
|
||||
dst.KeysOrder = keyspan.BySuffixAsc
|
||||
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 and are already in Suffix order. 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.
|
||||
func (ui *UserIteratorConfig) ShouldDefragment(equal base.Equal, a, b *keyspan.Span) bool {
|
||||
// This method is not called with internalKeys = true.
|
||||
if ui.internalKeys {
|
||||
panic("unexpected call to ShouldDefragment with internalKeys = true")
|
||||
}
|
||||
// This implementation must only be used on spans that have transformed by
|
||||
// ui.Transform. The transform applies shadowing, removes all keys besides
|
||||
// the resulting Sets and sorts the keys by suffix. 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
|
||||
}
|
||||
if a.KeysOrder != keyspan.BySuffixAsc || b.KeysOrder != keyspan.BySuffixAsc {
|
||||
panic("pebble: range key span's keys unexpectedly not in ascending suffix order")
|
||||
}
|
||||
|
||||
ret := true
|
||||
for i := range a.Keys {
|
||||
if invariants.Enabled {
|
||||
if a.Keys[i].Kind() != base.InternalKeyKindRangeKeySet ||
|
||||
b.Keys[i].Kind() != base.InternalKeyKindRangeKeySet {
|
||||
panic("pebble: unexpected non-RangeKeySet during defragmentation")
|
||||
}
|
||||
if i > 0 && (ui.comparer.Compare(a.Keys[i].Suffix, a.Keys[i-1].Suffix) < 0 ||
|
||||
ui.comparer.Compare(b.Keys[i].Suffix, b.Keys[i-1].Suffix) < 0) {
|
||||
panic("pebble: range keys not ordered by suffix during defragmentation")
|
||||
}
|
||||
}
|
||||
if !equal(a.Keys[i].Suffix, b.Keys[i].Suffix) {
|
||||
ret = false
|
||||
break
|
||||
}
|
||||
if !bytes.Equal(a.Keys[i].Value, b.Keys[i].Value) {
|
||||
ret = false
|
||||
break
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// The resulting dst Keys slice is sorted by Trailer.
|
||||
func Coalesce(cmp base.Compare, eq base.Equal, 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 := keyspan.KeysBySuffix{
|
||||
Cmp: cmp,
|
||||
Keys: (*dst)[:0],
|
||||
}
|
||||
if err := coalesce(eq, &keysBySuffix, math.MaxUint64, keys); err != nil {
|
||||
return err
|
||||
}
|
||||
// Update the span with the (potentially reduced) keys slice. coalesce left
|
||||
// the keys in *dst sorted by suffix. Re-sort them by trailer.
|
||||
*dst = keysBySuffix.Keys
|
||||
keyspan.SortKeysByTrailer(dst)
|
||||
return nil
|
||||
}
|
||||
|
||||
func coalesce(
|
||||
equal base.Equal, keysBySuffix *keyspan.KeysBySuffix, snapshot uint64, keys []keyspan.Key,
|
||||
) error {
|
||||
// First, enforce visibility and RangeKeyDelete mechanics. We only need to
|
||||
// consider the prefix of keys before and including the first
|
||||
// RangeKeyDelete. We also must skip any keys that aren't visible at the
|
||||
// provided snapshot sequence number.
|
||||
//
|
||||
// NB: Within a given sequence number, keys are ordered as:
|
||||
// RangeKeySet > RangeKeyUnset > RangeKeyDelete
|
||||
// This is significant, because this ensures that a Set or Unset sharing a
|
||||
// sequence number with a Delete do not shadow each other.
|
||||
deleteIdx := -1
|
||||
for i := range keys {
|
||||
if invariants.Enabled && i > 0 && keys[i].Trailer > keys[i-1].Trailer {
|
||||
panic("pebble: invariant violation: span keys unordered")
|
||||
}
|
||||
if !keys[i].VisibleAt(snapshot) {
|
||||
continue
|
||||
}
|
||||
// Once a RangeKeyDelete is observed, we know it shadows all subsequent
|
||||
// keys and we can break early. We don't add the RangeKeyDelete key to
|
||||
// keysBySuffix.keys yet, because we don't want a suffix-less key
|
||||
// that appeared earlier in the slice to elide it. It'll be added back
|
||||
// in at the end.
|
||||
if keys[i].Kind() == base.InternalKeyKindRangeKeyDelete {
|
||||
deleteIdx = i
|
||||
break
|
||||
}
|
||||
keysBySuffix.Keys = append(keysBySuffix.Keys, keys[i])
|
||||
}
|
||||
|
||||
// Sort the accumulated keys by suffix. There may be duplicates within a
|
||||
// suffix, in which case the one with a larger trailer survives.
|
||||
//
|
||||
// We use a stable sort so that the first key with a given suffix is the one
|
||||
// that with the highest Trailer (because the input `keys` was sorted by
|
||||
// trailer descending).
|
||||
sort.Stable(keysBySuffix)
|
||||
|
||||
// Grab a handle of the full sorted slice, before reslicing
|
||||
// keysBySuffix.keys to accumulate the final coalesced keys.
|
||||
sorted := keysBySuffix.Keys
|
||||
keysBySuffix.Keys = keysBySuffix.Keys[:0]
|
||||
|
||||
var (
|
||||
// prevSuffix is updated on each iteration of the below loop, and
|
||||
// compared by the subsequent iteration to determine whether adjacent
|
||||
// keys are defined at the same suffix.
|
||||
prevSuffix []byte
|
||||
// shadowing is set to true once any Key is shadowed by another key.
|
||||
// When it's set to true—or after the loop if no keys are shadowed—the
|
||||
// keysBySuffix.keys slice is resliced to contain the prefix of
|
||||
// unshadowed keys. This avoids copying them incrementally in the common
|
||||
// case of no shadowing.
|
||||
shadowing bool
|
||||
)
|
||||
for i := range sorted {
|
||||
if i > 0 && equal(prevSuffix, sorted[i].Suffix) {
|
||||
// Skip; this key is shadowed by the predecessor that had a larger
|
||||
// Trailer. If this is the first shadowed key, set shadowing=true
|
||||
// and reslice keysBySuffix.keys to hold the entire unshadowed
|
||||
// prefix.
|
||||
if !shadowing {
|
||||
keysBySuffix.Keys = keysBySuffix.Keys[:i]
|
||||
shadowing = true
|
||||
}
|
||||
continue
|
||||
}
|
||||
prevSuffix = sorted[i].Suffix
|
||||
if shadowing {
|
||||
keysBySuffix.Keys = append(keysBySuffix.Keys, sorted[i])
|
||||
}
|
||||
}
|
||||
// If there was no shadowing, keysBySuffix.keys is untouched. We can simply
|
||||
// set it to the existing `sorted` slice (also backed by keysBySuffix.keys).
|
||||
if !shadowing {
|
||||
keysBySuffix.Keys = sorted
|
||||
}
|
||||
// If the original input `keys` slice contained a RangeKeyDelete, add it.
|
||||
if deleteIdx >= 0 {
|
||||
keysBySuffix.Keys = append(keysBySuffix.Keys, keys[deleteIdx])
|
||||
}
|
||||
return nil
|
||||
}
|
||||
411
vendor/github.com/cockroachdb/pebble/internal/rangekey/rangekey.go
generated
vendored
Normal file
411
vendor/github.com/cockroachdb/pebble/internal/rangekey/rangekey.go
generated
vendored
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user