Skip to content

Commit

Permalink
feat(freecache): 新增单独获取和设置本地缓存的方法 (#870)
Browse files Browse the repository at this point in the history
Co-authored-by: 彭业昌 <refrain@douyu.tv>
  • Loading branch information
PengYechang and 彭业昌 authored May 16, 2023
1 parent 7aa27a6 commit fe36353
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 6 deletions.
54 changes: 48 additions & 6 deletions pkg/cache/xfreecache/v2/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,50 @@ func (c *cache[K, V]) GetAndSetCacheData(key string, id K, fn func() (V, error))
return
}

// GetCacheValue 获取缓存数据
func (c *cache[K, V]) GetCacheValue(key string, id K) (value V) {
resMap, _ := c.getCacheMap(key, []K{id})
value = resMap[id]
return
}

// SetCacheValue 设置缓存数据
func (c *cache[K, V]) SetCacheValue(key string, id K, fn func() (V, error)) (err error) {
err = c.setCacheMap(key, []K{id}, func([]K) (map[K]V, error) {
innerVal, innerErr := fn()
return map[K]V{id: innerVal}, innerErr
}, nil)
return
}

// GetAndSetCacheMap 获取缓存后数据 map形式
func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K]V, error)) (v map[K]V, err error) {
args := []zap.Field{zap.Any("key", key), zap.Any("ids", ids)}
// 获取缓存数据
v, idsNone := c.getCacheMap(key, ids)

// 设置缓存数据
err = c.setCacheMap(key, idsNone, fn, v)
return
}

// GetCacheMap 获取缓存数据 map形式
func (c *cache[K, V]) GetCacheMap(key string, ids []K) (v map[K]V) {
v, _ = c.getCacheMap(key, ids)
return
}

// SetCacheMap 设置缓存数据 map形式
func (c *cache[K, V]) SetCacheMap(key string, ids []K, fn func([]K) (map[K]V, error)) (err error) {
err = c.setCacheMap(key, ids, fn, nil)
return
}

func (c *cache[K, V]) getCacheMap(key string, ids []K) (v map[K]V, idsNone []K) {
v = make(map[K]V)
idsNone = make([]K, 0, len(ids))

// id去重
ids = lo.Uniq(ids)
idsNone := make([]K, 0, len(ids))
for _, id := range ids {
cacheKey := c.getKey(key, id)
resT, innerErr := c.GetCacheData(cacheKey)
Expand All @@ -45,7 +80,7 @@ func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K
// 反序列化
value, innerErr = unmarshal[V](resT)
if innerErr != nil {
xlog.Jupiter().Error("cache unmarshalWithPool", zap.String("key", key), zap.Error(err))
xlog.Jupiter().Error("cache unmarshalWithPool", zap.String("key", key), zap.Error(innerErr))
} else {
v[id] = value
}
Expand All @@ -54,6 +89,11 @@ func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K
idsNone = append(idsNone, id)
}
}
return
}

