-
Notifications
You must be signed in to change notification settings - Fork 6
/
iterator.go
61 lines (52 loc) · 1.54 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
package store
import (
"fmt"
)
// KVStorePrefixIteratorPaginated returns iterator over items in the selected page.
// Items iterated and skipped in ascending order.
func KVStorePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator {
pi := &PaginatedIterator{
Iterator: KVStorePrefixIterator(kvs, prefix),
page: page,
limit: limit,
}
pi.skip()
return pi
}
// KVStoreReversePrefixIteratorPaginated returns iterator over items in the selected page.
// Items iterated and skipped in descending order.
func KVStoreReversePrefixIteratorPaginated(kvs KVStore, prefix []byte, page, limit uint) Iterator {
pi := &PaginatedIterator{
Iterator: KVStoreReversePrefixIterator(kvs, prefix),
page: page,
limit: limit,
}
pi.skip()
return pi
}
// PaginatedIterator is a wrapper around Iterator that iterates over values starting for given page and limit.
type PaginatedIterator struct {
Iterator
page, limit uint // provided during initialization
iterated uint // incremented in a call to Next
}
func (pi *PaginatedIterator) skip() {
for i := (pi.page - 1) * pi.limit; i > 0 && pi.Iterator.Valid(); i-- {
pi.Iterator.Next()
}
}
// Next will panic after limit is reached.
func (pi *PaginatedIterator) Next() {
if !pi.Valid() {
panic(fmt.Sprintf("PaginatedIterator reached limit %d", pi.limit))
}
pi.Iterator.Next()
pi.iterated++
}
// Valid if below limit and underlying iterator is valid.
func (pi *PaginatedIterator) Valid() bool {
if pi.iterated >= pi.limit {
return false
}
return pi.Iterator.Valid()
}