-
Notifications
You must be signed in to change notification settings - Fork 19.7k
/
Copy pathLRUCacheTest.java
149 lines (118 loc) · 3.96 KB
/
LRUCacheTest.java
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
package com.thealgorithms.datastructures.caches;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class LRUCacheTest {
private static final int SIZE = 5;
private LRUCache<Integer, Integer> cache;
@BeforeEach
void setUp() {
cache = new LRUCache<>(SIZE);
}
@Test
public void testBasicOperations() {
cache.put(1, 100);
assertEquals(100, cache.get(1));
assertNull(cache.get(2));
}
@Test
public void testEvictionPolicy() {
// Fill cache to capacity
for (int i = 0; i < SIZE; i++) {
cache.put(i, i * 100);
}
// Verify all elements are present
for (int i = 0; i < SIZE; i++) {
assertEquals(i * 100, cache.get(i));
}
// Add one more element, causing eviction of least recently used
cache.put(SIZE, SIZE * 100);
// First element should be evicted
assertNull(cache.get(0));
assertEquals(SIZE * 100, cache.get(SIZE));
}
@Test
public void testAccessOrder() {
// Fill cache
for (int i = 0; i < SIZE; i++) {
cache.put(i, i);
}
// Access first element, making it most recently used
cache.get(0);
// Add new element, should evict second element (1)
cache.put(SIZE, SIZE);
assertEquals(0, cache.get(0)); // Should still exist
assertNull(cache.get(1)); // Should be evicted
assertEquals(SIZE, cache.get(SIZE)); // Should exist
}
@Test
public void testUpdateExistingKey() {
cache.put(1, 100);
assertEquals(100, cache.get(1));
// Update existing key
cache.put(1, 200);
assertEquals(200, cache.get(1));
}
@Test
public void testNullValues() {
cache.put(1, null);
assertNull(cache.get(1));
// Update null to non-null
cache.put(1, 100);
assertEquals(100, cache.get(1));
// Update non-null to null
cache.put(1, null);
assertNull(cache.get(1));
}
@Test
public void testStringKeysAndValues() {
LRUCache<String, String> stringCache = new LRUCache<>(SIZE);
stringCache.put("key1", "value1");
stringCache.put("key2", "value2");
assertEquals("value1", stringCache.get("key1"));
assertEquals("value2", stringCache.get("key2"));
}
@Test
public void testLongSequenceOfOperations() {
// Add elements beyond capacity multiple times
for (int i = 0; i < SIZE * 3; i++) {
cache.put(i, i * 100);
// Verify only the last SIZE elements are present
for (int j = Math.max(0, i - SIZE + 1); j <= i; j++) {
assertEquals(j * 100, cache.get(j));
}
// Verify elements before the window are evicted
if (i >= SIZE) {
assertNull(cache.get(i - SIZE));
}
}
}
@Test
void testCustomObjects() {
class TestObject {
private final String value;
TestObject(String value) {
this.value = value;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof TestObject) {
return value.equals(((TestObject) obj).value);
}
return false;
}
@Override
public int hashCode() {
return value == null ? 0 : value.hashCode();
}
}
LRUCache<Integer, TestObject> objectCache = new LRUCache<>(SIZE);
TestObject obj1 = new TestObject("test1");
TestObject obj2 = new TestObject("test2");
objectCache.put(1, obj1);
objectCache.put(2, obj2);
assertEquals(obj1, objectCache.get(1));
assertEquals(obj2, objectCache.get(2));
}
}