@@ -23,27 +23,38 @@ type prefixReplacingIterator struct {
23
23
contentPrefix []byte
24
24
syntheticPrefix []byte
25
25
26
- // keyInRange is a valid key in the logical range that has the syntheticPrefix.
27
- // When an argument to a seek function does not have the syntheticPrefix,
28
- // keyInRange is used to determine if the argument key is before or after the
29
- // range of keys produced by the iterator.
30
- keyInRange []byte
26
+ // lower is a valid key that has syntheticPrefix and is a lower bound for all
27
+ // keys produced by i. It is used to determine if the argument key is before
28
+ // or after the range of keys produced by the iterator.
29
+ lower []byte
31
30
32
31
// arg and arg2 are buffers that are used to avoid allocations when rewriting
33
32
// keys that are provided as arguments. They always start with contentPrefix.
34
33
arg , arg2 []byte
35
34
35
+ state prefixReplacingIteratorState
36
+ // Last bounds received via SetBounds.
37
+ lowerBound , upperBound []byte
36
38
// res is used to avoid allocations when rewriting result keys. It always
37
39
// starts with syntheticPrefix.
38
40
res InternalKey
39
41
err error
40
- // empty is set after a seek operation that returns no keys.
41
- empty bool
42
42
}
43
43
44
- func errInputPrefixMismatch () error {
45
- return errors .AssertionFailedf ("key argument does not have prefix required for replacement" )
46
- }
44
+ type prefixReplacingIteratorState int8
45
+
46
+ const (
47
+ // inRange indicates that the prefix replacing iterator is "in sync" with the
48
+ // underlying iterator; any Next/Prev calls can be passed through.
49
+ inRange prefixReplacingIteratorState = iota
50
+ // afterRange indicates that our iterator is positioned after the synthetic
51
+ // prefix range. A Prev() call should return the last key/span in the range.
52
+ afterRange
53
+ // beforeRange indicates that our iterator is positioned after the synthetic
54
+ // prefix range. A Next() call should return the first key/span in the range.
55
+ beforeRange
56
+ empty
57
+ )
47
58
48
59
func errOutputPrefixMismatch () error {
49
60
return errors .AssertionFailedf ("key returned does not have prefix required for replacement" )
@@ -56,29 +67,28 @@ var _ Iterator = (*prefixReplacingIterator)(nil)
56
67
// `syntheticPrefix`. Every key produced by the underlying iterator must have
57
68
// `contentPrefix`.
58
69
//
59
- // keyInRange is a valid key that starts with syntheticPrefix. When a seek
60
- // function is called with a key that does not start with syntheticPrefix,
61
- // keyInRange is used to determine if the key is before or after the synthetic
62
- // prefix range.
70
+ // lower is a valid key that has syntheticPreficx and is a lower bound for all
71
+ // keys produced by i. It is used to determine if an argument key is before
72
+ // or after the range of keys produced by the iterator.
63
73
//
64
74
// INVARIANT: len(syntheticPrefix) > 0 && keyInRange stars with syntheticPrefix.
65
75
func newPrefixReplacingIterator (
66
- i Iterator , contentPrefix , syntheticPrefix []byte , keyInRange []byte , cmp base.Compare ,
76
+ i Iterator , contentPrefix , syntheticPrefix []byte , lower []byte , cmp base.Compare ,
67
77
) Iterator {
68
78
if invariants .Enabled {
69
79
if len (syntheticPrefix ) == 0 {
70
80
panic ("newPrefixReplacingIterator called without synthetic prefix" )
71
81
}
72
- if ! bytes .HasPrefix (keyInRange , syntheticPrefix ) {
73
- panic (fmt .Sprintf ("keyInRange %q does not have synthetic prefix %q" , keyInRange , syntheticPrefix ))
82
+ if ! bytes .HasPrefix (lower , syntheticPrefix ) {
83
+ panic (fmt .Sprintf ("lower %q does not have synthetic prefix %q" , lower , syntheticPrefix ))
74
84
}
75
85
}
76
86
return & prefixReplacingIterator {
77
87
i : i ,
78
88
cmp : cmp ,
79
89
contentPrefix : contentPrefix ,
80
90
syntheticPrefix : syntheticPrefix ,
81
- keyInRange : keyInRange ,
91
+ lower : lower ,
82
92
arg : slices .Clone (contentPrefix ),
83
93
arg2 : slices .Clone (contentPrefix ),
84
94
res : InternalKey {UserKey : slices .Clone (syntheticPrefix )},
@@ -121,14 +131,16 @@ func (p *prefixReplacingIterator) rewriteResult(
121
131
func (p * prefixReplacingIterator ) SeekGE (
122
132
key []byte , flags base.SeekGEFlags ,
123
133
) (* InternalKey , base.LazyValue ) {
124
- p .empty = false
134
+ p .state = inRange
125
135
if ! bytes .HasPrefix (key , p .syntheticPrefix ) {
126
- if p .cmp (key , p .keyInRange ) > 0 {
127
- p .empty = true
136
+ if p .cmp (key , p .lower ) > 0 {
137
+ p .state = afterRange
128
138
return nil , base.LazyValue {}
129
139
}
130
- // Key must be before the range; use First instead.
131
- return p .rewriteResult (p .i .First ())
140
+ // Key must be before the range; seek to the lower bound instead.
141
+ // We don't use First because we may miss out on optimizations passed
142
+ // through SeekEFlags.
143
+ key = p .lower
132
144
}
133
145
return p .rewriteResult (p .i .SeekGE (p .rewriteArg (key ), flags ))
134
146
}
@@ -137,13 +149,15 @@ func (p *prefixReplacingIterator) SeekGE(
137
149
func (p * prefixReplacingIterator ) SeekPrefixGE (
138
150
prefix , key []byte , flags base.SeekGEFlags ,
139
151
) (* InternalKey , base.LazyValue ) {
140
- p .empty = false
141
- if invariants .Enabled && ! bytes .HasPrefix (key , prefix ) {
142
- panic (fmt .Sprintf ("key %q does not have prefix %q" , key , prefix ))
143
- }
144
- if ! bytes .HasPrefix (prefix , p .syntheticPrefix ) {
152
+ p .state = inRange
153
+ if ! bytes .HasPrefix (prefix , p .syntheticPrefix ) || ! bytes .HasPrefix (key , p .syntheticPrefix ) {
145
154
// We never produce keys with this prefix; we can return nil.
146
- p .empty = true
155
+ if p .cmp (prefix , p .lower ) < 0 {
156
+ // We still want to seek the underlying iterator to potentially enable
157
+ // optimizations passed through flags.
158
+ p .i .SeekGE (p .rewriteArg (p .lower ), flags )
159
+ }
160
+ p .state = empty
147
161
return nil , base.LazyValue {}
148
162
}
149
163
return p .rewriteResult (p .i .SeekPrefixGE (p .rewriteArg2 (prefix ), p .rewriteArg (key ), flags ))
@@ -153,52 +167,84 @@ func (p *prefixReplacingIterator) SeekPrefixGE(
153
167
func (p * prefixReplacingIterator ) SeekLT (
154
168
key []byte , flags base.SeekLTFlags ,
155
169
) (* InternalKey , base.LazyValue ) {
156
- p .empty = false
170
+ p .state = inRange
157
171
if ! bytes .HasPrefix (key , p .syntheticPrefix ) {
158
- if p .cmp (key , p .keyInRange ) < 0 {
159
- p .empty = true
172
+ if p .cmp (key , p .lower ) < 0 {
173
+ // Key before the range; no results.
174
+ p .state = beforeRange
160
175
return nil , base.LazyValue {}
161
176
}
162
177
// Key must be after the range. Use Last instead.
163
178
return p .rewriteResult (p .i .Last ())
164
179
}
180
+
165
181
return p .rewriteResult (p .i .SeekLT (p .rewriteArg (key ), flags ))
166
182
}
167
183
168
184
// First implements the Iterator interface.
169
185
func (p * prefixReplacingIterator ) First () (* InternalKey , base.LazyValue ) {
170
- p .empty = false
186
+ p .state = inRange
171
187
return p .rewriteResult (p .i .First ())
172
188
}
173
189
174
190
// Last implements the Iterator interface.
175
191
func (p * prefixReplacingIterator ) Last () (* InternalKey , base.LazyValue ) {
176
- p .empty = false
192
+ p .state = inRange
177
193
return p .rewriteResult (p .i .Last ())
178
194
}
179
195
180
196
// Next implements the Iterator interface.
181
197
func (p * prefixReplacingIterator ) Next () (* InternalKey , base.LazyValue ) {
182
- if p .empty {
198
+ switch p .state {
199
+ case empty , afterRange :
183
200
return nil , base.LazyValue {}
201
+ case beforeRange :
202
+ p .state = inRange
203
+ if p .lowerBound != nil {
204
+ return p .rewriteResult (p .i .SeekGE (p .lowerBound , base .SeekGEFlagsNone ))
205
+ }
206
+ return p .rewriteResult (p .i .First ())
207
+ case inRange :
208
+ return p .rewriteResult (p .i .Next ())
209
+ default :
210
+ panic ("invalid iterator state" )
184
211
}
185
- return p .rewriteResult (p .i .Next ())
186
212
}
187
213
188
214
// NextPrefix implements the Iterator interface.
189
215
func (p * prefixReplacingIterator ) NextPrefix (succKey []byte ) (* InternalKey , base.LazyValue ) {
190
- if p .empty {
216
+ switch p .state {
217
+ case empty , afterRange :
191
218
return nil , base.LazyValue {}
219
+ case beforeRange :
220
+ p .state = inRange
221
+ if p .lowerBound != nil {
222
+ return p .rewriteResult (p .i .SeekGE (p .lowerBound , base .SeekGEFlagsNone ))
223
+ }
224
+ return p .rewriteResult (p .i .First ())
225
+ case inRange :
226
+ return p .rewriteResult (p .i .NextPrefix (succKey ))
227
+ default :
228
+ panic ("invalid iterator state" )
192
229
}
193
- return p .rewriteResult (p .i .NextPrefix (p .rewriteArg (succKey )))
194
230
}
195
231
196
232
// Prev implements the Iterator interface.
197
233
func (p * prefixReplacingIterator ) Prev () (* InternalKey , base.LazyValue ) {
198
- if p .empty {
234
+ switch p .state {
235
+ case empty , beforeRange :
199
236
return nil , base.LazyValue {}
237
+ case afterRange :
238
+ p .state = inRange
239
+ if p .upperBound != nil {
240
+ return p .rewriteResult (p .i .SeekLT (p .upperBound , base .SeekLTFlagsNone ))
241
+ }
242
+ return p .rewriteResult (p .i .Last ())
243
+ case inRange :
244
+ return p .rewriteResult (p .i .Prev ())
245
+ default :
246
+ panic ("invalid iterator state" )
200
247
}
201
- return p .rewriteResult (p .i .Prev ())
202
248
}
203
249
204
250
// Error implements the Iterator interface.
@@ -260,6 +306,8 @@ type prefixReplacingFragmentIterator struct {
260
306
261
307
arg []byte
262
308
out1 , out2 []byte
309
+
310
+ state prefixReplacingIteratorState
263
311
}
264
312
265
313
// newPrefixReplacingFragmentIterator wraps a FragmentIterator over some reader
@@ -284,9 +332,6 @@ func newPrefixReplacingFragmentIterator(
284
332
}
285
333
286
334
func (p * prefixReplacingFragmentIterator ) rewriteArg (key []byte ) ([]byte , error ) {
287
- if ! bytes .HasPrefix (key , p .syntheticPrefix ) {
288
- return nil , errInputPrefixMismatch ()
289
- }
290
335
p .arg = append (p .arg [:len (p .contentPrefix )], key [len (p .syntheticPrefix ):]... )
291
336
return p .arg , nil
292
337
}
@@ -307,8 +352,10 @@ func (p *prefixReplacingFragmentIterator) rewriteSpan(
307
352
308
353
// SeekGE implements the FragmentIterator interface.
309
354
func (p * prefixReplacingFragmentIterator ) SeekGE (key []byte ) (* keyspan.Span , error ) {
355
+ p .state = inRange
310
356
if ! bytes .HasPrefix (key , p .syntheticPrefix ) {
311
357
if p .cmp (key , p .keyInRange ) > 0 {
358
+ p .state = afterRange
312
359
return nil , nil
313
360
}
314
361
// Key must be before the range; use First instead.
@@ -323,8 +370,10 @@ func (p *prefixReplacingFragmentIterator) SeekGE(key []byte) (*keyspan.Span, err
323
370
324
371
// SeekLT implements the FragmentIterator interface.
325
372
func (p * prefixReplacingFragmentIterator ) SeekLT (key []byte ) (* keyspan.Span , error ) {
373
+ p .state = inRange
326
374
if ! bytes .HasPrefix (key , p .syntheticPrefix ) {
327
375
if p .cmp (key , p .keyInRange ) < 0 {
376
+ p .state = beforeRange
328
377
return nil , nil
329
378
}
330
379
// Key must be after the range; use Last instead.
@@ -339,22 +388,44 @@ func (p *prefixReplacingFragmentIterator) SeekLT(key []byte) (*keyspan.Span, err
339
388
340
389
// First implements the FragmentIterator interface.
341
390
func (p * prefixReplacingFragmentIterator ) First () (* keyspan.Span , error ) {
391
+ p .state = inRange
342
392
return p .rewriteSpan (p .i .First ())
343
393
}
344
394
345
395
// Last implements the FragmentIterator interface.
346
396
func (p * prefixReplacingFragmentIterator ) Last () (* keyspan.Span , error ) {
397
+ p .state = inRange
347
398
return p .rewriteSpan (p .i .Last ())
348
399
}
349
400
350
- // Close implements the FragmentIterator interface.
401
+ // Next implements the FragmentIterator interface.
351
402
func (p * prefixReplacingFragmentIterator ) Next () (* keyspan.Span , error ) {
352
- return p .rewriteSpan (p .i .Next ())
403
+ switch p .state {
404
+ case empty , afterRange :
405
+ return nil , nil
406
+ case beforeRange :
407
+ p .state = inRange
408
+ return p .rewriteSpan (p .i .First ())
409
+ case inRange :
410
+ return p .rewriteSpan (p .i .Next ())
411
+ default :
412
+ panic ("invalid iterator state" )
413
+ }
353
414
}
354
415
355
416
// Prev implements the FragmentIterator interface.
356
417
func (p * prefixReplacingFragmentIterator ) Prev () (* keyspan.Span , error ) {
357
- return p .rewriteSpan (p .i .Prev ())
418
+ switch p .state {
419
+ case empty , beforeRange :
420
+ return nil , nil
421
+ case afterRange :
422
+ p .state = inRange
423
+ return p .rewriteSpan (p .i .Last ())
424
+ case inRange :
425
+ return p .rewriteSpan (p .i .Prev ())
426
+ default :
427
+ panic ("invalid iterator state" )
428
+ }
358
429
}
359
430
360
431
// Close implements the FragmentIterator interface.
0 commit comments