1 package simplelru
2
3 import "testing"
4
5 func TestLRU(t *testing.T) {
6 evictCounter := 0
7 onEvicted := func(k interface{}, v interface{}) {
8 if k != v {
9 t.Fatalf("Evict values not equal (%v!=%v)", k, v)
10 }
11 evictCounter++
12 }
13 l, err := NewLRU(128, onEvicted)
14 if err != nil {
15 t.Fatalf("err: %v", err)
16 }
17
18 for i := 0; i < 256; i++ {
19 l.Add(i, i)
20 }
21 if l.Len() != 128 {
22 t.Fatalf("bad len: %v", l.Len())
23 }
24
25 if evictCounter != 128 {
26 t.Fatalf("bad evict count: %v", evictCounter)
27 }
28
29 for i, k := range l.Keys() {
30 if v, ok := l.Get(k); !ok || v != k || v != i+128 {
31 t.Fatalf("bad key: %v", k)
32 }
33 }
34 for i := 0; i < 128; i++ {
35 _, ok := l.Get(i)
36 if ok {
37 t.Fatalf("should be evicted")
38 }
39 }
40 for i := 128; i < 256; i++ {
41 _, ok := l.Get(i)
42 if !ok {
43 t.Fatalf("should not be evicted")
44 }
45 }
46 for i := 128; i < 192; i++ {
47 ok := l.Remove(i)
48 if !ok {
49 t.Fatalf("should be contained")
50 }
51 ok = l.Remove(i)
52 if ok {
53 t.Fatalf("should not be contained")
54 }
55 _, ok = l.Get(i)
56 if ok {
57 t.Fatalf("should be deleted")
58 }
59 }
60
61 l.Get(192)
62
63 for i, k := range l.Keys() {
64 if (i < 63 && k != i+193) || (i == 63 && k != 192) {
65 t.Fatalf("out of order key: %v", k)
66 }
67 }
68
69 l.Purge()
70 if l.Len() != 0 {
71 t.Fatalf("bad len: %v", l.Len())
72 }
73 if _, ok := l.Get(200); ok {
74 t.Fatalf("should contain nothing")
75 }
76 }
77
78 func TestLRU_GetOldest_RemoveOldest(t *testing.T) {
79 l, err := NewLRU(128, nil)
80 if err != nil {
81 t.Fatalf("err: %v", err)
82 }
83 for i := 0; i < 256; i++ {
84 l.Add(i, i)
85 }
86 k, _, ok := l.GetOldest()
87 if !ok {
88 t.Fatalf("missing")
89 }
90 if k.(int) != 128 {
91 t.Fatalf("bad: %v", k)
92 }
93
94 k, _, ok = l.RemoveOldest()
95 if !ok {
96 t.Fatalf("missing")
97 }
98 if k.(int) != 128 {
99 t.Fatalf("bad: %v", k)
100 }
101
102 k, _, ok = l.RemoveOldest()
103 if !ok {
104 t.Fatalf("missing")
105 }
106 if k.(int) != 129 {
107 t.Fatalf("bad: %v", k)
108 }
109 }
110
111
112 func TestLRU_Add(t *testing.T) {
113 evictCounter := 0
114 onEvicted := func(k interface{}, v interface{}) {
115 evictCounter++
116 }
117
118 l, err := NewLRU(1, onEvicted)
119 if err != nil {
120 t.Fatalf("err: %v", err)
121 }
122
123 if l.Add(1, 1) == true || evictCounter != 0 {
124 t.Errorf("should not have an eviction")
125 }
126 if l.Add(2, 2) == false || evictCounter != 1 {
127 t.Errorf("should have an eviction")
128 }
129 }
130
131
132 func TestLRU_Contains(t *testing.T) {
133 l, err := NewLRU(2, nil)
134 if err != nil {
135 t.Fatalf("err: %v", err)
136 }
137
138 l.Add(1, 1)
139 l.Add(2, 2)
140 if !l.Contains(1) {
141 t.Errorf("1 should be contained")
142 }
143
144 l.Add(3, 3)
145 if l.Contains(1) {
146 t.Errorf("Contains should not have updated recent-ness of 1")
147 }
148 }
149
150
151 func TestLRU_Peek(t *testing.T) {
152 l, err := NewLRU(2, nil)
153 if err != nil {
154 t.Fatalf("err: %v", err)
155 }
156
157 l.Add(1, 1)
158 l.Add(2, 2)
159 if v, ok := l.Peek(1); !ok || v != 1 {
160 t.Errorf("1 should be set to 1: %v, %v", v, ok)
161 }
162
163 l.Add(3, 3)
164 if l.Contains(1) {
165 t.Errorf("should not have updated recent-ness of 1")
166 }
167 }
168
169
170 func TestLRU_Resize(t *testing.T) {
171 onEvictCounter := 0
172 onEvicted := func(k interface{}, v interface{}) {
173 onEvictCounter++
174 }
175 l, err := NewLRU(2, onEvicted)
176 if err != nil {
177 t.Fatalf("err: %v", err)
178 }
179
180
181 l.Add(1, 1)
182 l.Add(2, 2)
183 evicted := l.Resize(1)
184 if evicted != 1 {
185 t.Errorf("1 element should have been evicted: %v", evicted)
186 }
187 if onEvictCounter != 1 {
188 t.Errorf("onEvicted should have been called 1 time: %v", onEvictCounter)
189 }
190
191 l.Add(3, 3)
192 if l.Contains(1) {
193 t.Errorf("Element 1 should have been evicted")
194 }
195
196
197 evicted = l.Resize(2)
198 if evicted != 0 {
199 t.Errorf("0 elements should have been evicted: %v", evicted)
200 }
201
202 l.Add(4, 4)
203 if !l.Contains(3) || !l.Contains(4) {
204 t.Errorf("Cache should have contained 2 elements")
205 }
206 }
207
View as plain text