github.com/sandwich-go/boost@v1.3.29/xcontainer/syncmap/any.go (about) 1 package syncmap 2 3 import ( 4 "sort" 5 "sync" 6 ) 7 8 type mapKey interface { 9 int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | uintptr | float32 | float64 | complex64 | complex128 | string 10 } 11 12 // SyncMap 定义并发安全的映射,使用 sync.Map 来实现 13 type SyncMap[K mapKey, V any] struct { 14 sm sync.Map 15 locker sync.RWMutex 16 } 17 18 // New 构造函数,返回一个新的 SyncMap 19 func New[K mapKey, V any]() *SyncMap[K, V] { 20 return &SyncMap[K, V]{} 21 } 22 23 // Keys 获取映射中的所有键,返回一个 Key 类型的切片 24 func (s *SyncMap[K, V]) Keys() (ret []K) { 25 s.sm.Range(func(key, value interface{}) bool { 26 ret = append(ret, key.(K)) 27 return true 28 }) 29 return ret 30 } 31 32 // Len 获取映射中键值对的数量 33 func (s *SyncMap[K, V]) Len() (c int) { 34 s.sm.Range(func(key, value interface{}) bool { 35 c++ 36 return true 37 }) 38 return c 39 } 40 41 // Contains 检查映射中是否包含指定键 42 func (s *SyncMap[K, V]) Contains(key K) (ok bool) { 43 _, ok = s.Load(key) 44 return 45 } 46 47 // Get 获取映射中的值 48 func (s *SyncMap[K, V]) Get(key K) (value V) { 49 value, _ = s.Load(key) 50 return 51 } 52 53 // Load 获取映射中的值和是否成功加载的标志 54 func (s *SyncMap[K, V]) Load(key K) (value V, loaded bool) { 55 if v, ok := s.sm.Load(key); ok { 56 return v.(V), true 57 } 58 return 59 } 60 61 // DeleteMultiple 删除映射中的多个键 62 func (s *SyncMap[K, V]) DeleteMultiple(keys ...K) { 63 for _, k := range keys { 64 s.sm.Delete(k) 65 } 66 } 67 68 // Clear 清空映射 69 func (s *SyncMap[K, V]) Clear() { 70 s.sm.Range(func(key, value interface{}) bool { 71 s.sm.Delete(key) 72 return true 73 }) 74 } 75 76 // Delete 删除映射中的值 77 func (s *SyncMap[K, V]) Delete(key K) { s.sm.Delete(key) } 78 79 // Store 往映射中存储一个键值对 80 func (s *SyncMap[K, V]) Store(key K, val V) { s.sm.Store(key, val) } 81 82 // LoadAndDelete 获取映射中的值,并将其从映射中删除 83 func (s *SyncMap[K, V]) LoadAndDelete(key K) (value V, loaded bool) { 84 if v, ok := s.sm.LoadAndDelete(key); ok { 85 return v.(V), true 86 } 87 return 88 } 89 90 // GetOrSetFuncErrorLock 函数根据key查找值,如果key存在则返回对应的值,否则用cf函数计算得到一个新的值,存储到 SyncMap 中并返回。 91 // 如果执行cf函数时出错,则返回error。 92 // 函数内部使用读写锁实现并发安全 93 func (s *SyncMap[K, V]) GetOrSetFuncErrorLock(key K, cf func(key K) (V, error)) (value V, loaded bool, err error) { 94 return s.LoadOrStoreFuncErrorLock(key, cf) 95 } 96 97 // LoadOrStoreFuncErrorLock 函数根据key查找值,如果key存在则返回对应的值,否则用cf函数计算得到一个新的值,存储到 SyncMap 中并返回。 98 // 如果执行cf函数时出错,则返回error。 99 // 函数内部使用读写锁实现并发安全 100 func (s *SyncMap[K, V]) LoadOrStoreFuncErrorLock(key K, cf func(key K) (V, error)) (value V, loaded bool, err error) { 101 if v, ok := s.Load(key); ok { 102 return v, true, nil 103 } 104 // 如果不存在,则加写锁,再次查找,如果获取到则直接返回 105 s.locker.Lock() 106 defer s.locker.Unlock() 107 // 再次重试,如果获取到则直接返回 108 if v, ok := s.Load(key); ok { 109 return v, true, nil 110 } 111 // 如果还是不存在,则执行cf函数计算出value,并存储到 SyncMap 中 112 value, err = cf(key) 113 if err != nil { 114 return value, false, err 115 } 116 s.Store(key, value) 117 return value, false, nil 118 } 119 120 // GetOrSetFuncLock 根据key获取对应的value,若不存在则通过cf回调创建value并存储 121 func (s *SyncMap[K, V]) GetOrSetFuncLock(key K, cf func(key K) V) (value V, loaded bool) { 122 return s.LoadOrStoreFuncLock(key, cf) 123 } 124 125 // LoadOrStoreFuncLock 根据key获取对应的value,若不存在则通过cf回调创建value并存储 126 func (s *SyncMap[K, V]) LoadOrStoreFuncLock(key K, cf func(key K) V) (value V, loaded bool) { 127 value, loaded, _ = s.LoadOrStoreFuncErrorLock(key, func(key K) (V, error) { 128 return cf(key), nil 129 }) 130 return value, loaded 131 } 132 133 // LoadOrStore 存储一个 key-value 对,若key已存在则返回已存在的value 134 func (s *SyncMap[K, V]) LoadOrStore(key K, val V) (V, bool) { 135 actual, ok := s.sm.LoadOrStore(key, val) 136 return actual.(V), ok 137 } 138 139 // Range 遍历映射中的 key-value 对,对每个 key-value 对执行给定的函数f 140 func (s *SyncMap[K, V]) Range(f func(key K, value V) bool) { 141 s.sm.Range(func(k, v interface{}) bool { 142 return f(k.(K), v.(V)) 143 }) 144 } 145 146 // RangeDeterministic 按照 key 的顺序遍历映射中的 key-value 对,对每个 key-value 对执行给定的函数 f, f返回false则中断退出 147 // 参数 sortableGetter 接收一个 mapKey 切片并返回一个可排序接口,用于对key进行排序 148 func (s *SyncMap[K, V]) RangeDeterministic(f func(key K, value V) bool, sortableGetter func([]K) sort.Interface) { 149 var keys []K 150 s.sm.Range(func(key, value interface{}) bool { 151 keys = append(keys, key.(K)) 152 return true 153 }) 154 sort.Sort(sortableGetter(keys)) 155 for _, k := range keys { 156 if v, ok := s.Load(k); ok { 157 if !f(k, v) { 158 break 159 } 160 } 161 } 162 }