package storage import ( "fmt" "gitea.inhome.blapointe.com/local/storage/resolve" "sync" ) type Map struct { m map[string]map[string][]byte lock *sync.RWMutex } func NewMap() *Map { return &Map{ m: make(map[string]map[string][]byte), lock: &sync.RWMutex{}, } } func (m *Map) String() string { m.lock.RLock() defer m.lock.RUnlock() s := "" for k, v := range m.m { if s != "" { s += ",\n" } s += fmt.Sprintf("[%s]:[%s]", k, v) } return s } func (m *Map) Close() error { m.lock.Lock() defer m.lock.Unlock() m.m = nil return nil } func (m *Map) Namespaces() ([][]string, error) { keys := [][]string{} for key := range m.m { keys = append(keys, resolve.UnNamespace(key)) } return keys, nil } func (m *Map) List(ns []string, limits ...string) ([]string, error) { m.lock.RLock() defer m.lock.RUnlock() namespace := resolve.Namespace(ns) limits = resolve.Limits(limits) keys := []string{} if _, ok := m.m[namespace]; !ok { namespace = resolve.DefaultNamespace } for k := range m.m[namespace] { if k >= limits[0] && k <= limits[1] { keys = append(keys, k) } } return keys, nil } func (m *Map) Get(key string, ns ...string) ([]byte, error) { m.lock.RLock() defer m.lock.RUnlock() namespace := resolve.Namespace(ns) if _, ok := m.m[namespace]; !ok { return nil, ErrNotFound } if _, ok := m.m[namespace][key]; !ok { return nil, ErrNotFound } return m.m[namespace][key], nil } func (m *Map) Set(key string, value []byte, ns ...string) error { m.lock.Lock() defer m.lock.Unlock() namespace := resolve.Namespace(ns) if value == nil { if _, ok := m.m[namespace]; !ok { return nil } else if _, ok := m.m[namespace][key]; ok { delete(m.m[namespace], key) } } else { if _, ok := m.m[namespace]; !ok { m.m[namespace] = make(map[string][]byte) } m.m[namespace][key] = value } return nil }