Skip to content

Commit 44ef192

Browse files
authored
Merge pull request #4 from lxzan/dev
Add SetWithCallback Method
2 parents 8c25fb4 + ddd276c commit 44ef192

File tree

11 files changed

+239
-151
lines changed

11 files changed

+239
-151
lines changed

README.md

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
[4]: https://codecov.io/gh/lxzan/memorycache
1212

1313
### Description
14+
1415
Minimalist in-memory KV storage, powered by hashmap and minimal quad heap, without optimizations for GC.
1516
Cache deprecation policy: the set method cleans up overflowed keys; the cycle cleans up expired keys.
1617

1718
### Principle
19+
1820
- Storage Data Limit: Limited by maximum capacity
1921
- Expiration Time: Supported
2022
- Cache Elimination Policy: LRU-Like, Set method and Cycle Cleanup
@@ -23,6 +25,7 @@ Cache deprecation policy: the set method cleans up overflowed keys; the cycle cl
2325
- Locking Mechanism: Slicing + Mutual Exclusion Locking
2426

2527
### Usage
28+
2629
```go
2730
package main
2831

@@ -34,35 +37,36 @@ import (
3437

3538
func main() {
3639
mc := memorycache.New(
37-
memorycache.WithBucketNum(16),
38-
memorycache.WithBucketSize(1000, 100000),
39-
memorycache.WithInterval(100*time.Millisecond),
40+
memorycache.WithBucketNum(128),
41+
memorycache.WithBucketSize(1000, 10000),
42+
memorycache.WithInterval(5*time.Second, 30*time.Second),
4043
)
4144

42-
mc.Set("xxx", 1, 500*time.Millisecond)
45+
mc.Set("xxx", 1, 10*time.Second)
4346

4447
val, exist := mc.Get("xxx")
4548
fmt.Printf("val=%v, exist=%v\n", val, exist)
4649

47-
time.Sleep(time.Second)
50+
time.Sleep(32 * time.Second)
4851

4952
val, exist = mc.Get("xxx")
5053
fmt.Printf("val=%v, exist=%v\n", val, exist)
5154
}
5255
```
5356

5457
### Benchmark
58+
5559
- 1,000,000 elements
60+
5661
```
57-
go test -benchmem -run=^$ -bench . github.com/lxzan/memorycache/benchmark
58-
goos: linux
62+
goos: windows
5963
goarch: amd64
6064
pkg: github.com/lxzan/memorycache/benchmark
6165
cpu: AMD Ryzen 5 PRO 4650G with Radeon Graphics
62-
BenchmarkMemoryCache_Set-12 11499579 101.7 ns/op 16 B/op 0 allocs/op
63-
BenchmarkMemoryCache_Get-12 26326636 45.97 ns/op 0 B/op 0 allocs/op
64-
BenchmarkRistretto_Set-12 12341542 275.4 ns/op 119 B/op 2 allocs/op
65-
BenchmarkRistretto_Get-12 22825676 50.12 ns/op 16 B/op 1 allocs/op
66+
BenchmarkMemoryCache_Set-12 14058852 73.00 ns/op 14 B/op 0 allocs/op
67+
BenchmarkMemoryCache_Get-12 30767100 34.70 ns/op 0 B/op 0 allocs/op
68+
BenchmarkRistretto_Set-12 15583969 218.4 ns/op 114 B/op 2 allocs/op
69+
BenchmarkRistretto_Get-12 27272788 42.05 ns/op 16 B/op 1 allocs/op
6670
PASS
67-
ok github.com/lxzan/memorycache/benchmark 20.107s
71+
ok github.com/lxzan/memorycache/benchmark 17.232s
6872
```
Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,48 @@
1-
package heap
1+
package memorycache
22

