-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathtinylfu_test.go
120 lines (99 loc) · 2.22 KB
/
tinylfu_test.go
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
package tinylfu
import (
"hash/maphash"
"slices"
"testing"
)
func TestAddAlreadyInCache(t *testing.T) {
s := maphash.MakeSeed()
c := New[string, string](100, 10000, func(k string) uint64 {
return maphash.String(s, k)
})
c.Add("foo", "bar")
val, _ := c.Get("foo")
if val != "bar" {
t.Errorf("c.Get(foo)=%q, want %q", val, "bar")
}
c.Add("foo", "baz")
val, _ = c.Get("foo")
if val != "baz" {
t.Errorf("c.Get(foo)=%q, want %q", val, "baz")
}
}
func TestOnEvict(t *testing.T) {
type item struct {
k, v string
}
var evicted []item
var expected = []item{{k: "B", v: "2"}}
s := maphash.MakeSeed()
c := New[string, string](2, 20,
func(k string) uint64 {
return maphash.String(s, k)
},
OnEvict(func(k, v string) {
evicted = append(evicted, item{k, v})
}),
)
c.Add("A", "1")
c.Add("B", "2")
c.Add("C", "3")
if !slices.Equal(evicted, expected) {
t.Errorf("evicted=%+v, expected=%+v", evicted, expected)
}
}
func TestOnReplace(t *testing.T) {
type item struct {
k, v string
}
var evicted []item
var replaced []item
var expected = []item{{k: "A", v: "1"}}
s := maphash.MakeSeed()
c := New[string, string](10, 20,
func(k string) uint64 {
return maphash.String(s, k)
},
OnEvict(func(k, v string) {
evicted = append(evicted, item{k, v})
}),
OnReplace(func(k, v string) {
replaced = append(replaced, item{k, v})
}),
)
c.Add("A", "1")
c.Add("B", "2")
c.Add("A", "3")
if !slices.Equal(evicted, nil) {
t.Errorf("evicted=%+v, expected=%+v", evicted, nil)
}
if !slices.Equal(replaced, expected) {
t.Errorf("replaced=%+v, expected=%+v", replaced, expected)
}
}
func TestNoCachePollution(t *testing.T) {
c := New[int, int](10, 100, func(k int) uint64 { return uint64(k) })
for i := 0; i < 100; i++ {
c.Add(i, i)
for j := 0; j < i; j++ {
v, ok := c.Get(j)
if ok && v != j {
t.Fatalf("c.Get(%d)=%d, want %d", j, v, j)
}
}
}
}
var SinkString string
var SinkBool bool
func BenchmarkGet(b *testing.B) {
s := maphash.MakeSeed()
t := New[string, string](64, 640, func(k string) uint64 {
return maphash.String(s, k)
})
key := "some arbitrary key"
val := "some arbitrary value"
t.Add(key, val)
for i := 0; i < b.N; i++ {
SinkString, SinkBool = t.Get(key)
}
}