github.com/gogf/gf@v1.16.9/os/gcache/gcache_adapter_memory_data.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package gcache 8 9 import ( 10 "github.com/gogf/gf/os/gtime" 11 "sync" 12 "time" 13 ) 14 15 type adapterMemoryData struct { 16 mu sync.RWMutex // dataMu ensures the concurrent safety of underlying data map. 17 data map[interface{}]adapterMemoryItem // data is the underlying cache data which is stored in a hash table. 18 } 19 20 func newAdapterMemoryData() *adapterMemoryData { 21 return &adapterMemoryData{ 22 data: make(map[interface{}]adapterMemoryItem), 23 } 24 } 25 26 // Update updates the value of `key` without changing its expiration and returns the old value. 27 // The returned value `exist` is false if the `key` does not exist in the cache. 28 // 29 // It deletes the `key` if given `value` is nil. 30 // It does nothing if `key` does not exist in the cache. 31 func (d *adapterMemoryData) Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) { 32 d.mu.Lock() 33 defer d.mu.Unlock() 34 if item, ok := d.data[key]; ok { 35 d.data[key] = adapterMemoryItem{ 36 v: value, 37 e: item.e, 38 } 39 return item.v, true, nil 40 } 41 return nil, false, nil 42 } 43 44 // UpdateExpire updates the expiration of `key` and returns the old expiration duration value. 45 // 46 // It returns -1 and does nothing if the `key` does not exist in the cache. 47 // It deletes the `key` if `duration` < 0. 48 func (d *adapterMemoryData) UpdateExpire(key interface{}, expireTime int64) (oldDuration time.Duration, err error) { 49 d.mu.Lock() 50 defer d.mu.Unlock() 51 if item, ok := d.data[key]; ok { 52 d.data[key] = adapterMemoryItem{ 53 v: item.v, 54 e: expireTime, 55 } 56 return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond, nil 57 } 58 return -1, nil 59 } 60 61 // Remove deletes the one or more keys from cache, and returns its value. 62 // If multiple keys are given, it returns the value of the deleted last item. 63 func (d *adapterMemoryData) Remove(keys ...interface{}) (removedKeys []interface{}, value interface{}, err error) { 64 d.mu.Lock() 65 defer d.mu.Unlock() 66 removedKeys = make([]interface{}, 0) 67 for _, key := range keys { 68 item, ok := d.data[key] 69 if ok { 70 value = item.v 71 delete(d.data, key) 72 removedKeys = append(removedKeys, key) 73 } 74 } 75 return removedKeys, value, nil 76 } 77 78 // Data returns a copy of all key-value pairs in the cache as map type. 79 func (d *adapterMemoryData) Data() (map[interface{}]interface{}, error) { 80 d.mu.RLock() 81 m := make(map[interface{}]interface{}, len(d.data)) 82 for k, v := range d.data { 83 if !v.IsExpired() { 84 m[k] = v.v 85 } 86 } 87 d.mu.RUnlock() 88 return m, nil 89 } 90 91 // Keys returns all keys in the cache as slice. 92 func (d *adapterMemoryData) Keys() ([]interface{}, error) { 93 d.mu.RLock() 94 var ( 95 index = 0 96 keys = make([]interface{}, len(d.data)) 97 ) 98 for k, v := range d.data { 99 if !v.IsExpired() { 100 keys[index] = k 101 index++ 102 } 103 } 104 d.mu.RUnlock() 105 return keys, nil 106 } 107 108 // Values returns all values in the cache as slice. 109 func (d *adapterMemoryData) Values() ([]interface{}, error) { 110 d.mu.RLock() 111 var ( 112 index = 0 113 values = make([]interface{}, len(d.data)) 114 ) 115 for _, v := range d.data { 116 if !v.IsExpired() { 117 values[index] = v.v 118 index++ 119 } 120 } 121 d.mu.RUnlock() 122 return values, nil 123 } 124 125 // Size returns the size of the cache. 126 func (d *adapterMemoryData) Size() (size int, err error) { 127 d.mu.RLock() 128 size = len(d.data) 129 d.mu.RUnlock() 130 return size, nil 131 } 132 133 // Clear clears all data of the cache. 134 // Note that this function is sensitive and should be carefully used. 135 func (d *adapterMemoryData) Clear() error { 136 d.mu.Lock() 137 defer d.mu.Unlock() 138 d.data = make(map[interface{}]adapterMemoryItem) 139 return nil 140 } 141 142 func (d *adapterMemoryData) Get(key interface{}) (item adapterMemoryItem, ok bool) { 143 d.mu.RLock() 144 item, ok = d.data[key] 145 d.mu.RUnlock() 146 return 147 } 148 149 func (d *adapterMemoryData) Set(key interface{}, value adapterMemoryItem) { 150 d.mu.Lock() 151 d.data[key] = value 152 d.mu.Unlock() 153 } 154 155 // Sets batch sets cache with key-value pairs by `data`, which is expired after `duration`. 156 // 157 // It does not expire if `duration` == 0. 158 // It deletes the keys of `data` if `duration` < 0 or given `value` is nil. 159 func (d *adapterMemoryData) Sets(data map[interface{}]interface{}, expireTime int64) error { 160 d.mu.Lock() 161 for k, v := range data { 162 d.data[k] = adapterMemoryItem{ 163 v: v, 164 e: expireTime, 165 } 166 } 167 d.mu.Unlock() 168 return nil 169 } 170 171 func (d *adapterMemoryData) SetWithLock(key interface{}, value interface{}, expireTimestamp int64) (interface{}, error) { 172 d.mu.Lock() 173 defer d.mu.Unlock() 174 if v, ok := d.data[key]; ok && !v.IsExpired() { 175 return v.v, nil 176 } 177 if f, ok := value.(func() (interface{}, error)); ok { 178 v, err := f() 179 if err != nil { 180 return nil, err 181 } 182 if v == nil { 183 return nil, nil 184 } else { 185 value = v 186 } 187 } 188 d.data[key] = adapterMemoryItem{v: value, e: expireTimestamp} 189 return value, nil 190 } 191 192 func (d *adapterMemoryData) DeleteWithDoubleCheck(key interface{}, force ...bool) { 193 d.mu.Lock() 194 // Doubly check before really deleting it from cache. 195 if item, ok := d.data[key]; (ok && item.IsExpired()) || (len(force) > 0 && force[0]) { 196 delete(d.data, key) 197 } 198 d.mu.Unlock() 199 }