-
Notifications
You must be signed in to change notification settings - Fork 170
/
identifierList.go
116 lines (98 loc) · 3.16 KB
/
identifierList.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
package flow
import (
"golang.org/x/exp/slices"
)
// IdentifierList defines a sortable list of identifiers
type IdentifierList []Identifier
// Len returns length of the IdentifierList in the number of stored identifiers.
// It satisfies the sort.Interface making the IdentifierList sortable.
func (il IdentifierList) Len() int {
return len(il)
}
// Lookup converts the Identifiers to a lookup table.
func (il IdentifierList) Lookup() map[Identifier]struct{} {
lookup := make(map[Identifier]struct{}, len(il))
for _, id := range il {
lookup[id] = struct{}{}
}
return lookup
}
// Less returns true if element i in the IdentifierList is less than j based on its identifier.
// Otherwise it returns true.
// It satisfies the sort.Interface making the IdentifierList sortable.
func (il IdentifierList) Less(i, j int) bool {
return IsIdentifierCanonical(il[i], il[j])
}
// Swap swaps the element i and j in the IdentifierList.
// It satisfies the sort.Interface making the IdentifierList sortable.
func (il IdentifierList) Swap(i, j int) {
il[j], il[i] = il[i], il[j]
}
func (il IdentifierList) Strings() []string {
var list []string
for _, id := range il {
list = append(list, id.String())
}
return list
}
// ID returns a cryptographic commitment to the list of identifiers.
// Since an IdentifierList has no mutable fields, it is equal to the checksum.
func (il IdentifierList) ID() Identifier {
return il.Checksum()
}
// Checksum returns a cryptographic commitment to the list of identifiers.
func (il IdentifierList) Checksum() Identifier {
return MakeID(il)
}
func (il IdentifierList) Copy() IdentifierList {
cpy := make(IdentifierList, 0, il.Len())
return append(cpy, il...)
}
// Contains returns whether this identifier list contains the target identifier.
func (il IdentifierList) Contains(target Identifier) bool {
for _, id := range il {
if target == id {
return true
}
}
return false
}
// Union returns a new identifier list containing the union of `il` and `other`.
// There are no duplicates in the output.
func (il IdentifierList) Union(other IdentifierList) IdentifierList {
// stores the output, the union of the two lists
union := make(IdentifierList, 0, len(il)+len(other))
// efficient lookup to avoid duplicates
lookup := make(map[Identifier]struct{})
// add all identifiers, omitted duplicates
for _, identifier := range append(il.Copy(), other...) {
if _, exists := lookup[identifier]; exists {
continue
}
union = append(union, identifier)
lookup[identifier] = struct{}{}
}
return union
}
// Sample returns random sample of length 'size' of the ids
func (il IdentifierList) Sample(size uint) (IdentifierList, error) {
return Sample(size, il...)
}
// Filter will apply a filter to the identifier list.
func (il IdentifierList) Filter(filter IdentifierFilter) IdentifierList {
var dup IdentifierList
IDLoop:
for _, identifier := range il {
if !filter(identifier) {
continue IDLoop
}
dup = append(dup, identifier)
}
return dup
}
// Sort returns a sorted _copy_ of the IdentifierList, leaving the original invariant.
func (il IdentifierList) Sort(less IdentifierOrder) IdentifierList {
dup := il.Copy()
slices.SortFunc(dup, less)
return dup
}