add set data structure

This commit is contained in:
hdt3213
2019-08-18 01:11:29 +08:00
committed by wyb
parent 5e6e894c29
commit 900e92bb49
6 changed files with 764 additions and 0 deletions

122
src/datastruct/set/set.go Normal file
View File

@@ -0,0 +1,122 @@
package set
import "github.com/HDT3213/godis/src/datastruct/dict"
type Set struct {
dict *dict.Dict
}
func Make(shardCountHint int)*Set {
return &Set{
dict: dict.Make(shardCountHint),
}
}
func MakeFromVals(members ...string)*Set {
set := &Set{
dict: dict.Make(len(members)),
}
for _, member := range members {
set.Add(member)
}
return set
}
func (set *Set)Add(val string)int {
return set.dict.Put(val, true)
}
func (set *Set)Remove(val string)int {
return set.dict.Remove(val)
}
func (set *Set)Has(val string)bool {
_, exists := set.dict.Get(val)
return exists
}
func (set *Set)Len()int {
return set.dict.Len()
}
func (set *Set)ToSlice()[]string {
slice := make([]string, set.Len())
i := 0
set.dict.ForEach(func(key string, val interface{})bool {
if i < len(slice) {
slice[i] = key
} else {
// set extended during traversal
slice = append(slice, key)
}
i++
return true
})
return slice
}
func (set *Set)ForEach(consumer func(member string)bool) {
set.dict.ForEach(func(key string, val interface{})bool {
return consumer(key)
})
}
func (set *Set)Intersect(another *Set)*Set {
if set == nil {
panic("set is nil")
}
setSize := set.Len()
anotherSize := another.Len()
size := setSize
if anotherSize < setSize {
size = anotherSize
}
result := Make(size)
another.ForEach(func(member string)bool {
if set.Has(member) {
result.Add(member)
}
return true
})
return result
}
func (set *Set)Union(another *Set)*Set {
if set == nil {
panic("set is nil")
}
result := Make(set.Len() + another.Len())
another.ForEach(func(member string)bool {
result.Add(member)
return true
})
set.ForEach(func(member string)bool {
result.Add(member)
return true
})
return result
}
func (set *Set)Diff(another *Set)*Set {
if set == nil {
panic("set is nil")
}
result := Make(set.Len())
set.ForEach(func(member string)bool {
if !another.Has(member) {
result.Add(member)
}
return true
})
return result
}
func (set *Set)RandomMembers(limit int)[]string {
return set.dict.RandomKeys(limit)
}
func (set *Set)RandomDistinctMembers(limit int)[]string {
return set.dict.RandomDistinctKeys(limit)
}