github.com/nutsdb/nutsdb@v1.0.4/set.go (about) 1 // Copyright 2023 The nutsdb Author. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package nutsdb 16 17 import ( 18 "errors" 19 "hash/fnv" 20 ) 21 22 var ( 23 // ErrSetNotExist is returned when the key does not exist. 24 ErrSetNotExist = errors.New("set not exist") 25 26 // ErrSetMemberNotExist is returned when the member of set does not exist 27 ErrSetMemberNotExist = errors.New("set member not exist") 28 29 // ErrMemberEmpty is returned when the item received is nil 30 ErrMemberEmpty = errors.New("item empty") 31 ) 32 33 var fnvHash = fnv.New32a() 34 35 type Set struct { 36 M map[string]map[uint32]*Record 37 } 38 39 func NewSet() *Set { 40 return &Set{ 41 M: map[string]map[uint32]*Record{}, 42 } 43 } 44 45 // SAdd adds the specified members to the set stored at key. 46 func (s *Set) SAdd(key string, values [][]byte, records []*Record) error { 47 set, ok := s.M[key] 48 if !ok { 49 s.M[key] = map[uint32]*Record{} 50 set = s.M[key] 51 } 52 53 for i, value := range values { 54 hash, err := getFnv32(value) 55 if err != nil { 56 return err 57 } 58 set[hash] = records[i] 59 } 60 61 return nil 62 } 63 64 // SRem removes the specified members from the set stored at key. 65 func (s *Set) SRem(key string, values ...[]byte) error { 66 set, ok := s.M[key] 67 if !ok { 68 return ErrSetNotExist 69 } 70 71 if len(values) == 0 || values[0] == nil { 72 return ErrMemberEmpty 73 } 74 75 for _, value := range values { 76 hash, err := getFnv32(value) 77 if err != nil { 78 return err 79 } 80 delete(set, hash) 81 } 82 83 return nil 84 } 85 86 // SHasKey returns whether it has the set at given key. 87 func (s *Set) SHasKey(key string) bool { 88 if _, ok := s.M[key]; ok { 89 return true 90 } 91 return false 92 } 93 94 // SPop removes and returns one or more random elements from the set value store at key. 95 func (s *Set) SPop(key string) *Record { 96 if !s.SHasKey(key) { 97 return nil 98 } 99 100 for hash, record := range s.M[key] { 101 delete(s.M[key], hash) 102 return record 103 } 104 105 return nil 106 } 107 108 // SCard Returns the set cardinality (number of elements) of the set stored at key. 109 func (s *Set) SCard(key string) int { 110 if !s.SHasKey(key) { 111 return 0 112 } 113 114 return len(s.M[key]) 115 } 116 117 // SDiff Returns the members of the set resulting from the difference between the first set and all the successive sets. 118 func (s *Set) SDiff(key1, key2 string) ([]*Record, error) { 119 if !s.SHasKey(key1) || !s.SHasKey(key2) { 120 return nil, ErrSetNotExist 121 } 122 123 records := make([]*Record, 0) 124 125 for hash, record := range s.M[key1] { 126 if _, ok := s.M[key2][hash]; !ok { 127 records = append(records, record) 128 } 129 } 130 return records, nil 131 } 132 133 // SInter Returns the members of the set resulting from the intersection of all the given sets. 134 func (s *Set) SInter(key1, key2 string) ([]*Record, error) { 135 if !s.SHasKey(key1) || !s.SHasKey(key2) { 136 return nil, ErrSetNotExist 137 } 138 139 records := make([]*Record, 0) 140 141 for hash, record := range s.M[key1] { 142 if _, ok := s.M[key2][hash]; ok { 143 records = append(records, record) 144 } 145 } 146 return records, nil 147 } 148 149 // SIsMember Returns if member is a member of the set stored at key. 150 func (s *Set) SIsMember(key string, value []byte) (bool, error) { 151 if _, ok := s.M[key]; !ok { 152 return false, ErrSetNotExist 153 } 154 155 hash, err := getFnv32(value) 156 if err != nil { 157 return false, err 158 } 159 160 if _, ok := s.M[key][hash]; ok { 161 return true, nil 162 } 163 164 return false, nil 165 } 166 167 // SAreMembers Returns if members are members of the set stored at key. 168 // For multiple items it returns true only if all the items exist. 169 func (s *Set) SAreMembers(key string, values ...[]byte) (bool, error) { 170 if _, ok := s.M[key]; !ok { 171 return false, ErrSetNotExist 172 } 173 174 for _, value := range values { 175 176 hash, err := getFnv32(value) 177 if err != nil { 178 return false, err 179 } 180 181 if _, ok := s.M[key][hash]; !ok { 182 return false, nil 183 } 184 } 185 186 return true, nil 187 } 188 189 // SMembers returns all the members of the set value stored at key. 190 func (s *Set) SMembers(key string) ([]*Record, error) { 191 if _, ok := s.M[key]; !ok { 192 return nil, ErrSetNotExist 193 } 194 195 records := make([]*Record, 0) 196 197 for _, record := range s.M[key] { 198 records = append(records, record) 199 } 200 201 return records, nil 202 } 203 204 // SMove moves member from the set at source to the set at destination. 205 func (s *Set) SMove(key1, key2 string, value []byte) (bool, error) { 206 if !s.SHasKey(key1) || !s.SHasKey(key2) { 207 return false, ErrSetNotExist 208 } 209 210 set1, set2 := s.M[key1], s.M[key2] 211 212 hash, err := getFnv32(value) 213 if err != nil { 214 return false, err 215 } 216 217 var ( 218 member *Record 219 ok bool 220 ) 221 222 if member, ok = set1[hash]; !ok { 223 return false, ErrSetMemberNotExist 224 } 225 226 if _, ok = set2[hash]; !ok { 227 err = s.SAdd(key2, [][]byte{value}, []*Record{member}) 228 if err != nil { 229 return false, err 230 } 231 } 232 233 err = s.SRem(key1, value) 234 if err != nil { 235 return false, err 236 } 237 238 return true, nil 239 } 240 241 // SUnion returns the members of the set resulting from the union of all the given sets. 242 func (s *Set) SUnion(key1, key2 string) ([]*Record, error) { 243 if !s.SHasKey(key1) || !s.SHasKey(key2) { 244 return nil, ErrSetNotExist 245 } 246 247 records, err := s.SMembers(key1) 248 249 if err != nil { 250 return nil, err 251 } 252 253 for hash, record := range s.M[key2] { 254 if _, ok := s.M[key1][hash]; !ok { 255 records = append(records, record) 256 } 257 } 258 259 return records, nil 260 }