forked from krasun/fbptree
-
Notifications
You must be signed in to change notification settings - Fork 0
/
iterator.go
63 lines (51 loc) · 1.49 KB
/
iterator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package fbptree
import "fmt"
// Iterator returns a stateful Iterator for traversing the tree
// in ascending key order.
type Iterator struct {
next *node
i int
storage *storage
}
// Iterator returns a stateful iterator that traverses the tree
// in ascending key order.
func (t *FBPTree) Iterator() (*Iterator, error) {
if t.metadata == nil {
return &Iterator{nil, 0, t.storage}, nil
}
next, err := t.storage.loadNodeByID(t.metadata.leftmostID)
if err != nil {
return nil, fmt.Errorf("failed to load the leftmost node %d: %w", t.metadata.leftmostID, err)
}
return &Iterator{next, 0, t.storage}, nil
}
// HasNext returns true if there is a next element to retrive.
func (it *Iterator) HasNext() bool {
return it.next != nil && it.i < it.next.keyNum
}
// Next returns a key and a value at the current position of the iteration
// and advances the iterator.
// Caution! Next panics if called on the nil element.
func (it *Iterator) Next() ([]byte, []byte, error) {
if !it.HasNext() {
// to sleep well
return nil, nil, fmt.Errorf("there is no next node")
}
key, value := it.next.keys[it.i], it.next.pointers[it.i].asValue()
it.i++
if it.i == it.next.keyNum {
nextPointer := it.next.next()
if nextPointer != nil {
nodeID := nextPointer.asNodeID()
next, err := it.storage.loadNodeByID(nodeID)
if err != nil {
return nil, nil, fmt.Errorf("failed to load the next node: %w", err)
}
it.next = next
} else {
it.next = nil
}
it.i = 0
}
return key, value, nil
}