-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathalfu.go
More file actions
178 lines (154 loc) · 4 KB
/
Copy pathalfu.go
File metadata and controls
178 lines (154 loc) · 4 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package gocache
import (
"time"
)
// 基于 lfu 算法, 自动计算 访问频率
type Alfu[K comparable, V any] struct {
*Lfu[K, V]
}
// 唯一不同的多了一个自动计算 频率的goroutine
func (alfu *Alfu[K, V]) auto() {
tick := time.NewTicker(time.Hour * 24)
for range tick.C {
alfu.reduce()
}
}
func (alfu *Alfu[K, V]) Reduce() {
alfu.mu.Lock()
for index, lru := range alfu.layer {
if lru.last == nil {
continue
}
if index == alfu.min {
continue
}
key, value, _ := lru.GetLastKeyUpdateTime()
// 如果最后访问的时间大于1天时间了, 那么将访问频率减少一半
// 删除
lru.Remove(key)
// 添加到新层中
alfu.cache[key] = index / 2
newLevel := alfu.cache[key] / alfu.claddingSize
if alfu.min > newLevel {
alfu.min = newLevel
}
alfu.add(newLevel, key, value)
}
alfu.mu.Unlock()
}
func (alfu *Alfu[K, V]) reduce() {
alfu.mu.Lock()
for index, lru := range alfu.layer {
if index == alfu.min {
continue
}
key, value, update_time := lru.GetLastKeyUpdateTime()
if time.Since(update_time).Hours() >= 24 {
// 如果最后访问的时间大于1天时间了, 那么将访问频率减少一半
// 删除
lru.Remove(key)
// 添加到新层中
alfu.cache[key] = index / 2
newLevel := alfu.cache[key] / alfu.claddingSize
if alfu.min > newLevel {
alfu.min = newLevel
}
alfu.add(newLevel, key, value)
}
}
alfu.mu.Unlock()
}
// func (lfu *Alfu[K, V]) OrderPrint(frequent int) {
// lfu.mu.RLock()
// defer lfu.mu.RUnlock()
// for frequent, lru := range lfu.frequent {
// fmt.Printf("%#v\n", lru)
// lru.OrderPrint(frequent)
// }
// }
// // 为了方便修改, 一样也需要一个双向链表
// func (lfu *Alfu[K, V]) add(index int, key K, value V) {
// if _, ok := lfu.frequent[index]; !ok {
// lfu.frequent[index] = &Lru[K, V]{
// lru: make(map[K]*element[K, V], 0),
// size: lfu.size,
// lock: sync.RWMutex{},
// root: &element[K, V]{},
// last: &element[K, V]{},
// }
// }
// lfu.frequent[index].Add(key, value)
// }
// func (lfu *Alfu[K, V]) getMin(start int) int {
// if lfu.frequent[start].Len() > 0 {
// return start
// } else {
// return lfu.getMin(start + 1)
// }
// }
// func (lfu *Alfu[K, V]) Len() int {
// lfu.mu.RLock()
// defer lfu.mu.RUnlock()
// return len(lfu.cache)
// }
// // get lastKey
// func (lfu *Alfu[K, V]) LastKey() K {
// lfu.mu.RLock()
// defer lfu.mu.RUnlock()
// return lfu.frequent[lfu.min].LastKey()
// }
// func (lfu *Alfu[K, V]) Remove(key K) {
// lfu.mu.Lock()
// defer lfu.mu.Unlock()
// // 先找到这个key
// if index, ok := lfu.cache[key]; ok {
// if _, ok := lfu.frequent[index]; ok {
// lfu.frequent[index].Remove(key)
// }
// delete(lfu.cache, key)
// }
// }
// func (lfu *Alfu[K, V]) Add(key K, value V) (K, bool) {
// // 添加一个key
// lfu.mu.Lock()
// defer lfu.mu.Unlock()
// if li, ok := lfu.cache[key]; ok {
// // 如果存在的话,删除此层的值,
// lfu.frequent[li].Remove(key)
// //添加到新层中
// // 判断是否存在新层, 不存在就新建
// lfu.cache[key] = li + 1
// lfu.add(li+1, key, value)
// } else {
// lfu.cache[key] = 1
// lfu.min = 1
// lfu.add(1, key, value)
// // 判断是否超过了缓存值
// if len(lfu.cache) >= lfu.size {
// // 删除最后一个
// removeKey := lfu.frequent[lfu.min].RemoveLast()
// // 删除总缓存
// delete(lfu.cache, removeKey)
// if lfu.frequent[lfu.min].Len() == 0 {
// // 如果长度为空, 我们就要重新获取最小层
// // delete(frequent, min)
// // 继续取最小层数
// lfu.min = lfu.getMin(lfu.min + 1)
// }
// return removeKey, true
// }
// }
// return key, false
// }
// //
// func (lfu *Alfu[K, V]) Get(key K) (V, bool) {
// lfu.mu.RLock()
// defer lfu.mu.RUnlock()
// if index, ok := lfu.cache[key]; ok {
// if v, ok := lfu.frequent[index]; ok {
// return v.Get(key)
// }
// }
// var v V
// return reflect.Zero(reflect.TypeOf(v)).Interface().(V), false
// }