func (c *cache[K, V]) setCacheMap(key string, idsNone []K, fn func([]K) (map[K]V, error), v map[K]V) (err error) {
args := []zap.Field{zap.Any("key", key), zap.Any("ids", idsNone)}

if len(idsNone) == 0 {
return
Expand All @@ -67,8 +107,10 @@ func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K
}

// 填入返回中
for k, value := range resMap {
v[k] = value
if v != nil {
for k, value := range resMap {
v[k] = value
}
}

// 写入缓存
Expand All @@ -78,7 +120,7 @@ func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K
data []byte
)

if val, ok := v[id]; ok {
if val, ok := resMap[id]; ok {
cacheData = val
}
// 序列化
Expand Down
40 changes: 40 additions & 0 deletions pkg/cache/xfreecache/v2/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ func Test_cache_GetAndSetCacheData(t *testing.T) {
assert.Equalf(t, tt.stu, result, "GetAndSetCacheData(%v) cache value error", key)
}
assert.Equalf(t, missCount, 3, "GetAndSetCacheData miss count error")

missCount = 0
for _, tt := range tests {
key := fmt.Sprintf("%d-%s-new", tt.stu.Age, tt.stu.Name)

result := oneCache.GetCacheValue(key, tt.stu.Name)
fmt.Println(result)
if result == (Student{}) {
missCount++
fmt.Println("local cache miss hit")
} else {
assert.Equalf(t, tt.stu, result, "split GetAndSetCacheData(%v) cache value error", key)
}

err := oneCache.SetCacheValue(key, tt.stu.Name, func() (Student, error) {
return tt.stu, nil
})
assert.Emptyf(t, err, "split GetAndSetCacheData err not nil")
}
assert.Equalf(t, missCount, 3, "split GetAndSetCacheData miss count error")
}

func Test_cache_GetAndSetCacheData_proto(t *testing.T) {
Expand Down Expand Up @@ -134,6 +154,26 @@ func Test_cache_GetAndSetCacheData_proto(t *testing.T) {
assert.Equalf(t, tt.stu.GetName(), result.GetName(), "GetAndSetCacheData(%v) cache value error", key)
}
assert.Equalf(t, missCount, 4, "GetAndSetCacheData miss count error")

missCount = 0
for _, tt := range tests {
key := tt.stu.GetName() + "-new"

result := oneCache.GetCacheValue(key, tt.stu.GetName())
fmt.Println(result)
if result == nil {
missCount++
fmt.Println("local cache miss hit")
} else {
assert.Equalf(t, tt.stu.GetName(), result.GetName(), "split GetAndSetCacheData(%v) cache value error", key)
}

err := oneCache.SetCacheValue(key, tt.stu.GetName(), func() (*helloworldv1.SayHiRequest, error) {
return tt.stu, nil
})
assert.Emptyf(t, err, "split GetAndSetCacheData err not nil")
}
assert.Equalf(t, missCount, 5, "split GetAndSetCacheData miss count error")
}

func Test_cache_GetAndSetCacheMap(t *testing.T) {
Expand Down
26 changes: 26 additions & 0 deletions website/docs/jupiter/4.9freecache.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ func NewInstance() *Instance {
// err fn返回的错误以及其他报错
func (c *cache[K, V]) GetAndSetCacheData(key string, id K, fn func() (V, error)) (value V, err error)

// GetCacheValue 获取缓存数据
// key 缓存key
// id 索引(无作用,会组装到key里面)
// value
func (c *cache[K, V]) GetCacheValue(key string, id K) (value V)

// SetCacheValue 设置缓存数据
// key 缓存key
// id 索引(无作用,会组装到key里面)
// fn 获取返回数据需要执行的方法
// err fn返回的错误以及其他报错
func (c *cache[K, V]) SetCacheValue(key string, id K, fn func() (V, error)) (err error)

// GetAndSetCacheMap 获取缓存后数据 map形式 【推荐使用】
// key 缓存key
// ids 返回map中的key集合
Expand All @@ -73,6 +86,19 @@ func (c *cache[K, V]) GetAndSetCacheData(key string, id K, fn func() (V, error))
// err fn返回的错误以及其他报错
func (c *cache[K, V]) GetAndSetCacheMap(key string, ids []K, fn func([]K) (map[K]V, error)) (v map[K]V, err error)

// GetCacheMap 获取缓存数据 map形式
// key 缓存key
// ids 返回map中的key集合
// value
func (c *cache[K, V]) GetCacheMap(key string, ids []K) (v map[K]V)

// SetCacheMap 设置缓存数据 map形式
// key 缓存key
// ids 返回map中的key集合
// fn 获取返回数据需要执行的方法
// err fn返回的错误以及其他报错
func (c *cache[K, V]) SetCacheMap(key string, ids []K, fn func([]K) (map[K]V, error)) (err error)

// SetCacheData 设置本地缓存
// key 缓存key
// data 缓存value,传入序列化后的字节数组
Expand Down

0 comments on commit fe36353

Please sign in to comment.