mirror of
https://github.com/phishingclub/phishingclub.git
synced 2026-08-05 02:08:38 +02:00
77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package g
|
|
|
|
import "github.com/enetx/g/ref"
|
|
|
|
// Get returns Some(value) if the key exists, otherwise None.
|
|
func (e MapSafeEntry[K, V]) Get() Option[V] {
|
|
return e.m.Get(e.key)
|
|
}
|
|
|
|
// Set unconditionally sets the value for the key.
|
|
// Returns Some(old_value) if the key was already present, otherwise None.
|
|
func (e MapSafeEntry[K, V]) Set(value V) Option[V] {
|
|
return e.m.Set(e.key, value)
|
|
}
|
|
|
|
// Delete atomically retrieves and removes the value for the key from the map.
|
|
// Returns Some(value) if it existed, otherwise None.
|
|
func (e MapSafeEntry[K, V]) Delete() Option[V] {
|
|
if value, loaded := e.m.data.LoadAndDelete(e.key); loaded {
|
|
return Some(*(value.(*V)))
|
|
}
|
|
|
|
return None[V]()
|
|
}
|
|
|
|
// OrSet inserts `value` if the key is vacant.
|
|
// Returns the value that is in the map after the operation (either the old or the new one).
|
|
func (e MapSafeEntry[K, V]) OrSet(value V) Option[V] {
|
|
actual, loaded := e.m.data.LoadOrStore(e.key, &value)
|
|
if loaded {
|
|
return Some(*(actual.(*V)))
|
|
}
|
|
|
|
return None[V]()
|
|
}
|
|
|
|
// OrSetBy inserts the value produced by `fn` if the key is vacant. `fn` is only called if needed.
|
|
// Returns the value that is in the map after the operation.
|
|
func (e MapSafeEntry[K, V]) OrSetBy(fn func() V) Option[V] {
|
|
if actual, loaded := e.m.data.Load(e.key); loaded {
|
|
return Some(*(actual.(*V)))
|
|
}
|
|
|
|
if actual, loaded := e.m.data.LoadOrStore(e.key, ref.Of(fn())); loaded {
|
|
return Some(*(actual.(*V)))
|
|
}
|
|
|
|
return None[V]()
|
|
}
|
|
|
|
// OrDefault inserts V's zero value if the key is vacant.
|
|
// Returns the value that is in the map after the operation.
|
|
func (e MapSafeEntry[K, V]) OrDefault() Option[V] {
|
|
var zero V
|
|
return e.OrSet(zero)
|
|
}
|
|
|
|
// Transform atomically applies `fn` to the existing value if present.
|
|
// The function `fn` takes the old value and returns the new value.
|
|
// This operation is implemented using a lock-free Compare-And-Swap (CAS) loop.
|
|
// Returns Some(updated_value) if successful, or None if the key was missing.
|
|
func (e MapSafeEntry[K, V]) Transform(fn func(V) V) Option[V] {
|
|
for {
|
|
avalue, ok := e.m.data.Load(e.key)
|
|
if !ok {
|
|
return None[V]()
|
|
}
|
|
|
|
ovalue := avalue.(*V)
|
|
nvalue := fn(*ovalue)
|
|
|
|
if e.m.data.CompareAndSwap(e.key, ovalue, &nvalue) {
|
|
return Some(nvalue)
|
|
}
|
|
}
|
|
}
|