github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/model/flow/identifierList.go (about) 1 package flow 2 3 import ( 4 "golang.org/x/exp/slices" 5 ) 6 7 // IdentifierList defines a sortable list of identifiers 8 type IdentifierList []Identifier 9 10 // Len returns length of the IdentifierList in the number of stored identifiers. 11 // It satisfies the sort.Interface making the IdentifierList sortable. 12 func (il IdentifierList) Len() int { 13 return len(il) 14 } 15 16 // Lookup converts the Identifiers to a lookup table. 17 func (il IdentifierList) Lookup() map[Identifier]struct{} { 18 lookup := make(map[Identifier]struct{}, len(il)) 19 for _, id := range il { 20 lookup[id] = struct{}{} 21 } 22 return lookup 23 } 24 25 // Less returns true if element i in the IdentifierList is less than j based on its identifier. 26 // Otherwise it returns true. 27 // It satisfies the sort.Interface making the IdentifierList sortable. 28 func (il IdentifierList) Less(i, j int) bool { 29 return IsIdentifierCanonical(il[i], il[j]) 30 } 31 32 // Swap swaps the element i and j in the IdentifierList. 33 // It satisfies the sort.Interface making the IdentifierList sortable. 34 func (il IdentifierList) Swap(i, j int) { 35 il[j], il[i] = il[i], il[j] 36 } 37 38 func (il IdentifierList) Strings() []string { 39 var list []string 40 for _, id := range il { 41 list = append(list, id.String()) 42 } 43 44 return list 45 } 46 47 // ID returns a cryptographic commitment to the list of identifiers. 48 // Since an IdentifierList has no mutable fields, it is equal to the checksum. 49 func (il IdentifierList) ID() Identifier { 50 return il.Checksum() 51 } 52 53 // Checksum returns a cryptographic commitment to the list of identifiers. 54 func (il IdentifierList) Checksum() Identifier { 55 return MakeID(il) 56 } 57 58 func (il IdentifierList) Copy() IdentifierList { 59 cpy := make(IdentifierList, 0, il.Len()) 60 return append(cpy, il...) 61 } 62 63 // Contains returns whether this identifier list contains the target identifier. 64 func (il IdentifierList) Contains(target Identifier) bool { 65 for _, id := range il { 66 if target == id { 67 return true 68 } 69 } 70 return false 71 } 72 73 // Union returns a new identifier list containing the union of `il` and `other`. 74 // There are no duplicates in the output. 75 func (il IdentifierList) Union(other IdentifierList) IdentifierList { 76 // stores the output, the union of the two lists 77 union := make(IdentifierList, 0, len(il)+len(other)) 78 // efficient lookup to avoid duplicates 79 lookup := make(map[Identifier]struct{}) 80 81 // add all identifiers, omitted duplicates 82 for _, identifier := range append(il.Copy(), other...) { 83 if _, exists := lookup[identifier]; exists { 84 continue 85 } 86 union = append(union, identifier) 87 lookup[identifier] = struct{}{} 88 } 89 90 return union 91 } 92 93 // Sample returns random sample of length 'size' of the ids 94 func (il IdentifierList) Sample(size uint) (IdentifierList, error) { 95 return Sample(size, il...) 96 } 97 98 // Filter will apply a filter to the identifier list. 99 func (il IdentifierList) Filter(filter IdentifierFilter) IdentifierList { 100 var dup IdentifierList 101 IDLoop: 102 for _, identifier := range il { 103 if !filter(identifier) { 104 continue IDLoop 105 } 106 dup = append(dup, identifier) 107 } 108 return dup 109 } 110 111 // Sort returns a sorted _copy_ of the IdentifierList, leaving the original invariant. 112 func (il IdentifierList) Sort(less IdentifierOrder) IdentifierList { 113 dup := il.Copy() 114 slices.SortFunc(dup, less) 115 return dup 116 }