File tree 1 file changed +60
-0
lines changed
1 file changed +60
-0
lines changed Original file line number Diff line number Diff line change @@ -274,6 +274,66 @@ func (n *Node) WalkPath(path []byte, fn WalkFn) {
274
274
}
275
275
}
276
276
277
+ func (n * Node ) Seek (prefix []byte ) * Seeker {
278
+ search := prefix
279
+ p := & pos {n : n }
280
+ for {
281
+ // Check for key exhaution
282
+ if len (search ) == 0 {
283
+ return & Seeker {p }
284
+ }
285
+
286
+ num := len (n .edges )
287
+ idx := sort .Search (num , func (i int ) bool {
288
+ return n .edges [i ].label >= search [0 ]
289
+ })
290
+ p .current = idx
291
+ if idx < len (n .edges ) {
292
+ n = n .edges [idx ].node
293
+ if bytes .HasPrefix (search , n .prefix ) && len (n .edges ) > 0 {
294
+ search = search [len (n .prefix ):]
295
+ p .current ++
296
+ p = & pos {n : n , prev : p }
297
+ continue
298
+ }
299
+ }
300
+ p .current ++
301
+ return & Seeker {p }
302
+ }
303
+ }
304
+
305
+ type Seeker struct {
306
+ * pos
307
+ }
308
+
309
+ type pos struct {
310
+ n * Node
311
+ current int
312
+ prev * pos
313
+ isLeaf bool
314
+ }
315
+
316
+ func (s * Seeker ) Next () (k []byte , v interface {}, ok bool ) {
317
+ if s .current >= len (s .n .edges ) {
318
+ if s .prev == nil {
319
+ return nil , nil , false
320
+ }
321
+ s .pos = s .prev
322
+ return s .Next ()
323
+ }
324
+
325
+ edge := s .n .edges [s .current ]
326
+ s .current ++
327
+ if edge .node .leaf != nil && ! s .isLeaf {
328
+ s .isLeaf = true
329
+ s .current --
330
+ return edge .node .leaf .key , edge .node .leaf .val , true
331
+ }
332
+ s .isLeaf = false
333
+ s .pos = & pos {n : edge .node , prev : s .pos }
334
+ return s .Next ()
335
+ }
336
+
277
337
// recursiveWalk is used to do a pre-order walk of a node
278
338
// recursively. Returns true if the walk should be aborted
279
339
func recursiveWalk (n * Node , fn WalkFn ) bool {
You can’t perform that action at this time.
0 commit comments