-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathIterator.go
107 lines (94 loc) · 2.57 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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package kv
import (
"context"
"errors"
"github.com/0glabs/0g-storage-client/node"
"github.com/ethereum/go-ethereum/common"
)
var errIteratorInvalid = errors.New("iterator is invalid")
// Iterator to iterate over a kv stream
type Iterator struct {
client *Client
streamId common.Hash
version uint64
currentPair *node.KeyValue
}
// Valid check if current position is exist
func (iter *Iterator) Valid() bool {
return iter.currentPair != nil
}
// KeyValue return key-value at current position
func (iter *Iterator) KeyValue() *node.KeyValue {
return iter.currentPair
}
func (iter *Iterator) move(ctx context.Context, kv *node.KeyValue) error {
if kv == nil {
iter.currentPair = nil
return nil
}
value, err := iter.client.GetValue(ctx, iter.streamId, kv.Key, iter.version)
if err != nil {
return err
}
iter.currentPair = &node.KeyValue{
Version: value.Version,
Key: kv.Key,
Data: value.Data,
Size: value.Size,
}
return nil
}
// SeekBefore seek to the position before given key(inclusive)
func (iter *Iterator) SeekBefore(ctx context.Context, key []byte) error {
kv, err := iter.client.GetPrev(ctx, iter.streamId, key, 0, 0, true, iter.version)
if err != nil {
return err
}
return iter.move(ctx, kv)
}
// SeekAfter seek to the position after given key(inclusive)
func (iter *Iterator) SeekAfter(ctx context.Context, key []byte) error {
kv, err := iter.client.GetNext(ctx, iter.streamId, key, 0, 0, true, iter.version)
if err != nil {
return err
}
return iter.move(ctx, kv)
}
// SeekToFirst seek to the first position
func (iter *Iterator) SeekToFirst(ctx context.Context) error {
kv, err := iter.client.GetFirst(ctx, iter.streamId, 0, 0, iter.version)
if err != nil {
return err
}
return iter.move(ctx, kv)
}
// SeekToLast seek to the last position
func (iter *Iterator) SeekToLast(ctx context.Context) error {
kv, err := iter.client.GetLast(ctx, iter.streamId, 0, 0, iter.version)
if err != nil {
return err
}
return iter.move(ctx, kv)
}
// Next move to the next position
func (iter *Iterator) Next(ctx context.Context) error {
if !iter.Valid() {
return errIteratorInvalid
}
kv, err := iter.client.GetNext(ctx, iter.streamId, iter.currentPair.Key, 0, 0, false, iter.version)
if err != nil {
return err
}
return iter.move(ctx, kv)
}
// Prev move to the prev position
func (iter *Iterator) Prev(ctx context.Context) error {
if !iter.Valid() {
return errIteratorInvalid
}
kv, err := iter.client.GetPrev(ctx, iter.streamId, iter.currentPair.Key, 0, 0, false, iter.version)
if err != nil {
return err
}
return iter.move(ctx, kv)
}