package cmap import ( tmsync "github.com/tendermint/tendermint/internal/libs/sync" ) // CMap is a goroutine-safe map type CMap struct { m map[string]interface{} l tmsync.Mutex } func NewCMap() *CMap { return &CMap{ m: make(map[string]interface{}), } } func (cm *CMap) Set(key string, value interface{}) { cm.l.Lock() cm.m[key] = value cm.l.Unlock() } // GetOrSet returns the existing value if present. Othewise, it stores `newValue` and returns it. func (cm *CMap) GetOrSet(key string, newValue interface{}) (value interface{}, alreadyExists bool) { cm.l.Lock() defer cm.l.Unlock() if v, ok := cm.m[key]; ok { return v, true } cm.m[key] = newValue return newValue, false } func (cm *CMap) Get(key string) interface{} { cm.l.Lock() val := cm.m[key] cm.l.Unlock() return val } func (cm *CMap) Has(key string) bool { cm.l.Lock() _, ok := cm.m[key] cm.l.Unlock() return ok } func (cm *CMap) Delete(key string) { cm.l.Lock() delete(cm.m, key) cm.l.Unlock() } func (cm *CMap) Size() int { cm.l.Lock() size := len(cm.m) cm.l.Unlock() return size } func (cm *CMap) Clear() { cm.l.Lock() cm.m = make(map[string]interface{}) cm.l.Unlock() } func (cm *CMap) Keys() []string { cm.l.Lock() keys := make([]string, 0, len(cm.m)) for k := range cm.m { keys = append(keys, k) } cm.l.Unlock() return keys } func (cm *CMap) Values() []interface{} { cm.l.Lock() items := make([]interface{}, 0, len(cm.m)) for _, v := range cm.m { items = append(items, v) } cm.l.Unlock() return items }