v0.0.597 add update methods to SyncMap
All checks were successful
Build Docker and Deploy / Run goext test-suite (push) Successful in 3m47s

This commit is contained in:
2025-09-04 14:25:06 +02:00
parent 68b06158b3
commit 38467cb4e7
4 changed files with 60 additions and 3 deletions

View File

@@ -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()