github.com/insolar/vanilla@v0.0.0-20201023172447-248fdf805322/keyset/keyset.go (about) 1 // Copyright 2020 Insolar Network Ltd. 2 // All rights reserved. 3 // This material is licensed under the Insolar License version 1.0, 4 // available at https://github.com/insolar/assured-ledger/blob/master/LICENSE.md. 5 6 package keyset 7 8 import "github.com/insolar/vanilla/longbits" 9 10 type Key = longbits.ByteString 11 12 // A basic set of keys, that can be wrapped by an extra keyset logic. 13 type KeyList interface { 14 // returns true when the given key is within the set 15 Contains(Key) bool 16 // lists keys 17 EnumKeys(func(k Key) bool) bool 18 // number of unique keys 19 Count() int 20 } 21 22 // An advanced set of keys, that also represent an open set (tracks exclusions, not inclusions) 23 // 24 // NB! An immutable inclusive/closed set MUST be able to cast to KeyList & InclusiveKeySet. 25 // An open or a mutable KeySet MUST NOT be able to cast to KeyList & InclusiveKeySet. 26 // This behavior is supported by this package. 27 // 28 type KeySet interface { 29 // returns true when this set is empty 30 IsNothing() bool 31 // returns true when this set matches everything 32 IsEverything() bool 33 // returns true when the set is open / unbound and only Contains exclusions 34 IsOpenSet() bool 35 // returns true when the given key is within the set 36 Contains(Key) bool 37 // returns true when any key of the given set is within this set 38 ContainsAny(KeySet) bool 39 40 // returns true when this set Contains all keys from the given one 41 SupersetOf(KeySet) bool 42 // returns true when all keys of this set are contained in the given one 43 SubsetOf(KeySet) bool 44 // returns true when both sets have same set of keys 45 Equal(KeySet) bool 46 // a faster equivalent of Equal(ks.Inverse()) 47 EqualInverse(KeySet) bool 48 49 // returns a set that has all keys but this set 50 Inverse() KeySet 51 // returns a set of keys present in at least one sets 52 Union(KeySet) KeySet 53 // returns a set of keys present in both sets 54 Intersect(KeySet) KeySet 55 // returns a set of keys present in this set and not present in the given set 56 Subtract(KeySet) KeySet 57 58 // WARNING! Do not use 59 // lists keys (when IsOpenSet() == true, as then it lists _excluded_ keys) 60 EnumRawKeys(func(k Key, exclusive bool) bool) bool 61 // WARNING! Do not use. This must NOT be treated as a size of a set. 62 // number of keys (when IsOpenSet() == true, as then it gives a number of _excluded_ keys) 63 RawKeyCount() int 64 } 65 66 type InclusiveKeySet interface { 67 KeySet 68 // lists keys 69 EnumKeys(func(k Key) bool) bool 70 // number of unique keys 71 Count() int 72 } 73 74 func New(keys []Key) KeySet { 75 n := len(keys) 76 switch n { 77 case 0: 78 return Nothing() 79 case 1: 80 return SoloKeySet(keys[0]) 81 } 82 83 ks := make(basicKeySet, n) 84 for _, k := range keys { 85 ks.add(k) 86 } 87 return inclusiveKeySet{ks} 88 } 89 90 func Wrap(keys KeyList) KeySet { 91 if keys == nil { 92 panic("illegal state") 93 } 94 return inclusiveKeySet{listSet{keys}} 95 } 96 97 func CopyList(keys KeyList) KeySet { 98 n := keys.Count() 99 if n == 0 { 100 return Nothing() 101 } 102 return inclusiveKeySet{listSet{keys}.copy(0)} 103 } 104 105 func CopySet(keys KeySet) KeySet { 106 if iks, ok := keys.(internalKeySet); ok { 107 return newKeySet(keys.IsOpenSet(), iks.copy(0)) 108 } 109 110 switch n := keys.RawKeyCount(); { 111 case n > 0: 112 ks := make(basicKeySet, n) 113 keys.EnumRawKeys(func(k Key, _ bool) bool { 114 ks.add(k) 115 return false 116 }) 117 return newKeySet(keys.IsOpenSet(), ks) 118 case n != 0: 119 panic("illegal state") 120 case keys.IsOpenSet(): 121 return Everything() 122 default: 123 return Nothing() 124 } 125 } 126 127 func newKeySet(exclusive bool, ks internalKeySet) KeySet { 128 switch { 129 case ks == nil: 130 panic("illegal value") 131 case exclusive: 132 return exclusiveKeySet{ks} 133 default: 134 return inclusiveKeySet{ks} 135 } 136 }