@@ -15,62 +15,64 @@ int main(int argc, char* argv[]) {
1515 return 1 ;
1616 }
1717 size_t capacity = std::stoull (argv[1 ]);
18- if (capacity < 5 ) { // The simulation needs a capacity of at least 5 to work well
18+ if (capacity < 5 ) {
1919 std::cerr << " Please use a capacity of 5 or greater for this simulation." << std::endl;
2020 return 1 ;
2121 }
2222
2323 CacheManager manager (capacity);
2424 std::atomic<bool > stop_flag (false );
25-
2625 std::thread policyManagerThread (&CacheManager::switchPolicy, &manager, std::ref (stop_flag));
2726
27+ // --- PHASE 1: PROVING LFU IS BETTER ---
2828 separator ();
2929 std::cout << " >>> PHASE 1: Proving LFU is better <<<" << std::endl;
30- std::cout << " Workload: Accessing a few popular items repeatedly." << std::endl;
30+ std::cout << " Workload: Accessing a few popular items repeatedly, then flooding with unique items ." << std::endl;
3131 separator ();
32-
33- // Step 1: Access popular items (0, 1, 2) multiple times to increase their frequency
34- for (int i = 0 ; i < 10 ; ++i) {
35- manager.put (0 , 0 );
36- manager.put (1 , 10 );
37- manager.put (2 , 20 );
38- }
3932
40- // Step 2: Access a series of unique, one-off items to flush out an LRU cache
41- for (int i = 0 ; i < capacity; ++i) {
42- manager.put (100 + i, 1000 + i*10 );
33+ // Step 1: Make keys 0, 1, 2 "popular" by accessing them frequently.
34+ for (int i = 0 ; i < 10 ; ++i) {
35+ manager.put (0 , 0 ); manager.get (0 );
36+ manager.put (1 , 10 ); manager.get (1 );
37+ manager.put (2 , 20 ); manager.get (2 );
4338 }
39+ // Step 2: Flood the cache with new, unique items.
40+ // LRU will discard 0, 1, 2. LFU will keep them because their frequency is high.
41+ for (int i = 0 ; i < capacity; ++i) {
42+ manager.put (100 + i, 1000 + i * 10 );
43+ }
44+ // Step 3: Verify. Try to access the popular items.
45+ std::cout << " Verifying... LFU should have kept the popular items, LRU should not have.\n " ;
46+ manager.get (0 ); // LFU: Hit, LRU: Miss
47+ manager.get (1 ); // LFU: Hit, LRU: Miss
48+ manager.get (2 ); // LFU: Hit, LRU: Miss
4449
45- // Step 3: Now, try to access the popular items again
46- std::cout << " Verifying... trying to access popular items (0, 1, 2)." << std::endl;
47- manager.get (0 ); // LFU should HIT, LRU should MISS
48- manager.get (1 ); // LFU should HIT, LRU should MISS
49- manager.get (2 ); // LFU should HIT, LRU should MISS
50-
51- // Wait for the policy manager to run and see the performance difference
5250 std::this_thread::sleep_for (std::chrono::seconds (6 ));
53-
54- // Reset for the next phase
5551 manager.reset ();
5652
53+ // --- PHASE 2: PROVING LRU IS BETTER ---
5754 separator ();
5855 std::cout << " >>> PHASE 2: Proving LRU is better <<<" << std::endl;
59- std::cout << " Workload: A long, sequential scan of unique items." << std::endl;
56+ std::cout << " Workload: A 'burst' of popular items, followed by a long scan of new items." << std::endl;
6057 separator ();
61-
62- // Step 1: Fill the cache with unique items
63- for (int i = 0 ; i < capacity; ++i) {
64- manager.put (i, i*10 );
58+
59+ // Step 1: Create a "burst" of access for some items to pollute LFU's frequency counts.
60+ for (int i = 0 ; i < 5 ; ++i) {
61+ for (int j = 0 ; j < capacity; ++j) {
62+ manager.put (j, j*10 ); manager.get (j);
63+ }
6564 }
66-
67- // Step 2: Access the most recent half of those items again
68- std::cout << " Verifying... trying to access most recent items." << std::endl;
69- for (int i = capacity / 2 ; i < capacity; ++i) {
70- manager.get (i); // LRU should HIT, LFU performance will depend on its eviction choices
65+ // Step 2: Simulate a long scan of NEW, unique data that will never be used again.
66+ // LRU will correctly discard the old items. LFU will stubbornly hold them due to high frequency.
67+ for (int i = 0 ; i < 2 * capacity; ++i) {
68+ manager.put (100 + i, 1000 + i * 10 );
69+ }
70+ // Step 3: Verify. Try to access the MOST RECENT items from the scan.
71+ std::cout << " Verifying... LRU should have kept the most recent items, LFU should not have.\n " ;
72+ for (int i = 0 ; i < capacity; ++i) {
73+ manager.get (100 + capacity + i); // LRU: Hit, LFU: Miss
7174 }
7275
73- // Wait for the policy manager to run again
7476 std::this_thread::sleep_for (std::chrono::seconds (6 ));
7577
7678 // --- Shutdown ---
0 commit comments