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  }