1
1
package com .thealgorithms .datastructures .caches ;
2
2
3
3
import static org .junit .jupiter .api .Assertions .assertEquals ;
4
+ import static org .junit .jupiter .api .Assertions .assertNull ;
5
+ import static org .junit .jupiter .api .Assertions .assertThrows ;
4
6
5
7
import org .junit .jupiter .api .Test ;
6
8
@@ -22,15 +24,15 @@ void testLFUCacheWithIntegerValueShouldPass() {
22
24
lfuCache .put (6 , 60 );
23
25
24
26
// will return null as value with key 2 is now evicted
25
- assertEquals ( null , lfuCache .get (2 ));
27
+ assertNull ( lfuCache .get (2 ));
26
28
27
29
// should return 60
28
30
assertEquals (60 , lfuCache .get (6 ));
29
31
30
32
// this operation will remove value with key as 3
31
33
lfuCache .put (7 , 70 );
32
34
33
- assertEquals ( null , lfuCache .get (2 ));
35
+ assertNull ( lfuCache .get (2 ));
34
36
assertEquals (70 , lfuCache .get (7 ));
35
37
}
36
38
@@ -41,7 +43,7 @@ void testLFUCacheWithStringValueShouldPass() {
41
43
lfuCache .put (2 , "Beta" );
42
44
lfuCache .put (3 , "Gamma" );
43
45
lfuCache .put (4 , "Delta" );
44
- lfuCache .put (5 , "Eplison " );
46
+ lfuCache .put (5 , "Epsilon " );
45
47
46
48
// get method call will increase frequency of key 1 by 1
47
49
assertEquals ("Alpha" , lfuCache .get (1 ));
@@ -50,33 +52,87 @@ void testLFUCacheWithStringValueShouldPass() {
50
52
lfuCache .put (6 , "Digamma" );
51
53
52
54
// will return null as value with key 2 is now evicted
53
- assertEquals ( null , lfuCache .get (2 ));
55
+ assertNull ( lfuCache .get (2 ));
54
56
55
57
// should return string Digamma
56
58
assertEquals ("Digamma" , lfuCache .get (6 ));
57
59
58
60
// this operation will remove value with key as 3
59
61
lfuCache .put (7 , "Zeta" );
60
62
61
- assertEquals ( null , lfuCache .get (2 ));
63
+ assertNull ( lfuCache .get (2 ));
62
64
assertEquals ("Zeta" , lfuCache .get (7 ));
63
65
}
64
66
65
- /**
66
- * test addNodeWithUpdatedFrequency method
67
- * @author yuluo
68
- */
69
67
@ Test
70
- void testAddNodeWithUpdatedFrequency () {
68
+ void testUpdateValueShouldPreserveFrequency () {
71
69
LFUCache <Integer , String > lfuCache = new LFUCache <>(3 );
72
- lfuCache .put (1 , "beijing " );
73
- lfuCache .put (2 , "shanghai " );
74
- lfuCache .put (3 , "gansu " );
70
+ lfuCache .put (1 , "A " );
71
+ lfuCache .put (2 , "B " );
72
+ lfuCache .put (3 , "C " );
75
73
76
- assertEquals ("beijing" , lfuCache .get (1 ));
74
+ assertEquals ("A" , lfuCache .get (1 )); // Accessing key 1
75
+ lfuCache .put (4 , "D" ); // This should evict key 2
77
76
78
- lfuCache .put (1 , "shanxi" );
77
+ assertNull (lfuCache .get (2 )); // Key 2 should be evicted
78
+ assertEquals ("C" , lfuCache .get (3 )); // Key 3 should still exist
79
+ assertEquals ("A" , lfuCache .get (1 )); // Key 1 should still exist
79
80
80
- assertEquals ("shanxi" , lfuCache .get (1 ));
81
+ lfuCache .put (1 , "Updated A" ); // Update the value of key 1
82
+ assertEquals ("Updated A" , lfuCache .get (1 )); // Check if the update was successful
83
+ }
84
+
85
+ @ Test
86
+ void testEvictionPolicyWhenFull () {
87
+ LFUCache <Integer , String > lfuCache = new LFUCache <>(2 );
88
+ lfuCache .put (1 , "One" );
89
+ lfuCache .put (2 , "Two" );
90
+
91
+ assertEquals ("One" , lfuCache .get (1 )); // Access key 1
92
+ lfuCache .put (3 , "Three" ); // This should evict key 2 (least frequently used)
93
+
94
+ assertNull (lfuCache .get (2 )); // Key 2 should be evicted
95
+ assertEquals ("One" , lfuCache .get (1 )); // Key 1 should still exist
96
+ assertEquals ("Three" , lfuCache .get (3 )); // Check if key 3 exists
97
+ }
98
+
99
+ @ Test
100
+ void testGetFromEmptyCacheShouldReturnNull () {
101
+ LFUCache <Integer , String > lfuCache = new LFUCache <>(3 );
102
+ assertNull (lfuCache .get (1 )); // Should return null as the cache is empty
103
+ }
104
+
105
+ @ Test
106
+ void testPutNullValueShouldStoreNull () {
107
+ LFUCache <Integer , String > lfuCache = new LFUCache <>(3 );
108
+ lfuCache .put (1 , null ); // Store a null value
109
+
110
+ assertNull (lfuCache .get (1 )); // Should return null
111
+ }
112
+
113
+ @ Test
114
+ void testInvalidCacheCapacityShouldThrowException () {
115
+ assertThrows (IllegalArgumentException .class , () -> new LFUCache <>(0 ));
116
+ assertThrows (IllegalArgumentException .class , () -> new LFUCache <>(-1 ));
117
+ }
118
+
119
+ @ Test
120
+ void testMultipleAccessPatterns () {
121
+ LFUCache <Integer , String > lfuCache = new LFUCache <>(5 );
122
+ lfuCache .put (1 , "A" );
123
+ lfuCache .put (2 , "B" );
124
+ lfuCache .put (3 , "C" );
125
+ lfuCache .put (4 , "D" );
126
+
127
+ assertEquals ("A" , lfuCache .get (1 )); // Access 1
128
+ lfuCache .put (5 , "E" ); // Should not evict anything yet
129
+ lfuCache .put (6 , "F" ); // Evict B
130
+
131
+ assertNull (lfuCache .get (2 )); // B should be evicted
132
+ assertEquals ("C" , lfuCache .get (3 )); // C should still exist
133
+ assertEquals ("D" , lfuCache .get (4 )); // D should still exist
134
+ assertEquals ("A" , lfuCache .get (1 )); // A should still exist
135
+ assertEquals ("E" , lfuCache .get (5 )); // E should exist
136
+ assertEquals ("F" , lfuCache .get (6 )); // F should exist
81
137
}
82
138
}
0 commit comments