3-
import "github.com/lxzan/memorycache/internal/types"
4-
5-
// New 新建一个堆
3+
// newHeap 新建一个堆
64
// Create a new heap
7-
func New(cap int) *Heap {
8-
return &Heap{Data: make([]*types.Element, 0, cap)}
5+
func newHeap(cap int) *heap {
6+
return &heap{Data: make([]*Element, 0, cap)}
97
}
108

11-
type Heap struct {
12-
Data []*types.Element
9+
type heap struct {
10+
Data []*Element
1311
}
1412

15-
func (c *Heap) Less(i, j int) bool { return c.Data[i].ExpireAt < c.Data[j].ExpireAt }
13+
func (c *heap) Less(i, j int) bool { return c.Data[i].ExpireAt < c.Data[j].ExpireAt }
1614

17-
func (c *Heap) min(i, j int) int {
15+
func (c *heap) min(i, j int) int {
1816
if c.Data[i].ExpireAt < c.Data[j].ExpireAt {
1917
return i
2018
}
2119
return j
2220
}
2321

24-
func (c *Heap) Len() int {
22+
func (c *heap) Len() int {
2523
return len(c.Data)
2624
}
2725

28-
func (c *Heap) Swap(i, j int) {
29-
c.Data[i].Index, c.Data[j].Index = c.Data[j].Index, c.Data[i].Index
26+
func (c *heap) Swap(i, j int) {
27+
c.Data[i].index, c.Data[j].index = c.Data[j].index, c.Data[i].index
3028
c.Data[i], c.Data[j] = c.Data[j], c.Data[i]
3129
}
3230

33-
func (c *Heap) Push(ele *types.Element) {
34-
ele.Index = c.Len()
31+
func (c *heap) Push(ele *Element) {
32+
ele.index = c.Len()
3533
c.Data = append(c.Data, ele)
3634
c.Up(c.Len() - 1)
3735
}
3836

39-
func (c *Heap) Up(i int) {
40-
if i > 0 {
41-
var j = (i - 1) >> 2
42-
if c.Less(i, j) {
43-
c.Swap(i, j)
44-
c.Up(j)
45-
}
37+
func (c *heap) Up(i int) {
38+
var j = (i - 1) >> 2
39+
if i >= 1 && c.Less(i, j) {
40+
c.Swap(i, j)
41+
c.Up(j)
4642
}
4743
}
4844

49-
func (c *Heap) Pop() (ele *types.Element) {
45+
func (c *heap) Pop() (ele *Element) {
5046
var n = c.Len()
5147
switch n {
5248
case 0:
@@ -62,23 +58,25 @@ func (c *Heap) Pop() (ele *types.Element) {
6258
return
6359
}
6460

65-
func (c *Heap) Delete(i int) {
61+
func (c *heap) Delete(i int) {
6662
n := c.Len()
6763
c.Swap(i, n-1)
6864
c.Data = c.Data[:n-1]
6965
c.Down(i, n-1)
7066
}
7167

72-
func (c *Heap) Down(i, n int) {
73-
var j = -1
68+
func (c *heap) Down(i, n int) {
7469
var index1 = i<<2 + 1
70+
if index1 >= n {
71+
return
72+
}
73+
7574
var index2 = i<<2 + 2
7675
var index3 = i<<2 + 3
7776
var index4 = i<<2 + 4
77+
var j = -1
7878

79-
if index1 >= n {
80-
return
81-
} else if index4 < n {
79+
if index4 < n {
8280
j = c.min(c.min(index1, index2), c.min(index3, index4))
8381
} else if index3 < n {
8482
j = c.min(c.min(index1, index2), index3)
@@ -95,7 +93,7 @@ func (c *Heap) Down(i, n int) {
9593
}
9694

9795
// Front 访问堆顶元素
98-
// Accessing the top element of the heap
99-
func (c *Heap) Front() *types.Element {
96+
// Accessing the top Element of the heap
97+
func (c *heap) Front() *Element {
10098
return c.Data[0]
10199
}

internal/heap/heap_test.go renamed to heap_test.go

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
package heap
1+
package memorycache
22

33
import (
4-
"github.com/lxzan/memorycache/internal/types"
54
"github.com/stretchr/testify/assert"
65
"math/rand"
76
"sort"
@@ -10,10 +9,10 @@ import (
109

1110
func TestHeap_Sort(t *testing.T) {
1211
var as = assert.New(t)
13-
var h = New(0)
12+
var h = newHeap(0)
1413
for i := 0; i < 1000; i++ {
1514
num := rand.Int63n(1000)
16-
h.Push(&types.Element{ExpireAt: num})
15+
h.Push(&Element{ExpireAt: num})
1716
}
1817

1918
as.LessOrEqual(h.Front().ExpireAt, h.Data[1].ExpireAt)
@@ -34,17 +33,17 @@ func TestHeap_Sort(t *testing.T) {
3433

3534
func TestHeap_Delete(t *testing.T) {
3635
var as = assert.New(t)
37-
var h = New(0)
38-
h.Push(&types.Element{ExpireAt: 1})
39-
h.Push(&types.Element{ExpireAt: 2})
40-
h.Push(&types.Element{ExpireAt: 3})
41-
h.Push(&types.Element{ExpireAt: 4})
42-
h.Push(&types.Element{ExpireAt: 5})
43-
h.Push(&types.Element{ExpireAt: 6})
44-
h.Push(&types.Element{ExpireAt: 7})
45-
h.Push(&types.Element{ExpireAt: 8})
46-
h.Push(&types.Element{ExpireAt: 9})
47-
h.Push(&types.Element{ExpireAt: 10})
36+
var h = newHeap(0)
37+
h.Push(&Element{ExpireAt: 1})
38+
h.Push(&Element{ExpireAt: 2})
39+
h.Push(&Element{ExpireAt: 3})
40+
h.Push(&Element{ExpireAt: 4})
41+
h.Push(&Element{ExpireAt: 5})
42+
h.Push(&Element{ExpireAt: 6})
43+
h.Push(&Element{ExpireAt: 7})
44+
h.Push(&Element{ExpireAt: 8})
45+
h.Push(&Element{ExpireAt: 9})
46+
h.Push(&Element{ExpireAt: 10})
4847
h.Delete(3)
4948
h.Delete(5)
5049

0 commit comments

Comments
 (0)