-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathcache.go
More file actions
119 lines (104 loc) · 2.42 KB
/
Copy pathcache.go
File metadata and controls
119 lines (104 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package xmux
import (
"sync"
)
var rc *responseCache
// 返回的缓存
type responseCache struct {
store Cacher
status map[string]int // 0 说明是缓存 1 说明是正在更新 2: 说明需要更新
mu sync.RWMutex
}
type Cacher interface {
Add(string, []byte) (string, bool)
Get(string) ([]byte, bool)
}
// 设置缓存值
func SetCache(key string, value []byte) {
rc.mu.Lock()
defer rc.mu.Unlock()
if _, ok := rc.status[key]; ok {
rc.status[key] = 0
}
rk, ok := rc.store.Add(key, value)
if ok {
// 如果删除了值, 也要删除对应的update
delete(rc.status, rk)
}
}
// 获取缓存值, 如果不存在返回nil
func GetCache(key string) []byte {
rc.mu.RLock()
defer rc.mu.RUnlock()
value, ok := rc.store.Get(key)
if ok {
return value
}
return nil
}
type CacheStatus string
const (
NotFoundCache CacheStatus = "Not found cache"
CacheIsUpdateing CacheStatus = "Cache is Updating"
CacheNeedUpdate CacheStatus = "Cache need Updating"
CacheHit CacheStatus = "cache hit"
)
// 获取缓存,如果正在更新
// 如果返回 NotFoundCache 说明不存在这个缓存
// 如果返回 CacheIsUpdateing 说明当前还在更新中, 还不是最新的缓存
// 如果返回 CacheNeedUpdate 说明缓存需要更新
// 如果返回 CacheHit 说明是最新的,可以直接返回
func GetCacheIfUpdating(key string) ([]byte, CacheStatus) {
rc.mu.RLock()
defer rc.mu.RUnlock()
if status, ok := rc.status[key]; ok {
// 判断是否存在,存在, 如果正在更新,并且值是nil
value, _ := rc.store.Get(key)
switch status {
case 0:
return value, CacheHit
case 1:
return nil, CacheIsUpdateing
default:
return nil, CacheNeedUpdate
}
} else {
return nil, NotFoundCache
}
}
// 是否存在缓存
func ExistsCache(key string) bool {
rc.mu.RLock()
defer rc.mu.RUnlock()
_, ok := rc.status[key]
return ok
}
// 是否在更新缓存
func IsUpdate(key string) bool {
rc.mu.RLock()
defer rc.mu.RUnlock()
if v, ok := rc.status[key]; ok {
return v == 1
}
return false
}
// need update cache
func NeedUpdate(key string) {
rc.mu.Lock()
defer rc.mu.Unlock()
rc.status[key] = 2
rc.store.Add(key, nil)
}
func SetUpdate(key string) {
rc.mu.Lock()
defer rc.mu.Unlock()
rc.status[key] = 1
rc.store.Add(key, []byte(""))
}
func InitResponseCache(cache Cacher) {
rc = &responseCache{
store: cache,
status: make(map[string]int),
mu: sync.RWMutex{},
}
}