v0.0.597 add update methods to SyncMap
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m47s
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m47s
This commit is contained in:
@@ -2,6 +2,8 @@ package dataext
|
||||
|
||||
import "sync"
|
||||
|
||||
// SyncMap is a thread-safe map implementation for generic key-value pairs.
|
||||
// All functions aresafe to be called in parallel.
|
||||
type SyncMap[TKey comparable, TData any] struct {
|
||||
data map[TKey]TData
|
||||
lock sync.Mutex
|
||||
@@ -11,6 +13,7 @@ func NewSyncMap[TKey comparable, TData any]() *SyncMap[TKey, TData] {
|
||||
return &SyncMap[TKey, TData]{data: make(map[TKey]TData), lock: sync.Mutex{}}
|
||||
}
|
||||
|
||||
// Set sets the value for the provided key
|
||||
func (s *SyncMap[TKey, TData]) Set(key TKey, data TData) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -22,6 +25,7 @@ func (s *SyncMap[TKey, TData]) Set(key TKey, data TData) {
|
||||
s.data[key] = data
|
||||
}
|
||||
|
||||
// SetIfNotContains sets the value for the provided key if it does not already exist
|
||||
func (s *SyncMap[TKey, TData]) SetIfNotContains(key TKey, data TData) bool {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -39,6 +43,7 @@ func (s *SyncMap[TKey, TData]) SetIfNotContains(key TKey, data TData) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// SetIfNotContainsFunc sets the value for the provided key using the provided function
|
||||
func (s *SyncMap[TKey, TData]) SetIfNotContainsFunc(key TKey, data func() TData) bool {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -56,6 +61,7 @@ func (s *SyncMap[TKey, TData]) SetIfNotContainsFunc(key TKey, data func() TData)
|
||||
return true
|
||||
}
|
||||
|
||||
// Get retrieves the value for the provided key
|
||||
func (s *SyncMap[TKey, TData]) Get(key TKey) (TData, bool) {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -71,6 +77,8 @@ func (s *SyncMap[TKey, TData]) Get(key TKey) (TData, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
// GetAndSetIfNotContains returns the existing value if the key exists.
|
||||
// Otherwise, it sets the provided value and returns it.
|
||||
func (s *SyncMap[TKey, TData]) GetAndSetIfNotContains(key TKey, data TData) TData {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -87,6 +95,8 @@ func (s *SyncMap[TKey, TData]) GetAndSetIfNotContains(key TKey, data TData) TDat
|
||||
}
|
||||
}
|
||||
|
||||
// GetAndSetIfNotContainsFunc returns the existing value if the key exists.
|
||||
// Otherwise, it calls the provided function to generate the value, sets it, and returns it.
|
||||
func (s *SyncMap[TKey, TData]) GetAndSetIfNotContainsFunc(key TKey, data func() TData) TData {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -104,6 +114,7 @@ func (s *SyncMap[TKey, TData]) GetAndSetIfNotContainsFunc(key TKey, data func()
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removes the entry with the provided key and returns true if the key existed before.
|
||||
func (s *SyncMap[TKey, TData]) Delete(key TKey) bool {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -119,6 +130,7 @@ func (s *SyncMap[TKey, TData]) Delete(key TKey) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// DeleteIf deletes all entries that match the provided function and returns the number of removed entries.
|
||||
func (s *SyncMap[TKey, TData]) DeleteIf(fn func(key TKey, data TData) bool) int {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -138,6 +150,42 @@ func (s *SyncMap[TKey, TData]) DeleteIf(fn func(key TKey, data TData) bool) int
|
||||
return rm
|
||||
}
|
||||
|
||||
// UpdateIfExists updates the value if the key exists, otherwise it does nothing.
|
||||
func (s *SyncMap[TKey, TData]) UpdateIfExists(key TKey, fn func(data TData) TData) bool {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.data == nil {
|
||||
s.data = make(map[TKey]TData)
|
||||
}
|
||||
|
||||
if v, ok := s.data[key]; ok {
|
||||
s.data[key] = fn(v)
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateOrInsert updates the value if the key exists, otherwise it inserts the provided `insertValue`.
|
||||
func (s *SyncMap[TKey, TData]) UpdateOrInsert(key TKey, fn func(data TData) TData, insertValue TData) bool {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
||||
if s.data == nil {
|
||||
s.data = make(map[TKey]TData)
|
||||
}
|
||||
|
||||
if v, ok := s.data[key]; ok {
|
||||
s.data[key] = fn(v)
|
||||
return true
|
||||
} else {
|
||||
s.data[key] = insertValue
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Clear removes all entries from the map.
|
||||
func (s *SyncMap[TKey, TData]) Clear() {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -145,6 +193,7 @@ func (s *SyncMap[TKey, TData]) Clear() {
|
||||
s.data = make(map[TKey]TData)
|
||||
}
|
||||
|
||||
// Contains checks if the map contains the provided key.
|
||||
func (s *SyncMap[TKey, TData]) Contains(key TKey) bool {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -158,6 +207,7 @@ func (s *SyncMap[TKey, TData]) Contains(key TKey) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
// GetAllKeys returns a copy (!) of all keys in the map.
|
||||
func (s *SyncMap[TKey, TData]) GetAllKeys() []TKey {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -175,6 +225,7 @@ func (s *SyncMap[TKey, TData]) GetAllKeys() []TKey {
|
||||
return r
|
||||
}
|
||||
|
||||
// GetAllValues returns a copy (!) of all values in the map.
|
||||
func (s *SyncMap[TKey, TData]) GetAllValues() []TData {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
@@ -192,6 +243,7 @@ func (s *SyncMap[TKey, TData]) GetAllValues() []TData {
|
||||
return r
|
||||
}
|
||||
|
||||
// Count returns the number of entries in the map.
|
||||
func (s *SyncMap[TKey, TData]) Count() int {
|
||||
s.lock.Lock()
|
||||
defer s.lock.Unlock()
|
||||
|
Reference in New Issue
Block a user