summaryrefslogtreecommitdiffstats
path: root/vendor/maunium.net/go/mautrix/util/syncmap.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/maunium.net/go/mautrix/util/syncmap.go')
-rw-r--r--vendor/maunium.net/go/mautrix/util/syncmap.go94
1 files changed, 94 insertions, 0 deletions
diff --git a/vendor/maunium.net/go/mautrix/util/syncmap.go b/vendor/maunium.net/go/mautrix/util/syncmap.go
new file mode 100644
index 00000000..a6b20d3b
--- /dev/null
+++ b/vendor/maunium.net/go/mautrix/util/syncmap.go
@@ -0,0 +1,94 @@
+// Copyright (c) 2023 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+package util
+
+import "sync"
+
+// SyncMap is a simple map with a built-in mutex.
+type SyncMap[Key comparable, Value any] struct {
+ data map[Key]Value
+ lock sync.RWMutex
+}
+
+func NewSyncMap[Key comparable, Value any]() *SyncMap[Key, Value] {
+ return &SyncMap[Key, Value]{
+ data: make(map[Key]Value),
+ }
+}
+
+// Set stores a value in the map.
+func (sm *SyncMap[Key, Value]) Set(key Key, value Value) {
+ sm.Swap(key, value)
+}
+
+// Swap sets a value in the map and returns the old value.
+//
+// The boolean return parameter is true if the value already existed, false if not.
+func (sm *SyncMap[Key, Value]) Swap(key Key, value Value) (oldValue Value, wasReplaced bool) {
+ sm.lock.Lock()
+ oldValue, wasReplaced = sm.data[key]
+ sm.data[key] = value
+ sm.lock.Unlock()
+ return
+}
+
+// Delete removes a key from the map.
+func (sm *SyncMap[Key, Value]) Delete(key Key) {
+ sm.Pop(key)
+}
+
+// Pop removes a key from the map and returns the old value.
+//
+// The boolean return parameter is the same as with normal Go map access (true if the key exists, false if not).
+func (sm *SyncMap[Key, Value]) Pop(key Key) (value Value, ok bool) {
+ sm.lock.Lock()
+ value, ok = sm.data[key]
+ delete(sm.data, key)
+ sm.lock.Unlock()
+ return
+}
+
+// Get gets a value in the map.
+//
+// The boolean return parameter is the same as with normal Go map access (true if the key exists, false if not).
+func (sm *SyncMap[Key, Value]) Get(key Key) (value Value, ok bool) {
+ sm.lock.RLock()
+ value, ok = sm.data[key]
+ sm.lock.RUnlock()
+ return
+}
+
+// GetOrSet gets a value in the map if the key already exists, otherwise inserts the given value and returns it.
+//
+// The boolean return parameter is true if the key already exists, and false if the given value was inserted.
+func (sm *SyncMap[Key, Value]) GetOrSet(key Key, value Value) (actual Value, wasGet bool) {
+ sm.lock.Lock()
+ defer sm.lock.Unlock()
+ actual, wasGet = sm.data[key]
+ if wasGet {
+ return
+ }
+ sm.data[key] = value
+ actual = value
+ return
+}
+
+// Clone returns a copy of the map.
+func (sm *SyncMap[Key, Value]) Clone() *SyncMap[Key, Value] {
+ return &SyncMap[Key, Value]{data: sm.CopyData()}
+}
+
+// CopyData returns a copy of the data in the map as a normal (non-atomic) map.
+func (sm *SyncMap[Key, Value]) CopyData() map[Key]Value {
+ sm.lock.RLock()
+ copied := make(map[Key]Value, len(sm.data))
+ for key, value := range sm.data {
+ copied[key] = value
+ }
+ sm.lock.RUnlock()
+ return copied
+}