Skip to content

Commit 16f20c6

Browse files
authored
Merge pull request #18 from lxzan/dev
v1.2.0
2 parents d585e85 + ad3b402 commit 16f20c6

File tree

8 files changed

+164
-119
lines changed

8 files changed

+164
-119
lines changed

benchmark/benchmark_test.go

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
const (
1414
sharding = 128
15+
capacity = 10000
1516
benchcount = 1 << 20
1617
)
1718

@@ -20,8 +21,9 @@ var (
2021

2122
options = []memorycache.Option{
2223
memorycache.WithBucketNum(sharding),
23-
memorycache.WithBucketSize(benchcount/sharding/10, benchcount/sharding),
24-
memorycache.WithSwissTable(),
24+
memorycache.WithBucketSize(capacity/10, capacity),
25+
memorycache.WithSwissTable(true),
26+
memorycache.WithLRU(true),
2527
}
2628
)
2729

@@ -87,9 +89,9 @@ func BenchmarkMemoryCache_SetAndGet(b *testing.B) {
8789

8890
func BenchmarkRistretto_Set(b *testing.B) {
8991
var mc, _ = ristretto.NewCache(&ristretto.Config{
90-
NumCounters: benchcount * 10, // number of keys to track frequency of (10M).
91-
MaxCost: 1 << 30, // maximum cost of cache (1GB).
92-
BufferItems: 64, // number of keys per Get buffer.
92+
NumCounters: capacity * sharding * 10, // number of keys to track frequency of (10M).
93+
MaxCost: 1 << 30, // maximum cost of cache (1GB).
94+
BufferItems: 64, // number of keys per Get buffer.
9395
})
9496
b.RunParallel(func(pb *testing.PB) {
9597
var i = 0
@@ -103,9 +105,9 @@ func BenchmarkRistretto_Set(b *testing.B) {
103105

104106
func BenchmarkRistretto_Get(b *testing.B) {
105107
var mc, _ = ristretto.NewCache(&ristretto.Config{
106-
NumCounters: benchcount * 10, // number of keys to track frequency of (10M).
107-
MaxCost: 1 << 30, // maximum cost of cache (1GB).
108-
BufferItems: 64, // number of keys per Get buffer.
108+
NumCounters: capacity * sharding * 10, // number of keys to track frequency of (10M).
109+
MaxCost: 1 << 30, // maximum cost of cache (1GB).
110+
BufferItems: 64, // number of keys per Get buffer.
109111
})
110112
for i := 0; i < benchcount; i++ {
111113
mc.SetWithTTL(benchkeys[i%benchcount], 1, 1, time.Hour)
@@ -124,9 +126,9 @@ func BenchmarkRistretto_Get(b *testing.B) {
124126

125127
func BenchmarkRistretto_SetAndGet(b *testing.B) {
126128
var mc, _ = ristretto.NewCache(&ristretto.Config{
127-
NumCounters: benchcount * 10, // number of keys to track frequency of (10M).
128-
MaxCost: 1 << 30, // maximum cost of cache (1GB).
129-
BufferItems: 64, // number of keys per Get buffer.
129+
NumCounters: capacity * sharding * 10, // number of keys to track frequency of (10M).
130+
MaxCost: 1 << 30, // maximum cost of cache (1GB).
131+
BufferItems: 64, // number of keys per Get buffer.
130132
})
131133
for i := 0; i < benchcount; i++ {
132134
mc.SetWithTTL(benchkeys[i%benchcount], 1, 1, time.Hour)
@@ -148,7 +150,7 @@ func BenchmarkRistretto_SetAndGet(b *testing.B) {
148150
}
149151

150152
func BenchmarkTheine_Set(b *testing.B) {
151-
mc, _ := theine.NewBuilder[string, int](benchcount).Build()
153+
mc, _ := theine.NewBuilder[string, int](sharding * capacity).Build()
152154
b.RunParallel(func(pb *testing.PB) {
153155
i := 0
154156
for pb.Next() {
@@ -160,7 +162,7 @@ func BenchmarkTheine_Set(b *testing.B) {
160162
}
161163

162164
func BenchmarkTheine_Get(b *testing.B) {
163-
mc, _ := theine.NewBuilder[string, int](benchcount).Build()
165+
mc, _ := theine.NewBuilder[string, int](sharding * capacity).Build()
164166
for i := 0; i < benchcount; i++ {
165167
mc.SetWithTTL(benchkeys[i%benchcount], 1, 1, time.Hour)
166168
}
@@ -177,7 +179,7 @@ func BenchmarkTheine_Get(b *testing.B) {
177179
}
178180

179181
func BenchmarkTheine_SetAndGet(b *testing.B) {
180-
mc, _ := theine.NewBuilder[string, int](benchcount).Build()
182+
mc, _ := theine.NewBuilder[string, int](sharding * capacity).Build()
181183
for i := 0; i < benchcount; i++ {
182184
mc.SetWithTTL(benchkeys[i%benchcount], 1, 1, time.Hour)
183185
}

cache.go

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type MemoryCache[K comparable, V any] struct {
2727
// New 创建缓存数据库实例
2828
// Creating a Cached Database Instance
2929
func New[K comparable, V any](options ...Option) *MemoryCache[K, V] {
30-
var conf = &config{TimeCacheEnabled: true}
30+
var conf = &config{CachedTime: true, LRU: true}
3131
options = append(options, withInitialize())
3232
for _, fn := range options {
3333
fn(conf)
@@ -46,10 +46,10 @@ func New[K comparable, V any](options ...Option) *MemoryCache[K, V] {
4646

4747
for i, _ := range mc.storage {
4848
mc.storage[i] = &bucket[K, V]{
49-
MaxCapacity: conf.MaxCapacity,
50-
Map: containers.NewMap[K, *Element[K, V]](conf.InitialSize, conf.SwissTable),
51-
Heap: newHeap[K, V](conf.InitialSize),
52-
List: new(queue[K, V]),
49+
conf: conf,
50+
Map: containers.NewMap[K, *Element[K, V]](conf.BucketSize, conf.SwissTable),
51+
Heap: newHeap[K, V](conf.BucketSize),
52+
List: newQueue[K, V](conf.LRU),
5353
}
5454
}
5555

@@ -66,11 +66,11 @@ func New[K comparable, V any](options ...Option) *MemoryCache[K, V] {
6666
case now := <-ticker.C:
6767
var sum = 0
6868
for _, b := range mc.storage {
69-
sum += b.ExpireCheck(now.UnixMilli(), conf.MaxKeysDeleted)
69+
sum += b.Check(now.UnixMilli(), conf.DeleteLimits)
7070
}
7171

7272
// 删除数量超过阈值, 缩小时间间隔
73-
if d1 := utils.SelectValue(sum > conf.BucketNum*conf.MaxKeysDeleted*7/10, conf.MinInterval, conf.MaxInterval); d1 != d0 {
73+
if d1 := utils.SelectValue(sum > conf.BucketNum*conf.DeleteLimits*7/10, conf.MinInterval, conf.MaxInterval); d1 != d0 {
7474
d0 = d1
7575
ticker.Reset(d0)
7676
}
@@ -102,9 +102,9 @@ func New[K comparable, V any](options ...Option) *MemoryCache[K, V] {
102102
func (c *MemoryCache[K, V]) Clear() {
103103
for _, b := range c.storage {
104104
b.Lock()
105-
b.Heap = newHeap[K, V](c.conf.InitialSize)
106-
b.Map = containers.NewMap[K, *Element[K, V]](c.conf.InitialSize, c.conf.SwissTable)
107-
b.List = new(queue[K, V])
105+
b.Heap = newHeap[K, V](c.conf.BucketSize)
106+
b.Map = containers.NewMap[K, *Element[K, V]](c.conf.BucketSize, c.conf.SwissTable)
107+
b.List = newQueue[K, V](c.conf.LRU)
108108
b.Unlock()
109109
}
110110
}
@@ -123,7 +123,7 @@ func (c *MemoryCache[K, V]) getBucket(key K) *bucket[K, V] {
123123
}
124124

125125
func (c *MemoryCache[K, V]) getTimestamp() int64 {
126-
if c.conf.TimeCacheEnabled {
126+
if c.conf.CachedTime {
127127
return c.timestamp.Load()
128128
}
129129
return time.Now().UnixMilli()
@@ -168,15 +168,17 @@ func (c *MemoryCache[K, V]) SetWithCallback(key K, value V, exp time.Duration, c
168168
var expireAt = c.getExp(exp)
169169
ele, ok := c.fetch(b, key)
170170
if ok {
171-
b.UpdateAll(ele, value, expireAt, cb)
171+
ele.Value, ele.cb = value, cb
172+
b.UpdateTTL(ele, expireAt)
172173
return true
173174
}
174175

175176
b.Insert(key, value, expireAt, cb)
176177
return false
177178
}
178179

179-
// Get
180+
// Get 查询缓存
181+
// query cache
180182
func (c *MemoryCache[K, V]) Get(key K) (v V, exist bool) {
181183
var b = c.getBucket(key)
182184
b.Lock()
@@ -229,7 +231,8 @@ func (c *MemoryCache[K, V]) GetOrCreateWithCallback(key K, value V, exp time.Dur
229231
return value, false
230232
}
231233

232-
// Delete
234+
// Delete 删除缓存
235+
// delete cache
233236
func (c *MemoryCache[K, V]) Delete(key K) (deleted bool) {
234237
var b = c.getBucket(key)
235238
b.Lock()
@@ -244,7 +247,8 @@ func (c *MemoryCache[K, V]) Delete(key K) (deleted bool) {
244247
return true
245248
}
246249

247-
// Range
250+
// Range 遍历缓存. 注意: 不要在回调函数里面操作 MemoryCache[K, V] 实例, 可能会造成死锁.
251+
// Traverse the cache. Note: Do not manipulate MemoryCache[K, V] instances inside callback functions, as this may cause deadlocks.
248252
func (c *MemoryCache[K, V]) Range(f func(K, V) bool) {
249253
var now = time.Now().UnixMilli()
250254
for _, b := range c.storage {
@@ -262,8 +266,8 @@ func (c *MemoryCache[K, V]) Range(f func(K, V) bool) {
262266
}
263267
}
264268

265-
// Len 获取当前元素数量
266-
// Get the number of Elements
269+
// Len 快速获取当前缓存元素数量, 不做过期检查.
270+
// Quickly gets the current number of cached elements, without checking for expiration.
267271
func (c *MemoryCache[K, V]) Len() int {
268272
var num = 0
269273
for _, b := range c.storage {
@@ -276,14 +280,14 @@ func (c *MemoryCache[K, V]) Len() int {
276280

277281
type bucket[K comparable, V any] struct {
278282
sync.Mutex
279-
MaxCapacity int
280-
Map containers.Map[K, *Element[K, V]]
281-
Heap *heap[K, V]
282-
List *queue[K, V]
283+
conf *config
284+
Map containers.Map[K, *Element[K, V]]
285+
Heap *heap[K, V]
286+
List *queue[K, V]
283287
}
284288

285-
// ExpireCheck 过期时间检查
286-
func (c *bucket[K, V]) ExpireCheck(now int64, num int) int {
289+
// Check 过期时间检查
290+
func (c *bucket[K, V]) Check(now int64, num int) int {
287291
c.Lock()
288292
defer c.Unlock()
289293

@@ -302,20 +306,15 @@ func (c *bucket[K, V]) Delete(ele *Element[K, V], reason Reason) {
302306
ele.cb(ele, reason)
303307
}
304308

305-
func (c *bucket[K, V]) UpdateAll(ele *Element[K, V], value V, expireAt int64, cb CallbackFunc[*Element[K, V]]) {
306-
ele.Value = value
307-
ele.cb = cb
308-
c.UpdateTTL(ele, expireAt)
309-
}
310-
311309
func (c *bucket[K, V]) UpdateTTL(ele *Element[K, V], expireAt int64) {
312310
c.Heap.UpdateTTL(ele, expireAt)
313311
c.List.MoveToBack(ele)
314312
}
315313

316314
func (c *bucket[K, V]) Insert(key K, value V, expireAt int64, cb CallbackFunc[*Element[K, V]]) {
317-
if c.List.Len() >= c.MaxCapacity {
318-
c.Delete(c.List.Front(), ReasonEvicted)
315+
if c.Heap.Len() >= c.conf.BucketCap {
316+
head := utils.SelectValue(c.conf.LRU, c.List.Front(), c.Heap.Front())
317+
c.Delete(head, ReasonEvicted)
319318
}
320319

321320
var ele = &Element[K, V]{Key: key, Value: value, ExpireAt: expireAt, cb: cb}

cache_test.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestMemoryCache(t *testing.T) {
2828
var db = New[string, any](
2929
WithInterval(10*time.Millisecond, 10*time.Millisecond),
3030
WithBucketNum(1),
31-
WithTimeCache(false),
31+
WithCachedTime(false),
3232
)
3333
db.Set("a", 1, 100*time.Millisecond)
3434
db.Set("b", 1, 300*time.Millisecond)
@@ -45,7 +45,7 @@ func TestMemoryCache(t *testing.T) {
4545
t.Run("", func(t *testing.T) {
4646
var db = New[string, any](
4747
WithInterval(10*time.Millisecond, 10*time.Millisecond),
48-
WithTimeCache(false),
48+
WithCachedTime(false),
4949
)
5050
db.Set("a", 1, 100*time.Millisecond)
5151
db.Set("b", 1, 200*time.Millisecond)
@@ -62,7 +62,7 @@ func TestMemoryCache(t *testing.T) {
6262
t.Run("", func(t *testing.T) {
6363
var db = New[string, any](
6464
WithInterval(10*time.Millisecond, 10*time.Millisecond),
65-
WithTimeCache(false),
65+
WithCachedTime(false),
6666
)
6767
db.Set("a", 1, 100*time.Millisecond)
6868
db.Set("b", 1, 200*time.Millisecond)
@@ -80,7 +80,7 @@ func TestMemoryCache(t *testing.T) {
8080
var mc = New[string, any](
8181
WithInterval(10*time.Millisecond, 10*time.Millisecond),
8282
WithBucketNum(1),
83-
WithTimeCache(false),
83+
WithCachedTime(false),
8484
)
8585
var m1 = make(map[string]int)
8686
var m2 = make(map[string]int64)
@@ -121,9 +121,9 @@ func TestMemoryCache(t *testing.T) {
121121
t.Run("expire", func(t *testing.T) {
122122
var mc = New[string, any](
123123
WithBucketNum(1),
124-
WithMaxKeysDeleted(3),
124+
WithDeleteLimits(3),
125125
WithInterval(50*time.Millisecond, 100*time.Millisecond),
126-
WithTimeCache(false),
126+
WithCachedTime(false),
127127
)
128128
mc.Set("a", 1, 150*time.Millisecond)
129129
mc.Set("b", 1, 150*time.Millisecond)
@@ -161,6 +161,7 @@ func TestMemoryCache_Set(t *testing.T) {
161161
var mc = New[string, any](
162162
WithBucketNum(1),
163163
WithBucketSize(0, 2),
164+
WithLRU(true),
164165
)
165166
mc.Set("ming", 1, 3*time.Hour)
166167
mc.Set("hong", 1, 1*time.Hour)
@@ -578,7 +579,10 @@ func TestMemoryCache_Range(t *testing.T) {
578579

579580
func TestMemoryCache_LRU(t *testing.T) {
580581
const count = 10000
581-
var mc = New[string, int](WithBucketNum(1))
582+
var mc = New[string, int](
583+
WithBucketNum(1),
584+
WithLRU(true),
585+
)
582586
var indexes []int
583587
for i := 0; i < count; i++ {
584588
indexes = append(indexes, i)
@@ -605,7 +609,9 @@ func TestMemoryCache_LRU(t *testing.T) {
605609
}
606610

607611
func TestMemoryCache_Random(t *testing.T) {
608-
var mc = New[string, int]()
612+
var mc = New[string, int](
613+
WithLRU(true),
614+
)
609615
const count = 10000
610616
for i := 0; i < count; i++ {
611617
var key = string(utils.AlphabetNumeric.Generate(3))

0 commit comments

Comments
 (0)