Compare commits
2 Commits
mapset/v0.
...
concurrent
| Author | SHA1 | Date | |
|---|---|---|---|
| 2582171d99 | |||
| 3671b9f80a |
5
concurrentsafemapset/go.mod
Normal file
5
concurrentsafemapset/go.mod
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
module git.blauwelle.com/go/crate/concurrentsafemapset
|
||||||
|
|
||||||
|
go 1.20
|
||||||
|
|
||||||
|
require git.blauwelle.com/go/crate/mapset v0.1.0
|
||||||
2
concurrentsafemapset/go.sum
Normal file
2
concurrentsafemapset/go.sum
Normal file
@@ -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=
|
||||||
243
concurrentsafemapset/mapset.go
Normal file
243
concurrentsafemapset/mapset.go
Normal file
@@ -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()
|
||||||
|
}
|
||||||
@@ -131,12 +131,12 @@ func (g *Group) wait(c chan error, cancel context.CancelFunc) (err error) {
|
|||||||
ctx, cancel = context.WithTimeout(context.Background(), g.cfg.stopTimeout)
|
ctx, cancel = context.WithTimeout(context.Background(), g.cfg.stopTimeout)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
}
|
}
|
||||||
for _, m := range g.actors {
|
for i := len(g.actors) - 1; i >= 0; i-- {
|
||||||
if m.stopFunc != nil {
|
if g.actors[i].stopFunc != nil {
|
||||||
if g.cfg.concurrentStop {
|
if g.cfg.concurrentStop {
|
||||||
go m.stopFunc(ctx)
|
go g.actors[i].stopFunc(ctx)
|
||||||
} else {
|
} else {
|
||||||
m.stopFunc(ctx)
|
g.actors[i].stopFunc(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user