gob/collection/concurrent/map.go

120 lines
2.1 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package concurrent
import (
"sync"
. "gitea.zaclys.com/bvaudour/gob/option"
)
// Map fournit une solution pour ajouter des éléments dans un map de façon concurrente.
type Map[K comparable, V any] struct {
data map[K]V
mtx sync.Mutex
closed bool
}
func (m *Map[K, V]) checkOpened() {
if m.closed {
panic("The map cannot be modified anymore.")
}
}
func (m *Map[K, V]) checkClosed() {
if !m.closed {
panic("The Map needs to be opened.")
}
}
func (m *Map[K, V]) changeState(closed bool) {
m.mtx.Lock()
defer m.mtx.Unlock()
m.closed = closed
}
func (m *Map[K, V]) get() (out map[K]V) {
out = make(map[K]V)
for k, v := range m.data {
out[k] = v
}
return
}
// Clear vide le map.
// Cette méthode nécessite que le map soit ouvert.
func (m *Map[K, V]) Clear() {
m.mtx.Lock()
defer m.mtx.Unlock()
m.checkOpened()
clear(m.data)
}
// Close empêche les modifications du map.
func (m *Map[K, V]) Close() {
m.changeState(true)
}
// Open permet les modifications du map.
func (m *Map[K, V]) Open() {
m.changeState(false)
}
// Set associe la clé et la valeur données dans le map.
// Cette méthode nécessite que le map soit ouvert.
func (m *Map[K, V]) Set(key K, value V) {
m.mtx.Lock()
defer m.mtx.Unlock()
m.checkOpened()
m.data[key] = value
}
// Get retourne la valeur du map à la clé donnée.
func (m *Map[K, V]) Get(key K) (value Option[V]) {
m.mtx.Lock()
defer m.mtx.Unlock()
if v, ok := m.data[key]; ok {
value = Some(v)
}
return
}
// Data retourne le map.
// Cette méthode nécessite que le map soit fermé.
func (m *Map[K, V]) Data() map[K]V {
m.mtx.Lock()
defer m.mtx.Unlock()
m.checkClosed()
return m.get()
}
// CloseData retourne le map après lavoir préalablement fermé en écriture.
func (m *Map[K, V]) CloseData() map[K]V {
m.mtx.Lock()
defer m.mtx.Unlock()
m.closed = true
return m.get()
}
// NewMap retourne un map initialisé avec les valeurs fournies.
func NewMap[K comparable, V any](elems ...map[K]V) *Map[K, V] {
out := make(map[K]V)
for _, m := range elems {
for k, v := range m {
out[k] = v
}
}
return &Map[K, V]{
data: out,
}
}