/* * Copyright (c) 2022 tursom. All rights reserved. * Use of this source code is governed by a GPL-3 * license that can be found in the LICENSE file. */ package collections import ( "sync" "github.com/tursom/GoCollections/collections" "github.com/tursom/GoCollections/concurrent" "github.com/tursom/GoCollections/exceptions" "github.com/tursom/GoCollections/lang" ) type ( // GoSyncMap an map use go sync.Map to store hash slot GoSyncMap[K lang.Object, V any] struct { collections.NodeMap[K, V] m sync.Map lock concurrent.RWLock } ) func NewGoSyncMap[K lang.Object, V any]() *GoSyncMap[K, V] { m := &GoSyncMap[K, V]{lock: &sync.RWMutex{}} m.MapNodeFinder = collections.NewMapNodeFinderBySlot[K, V](m) return m } func (g *GoSyncMap[K, V]) ToString() lang.String { return collections.MapToString[K, V](g) } func (g *GoSyncMap[K, V]) FindSlot(k K) collections.MapNode[K, V] { hashCode := lang.HashCode(k) p, _ := g.m.Load(hashCode) root := lang.Cast[*collections.SimpleMapNode[K, V]](p) if root == nil { root = &collections.SimpleMapNode[K, V]{} g.m.Store(hashCode, root) } return root } func (g *GoSyncMap[K, V]) Put(k K, v V) (bool, exceptions.Exception) { g.lock.Lock() defer g.lock.Unlock() return g.NodeMap.Put(k, v) } func (g *GoSyncMap[K, V]) Get(k K) (V, bool, exceptions.Exception) { g.lock.RLock() defer g.lock.RUnlock() return g.NodeMap.Get(k) } func (g *GoSyncMap[K, V]) Remove(k K) (V, bool, exceptions.Exception) { g.lock.Lock() defer g.lock.Unlock() return g.NodeMap.Remove(k) } func (g *GoSyncMap[K, V]) Loop(f func(K, V) exceptions.Exception) (err exceptions.Exception) { g.lock.RLock() defer g.lock.RUnlock() g.m.Range(func(key, value any) bool { err = f(lang.Cast[K](key), lang.Cast[V](value)) return err == nil }) return }