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