github.com/webx-top/com@v1.2.12/safemap.go (about) 1 package com 2 3 import ( 4 "sync" 5 ) 6 7 type SafeMap struct { 8 lock *sync.RWMutex 9 bm map[interface{}]interface{} 10 } 11 12 func NewSafeMap() *SafeMap { 13 return &SafeMap{ 14 lock: new(sync.RWMutex), 15 bm: make(map[interface{}]interface{}), 16 } 17 } 18 19 //Get from maps return the k's value 20 func (m *SafeMap) Get(k interface{}) interface{} { 21 m.lock.RLock() 22 defer m.lock.RUnlock() 23 if val, ok := m.bm[k]; ok { 24 return val 25 } 26 return nil 27 } 28 29 // Set maps the given key and value. Returns false 30 // if the key is already in the map and changes nothing. 31 func (m *SafeMap) Set(k interface{}, v interface{}) bool { 32 m.lock.Lock() 33 defer m.lock.Unlock() 34 if val, ok := m.bm[k]; !ok { 35 m.bm[k] = v 36 } else if val != v { 37 m.bm[k] = v 38 } else { 39 return false 40 } 41 return true 42 } 43 44 // Check returns true if k is exist in the map. 45 func (m *SafeMap) Check(k interface{}) bool { 46 m.lock.RLock() 47 defer m.lock.RUnlock() 48 if _, ok := m.bm[k]; !ok { 49 return false 50 } 51 return true 52 } 53 54 func (m *SafeMap) Delete(k interface{}) { 55 m.lock.Lock() 56 defer m.lock.Unlock() 57 delete(m.bm, k) 58 } 59 60 func (m *SafeMap) Items() map[interface{}]interface{} { 61 m.lock.RLock() 62 defer m.lock.RUnlock() 63 return m.bm 64 } 65 66 func NewOrderlySafeMap() *OrderlySafeMap { 67 return &OrderlySafeMap{ 68 SafeMap: NewSafeMap(), 69 keys: make([]interface{}, 0), 70 } 71 } 72 73 type OrderlySafeMap struct { 74 *SafeMap 75 keys []interface{} // map keys 76 values []interface{} // map values 77 } 78 79 func (m *OrderlySafeMap) Set(k interface{}, v interface{}) bool { 80 m.lock.Lock() 81 defer m.lock.Unlock() 82 if val, ok := m.bm[k]; !ok { 83 m.bm[k] = v 84 m.keys = append(m.keys, k) 85 } else if val != v { 86 m.bm[k] = v 87 } else { 88 return false 89 } 90 return true 91 } 92 93 func (m *OrderlySafeMap) Delete(k interface{}) { 94 m.lock.Lock() 95 defer m.lock.Unlock() 96 delete(m.bm, k) 97 endIndex := len(m.keys) - 1 98 for index, mapKey := range m.keys { 99 if mapKey != k { 100 continue 101 } 102 if index == endIndex { 103 m.keys = m.keys[0:index] 104 break 105 } 106 if index == 0 { 107 m.keys = m.keys[1:] 108 break 109 } 110 m.keys = append(m.keys[0:index], m.keys[index+1:]...) 111 break 112 } 113 } 114 115 func (m *OrderlySafeMap) Keys() []interface{} { 116 m.lock.Lock() 117 defer m.lock.Unlock() 118 return m.keys 119 } 120 121 func (m *OrderlySafeMap) Values(force ...bool) []interface{} { 122 m.lock.Lock() 123 defer m.lock.Unlock() 124 if (len(force) == 0 || !force[0]) && m.values != nil { 125 return m.values 126 } 127 m.values = []interface{}{} 128 for _, mapKey := range m.keys { 129 m.values = append(m.values, m.bm[mapKey]) 130 } 131 return m.values 132 } 133 134 func (m *OrderlySafeMap) VisitAll(callback func(int, interface{}, interface{})) { 135 m.lock.Lock() 136 for index, mapKey := range m.keys { 137 callback(index, mapKey, m.bm[mapKey]) 138 } 139 m.lock.Unlock() 140 }