Line data Source code
1 : // Copyright 2023 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 : // of this source code is governed by a BSD-style license that can be found in 3 : // the LICENSE file. 4 : 5 : package invalidating 6 : 7 : import ( 8 : "context" 9 : 10 : "github.com/cockroachdb/pebble/internal/base" 11 : "github.com/cockroachdb/pebble/internal/fastrand" 12 : "github.com/cockroachdb/pebble/internal/invariants" 13 : ) 14 : 15 : // MaybeWrapIfInvariants wraps some iterators with an invalidating iterator. 16 : // MaybeWrapIfInvariants does nothing in non-invariant builds. 17 1 : func MaybeWrapIfInvariants(iter base.InternalIterator) base.InternalIterator { 18 1 : if invariants.Enabled { 19 1 : if fastrand.Uint32n(10) == 1 { 20 1 : return NewIter(iter) 21 1 : } 22 : } 23 1 : return iter 24 : } 25 : 26 : // iter tests unsafe key/value slice reuse by modifying the last 27 : // returned key/value to all 1s. 28 : type iter struct { 29 : iter base.InternalIterator 30 : lastKey *base.InternalKey 31 : lastValue base.LazyValue 32 : ignoreKinds [base.InternalKeyKindMax + 1]bool 33 : err error 34 : } 35 : 36 : // Option configures the behavior of an invalidating iterator. 37 : type Option interface { 38 : apply(*iter) 39 : } 40 : 41 : type funcOpt func(*iter) 42 : 43 1 : func (f funcOpt) apply(i *iter) { f(i) } 44 : 45 : // IgnoreKinds constructs an Option that configures an invalidating iterator to 46 : // skip trashing k/v pairs with the provided key kinds. Some iterators provided 47 : // key stability guarantees for specific key kinds. 48 1 : func IgnoreKinds(kinds ...base.InternalKeyKind) Option { 49 1 : return funcOpt(func(i *iter) { 50 1 : for _, kind := range kinds { 51 1 : i.ignoreKinds[kind] = true 52 1 : } 53 : }) 54 : } 55 : 56 : // NewIter constructs a new invalidating iterator that wraps the provided 57 : // iterator, trashing buffers for previously returned keys. 58 1 : func NewIter(originalIterator base.InternalIterator, opts ...Option) base.InternalIterator { 59 1 : i := &iter{iter: originalIterator} 60 1 : for _, opt := range opts { 61 1 : opt.apply(i) 62 1 : } 63 1 : return i 64 : } 65 : 66 : func (i *iter) update( 67 : key *base.InternalKey, value base.LazyValue, 68 1 : ) (*base.InternalKey, base.LazyValue) { 69 1 : i.trashLastKV() 70 1 : if key == nil { 71 1 : i.lastKey = nil 72 1 : i.lastValue = base.LazyValue{} 73 1 : return nil, base.LazyValue{} 74 1 : } 75 : 76 1 : i.lastKey = &base.InternalKey{} 77 1 : *i.lastKey = key.Clone() 78 1 : i.lastValue = base.LazyValue{ 79 1 : ValueOrHandle: append(make([]byte, 0, len(value.ValueOrHandle)), value.ValueOrHandle...), 80 1 : } 81 1 : if value.Fetcher != nil { 82 1 : fetcher := new(base.LazyFetcher) 83 1 : *fetcher = *value.Fetcher 84 1 : i.lastValue.Fetcher = fetcher 85 1 : } 86 1 : return i.lastKey, i.lastValue 87 : } 88 : 89 1 : func (i *iter) trashLastKV() { 90 1 : if i.lastKey == nil { 91 1 : return 92 1 : } 93 1 : if i.ignoreKinds[i.lastKey.Kind()] { 94 1 : return 95 1 : } 96 : 97 1 : if i.lastKey != nil { 98 1 : for j := range i.lastKey.UserKey { 99 1 : i.lastKey.UserKey[j] = 0xff 100 1 : } 101 1 : i.lastKey.Trailer = 0xffffffffffffffff 102 : } 103 1 : for j := range i.lastValue.ValueOrHandle { 104 1 : i.lastValue.ValueOrHandle[j] = 0xff 105 1 : } 106 1 : if i.lastValue.Fetcher != nil { 107 1 : // Not all the LazyFetcher fields are visible, so we zero out the last 108 1 : // value's Fetcher struct entirely. 109 1 : *i.lastValue.Fetcher = base.LazyFetcher{} 110 1 : } 111 : } 112 : 113 1 : func (i *iter) SeekGE(key []byte, flags base.SeekGEFlags) (*base.InternalKey, base.LazyValue) { 114 1 : return i.update(i.iter.SeekGE(key, flags)) 115 1 : } 116 : 117 : func (i *iter) SeekPrefixGE( 118 : prefix, key []byte, flags base.SeekGEFlags, 119 1 : ) (*base.InternalKey, base.LazyValue) { 120 1 : return i.update(i.iter.SeekPrefixGE(prefix, key, flags)) 121 1 : } 122 : 123 1 : func (i *iter) SeekLT(key []byte, flags base.SeekLTFlags) (*base.InternalKey, base.LazyValue) { 124 1 : return i.update(i.iter.SeekLT(key, flags)) 125 1 : } 126 : 127 1 : func (i *iter) First() (*base.InternalKey, base.LazyValue) { 128 1 : return i.update(i.iter.First()) 129 1 : } 130 : 131 1 : func (i *iter) Last() (*base.InternalKey, base.LazyValue) { 132 1 : return i.update(i.iter.Last()) 133 1 : } 134 : 135 1 : func (i *iter) Next() (*base.InternalKey, base.LazyValue) { 136 1 : return i.update(i.iter.Next()) 137 1 : } 138 : 139 1 : func (i *iter) Prev() (*base.InternalKey, base.LazyValue) { 140 1 : return i.update(i.iter.Prev()) 141 1 : } 142 : 143 1 : func (i *iter) NextPrefix(succKey []byte) (*base.InternalKey, base.LazyValue) { 144 1 : return i.update(i.iter.NextPrefix(succKey)) 145 1 : } 146 : 147 1 : func (i *iter) Error() error { 148 1 : if err := i.iter.Error(); err != nil { 149 1 : return err 150 1 : } 151 1 : return i.err 152 : } 153 : 154 1 : func (i *iter) Close() error { 155 1 : return i.iter.Close() 156 1 : } 157 : 158 1 : func (i *iter) SetBounds(lower, upper []byte) { 159 1 : i.iter.SetBounds(lower, upper) 160 1 : } 161 : 162 0 : func (i *iter) SetContext(ctx context.Context) { 163 0 : i.iter.SetContext(ctx) 164 0 : } 165 : 166 0 : func (i *iter) String() string { 167 0 : return i.iter.String() 168 0 : }