nettools/data_structures/syncmap.go

67 lines
1.5 KiB
Go

package ds_utils
import (
"sync"
common "git.mic.pp.ua/anderson/nettools/common"
)
type IIdSyncMap[IDType common.Int, ItemType any] interface {
GetAll() map[IDType]ItemType
Add(items ...ItemType) (id IDType)
Rm(id IDType)
Pop(id IDType) (item ItemType, exists bool)
}
type IdSyncMap[IDType common.Int, ItemType any] struct {
IIdSyncMap[IDType, ItemType]
Lock *sync.RWMutex
Data map[IDType]ItemType
NextID IDType
}
func (idsyncmap *IdSyncMap[IDType, ItemType]) GetAll() map[IDType]ItemType {
dataCopy := map[IDType]ItemType{}
idsyncmap.Lock.RLock()
for id, item := range idsyncmap.Data {
dataCopy[id] = item
}
idsyncmap.Lock.RUnlock()
return dataCopy
}
func (idsyncmap *IdSyncMap[IDType, ItemType]) Add(items ...ItemType) (id IDType) {
idsyncmap.Lock.Lock()
id = idsyncmap.NextID
for i, item := range items {
idsyncmap.Data[id+IDType(i)] = item
}
idsyncmap.NextID += IDType(len(items))
idsyncmap.Lock.Unlock()
return id
}
func (idsyncmap *IdSyncMap[IDType, ItemType]) Rm(id IDType) {
idsyncmap.Lock.Lock()
delete(idsyncmap.Data, id)
idsyncmap.Lock.Unlock()
}
func (idsyncmap *IdSyncMap[IDType, ItemType]) Pop(id IDType) (item ItemType, exists bool) {
idsyncmap.Lock.Lock()
defer idsyncmap.Lock.Unlock()
if item, exists = idsyncmap.Data[id]; !exists {
return item, exists
}
delete(idsyncmap.Data, id)
return item, exists
}
func NewIDSyncMap[IDType common.Int, ItemType any]() IIdSyncMap[IDType, ItemType] {
return &IdSyncMap[IDType, ItemType]{
Lock: &sync.RWMutex{},
Data: map[IDType]ItemType{},
NextID: 0,
}
}