11package com .thealgorithms .datastructures .caches ;
22
33import 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 ;
46
57import org .junit .jupiter .api .Test ;
68
@@ -22,15 +24,15 @@ void testLFUCacheWithIntegerValueShouldPass() {
2224 lfuCache .put (6 , 60 );
2325
2426 // will return null as value with key 2 is now evicted
25- assertEquals ( null , lfuCache .get (2 ));
27+ assertNull ( lfuCache .get (2 ));
2628
2729 // should return 60
2830 assertEquals (60 , lfuCache .get (6 ));
2931
3032 // this operation will remove value with key as 3
3133 lfuCache .put (7 , 70 );
3234
33- assertEquals ( null , lfuCache .get (2 ));
35+ assertNull ( lfuCache .get (2 ));
3436 assertEquals (70 , lfuCache .get (7 ));
3537 }
3638
@@ -41,7 +43,7 @@ void testLFUCacheWithStringValueShouldPass() {
4143 lfuCache .put (2 , "Beta" );
4244 lfuCache .put (3 , "Gamma" );
4345 lfuCache .put (4 , "Delta" );
44- lfuCache .put (5 , "Eplison " );
46+ lfuCache .put (5 , "Epsilon " );
4547
4648 // get method call will increase frequency of key 1 by 1
4749 assertEquals ("Alpha" , lfuCache .get (1 ));
@@ -50,33 +52,87 @@ void testLFUCacheWithStringValueShouldPass() {
5052 lfuCache .put (6 , "Digamma" );
5153
5254 // will return null as value with key 2 is now evicted
53- assertEquals ( null , lfuCache .get (2 ));
55+ assertNull ( lfuCache .get (2 ));
5456
5557 // should return string Digamma
5658 assertEquals ("Digamma" , lfuCache .get (6 ));
5759
5860 // this operation will remove value with key as 3
5961 lfuCache .put (7 , "Zeta" );
6062
61- assertEquals ( null , lfuCache .get (2 ));
63+ assertNull ( lfuCache .get (2 ));
6264 assertEquals ("Zeta" , lfuCache .get (7 ));
6365 }
6466
65- /**
66- * test addNodeWithUpdatedFrequency method
67- * @author yuluo
68- */
6967 @ Test
70- void testAddNodeWithUpdatedFrequency () {
68+ void testUpdateValueShouldPreserveFrequency () {
7169 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 " );
7573
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
7776
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
7980
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
81137 }
82138}
0 commit comments