summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-mutexes/hash_map.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/codeberg.org/gruf/go-mutexes/hash_map.go')
-rw-r--r--vendor/codeberg.org/gruf/go-mutexes/hash_map.go56
1 files changed, 56 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-mutexes/hash_map.go b/vendor/codeberg.org/gruf/go-mutexes/hash_map.go
new file mode 100644
index 000000000..a177133b5
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-mutexes/hash_map.go
@@ -0,0 +1,56 @@
+package mutexes
+
+type hashmap struct {
+ m map[string]*rwmutex
+ n int
+}
+
+func (m *hashmap) init(cap int) {
+ m.m = make(map[string]*rwmutex, cap)
+ m.n = cap
+}
+
+func (m *hashmap) Get(key string) *rwmutex { return m.m[key] }
+
+func (m *hashmap) Put(key string, mu *rwmutex) {
+ m.m[key] = mu
+ if n := len(m.m); n > m.n {
+ m.n = n
+ }
+}
+
+func (m *hashmap) Delete(key string) {
+ delete(m.m, key)
+}
+
+func (m *hashmap) Compact() {
+ // Noop when hashmap size
+ // is too small to matter.
+ if m.n < 2048 {
+ return
+ }
+
+ // Difference between maximum map
+ // size and the current map size.
+ diff := m.n - len(m.m)
+
+ // Maximum load factor before
+ // runtime allocates new hmap:
+ // maxLoad = 13 / 16
+ //
+ // So we apply the inverse/2, once
+ // $maxLoad/2 % of hmap is empty we
+ // compact the map to drop buckets.
+ if 2*16*diff > m.n*13 {
+
+ // Create new map only as big as required.
+ m2 := make(map[string]*rwmutex, len(m.m))
+ for k, v := range m.m {
+ m2[k] = v
+ }
+
+ // Set new.
+ m.m = m2
+ m.n = len(m2)
+ }
+}