-
Notifications
You must be signed in to change notification settings - Fork 3.8k
/
Copy pathhelpers.go
113 lines (97 loc) · 2.65 KB
/
helpers.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
package indexes
import (
"context"
"cosmossdk.io/collections"
)
// iterator defines the minimum set of methods of an index iterator
// required to work with the helpers.
type iterator[K any] interface {
// PrimaryKey returns the iterator current primary key.
PrimaryKey() (K, error)
// Next advances the iterator by one element.
Next()
// Valid asserts if the Iterator is valid.
Valid() bool
// Close closes the iterator.
Close() error
}
// CollectKeyValues collects all the keys and the values of an indexed map index iterator.
// The Iterator is fully consumed and closed.
func CollectKeyValues[K, V any, I iterator[K], Idx collections.Indexes[K, V]](
ctx context.Context,
indexedMap *collections.IndexedMap[K, V, Idx],
iter I,
) (kvs []collections.KeyValue[K, V], err error) {
err = ScanKeyValues(ctx, indexedMap, iter, func(kv collections.KeyValue[K, V]) bool {
kvs = append(kvs, kv)
return false
})
return
}
// ScanKeyValues calls the do function on every record found, in the indexed map
// from the index iterator. Returning true stops the iteration.
// The Iterator is closed when this function exits.
func ScanKeyValues[K, V any, I iterator[K], Idx collections.Indexes[K, V]](
ctx context.Context,
indexedMap *collections.IndexedMap[K, V, Idx],
iter I,
do func(kv collections.KeyValue[K, V]) (stop bool),
) (err error) {
defer iter.Close()
for ; iter.Valid(); iter.Next() {
pk, err := iter.PrimaryKey()
if err != nil {
return err
}
value, err := indexedMap.Get(ctx, pk)
if err != nil {
return err
}
kv := collections.KeyValue[K, V]{
Key: pk,
Value: value,
}
if do(kv) {
break
}
}
return nil
}
// CollectValues collects all the values from an Index iterator and the IndexedMap.
// Closes the Iterator.
func CollectValues[K, V any, I iterator[K], Idx collections.Indexes[K, V]](
ctx context.Context,
indexedMap *collections.IndexedMap[K, V, Idx],
iter I,
) (values []V, err error) {
err = ScanValues(ctx, indexedMap, iter, func(value V) (stop bool) {
values = append(values, value)
return false
})
return
}
// ScanValues collects all the values from an Index iterator and the IndexedMap in a lazy way.
// The iterator is closed when this function exits.
func ScanValues[K, V any, I iterator[K], Idx collections.Indexes[K, V]](
ctx context.Context,
indexedMap *collections.IndexedMap[K, V, Idx],
iter I,
f func(value V) (stop bool),
) error {
defer iter.Close()
for ; iter.Valid(); iter.Next() {
key, err := iter.PrimaryKey()
if err != nil {
return err
}
value, err := indexedMap.Get(ctx, key)
if err != nil {
return err
}
stop := f(value)
if stop {
return nil
}
}
return nil
}