forked from notional-labs/tm-db
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpebble_iterator.go
127 lines (105 loc) · 2.16 KB
/
pebble_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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//go:build pebbledb
package db
import (
"bytes"
"github.com/cockroachdb/pebble"
)
type pebbleDBIterator struct {
source *pebble.Iterator
start, end []byte
isReverse bool
isInvalid bool
}
var _ Iterator = (*pebbleDBIterator)(nil)
func newPebbleDBIterator(source *pebble.Iterator, start, end []byte, isReverse bool) *pebbleDBIterator {
if isReverse {
if end == nil {
source.Last()
}
} else {
if start == nil {
source.First()
}
}
return &pebbleDBIterator{
source: source,
start: start,
end: end,
isReverse: isReverse,
isInvalid: false,
}
}
// Domain implements Iterator.
func (itr *pebbleDBIterator) Domain() ([]byte, []byte) {
return itr.start, itr.end
}
// Valid implements Iterator.
func (itr *pebbleDBIterator) Valid() bool {
// Once invalid, forever invalid.
if itr.isInvalid {
return false
}
// If source has error, invalid.
if err := itr.source.Error(); err != nil {
itr.isInvalid = true
return false
}
// If source is invalid, invalid.
if !itr.source.Valid() {
itr.isInvalid = true
return false
}
// If key is end or past it, invalid.
start := itr.start
end := itr.end
key := itr.source.Key()
if itr.isReverse {
if start != nil && bytes.Compare(key, start) < 0 {
itr.isInvalid = true
return false
}
} else {
if end != nil && bytes.Compare(end, key) <= 0 {
itr.isInvalid = true
return false
}
}
// It's valid.
return true
}
// Key implements Iterator.
func (itr *pebbleDBIterator) Key() []byte {
itr.assertIsValid()
return itr.source.Key()
}
// Value implements Iterator.
func (itr *pebbleDBIterator) Value() []byte {
itr.assertIsValid()
return itr.source.Value()
}
// Next implements Iterator.
func (itr pebbleDBIterator) Next() {
itr.assertIsValid()
if itr.isReverse {
itr.source.Prev()
} else {
itr.source.Next()
}
}
// Error implements Iterator.
func (itr *pebbleDBIterator) Error() error {
return itr.source.Error()
}
// Close implements Iterator.
func (itr *pebbleDBIterator) Close() error {
err := itr.source.Close()
if err != nil {
return err
}
return nil
}
func (itr *pebbleDBIterator) assertIsValid() {
if !itr.Valid() {
panic("iterator is invalid")
}
}