diff --git a/safety/rwmap.go b/safety/rwmap.go new file mode 100644 index 0000000..4a84153 --- /dev/null +++ b/safety/rwmap.go @@ -0,0 +1,67 @@ +package safety + +import "sync" + +type RWMap[K comparable, V any] struct { + m map[K]V + mux sync.RWMutex +} + +func NewRWMap[K comparable, V any](val ...map[K]V) *RWMap[K, V] { + var m map[K]V + if len(val) < 1 { + m = make(map[K]V) + } else { + m = val[0] + } + return &RWMap[K, V]{m: m, mux: sync.RWMutex{}} +} + +func (v *RWMap[K, V]) Store(key K, val V) { + v.mux.Lock() + defer v.mux.Unlock() + v.m[key] = val +} + +func (v *RWMap[K, V]) Load(key K) (V, bool) { + v.mux.RLock() + defer v.mux.RUnlock() + val, ok := v.m[key] + return val, ok +} + +func (v *RWMap[K, V]) Del(keys ...K) { + v.mux.Lock() + defer v.mux.Unlock() + for _, key := range keys { + delete(v.m, key) + } +} + +func (v *RWMap[K, V]) Raw() map[K]V { + v.mux.RLock() + defer v.mux.RUnlock() + return v.m +} + +func (v *RWMap[K, V]) Len() int { + v.mux.RLock() + defer v.mux.RUnlock() + return len(v.m) +} + +func (v *RWMap[K, V]) Range(fn func(K, V) bool) { + v.mux.RLock() + defer v.mux.RUnlock() + for key, val := range v.m { + if !fn(key, val) { + break + } + } +} + +func (v *RWMap[K, V]) Set(m map[K]V) { + v.mux.Lock() + defer v.mux.Unlock() + v.m = m +} diff --git a/safety/slice.go b/safety/slice.go index 6be8ee0..84b5a41 100644 --- a/safety/slice.go +++ b/safety/slice.go @@ -17,7 +17,23 @@ func NewSlice[T any](a []T) *Slice[T] { func (r *Slice[T]) Append(t ...T) { r.mu.Lock() defer r.mu.Unlock() - ts := append(r.Load(), t...) + ts := append(r.Var.Load(), t...) r.Store(ts) - +} + +func (r *Slice[T]) Set(index int, val T) { + v := r.Var.Load() + if index >= len(v) { + return + } + r.mu.Lock() + defer r.mu.Unlock() + v[index] = val +} + +func (r *Slice[T]) Load() (a []T) { + v := r.Var.Load() + a = make([]T, len(v)) + copy(a, v) + return }