mirror of
https://gitee.com/johng/gf.git
synced 2024-12-02 12:17:53 +08:00
improve package gcache
This commit is contained in:
parent
796774efe4
commit
c01b520ba6
@ -9,6 +9,7 @@
|
|||||||
package gcache
|
package gcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"github.com/gogf/gf/container/gvar"
|
"github.com/gogf/gf/container/gvar"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -16,6 +17,12 @@ import (
|
|||||||
// Default cache object.
|
// Default cache object.
|
||||||
var defaultCache = New()
|
var defaultCache = New()
|
||||||
|
|
||||||
|
// Ctx is a chaining function, which shallowly clones current object and sets the context
|
||||||
|
// for next operation.
|
||||||
|
func Ctx(ctx context.Context) *Cache {
|
||||||
|
return defaultCache.Ctx(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
// Set sets cache with <key>-<value> pair, which is expired after <duration>.
|
// Set sets cache with <key>-<value> pair, which is expired after <duration>.
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
func Set(key interface{}, value interface{}, duration time.Duration) {
|
func Set(key interface{}, value interface{}, duration time.Duration) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package gcache
|
package gcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,13 +17,13 @@ type Adapter interface {
|
|||||||
//
|
//
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0.
|
// It deletes the <key> if <duration> < 0.
|
||||||
Set(key interface{}, value interface{}, duration time.Duration) error
|
Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error
|
||||||
|
|
||||||
// Sets batch sets cache with key-value pairs by <data>, which is expired after <duration>.
|
// Sets batch sets cache with key-value pairs by <data>, which is expired after <duration>.
|
||||||
//
|
//
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the keys of <data> if <duration> < 0 or given <value> is nil.
|
// It deletes the keys of <data> if <duration> < 0 or given <value> is nil.
|
||||||
Sets(data map[interface{}]interface{}, duration time.Duration) error
|
Sets(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error
|
||||||
|
|
||||||
// SetIfNotExist sets cache with <key>-<value> pair which is expired after <duration>
|
// SetIfNotExist sets cache with <key>-<value> pair which is expired after <duration>
|
||||||
// if <key> does not exist in the cache. It returns true the <key> dose not exist in the
|
// if <key> does not exist in the cache. It returns true the <key> dose not exist in the
|
||||||
@ -33,11 +34,11 @@ type Adapter interface {
|
|||||||
//
|
//
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0 or given <value> is nil.
|
// It deletes the <key> if <duration> < 0 or given <value> is nil.
|
||||||
SetIfNotExist(key interface{}, value interface{}, duration time.Duration) (bool, error)
|
SetIfNotExist(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (bool, error)
|
||||||
|
|
||||||
// Get retrieves and returns the associated value of given <key>.
|
// Get retrieves and returns the associated value of given <key>.
|
||||||
// It returns nil if it does not exist, its value is nil or it's expired.
|
// It returns nil if it does not exist, its value is nil or it's expired.
|
||||||
Get(key interface{}) (interface{}, error)
|
Get(ctx context.Context, key interface{}) (interface{}, error)
|
||||||
|
|
||||||
// GetOrSet retrieves and returns the value of <key>, or sets <key>-<value> pair and
|
// GetOrSet retrieves and returns the value of <key>, or sets <key>-<value> pair and
|
||||||
// returns <value> if <key> does not exist in the cache. The key-value pair expires
|
// returns <value> if <key> does not exist in the cache. The key-value pair expires
|
||||||
@ -46,7 +47,7 @@ type Adapter interface {
|
|||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
||||||
// if <value> is a function and the function result is nil.
|
// if <value> is a function and the function result is nil.
|
||||||
GetOrSet(key interface{}, value interface{}, duration time.Duration) (interface{}, error)
|
GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (interface{}, error)
|
||||||
|
|
||||||
// GetOrSetFunc retrieves and returns the value of <key>, or sets <key> with result of
|
// GetOrSetFunc retrieves and returns the value of <key>, or sets <key> with result of
|
||||||
// function <f> and returns its result if <key> does not exist in the cache. The key-value
|
// function <f> and returns its result if <key> does not exist in the cache. The key-value
|
||||||
@ -55,7 +56,7 @@ type Adapter interface {
|
|||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
||||||
// if <value> is a function and the function result is nil.
|
// if <value> is a function and the function result is nil.
|
||||||
GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error)
|
GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error)
|
||||||
|
|
||||||
// GetOrSetFuncLock retrieves and returns the value of <key>, or sets <key> with result of
|
// GetOrSetFuncLock retrieves and returns the value of <key>, or sets <key> with result of
|
||||||
// function <f> and returns its result if <key> does not exist in the cache. The key-value
|
// function <f> and returns its result if <key> does not exist in the cache. The key-value
|
||||||
@ -66,52 +67,52 @@ type Adapter interface {
|
|||||||
//
|
//
|
||||||
// Note that the function <f> should be executed within writing mutex lock for concurrent
|
// Note that the function <f> should be executed within writing mutex lock for concurrent
|
||||||
// safety purpose.
|
// safety purpose.
|
||||||
GetOrSetFuncLock(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error)
|
GetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error)
|
||||||
|
|
||||||
// Contains returns true if <key> exists in the cache, or else returns false.
|
// Contains returns true if <key> exists in the cache, or else returns false.
|
||||||
Contains(key interface{}) (bool, error)
|
Contains(ctx context.Context, key interface{}) (bool, error)
|
||||||
|
|
||||||
// GetExpire retrieves and returns the expiration of <key> in the cache.
|
// GetExpire retrieves and returns the expiration of <key> in the cache.
|
||||||
//
|
//
|
||||||
// It returns 0 if the <key> does not expire.
|
// It returns 0 if the <key> does not expire.
|
||||||
// It returns -1 if the <key> does not exist in the cache.
|
// It returns -1 if the <key> does not exist in the cache.
|
||||||
GetExpire(key interface{}) (time.Duration, error)
|
GetExpire(ctx context.Context, key interface{}) (time.Duration, error)
|
||||||
|
|
||||||
// Remove deletes one or more keys from cache, and returns its value.
|
// Remove deletes one or more keys from cache, and returns its value.
|
||||||
// If multiple keys are given, it returns the value of the last deleted item.
|
// If multiple keys are given, it returns the value of the last deleted item.
|
||||||
Remove(keys ...interface{}) (value interface{}, err error)
|
Remove(ctx context.Context, keys ...interface{}) (value interface{}, err error)
|
||||||
|
|
||||||
// Update updates the value of <key> without changing its expiration and returns the old value.
|
// Update updates the value of <key> without changing its expiration and returns the old value.
|
||||||
// The returned value <exist> is false if the <key> does not exist in the cache.
|
// The returned value <exist> is false if the <key> does not exist in the cache.
|
||||||
//
|
//
|
||||||
// It deletes the <key> if given <value> is nil.
|
// It deletes the <key> if given <value> is nil.
|
||||||
// It does nothing if <key> does not exist in the cache.
|
// It does nothing if <key> does not exist in the cache.
|
||||||
Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error)
|
Update(ctx context.Context, key interface{}, value interface{}) (oldValue interface{}, exist bool, err error)
|
||||||
|
|
||||||
// UpdateExpire updates the expiration of <key> and returns the old expiration duration value.
|
// UpdateExpire updates the expiration of <key> and returns the old expiration duration value.
|
||||||
//
|
//
|
||||||
// It returns -1 and does nothing if the <key> does not exist in the cache.
|
// It returns -1 and does nothing if the <key> does not exist in the cache.
|
||||||
// It deletes the <key> if <duration> < 0.
|
// It deletes the <key> if <duration> < 0.
|
||||||
UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration, err error)
|
UpdateExpire(ctx context.Context, key interface{}, duration time.Duration) (oldDuration time.Duration, err error)
|
||||||
|
|
||||||
// Size returns the number of items in the cache.
|
// Size returns the number of items in the cache.
|
||||||
Size() (size int, err error)
|
Size(ctx context.Context) (size int, err error)
|
||||||
|
|
||||||
// Data returns a copy of all key-value pairs in the cache as map type.
|
// Data returns a copy of all key-value pairs in the cache as map type.
|
||||||
// Note that this function may leads lots of memory usage, you can implement this function
|
// Note that this function may leads lots of memory usage, you can implement this function
|
||||||
// if necessary.
|
// if necessary.
|
||||||
Data() (map[interface{}]interface{}, error)
|
Data(ctx context.Context) (map[interface{}]interface{}, error)
|
||||||
|
|
||||||
// Keys returns all keys in the cache as slice.
|
// Keys returns all keys in the cache as slice.
|
||||||
Keys() ([]interface{}, error)
|
Keys(ctx context.Context) ([]interface{}, error)
|
||||||
|
|
||||||
// Values returns all values in the cache as slice.
|
// Values returns all values in the cache as slice.
|
||||||
Values() ([]interface{}, error)
|
Values(ctx context.Context) ([]interface{}, error)
|
||||||
|
|
||||||
// Clear clears all data of the cache.
|
// Clear clears all data of the cache.
|
||||||
// Note that this function is sensitive and should be carefully used.
|
// Note that this function is sensitive and should be carefully used.
|
||||||
Clear() error
|
Clear(ctx context.Context) error
|
||||||
|
|
||||||
// Close closes the cache if necessary.
|
// Close closes the cache if necessary.
|
||||||
Close() error
|
Close(ctx context.Context) error
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package gcache
|
package gcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ func newAdapterMemory(lruCap ...int) *adapterMemory {
|
|||||||
//
|
//
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0.
|
// It deletes the <key> if <duration> < 0.
|
||||||
func (c *adapterMemory) Set(key interface{}, value interface{}, duration time.Duration) error {
|
func (c *adapterMemory) Set(ctx context.Context, key interface{}, value interface{}, duration time.Duration) error {
|
||||||
expireTime := c.getInternalExpire(duration)
|
expireTime := c.getInternalExpire(duration)
|
||||||
c.data.Set(key, adapterMemoryItem{
|
c.data.Set(key, adapterMemoryItem{
|
||||||
v: value,
|
v: value,
|
||||||
@ -90,7 +91,7 @@ func (c *adapterMemory) Set(key interface{}, value interface{}, duration time.Du
|
|||||||
//
|
//
|
||||||
// It deletes the <key> if given <value> is nil.
|
// It deletes the <key> if given <value> is nil.
|
||||||
// It does nothing if <key> does not exist in the cache.
|
// It does nothing if <key> does not exist in the cache.
|
||||||
func (c *adapterMemory) Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) {
|
func (c *adapterMemory) Update(ctx context.Context, key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) {
|
||||||
return c.data.Update(key, value)
|
return c.data.Update(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ func (c *adapterMemory) Update(key interface{}, value interface{}) (oldValue int
|
|||||||
//
|
//
|
||||||
// It returns -1 and does nothing if the <key> does not exist in the cache.
|
// It returns -1 and does nothing if the <key> does not exist in the cache.
|
||||||
// It deletes the <key> if <duration> < 0.
|
// It deletes the <key> if <duration> < 0.
|
||||||
func (c *adapterMemory) UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration, err error) {
|
func (c *adapterMemory) UpdateExpire(ctx context.Context, key interface{}, duration time.Duration) (oldDuration time.Duration, err error) {
|
||||||
newExpireTime := c.getInternalExpire(duration)
|
newExpireTime := c.getInternalExpire(duration)
|
||||||
oldDuration, err = c.data.UpdateExpire(key, newExpireTime)
|
oldDuration, err = c.data.UpdateExpire(key, newExpireTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -117,7 +118,7 @@ func (c *adapterMemory) UpdateExpire(key interface{}, duration time.Duration) (o
|
|||||||
//
|
//
|
||||||
// It returns 0 if the <key> does not expire.
|
// It returns 0 if the <key> does not expire.
|
||||||
// It returns -1 if the <key> does not exist in the cache.
|
// It returns -1 if the <key> does not exist in the cache.
|
||||||
func (c *adapterMemory) GetExpire(key interface{}) (time.Duration, error) {
|
func (c *adapterMemory) GetExpire(ctx context.Context, key interface{}) (time.Duration, error) {
|
||||||
if item, ok := c.data.Get(key); ok {
|
if item, ok := c.data.Get(key); ok {
|
||||||
return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond, nil
|
return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond, nil
|
||||||
}
|
}
|
||||||
@ -132,8 +133,8 @@ func (c *adapterMemory) GetExpire(key interface{}) (time.Duration, error) {
|
|||||||
//
|
//
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0 or given <value> is nil.
|
// It deletes the <key> if <duration> < 0 or given <value> is nil.
|
||||||
func (c *adapterMemory) SetIfNotExist(key interface{}, value interface{}, duration time.Duration) (bool, error) {
|
func (c *adapterMemory) SetIfNotExist(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (bool, error) {
|
||||||
isContained, err := c.Contains(key)
|
isContained, err := c.Contains(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -151,7 +152,7 @@ func (c *adapterMemory) SetIfNotExist(key interface{}, value interface{}, durati
|
|||||||
//
|
//
|
||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the keys of <data> if <duration> < 0 or given <value> is nil.
|
// It deletes the keys of <data> if <duration> < 0 or given <value> is nil.
|
||||||
func (c *adapterMemory) Sets(data map[interface{}]interface{}, duration time.Duration) error {
|
func (c *adapterMemory) Sets(ctx context.Context, data map[interface{}]interface{}, duration time.Duration) error {
|
||||||
var (
|
var (
|
||||||
expireTime = c.getInternalExpire(duration)
|
expireTime = c.getInternalExpire(duration)
|
||||||
err = c.data.Sets(data, expireTime)
|
err = c.data.Sets(data, expireTime)
|
||||||
@ -170,7 +171,7 @@ func (c *adapterMemory) Sets(data map[interface{}]interface{}, duration time.Dur
|
|||||||
|
|
||||||
// Get retrieves and returns the associated value of given <key>.
|
// Get retrieves and returns the associated value of given <key>.
|
||||||
// It returns nil if it does not exist or its value is nil.
|
// It returns nil if it does not exist or its value is nil.
|
||||||
func (c *adapterMemory) Get(key interface{}) (interface{}, error) {
|
func (c *adapterMemory) Get(ctx context.Context, key interface{}) (interface{}, error) {
|
||||||
item, ok := c.data.Get(key)
|
item, ok := c.data.Get(key)
|
||||||
if ok && !item.IsExpired() {
|
if ok && !item.IsExpired() {
|
||||||
// Adding to LRU history if LRU feature is enabled.
|
// Adding to LRU history if LRU feature is enabled.
|
||||||
@ -189,8 +190,8 @@ func (c *adapterMemory) Get(key interface{}) (interface{}, error) {
|
|||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
||||||
// if <value> is a function and the function result is nil.
|
// if <value> is a function and the function result is nil.
|
||||||
func (c *adapterMemory) GetOrSet(key interface{}, value interface{}, duration time.Duration) (interface{}, error) {
|
func (c *adapterMemory) GetOrSet(ctx context.Context, key interface{}, value interface{}, duration time.Duration) (interface{}, error) {
|
||||||
v, err := c.Get(key)
|
v, err := c.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -208,8 +209,8 @@ func (c *adapterMemory) GetOrSet(key interface{}, value interface{}, duration ti
|
|||||||
// It does not expire if <duration> == 0.
|
// It does not expire if <duration> == 0.
|
||||||
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
||||||
// if <value> is a function and the function result is nil.
|
// if <value> is a function and the function result is nil.
|
||||||
func (c *adapterMemory) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) {
|
func (c *adapterMemory) GetOrSetFunc(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) {
|
||||||
v, err := c.Get(key)
|
v, err := c.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -236,8 +237,8 @@ func (c *adapterMemory) GetOrSetFunc(key interface{}, f func() (interface{}, err
|
|||||||
//
|
//
|
||||||
// Note that the function <f> should be executed within writing mutex lock for concurrent
|
// Note that the function <f> should be executed within writing mutex lock for concurrent
|
||||||
// safety purpose.
|
// safety purpose.
|
||||||
func (c *adapterMemory) GetOrSetFuncLock(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) {
|
func (c *adapterMemory) GetOrSetFuncLock(ctx context.Context, key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) {
|
||||||
v, err := c.Get(key)
|
v, err := c.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -249,8 +250,8 @@ func (c *adapterMemory) GetOrSetFuncLock(key interface{}, f func() (interface{},
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Contains returns true if <key> exists in the cache, or else returns false.
|
// Contains returns true if <key> exists in the cache, or else returns false.
|
||||||
func (c *adapterMemory) Contains(key interface{}) (bool, error) {
|
func (c *adapterMemory) Contains(ctx context.Context, key interface{}) (bool, error) {
|
||||||
v, err := c.Get(key)
|
v, err := c.Get(ctx, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -259,7 +260,7 @@ func (c *adapterMemory) Contains(key interface{}) (bool, error) {
|
|||||||
|
|
||||||
// Remove deletes the one or more keys from cache, and returns its value.
|
// Remove deletes the one or more keys from cache, and returns its value.
|
||||||
// If multiple keys are given, it returns the value of the deleted last item.
|
// If multiple keys are given, it returns the value of the deleted last item.
|
||||||
func (c *adapterMemory) Remove(keys ...interface{}) (value interface{}, err error) {
|
func (c *adapterMemory) Remove(ctx context.Context, keys ...interface{}) (value interface{}, err error) {
|
||||||
var removedKeys []interface{}
|
var removedKeys []interface{}
|
||||||
removedKeys, value, err = c.data.Remove(keys...)
|
removedKeys, value, err = c.data.Remove(keys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -275,33 +276,33 @@ func (c *adapterMemory) Remove(keys ...interface{}) (value interface{}, err erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Data returns a copy of all key-value pairs in the cache as map type.
|
// Data returns a copy of all key-value pairs in the cache as map type.
|
||||||
func (c *adapterMemory) Data() (map[interface{}]interface{}, error) {
|
func (c *adapterMemory) Data(ctx context.Context) (map[interface{}]interface{}, error) {
|
||||||
return c.data.Data()
|
return c.data.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keys returns all keys in the cache as slice.
|
// Keys returns all keys in the cache as slice.
|
||||||
func (c *adapterMemory) Keys() ([]interface{}, error) {
|
func (c *adapterMemory) Keys(ctx context.Context) ([]interface{}, error) {
|
||||||
return c.data.Keys()
|
return c.data.Keys()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Values returns all values in the cache as slice.
|
// Values returns all values in the cache as slice.
|
||||||
func (c *adapterMemory) Values() ([]interface{}, error) {
|
func (c *adapterMemory) Values(ctx context.Context) ([]interface{}, error) {
|
||||||
return c.data.Values()
|
return c.data.Values()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Size returns the size of the cache.
|
// Size returns the size of the cache.
|
||||||
func (c *adapterMemory) Size() (size int, err error) {
|
func (c *adapterMemory) Size(ctx context.Context) (size int, err error) {
|
||||||
return c.data.Size()
|
return c.data.Size()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear clears all data of the cache.
|
// Clear clears all data of the cache.
|
||||||
// Note that this function is sensitive and should be carefully used.
|
// Note that this function is sensitive and should be carefully used.
|
||||||
func (c *adapterMemory) Clear() error {
|
func (c *adapterMemory) Clear(ctx context.Context) error {
|
||||||
return c.data.Clear()
|
return c.data.Clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes the cache.
|
// Close closes the cache.
|
||||||
func (c *adapterMemory) Close() error {
|
func (c *adapterMemory) Close(ctx context.Context) error {
|
||||||
if c.cap > 0 {
|
if c.cap > 0 {
|
||||||
c.lru.Close()
|
c.lru.Close()
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
package gcache
|
package gcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"github.com/gogf/gf/container/gvar"
|
"github.com/gogf/gf/container/gvar"
|
||||||
"github.com/gogf/gf/os/gtimer"
|
"github.com/gogf/gf/os/gtimer"
|
||||||
"github.com/gogf/gf/util/gconv"
|
"github.com/gogf/gf/util/gconv"
|
||||||
@ -15,7 +16,8 @@ import (
|
|||||||
|
|
||||||
// Cache struct.
|
// Cache struct.
|
||||||
type Cache struct {
|
type Cache struct {
|
||||||
Adapter // Adapter for cache features.
|
adapter Adapter // Adapter for cache features.
|
||||||
|
ctx context.Context // Context for operations.
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates and returns a new cache object using default memory adapter.
|
// New creates and returns a new cache object using default memory adapter.
|
||||||
@ -23,7 +25,7 @@ type Cache struct {
|
|||||||
func New(lruCap ...int) *Cache {
|
func New(lruCap ...int) *Cache {
|
||||||
memAdapter := newAdapterMemory(lruCap...)
|
memAdapter := newAdapterMemory(lruCap...)
|
||||||
c := &Cache{
|
c := &Cache{
|
||||||
Adapter: memAdapter,
|
adapter: memAdapter,
|
||||||
}
|
}
|
||||||
// Here may be a "timer leak" if adapter is manually changed from memory adapter.
|
// Here may be a "timer leak" if adapter is manually changed from memory adapter.
|
||||||
// Do not worry about this, as adapter is less changed and it dose nothing if it's not used.
|
// Do not worry about this, as adapter is less changed and it dose nothing if it's not used.
|
||||||
@ -31,11 +33,27 @@ func New(lruCap ...int) *Cache {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Clone returns a shallow copy of current object.
|
||||||
|
func (c *Cache) Clone() *Cache {
|
||||||
|
return &Cache{
|
||||||
|
adapter: c.adapter,
|
||||||
|
ctx: c.ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ctx is a chaining function, which shallowly clones current object and sets the context
|
||||||
|
// for next operation.
|
||||||
|
func (c *Cache) Ctx(ctx context.Context) *Cache {
|
||||||
|
newCache := c.Clone()
|
||||||
|
newCache.ctx = ctx
|
||||||
|
return newCache
|
||||||
|
}
|
||||||
|
|
||||||
// SetAdapter changes the adapter for this cache.
|
// SetAdapter changes the adapter for this cache.
|
||||||
// Be very note that, this setting function is not concurrent-safe, which means you should not call
|
// Be very note that, this setting function is not concurrent-safe, which means you should not call
|
||||||
// this setting function concurrently in multiple goroutines.
|
// this setting function concurrently in multiple goroutines.
|
||||||
func (c *Cache) SetAdapter(adapter Adapter) {
|
func (c *Cache) SetAdapter(adapter Adapter) {
|
||||||
c.Adapter = adapter
|
c.adapter = adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVar retrieves and returns the value of <key> as gvar.Var.
|
// GetVar retrieves and returns the value of <key> as gvar.Var.
|
||||||
@ -59,3 +77,11 @@ func (c *Cache) KeyStrings() ([]string, error) {
|
|||||||
}
|
}
|
||||||
return gconv.Strings(keys), nil
|
return gconv.Strings(keys), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KeyStrings returns all keys in the cache as string slice.
|
||||||
|
func (c *Cache) getCtx() context.Context {
|
||||||
|
if c.ctx == nil {
|
||||||
|
return context.Background()
|
||||||
|
}
|
||||||
|
return c.ctx
|
||||||
|
}
|
||||||
|
150
os/gcache/gcache_cache_adapter.go
Normal file
150
os/gcache/gcache_cache_adapter.go
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the MIT License.
|
||||||
|
// If a copy of the MIT was not distributed with this file,
|
||||||
|
// You can obtain one at https://github.com/gogf/gf.
|
||||||
|
|
||||||
|
package gcache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Set sets cache with <key>-<value> pair, which is expired after <duration>.
|
||||||
|
//
|
||||||
|
// It does not expire if <duration> == 0.
|
||||||
|
// It deletes the <key> if <duration> < 0.
|
||||||
|
func (c *Cache) Set(key interface{}, value interface{}, duration time.Duration) error {
|
||||||
|
return c.adapter.Set(c.getCtx(), key, value, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sets batch sets cache with key-value pairs by <data>, which is expired after <duration>.
|
||||||
|
//
|
||||||
|
// It does not expire if <duration> == 0.
|
||||||
|
// It deletes the keys of <data> if <duration> < 0 or given <value> is nil.
|
||||||
|
func (c *Cache) Sets(data map[interface{}]interface{}, duration time.Duration) error {
|
||||||
|
return c.adapter.Sets(c.getCtx(), data, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetIfNotExist sets cache with <key>-<value> pair which is expired after <duration>
|
||||||
|
// if <key> does not exist in the cache. It returns true the <key> dose not exist in the
|
||||||
|
// cache and it sets <value> successfully to the cache, or else it returns false.
|
||||||
|
//
|
||||||
|
// The parameter <value> can be type of <func() interface{}>, but it dose nothing if its
|
||||||
|
// result is nil.
|
||||||
|
//
|
||||||
|
// It does not expire if <duration> == 0.
|
||||||
|
// It deletes the <key> if <duration> < 0 or given <value> is nil.
|
||||||
|
func (c *Cache) SetIfNotExist(key interface{}, value interface{}, duration time.Duration) (bool, error) {
|
||||||
|
return c.adapter.SetIfNotExist(c.getCtx(), key, value, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get retrieves and returns the associated value of given <key>.
|
||||||
|
// It returns nil if it does not exist, its value is nil or it's expired.
|
||||||
|
func (c *Cache) Get(key interface{}) (interface{}, error) {
|
||||||
|
return c.adapter.Get(c.getCtx(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrSet retrieves and returns the value of <key>, or sets <key>-<value> pair and
|
||||||
|
// returns <value> if <key> does not exist in the cache. The key-value pair expires
|
||||||
|
// after <duration>.
|
||||||
|
//
|
||||||
|
// It does not expire if <duration> == 0.
|
||||||
|
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
||||||
|
// if <value> is a function and the function result is nil.
|
||||||
|
func (c *Cache) GetOrSet(key interface{}, value interface{}, duration time.Duration) (interface{}, error) {
|
||||||
|
return c.adapter.GetOrSet(c.getCtx(), key, value, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrSetFunc retrieves and returns the value of <key>, or sets <key> with result of
|
||||||
|
// function <f> and returns its result if <key> does not exist in the cache. The key-value
|
||||||
|
// pair expires after <duration>.
|
||||||
|
//
|
||||||
|
// It does not expire if <duration> == 0.
|
||||||
|
// It deletes the <key> if <duration> < 0 or given <value> is nil, but it does nothing
|
||||||
|
// if <value> is a function and the function result is nil.
|
||||||
|
func (c *Cache) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) {
|
||||||
|
return c.adapter.GetOrSetFunc(c.getCtx(), key, f, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOrSetFuncLock retrieves and returns the value of <key>, or sets <key> with result of
|
||||||
|
// function <f> and returns its result if <key> does not exist in the cache. The key-value
|
||||||
|
// pair expires after <duration>.
|
||||||
|
//
|
||||||
|
// It does not expire if <duration> == 0.
|
||||||
|
// It does nothing if function <f> returns nil.
|
||||||
|
//
|
||||||
|
// Note that the function <f> should be executed within writing mutex lock for concurrent
|
||||||
|
// safety purpose.
|
||||||
|
func (c *Cache) GetOrSetFuncLock(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) {
|
||||||
|
return c.adapter.GetOrSetFuncLock(c.getCtx(), key, f, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Contains returns true if <key> exists in the cache, or else returns false.
|
||||||
|
func (c *Cache) Contains(key interface{}) (bool, error) {
|
||||||
|
return c.adapter.Contains(c.getCtx(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetExpire retrieves and returns the expiration of <key> in the cache.
|
||||||
|
//
|
||||||
|
// It returns 0 if the <key> does not expire.
|
||||||
|
// It returns -1 if the <key> does not exist in the cache.
|
||||||
|
func (c *Cache) GetExpire(key interface{}) (time.Duration, error) {
|
||||||
|
return c.adapter.GetExpire(c.getCtx(), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove deletes one or more keys from cache, and returns its value.
|
||||||
|
// If multiple keys are given, it returns the value of the last deleted item.
|
||||||
|
func (c *Cache) Remove(keys ...interface{}) (value interface{}, err error) {
|
||||||
|
return c.adapter.Remove(c.getCtx(), keys...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update updates the value of <key> without changing its expiration and returns the old value.
|
||||||
|
// The returned value <exist> is false if the <key> does not exist in the cache.
|
||||||
|
//
|
||||||
|
// It deletes the <key> if given <value> is nil.
|
||||||
|
// It does nothing if <key> does not exist in the cache.
|
||||||
|
func (c *Cache) Update(key interface{}, value interface{}) (oldValue interface{}, exist bool, err error) {
|
||||||
|
return c.adapter.Update(c.getCtx(), key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateExpire updates the expiration of <key> and returns the old expiration duration value.
|
||||||
|
//
|
||||||
|
// It returns -1 and does nothing if the <key> does not exist in the cache.
|
||||||
|
// It deletes the <key> if <duration> < 0.
|
||||||
|
func (c *Cache) UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration, err error) {
|
||||||
|
return c.adapter.UpdateExpire(c.getCtx(), key, duration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns the number of items in the cache.
|
||||||
|
func (c *Cache) Size() (size int, err error) {
|
||||||
|
return c.adapter.Size(c.getCtx())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data returns a copy of all key-value pairs in the cache as map type.
|
||||||
|
// Note that this function may leads lots of memory usage, you can implement this function
|
||||||
|
// if necessary.
|
||||||
|
func (c *Cache) Data() (map[interface{}]interface{}, error) {
|
||||||
|
return c.adapter.Data(c.getCtx())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keys returns all keys in the cache as slice.
|
||||||
|
func (c *Cache) Keys() ([]interface{}, error) {
|
||||||
|
return c.adapter.Keys(c.getCtx())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Values returns all values in the cache as slice.
|
||||||
|
func (c *Cache) Values() ([]interface{}, error) {
|
||||||
|
return c.adapter.Values(c.getCtx())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear clears all data of the cache.
|
||||||
|
// Note that this function is sensitive and should be carefully used.
|
||||||
|
func (c *Cache) Clear() error {
|
||||||
|
return c.adapter.Clear(c.getCtx())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the cache if necessary.
|
||||||
|
func (c *Cache) Close() error {
|
||||||
|
return c.adapter.Close(c.getCtx())
|
||||||
|
}
|
@ -9,6 +9,7 @@
|
|||||||
package gcache_test
|
package gcache_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"github.com/gogf/gf/util/guid"
|
"github.com/gogf/gf/util/guid"
|
||||||
"math"
|
"math"
|
||||||
"testing"
|
"testing"
|
||||||
@ -413,3 +414,14 @@ func TestCache_Basic(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCache_Ctx(t *testing.T) {
|
||||||
|
gtest.C(t, func(t *gtest.T) {
|
||||||
|
cache := gcache.New()
|
||||||
|
cache.Ctx(context.Background()).Sets(g.MapAnyAny{1: 11, 2: 22}, 0)
|
||||||
|
b, _ := cache.Contains(1)
|
||||||
|
t.Assert(b, true)
|
||||||
|
v, _ := cache.Get(1)
|
||||||
|
t.Assert(v, 11)
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user