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