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  }