package utl import ( "errors" "sync" ) var ( ErrKeyExists = errors.New("key already exists") ErrKeyNotExists = errors.New("key not exists") ) // secure map // exports funny interfaces type SMap struct { *sync.RWMutex m map[interface{}]interface{} } func NewSMap() *SMap { return &SMap{ RWMutex: &sync.RWMutex{}, m: make(map[interface{}]interface{}), } } func (self *SMap) Exists(k interface{}) bool { self.RLock() _, ok := self.m[k] self.RUnlock() return ok } func (self *SMap) Get(k interface{}) (interface{}, bool) { self.RLock() defer self.RUnlock() v, ok := self.m[k] return v, ok } func (self *SMap) Set(k, v interface{}) { self.Lock() self.m[k] = v self.Unlock() } func (self *SMap) Del(k interface{}) { self.Lock() delete(self.m, k) self.Unlock() } func (self *SMap) Insert(k, v interface{}) error { self.Lock() defer self.Unlock() _, ok := self.m[k] if ok { return ErrKeyExists } self.m[k] = v return nil } func (self *SMap) Update(k, v interface{}) error { self.Lock() defer self.Unlock() _, ok := self.m[k] if !ok { return ErrKeyNotExists } self.m[k] = v return nil } func (self *SMap) Keys() []interface{} { var retval []interface{} self.RLock() defer self.RUnlock() for k, _ := range self.m { retval = append(retval, k) } return retval } func (self *SMap) Values() []interface{} { var retval []interface{} self.RLock() defer self.RUnlock() for _, v := range self.m { retval = append(retval, v) } return retval } func (self *SMap) Foreach(each func(k, v interface{})) { self.RLock() for k, v := range self.m { each(k, v) } self.RUnlock() }