Upgrade versions of vendored libs

This commit is contained in:
eleksir
2023-06-14 01:06:17 +03:00
parent 37898d3013
commit 747ff1454e
120 changed files with 5126 additions and 1245 deletions

View File

@@ -6,6 +6,7 @@ package pebble
import (
"bytes"
"encoding/binary"
"fmt"
"io"
"sort"
@@ -205,6 +206,21 @@ type compactionIter struct {
// compaction iterator was only returned because an open snapshot prevents
// its elision. This field only applies to point keys, and not to range
// deletions or range keys.
//
// snapshotPinned is also used to set the forceObsolete value in the call to
// Writer.AddWithForceObsolete. Note that in that call, it is sufficient to
// mark all keys obsoleted by RANGEDELs as forceObsolete=true and that the
// implementation of Writer.AddWithForceObsolete will itself discover other
// causes of obsolescence. We mention this since in the presence of MERGE,
// obsolescence due to multiple keys at the same user key is not fully
// represented by snapshotPinned=true:
//
// For MERGE, it is possible that doing the merge is interrupted even when
// the next point key is in the same stripe. This can happen if the loop in
// mergeNext gets interrupted by sameStripeNonSkippable.
// sameStripeNonSkippable occurs due to RANGEDELs that sort before
// SET/MERGE/DEL with the same seqnum, so the RANGEDEL does not necessarily
// delete the subsequent SET/MERGE/DEL keys.
snapshotPinned bool
// The index of the snapshot for the current key within the snapshots slice.
curSnapshotIdx int
@@ -240,6 +256,10 @@ type compactionIter struct {
// The on-disk format major version. This informs the types of keys that
// may be written to disk during a compaction.
formatVersion FormatMajorVersion
stats struct {
// count of DELSIZED keys that were missized.
countMissizedDels uint64
}
}
func newCompactionIter(
@@ -310,10 +330,10 @@ func (i *compactionIter) Next() (*InternalKey, []byte) {
// respect to `iterKey` and related state:
//
// - `!skip && pos == iterPosNext`: `iterKey` is already at the next key.
// - `!skip && pos == iterPosCur`: We are at the key that has been returned.
// - `!skip && pos == iterPosCurForward`: We are at the key that has been returned.
// To move forward we advance by one key, even if that lands us in the same
// snapshot stripe.
// - `skip && pos == iterPosCur`: We are at the key that has been returned.
// - `skip && pos == iterPosCurForward`: We are at the key that has been returned.
// To move forward we skip skippable entries in the stripe.
if i.pos == iterPosCurForward {
if i.skip {
@@ -382,11 +402,18 @@ func (i *compactionIter) Next() (*InternalKey, []byte) {
} else if cover == keyspan.CoversInvisibly {
// i.iterKey would be deleted by a range deletion if there weren't
// any open snapshots. Mark it as pinned.
//
// NB: there are multiple places in this file where we call
// i.rangeDelFrag.Covers and this is the only one where we are writing
// to i.snapshotPinned. Those other cases occur in mergeNext where the
// caller is deciding whether the value should be merged or not, and the
// key is in the same snapshot stripe. Hence, snapshotPinned is by
// definition false in those cases.
i.snapshotPinned = true
}
switch i.iterKey.Kind() {
case InternalKeyKindDelete, InternalKeyKindSingleDelete:
case InternalKeyKindDelete, InternalKeyKindSingleDelete, InternalKeyKindDeleteSized:
if i.elideTombstone(i.iterKey.UserKey) {
if i.curSnapshotIdx == 0 {
// If we're at the last snapshot stripe and the tombstone
@@ -410,6 +437,12 @@ func (i *compactionIter) Next() (*InternalKey, []byte) {
i.skip = true
return &i.key, i.value
case InternalKeyKindDeleteSized:
// We may skip subsequent keys because of this tombstone. Scan
// ahead to see just how much data this tombstone drops and if
// the tombstone's value should be updated accordingly.
return i.deleteSizedNext()
case InternalKeyKindSingleDelete:
if i.singleDeleteNext() {
return &i.key, i.value
@@ -686,11 +719,12 @@ func (i *compactionIter) setNext() {
i.skip = true
return
case sameStripeSkippable:
// We're still in the same stripe. If this is a DEL/SINGLEDEL, we
// stop looking and emit a SETWITHDEL. Subsequent keys are
// eligible for skipping.
// We're still in the same stripe. If this is a
// DEL/SINGLEDEL/DELSIZED, we stop looking and emit a SETWITHDEL.
// Subsequent keys are eligible for skipping.
if i.iterKey.Kind() == InternalKeyKindDelete ||
i.iterKey.Kind() == InternalKeyKindSingleDelete {
i.iterKey.Kind() == InternalKeyKindSingleDelete ||
i.iterKey.Kind() == InternalKeyKindDeleteSized {
i.key.SetKind(InternalKeyKindSetWithDelete)
i.skip = true
return
@@ -715,7 +749,7 @@ func (i *compactionIter) mergeNext(valueMerger ValueMerger) stripeChangeType {
}
key := i.iterKey
switch key.Kind() {
case InternalKeyKindDelete, InternalKeyKindSingleDelete:
case InternalKeyKindDelete, InternalKeyKindSingleDelete, InternalKeyKindDeleteSized:
// We've hit a deletion tombstone. Return everything up to this point and
// then skip entries until the next snapshot stripe. We change the kind
// of the result key to a Set so that it shadows keys in lower
@@ -802,9 +836,9 @@ func (i *compactionIter) singleDeleteNext() bool {
key := i.iterKey
switch key.Kind() {
case InternalKeyKindDelete, InternalKeyKindMerge, InternalKeyKindSetWithDelete:
// We've hit a Delete, Merge or SetWithDelete, transform the
// SingleDelete into a full Delete.
case InternalKeyKindDelete, InternalKeyKindMerge, InternalKeyKindSetWithDelete, InternalKeyKindDeleteSized:
// We've hit a Delete, DeleteSized, Merge, SetWithDelete, transform
// the SingleDelete into a full Delete.
i.key.SetKind(InternalKeyKindDelete)
i.skip = true
return true
@@ -825,6 +859,110 @@ func (i *compactionIter) singleDeleteNext() bool {
}
}
// deleteSizedNext processes a DELSIZED point tombstone. Unlike ordinary DELs,
// these tombstones carry a value that's a varint indicating the size of the
// entry (len(key)+len(value)) that the tombstone is expected to delete.
//
// When a deleteSizedNext is encountered, we skip ahead to see which keys, if
// any, are elided as a result of the tombstone.
func (i *compactionIter) deleteSizedNext() (*base.InternalKey, []byte) {
i.saveKey()
i.valid = true
i.skip = true
// The DELSIZED tombstone may have no value at all. This happens when the
// tombstone has already deleted the key that the user originally predicted.
// In this case, we still peek forward in case there's another DELSIZED key
// with a lower sequence number, in which case we'll adopt its value.
if len(i.iterValue) == 0 {
i.value = i.valueBuf[:0]
} else {
i.valueBuf = append(i.valueBuf[:0], i.iterValue...)
i.value = i.valueBuf
}
// Loop through all the keys within this stripe that are skippable,
// totalling the size of their keys and values.
i.pos = iterPosNext
var elidedSize uint64
for i.nextInStripe() == sameStripeSkippable {
elidedSize += uint64(len(i.iterKey.UserKey)) + uint64(len(i.iterValue))
if i.iterKey.Kind() == InternalKeyKindDeleteSized {
// We encountered a DELSIZED that's deleted by the original
// DELSIZED. These tombstones could've been intended to delete two
// distinct values, eg:
//
// a.DELSIZED.9 a.SET.7 a.DELSIZED.5 a.SET.4
//
// If a.DELSIZED.9 has already deleted a.SET.7, its size has already
// been zeroed out. In this case, we want to adopt the value of the
// DELSIZED with the lower sequence number, in case the a.SET.4 key
// has not yet been elided.
i.valueBuf = append(i.valueBuf[:0], i.iterValue...)
i.value = i.valueBuf
// Reset the elided total.
elidedSize = 0
}
}
// Reset skip if we landed outside the original stripe. Otherwise, we landed
// in the same stripe on a non-skippable key. In that case we should preserve
// `i.skip == true` such that later keys in the stripe will continue to be
// skipped.
if i.iterStripeChange == newStripeNewKey || i.iterStripeChange == newStripeSameKey {
i.skip = false
}
if elidedSize == 0 {
// If we didn't find any keys that we could elide due to this tombstone
// (or at least none since the last DELSIZED encountered), we can return
// the key and our existing saved value verbatim.
return &i.key, i.value
}
// Some key(s) were elided as a result of this tombstone. Decode the
// tombstone's value to see if it matches the amount of data actually
// elided.
var v uint64
if len(i.value) > 0 {
var n int
v, n = binary.Uvarint(i.value)
if n != len(i.value) {
i.err = base.CorruptionErrorf("DELSIZED holds invalid value: %x", errors.Safe(i.value))
i.valid = false
return nil, nil
}
}
// If the user's prediction of the value size was correct, then from now on
// it's predicted to delete nothing. Return an empty value.
//
// NB: It's important that we still always return the tombstone, because
// DELSIZED's values are a best effort optimization, not a correctness
// mechanic. There is no guarantee that this key was only set once before
// the DELSIZED was written.
// If the tombstone carried a larger size than what was actually elided,
// it's unclear what to do. The user-provided size was wrong, so it's
// unlikely to be accurate or meaningful. We could:
//
// 1. return the DELSIZED with the original user-provided size unmodified
// 2. return the DELZIZED with a zeroed size to reflect that a key was
// elided, even if it wasn't the anticipated size.
// 3. subtract the elided size from the estimate and re-encode.
// 4. convert the DELSIZED into a value-less DEL, so that ordinary DEL
// heuristics apply.
//
// We opt for (4) under the rationale that we can't rely on the
// user-provided size for accuracy, so ordinary DEL heuristics are safer.
i.value = i.valueBuf[:0]
if elidedSize != v {
i.stats.countMissizedDels++
i.key.SetKind(InternalKeyKindDelete)
}
return &i.key, i.value
}
func (i *compactionIter) saveKey() {
i.keyBuf = append(i.keyBuf[:0], i.iterKey.UserKey...)
i.key.UserKey = i.keyBuf