diff --git a/concurrentsafemapset/go.mod b/concurrentsafemapset/go.mod new file mode 100644 index 0000000..e4b2077 --- /dev/null +++ b/concurrentsafemapset/go.mod @@ -0,0 +1,5 @@ +module git.blauwelle.com/go/crate/concurrentsafemapset + +go 1.20 + +require git.blauwelle.com/go/crate/mapset v0.1.0 diff --git a/concurrentsafemapset/go.sum b/concurrentsafemapset/go.sum new file mode 100644 index 0000000..e17ee1d --- /dev/null +++ b/concurrentsafemapset/go.sum @@ -0,0 +1,2 @@ +git.blauwelle.com/go/crate/mapset v0.1.0 h1:ZkiToAFhsRUyKW56BVYibkho1p2oYxZApia9Ct4AY9c= +git.blauwelle.com/go/crate/mapset v0.1.0/go.mod h1:3dV0xm7uslz6n6a2MuExeytiImgb7LwS8vQhlS/j22M= diff --git a/concurrentsafemapset/mapset.go b/concurrentsafemapset/mapset.go new file mode 100644 index 0000000..73e69c8 --- /dev/null +++ b/concurrentsafemapset/mapset.go @@ -0,0 +1,243 @@ +package concurrentsafemapset + +import ( + "sync" + + "git.blauwelle.com/go/crate/mapset" +) + +// New 返回 [MapSet] +func New[T comparable](keys ...T) *MapSet[T] { + return &MapSet[T]{ + s: mapset.New(keys...), + } +} + +// MapSet 并发安全的 [mapset.MapSet] +type MapSet[T comparable] struct { + s mapset.MapSet[T] + lock sync.RWMutex +} + +// Cardinality 返回集合的元素个数 +func (cs *MapSet[T]) Cardinality() int { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.Cardinality() +} + +// AddOne 添加元素到集合 +func (cs *MapSet[T]) AddOne(key T) { + cs.lock.Lock() + cs.s.AddOne(key) + cs.lock.Unlock() +} + +// AddOneOk 添加元素到集合并返回是否添加成功 +func (cs *MapSet[T]) AddOneOk(key T) bool { + cs.lock.Lock() + defer cs.lock.Unlock() + return cs.s.AddOneOk(key) +} + +// AddMany 添加多个元素到集合 +func (cs *MapSet[T]) AddMany(keys ...T) { + cs.lock.Lock() + cs.s.AddMany(keys...) + cs.lock.Unlock() +} + +// AddManyOk 添加多个元素到集合并返回添加成功的个数 +func (cs *MapSet[T]) AddManyOk(keys ...T) int { + cs.lock.Lock() + defer cs.lock.Unlock() + return cs.s.AddManyOk(keys...) +} + +// DeleteOne 从集合中删除元素 +func (cs *MapSet[T]) DeleteOne(key T) { + cs.lock.Lock() + cs.s.DeleteOne(key) + cs.lock.Unlock() +} + +// DeleteOneOk 从集合中删除元素并返回是否删除成功 +func (cs *MapSet[T]) DeleteOneOk(key T) bool { + cs.lock.Lock() + defer cs.lock.Unlock() + return cs.s.DeleteOneOk(key) +} + +// DeleteMany 从集合删除多个元素 +func (cs *MapSet[T]) DeleteMany(keys ...T) { + cs.lock.Lock() + cs.s.DeleteMany(keys...) + cs.lock.Unlock() +} + +// DeleteManyOk 从集合删除多个元素并返回成功删除的个数 +func (cs *MapSet[T]) DeleteManyOk(keys ...T) int { + cs.lock.Lock() + defer cs.lock.Unlock() + return cs.s.DeleteManyOk(keys...) +} + +// PopOne 从集合中删除1个元素, 并把被删除的元素返回 +func (cs *MapSet[T]) PopOne() (T, bool) { + cs.lock.Lock() + defer cs.lock.Unlock() + return cs.s.PopOne() +} + +// Clear 清空集合 +func (cs *MapSet[T]) Clear() { + cs.lock.Lock() + cs.s.Clear() + cs.lock.Unlock() +} + +// Clone 返回集合的浅拷贝 +func (cs *MapSet[T]) Clone() *MapSet[T] { + cs.lock.RLock() + defer cs.lock.RUnlock() + return &MapSet[T]{s: cs.s.Clone()} +} + +// IsEmpty 判断集合是否为空 +func (cs *MapSet[T]) IsEmpty() bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.IsEmpty() +} + +// Equal 判断集合是否和另1个集合相等 +func (cs *MapSet[T]) Equal(co *MapSet[T]) bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return cs.s.Equal(co.s) +} + +// ContainsOne 判断集合是否包含1个元素 +func (cs *MapSet[T]) ContainsOne(key T) bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.ContainsOne(key) +} + +// ContainsAll 判断集合是否包含全部元素 +// 参数为空时返回 true +func (cs *MapSet[T]) ContainsAll(keys ...T) bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.ContainsAll(keys...) +} + +// ContainsAny 判断集合是否包含任意元素 +// 参数为空时返回 false +func (cs *MapSet[T]) ContainsAny(keys ...T) bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.ContainsAny(keys...) +} + +// IsSubsetOf 判断集合是否是另1个集合的子集 +func (cs *MapSet[T]) IsSubsetOf(co *MapSet[T]) bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return cs.s.IsSubsetOf(co.s) +} + +// IsProperSubsetOf 判断集合是否是另1个集合的真子集 +func (cs *MapSet[T]) IsProperSubsetOf(co *MapSet[T]) bool { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return cs.s.IsProperSubsetOf(co.s) +} + +// Union 返回集合和另1个集合的并集 +func (cs *MapSet[T]) Union(co *MapSet[T]) *MapSet[T] { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return &MapSet[T]{s: cs.s.Union(co.s)} +} + +// Intersection 返回集合和另1个集合的交集 +func (cs *MapSet[T]) Intersection(co *MapSet[T]) *MapSet[T] { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return &MapSet[T]{s: cs.s.Intersection(co.s)} +} + +// Difference 返回集合和另1个集合的差集 +func (cs *MapSet[T]) Difference(co *MapSet[T]) *MapSet[T] { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return &MapSet[T]{s: cs.s.Difference(co.s)} +} + +// SymmetricDifference 返回集合和另1个集合相互差集的并集 +func (cs *MapSet[T]) SymmetricDifference(co *MapSet[T]) *MapSet[T] { + cs.lock.RLock() + defer cs.lock.RUnlock() + co.lock.RLock() + defer co.lock.RUnlock() + return &MapSet[T]{s: cs.s.SymmetricDifference(co.s)} +} + +// ToSlice 把集合转换成切片 +func (cs *MapSet[T]) ToSlice() []T { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.ToSlice() +} + +// ToAnySlice 把集合转换成 []any +func (cs *MapSet[T]) ToAnySlice() []any { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.ToAnySlice() +} + +// MarshalJSON 实现 [encoding/json.Marshaler] +func (cs *MapSet[T]) MarshalJSON() ([]byte, error) { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.MarshalJSON() +} + +// UnmarshalJSON 实现 [encoding/json.Unmarshaler] +func (cs *MapSet[T]) UnmarshalJSON(b []byte) error { + cs.lock.Lock() + defer cs.lock.Unlock() + return cs.s.UnmarshalJSON(b) +} + +func (cs *MapSet[T]) String() string { + cs.lock.RLock() + defer cs.lock.RUnlock() + return cs.s.String() +} + +func (cs *MapSet[T]) WithLock(fn func(s mapset.MapSet[T])) { + cs.lock.Lock() + fn(cs.s) + cs.lock.Unlock() +} + +func (cs *MapSet[T]) WithRLock(fn func(s mapset.MapSet[T])) { + cs.lock.RLock() + fn(cs.s) + cs.lock.RUnlock() +}