Files
phishingclub/backend/vendor/github.com/enetx/g/map_safe.go
T
Ronni Skansing 07c8adaf76 update vendor deps
Signed-off-by: Ronni Skansing <rskansing@gmail.com>
2025-11-06 23:31:08 +01:00

219 lines
4.6 KiB
Go

package g
import (
"fmt"
"github.com/enetx/g/f"
)
// NewMapSafe creates a new instance of MapSafe.
func NewMapSafe[K comparable, V any]() *MapSafe[K, V] { return &MapSafe[K, V]{} }
// Iter provides a thread-safe iterator over the MapSafe's key-value pairs.
func (ms *MapSafe[K, V]) Iter() SeqMap[K, V] {
return func(yield func(K, V) bool) {
ms.data.Range(func(key, value any) bool {
return yield(key.(K), *(value.(*V)))
})
}
}
// Entry returns a MapSafeEntry for a given key, allowing for more complex atomic operations.
func (ms *MapSafe[K, V]) Entry(key K) MapSafeEntry[K, V] {
return MapSafeEntry[K, V]{m: ms, key: key}
}
// Keys returns a slice of the MapSafe's keys.
func (ms *MapSafe[K, V]) Keys() Slice[K] {
var keys Slice[K]
ms.data.Range(func(key, _ any) bool {
keys = append(keys, key.(K))
return true
})
return keys
}
// Values returns a slice of the MapSafe's values.
func (ms *MapSafe[K, V]) Values() Slice[V] {
var values Slice[V]
ms.data.Range(func(_, value any) bool {
values = append(values, *(value.(*V)))
return true
})
return values
}
// Invert inverts keys and values. The new map will also follow the pointer-storage rule.
func (ms *MapSafe[K, V]) Invert() *MapSafe[any, K] {
res := NewMapSafe[any, K]()
ms.data.Range(func(key, value any) bool {
k := key.(K)
res.data.Store(*(value.(*V)), &k)
return true
})
return res
}
// Contains checks if the MapSafe contains the specified key.
func (ms *MapSafe[K, V]) Contains(key K) bool {
_, ok := ms.data.Load(key)
return ok
}
// Clone creates a deep copy of the MapSafe.
func (ms *MapSafe[K, V]) Clone() *MapSafe[K, V] {
res := NewMapSafe[K, V]()
ms.data.Range(func(key, value any) bool {
v := *(value.(*V))
res.data.Store(key, &v)
return true
})
return res
}
// Copy performs a deep copy of the source MapSafe's pairs into the current map.
func (ms *MapSafe[K, V]) Copy(src *MapSafe[K, V]) {
src.data.Range(func(key, value any) bool {
v := *(value.(*V))
ms.data.Store(key, &v)
return true
})
}
// Delete removes the specified keys from the MapSafe.
func (ms *MapSafe[K, V]) Delete(keys ...K) {
for _, k := range keys {
ms.data.Delete(k)
}
}
// Eq checks if two MapSafes are equal by deep-comparing their values.
func (ms *MapSafe[K, V]) Eq(other *MapSafe[K, V]) bool {
n := ms.Len()
if n != other.Len() {
return false
}
if n == 0 {
return true
}
var zero V
comparable := f.IsComparable(zero)
equal := true
ms.data.Range(func(key, value any) bool {
ovalue, ok := other.data.Load(key)
if !ok {
equal = false
return false
}
v1 := *(value.(*V))
v2 := *(ovalue.(*V))
if comparable && !f.Eq[any](v1)(v2) || !comparable && !f.Eqd(v1)(v2) {
equal = false
return false
}
return true
})
return equal
}
// Get retrieves the value associated with the given key.
func (ms *MapSafe[K, V]) Get(key K) Option[V] {
if value, ok := ms.data.Load(key); ok {
return Some(*(value.(*V)))
}
return None[V]()
}
// Set stores the value for the given key, returning the previous value if it existed.
func (ms *MapSafe[K, V]) Set(key K, value V) Option[V] {
if previous, loaded := ms.data.Swap(key, &value); loaded {
return Some(*(previous.(*V)))
}
return None[V]()
}
// Len returns the number of key-value pairs in the MapSafe.
func (ms *MapSafe[K, V]) Len() int {
count := 0
ms.data.Range(func(_, _ any) bool {
count++
return true
})
return count
}
// Ne checks if two MapSafes are not equal.
func (ms *MapSafe[K, V]) Ne(other *MapSafe[K, V]) bool { return !ms.Eq(other) }
// NotEmpty checks if the MapSafe is not empty.
func (ms *MapSafe[K, V]) NotEmpty() bool { return !ms.Empty() }
// Clear removes all key-value pairs from the MapSafe.
func (ms *MapSafe[K, V]) Clear() { ms.data.Clear() }
// Empty checks if the MapSafe is empty.
func (ms *MapSafe[K, V]) Empty() bool {
empty := true
ms.data.Range(func(_, _ any) bool {
empty = false
return false
})
return empty
}
// String returns a string representation of the MapSafe.
func (ms *MapSafe[K, V]) String() string {
var b Builder
b.WriteString("MapSafe{")
first := true
ms.data.Range(func(key, value any) bool {
if !first {
b.WriteString(", ")
}
first = false
if vptr, ok := value.(*V); ok && vptr != nil {
b.WriteString(Format("{}:{}", key, *vptr))
} else {
b.WriteString(Format("{}:<invalid>", key))
}
return true
})
b.WriteString("}")
return b.String().Std()
}
// Print writes the MapSafe to standard output.
func (ms *MapSafe[K, V]) Print() *MapSafe[K, V] { fmt.Print(ms); return ms }
// Println writes the MapSafe to standard output with a newline.
func (ms *MapSafe[K, V]) Println() *MapSafe[K, V] { fmt.Println(ms); return ms }