Line data Source code
1 : // Copyright 2024 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 base
6 :
7 : import (
8 : "context"
9 : "fmt"
10 : "io"
11 : "strconv"
12 : "strings"
13 :
14 : "github.com/cockroachdb/pebble/internal/treeprinter"
15 : )
16 :
17 : // NewDeletableSumValueMerger return a ValueMerger which computes the sum of its
18 : // arguments, but transforms a zero sum into a non-existent entry.
19 1 : func NewDeletableSumValueMerger(key, value []byte) (ValueMerger, error) {
20 1 : m := &deletableSumValueMerger{}
21 1 : return m, m.MergeNewer(value)
22 1 : }
23 :
24 : type deletableSumValueMerger struct {
25 : sum int64
26 : }
27 :
28 1 : func (m *deletableSumValueMerger) parseAndCalculate(value []byte) error {
29 1 : v, err := strconv.ParseInt(string(value), 10, 64)
30 1 : if err == nil {
31 1 : m.sum += v
32 1 : }
33 1 : return err
34 : }
35 :
36 1 : func (m *deletableSumValueMerger) MergeNewer(value []byte) error {
37 1 : return m.parseAndCalculate(value)
38 1 : }
39 :
40 1 : func (m *deletableSumValueMerger) MergeOlder(value []byte) error {
41 1 : return m.parseAndCalculate(value)
42 1 : }
43 :
44 1 : func (m *deletableSumValueMerger) Finish(includesBase bool) ([]byte, io.Closer, error) {
45 1 : if m.sum == 0 {
46 1 : return nil, nil, nil
47 1 : }
48 1 : return []byte(strconv.FormatInt(m.sum, 10)), nil, nil
49 : }
50 :
51 : func (m *deletableSumValueMerger) DeletableFinish(
52 : includesBase bool,
53 1 : ) ([]byte, bool, io.Closer, error) {
54 1 : value, closer, err := m.Finish(includesBase)
55 1 : return value, len(value) == 0, closer, err
56 1 : }
57 :
58 : // FakeKVs constructs InternalKVs from the given key strings, in the format
59 : // "key:seq-num". The values are empty.
60 1 : func FakeKVs(keys ...string) []InternalKV {
61 1 : kvs := make([]InternalKV, len(keys))
62 1 : for i, k := range keys {
63 1 : kvs[i] = InternalKV{K: fakeIkey(k)}
64 1 : }
65 1 : return kvs
66 : }
67 :
68 1 : func fakeIkey(s string) InternalKey {
69 1 : j := strings.Index(s, ":")
70 1 : seqNum, err := strconv.Atoi(s[j+1:])
71 1 : if err != nil {
72 0 : panic(err)
73 : }
74 1 : return MakeInternalKey([]byte(s[:j]), SeqNum(seqNum), InternalKeyKindSet)
75 : }
76 :
77 : // NewFakeIter returns an iterator over the given KVs.
78 1 : func NewFakeIter(kvs []InternalKV) *FakeIter {
79 1 : return &FakeIter{
80 1 : kvs: kvs,
81 1 : index: 0,
82 1 : valid: len(kvs) > 0,
83 1 : }
84 1 : }
85 :
86 : // FakeIter is an iterator over a fixed set of KVs.
87 : type FakeIter struct {
88 : lower []byte
89 : upper []byte
90 : kvs []InternalKV
91 : index int
92 : valid bool
93 : closeErr error
94 : }
95 :
96 : // FakeIter implements the InternalIterator interface.
97 : var _ InternalIterator = (*FakeIter)(nil)
98 :
99 : // SetCloseErr causes future calls to Error() and Close() to return this error.
100 1 : func (f *FakeIter) SetCloseErr(closeErr error) {
101 1 : f.closeErr = closeErr
102 1 : }
103 :
104 0 : func (f *FakeIter) String() string {
105 0 : return "fake"
106 0 : }
107 :
108 : // SeekGE is part of the InternalIterator interface.
109 1 : func (f *FakeIter) SeekGE(key []byte, flags SeekGEFlags) *InternalKV {
110 1 : f.valid = false
111 1 : for f.index = 0; f.index < len(f.kvs); f.index++ {
112 1 : if DefaultComparer.Compare(key, f.key().UserKey) <= 0 {
113 1 : if f.upper != nil && DefaultComparer.Compare(f.upper, f.key().UserKey) <= 0 {
114 1 : return nil
115 1 : }
116 1 : f.valid = true
117 1 : return f.KV()
118 : }
119 : }
120 1 : return nil
121 : }
122 :
123 : // SeekPrefixGE is part of the InternalIterator interface.
124 1 : func (f *FakeIter) SeekPrefixGE(prefix, key []byte, flags SeekGEFlags) *InternalKV {
125 1 : return f.SeekGE(key, flags)
126 1 : }
127 :
128 : // SeekLT is part of the InternalIterator interface.
129 1 : func (f *FakeIter) SeekLT(key []byte, flags SeekLTFlags) *InternalKV {
130 1 : f.valid = false
131 1 : for f.index = len(f.kvs) - 1; f.index >= 0; f.index-- {
132 1 : if DefaultComparer.Compare(key, f.key().UserKey) > 0 {
133 1 : if f.lower != nil && DefaultComparer.Compare(f.lower, f.key().UserKey) > 0 {
134 1 : return nil
135 1 : }
136 1 : f.valid = true
137 1 : return f.KV()
138 : }
139 : }
140 1 : return nil
141 : }
142 :
143 : // First is part of the InternalIterator interface.
144 1 : func (f *FakeIter) First() *InternalKV {
145 1 : f.valid = false
146 1 : f.index = -1
147 1 : if kv := f.Next(); kv == nil {
148 1 : return nil
149 1 : }
150 1 : if f.upper != nil && DefaultComparer.Compare(f.upper, f.key().UserKey) <= 0 {
151 0 : return nil
152 0 : }
153 1 : f.valid = true
154 1 : return f.KV()
155 : }
156 :
157 : // Last is part of the InternalIterator interface.
158 1 : func (f *FakeIter) Last() *InternalKV {
159 1 : f.valid = false
160 1 : f.index = len(f.kvs)
161 1 : if kv := f.Prev(); kv == nil {
162 0 : return nil
163 0 : }
164 1 : if f.lower != nil && DefaultComparer.Compare(f.lower, f.key().UserKey) > 0 {
165 0 : return nil
166 0 : }
167 1 : f.valid = true
168 1 : return f.KV()
169 : }
170 :
171 : // Next is part of the InternalIterator interface.
172 1 : func (f *FakeIter) Next() *InternalKV {
173 1 : f.valid = false
174 1 : if f.index == len(f.kvs) {
175 1 : return nil
176 1 : }
177 1 : f.index++
178 1 : if f.index == len(f.kvs) {
179 1 : return nil
180 1 : }
181 1 : if f.upper != nil && DefaultComparer.Compare(f.upper, f.key().UserKey) <= 0 {
182 1 : return nil
183 1 : }
184 1 : f.valid = true
185 1 : return f.KV()
186 : }
187 :
188 : // Prev is part of the InternalIterator interface.
189 1 : func (f *FakeIter) Prev() *InternalKV {
190 1 : f.valid = false
191 1 : if f.index < 0 {
192 0 : return nil
193 0 : }
194 1 : f.index--
195 1 : if f.index < 0 {
196 1 : return nil
197 1 : }
198 1 : if f.lower != nil && DefaultComparer.Compare(f.lower, f.key().UserKey) > 0 {
199 1 : return nil
200 1 : }
201 1 : f.valid = true
202 1 : return f.KV()
203 : }
204 :
205 : // NextPrefix is part of the InternalIterator interface.
206 0 : func (f *FakeIter) NextPrefix(succKey []byte) *InternalKV {
207 0 : return f.SeekGE(succKey, SeekGEFlagsNone)
208 0 : }
209 :
210 : // key returns the current Key the iterator is positioned at regardless of the
211 : // value of f.valid.
212 1 : func (f *FakeIter) key() *InternalKey {
213 1 : return &f.kvs[f.index].K
214 1 : }
215 :
216 : // KV is part of the InternalIterator interface.
217 1 : func (f *FakeIter) KV() *InternalKV {
218 1 : if f.valid {
219 1 : return &f.kvs[f.index]
220 1 : }
221 : // It is invalid to call Key() when Valid() returns false. Rather than
222 : // returning nil here which would technically be more correct, return a
223 : // non-nil key which is the behavior of some InternalIterator
224 : // implementations. This provides better testing of users of
225 : // InternalIterators.
226 0 : if f.index < 0 {
227 0 : return &f.kvs[0]
228 0 : }
229 0 : return &f.kvs[len(f.kvs)-1]
230 : }
231 :
232 : // Valid is part of the InternalIterator interface.
233 0 : func (f *FakeIter) Valid() bool {
234 0 : return f.index >= 0 && f.index < len(f.kvs) && f.valid
235 0 : }
236 :
237 : // Error is part of the InternalIterator interface.
238 1 : func (f *FakeIter) Error() error {
239 1 : return f.closeErr
240 1 : }
241 :
242 : // Close is part of the InternalIterator interface.
243 1 : func (f *FakeIter) Close() error {
244 1 : return f.closeErr
245 1 : }
246 :
247 : // SetBounds is part of the InternalIterator interface.
248 1 : func (f *FakeIter) SetBounds(lower, upper []byte) {
249 1 : f.lower = lower
250 1 : f.upper = upper
251 1 : }
252 :
253 : // SetContext is part of the InternalIterator interface.
254 0 : func (f *FakeIter) SetContext(_ context.Context) {}
255 :
256 : // DebugTree is part of the InternalIterator interface.
257 0 : func (f *FakeIter) DebugTree(tp treeprinter.Node) {
258 0 : tp.Childf("%T(%p)", f, f)
259 0 : }
260 :
261 : // ParseUserKeyBounds parses UserKeyBounds from a string representation of the
262 : // form "[foo, bar]" or "[foo, bar)".
263 1 : func ParseUserKeyBounds(s string) UserKeyBounds {
264 1 : first, last, s := s[0], s[len(s)-1], s[1:len(s)-1]
265 1 : start, end, ok := strings.Cut(s, ", ")
266 1 : if !ok || first != '[' || (last != ']' && last != ')') {
267 0 : panic(fmt.Sprintf("invalid bounds %q", s))
268 : }
269 1 : return UserKeyBoundsEndExclusiveIf([]byte(start), []byte(end), last == ')')
270 : }
|