Skip to content

Commit 8b4db4a

Browse files
authored
Update LFUCache.cpp
1 parent 37c24ef commit 8b4db4a

File tree

1 file changed

+48
-32
lines changed

1 file changed

+48
-32
lines changed

src/LFUCache.cpp

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,73 @@
1-
#include "LRUCache.h"
2-
#include <algorithm> // Required for std::find
1+
#include "LFUCache.h"
2+
#include <iostream>
33

4-
LRUCache::LRUCache(int capacity) : capacity(capacity) {}
4+
LFUCache::LFUCache(size_t capacity) : capacity(capacity), hits(0), accesses(0) {}
55

6-
// Private helper to move a key to the front of the access_order list
7-
void LRUCache::moveToFront(int key) {
8-
access_order.remove(key);
9-
access_order.push_front(key);
6+
// --- New Methods ---
7+
double LFUCache::getHitRate() const {
8+
if (accesses == 0) return 0.0;
9+
return static_cast<double>(hits.load()) / accesses.load();
1010
}
1111

12-
// Private helper to evict the least recently used item
13-
void LRUCache::evict() {
14-
if (access_order.empty()) return;
15-
16-
// Get the least recently used key from the back of the list
17-
int key_to_evict = access_order.back();
18-
access_order.pop_back();
19-
20-
// Erase it from the cache map
21-
cache.erase(key_to_evict);
12+
void LFUCache::resetStats() {
13+
hits = 0;
14+
accesses = 0;
2215
}
16+
// ---
2317

24-
int LRUCache::get(int key) {
18+
int LFUCache::get(int key) {
2519
std::lock_guard<std::mutex> lock(cache_mutex);
20+
accesses++; // Track every access
2621

27-
// If key is not in the cache, return -1
2822
if (cache.find(key) == cache.end()) {
29-
return -1;
23+
return -1; // Miss
3024
}
31-
32-
// Key exists, so it's being used. Move it to the front.
33-
moveToFront(key);
3425

35-
// Note: Assuming the value is stored in the 'first' element of the pair
26+
hits++; // Track hit
27+
touch(key);
3628
return cache[key].first;
3729
}
3830

39-
void LRUCache::put(int key, int value) {
31+
void LFUCache::put(int key, int value) {
4032
std::lock_guard<std::mutex> lock(cache_mutex);
41-
4233
if (capacity == 0) return;
4334

44-
// If key already exists, update its value and move it to the front
4535
if (cache.find(key) != cache.end()) {
4636
cache[key].first = value;
47-
moveToFront(key);
37+
touch(key);
4838
} else {
49-
// If the cache is full, evict the least recently used item first
5039
if (cache.size() >= capacity) {
5140
evict();
5241
}
53-
// Add the new key-value pair
54-
cache[key] = {value, 0}; // Storing value in .first, .second is unused per your header
55-
access_order.push_front(key);
42+
cache[key] = {value, 1};
43+
freq_map[1].push_front(key);
44+
}
45+
}
46+
47+
// Unchanged private helpers...
48+
void LFUCache::touch(int key) {
49+
int old_freq = cache[key].second;
50+
cache[key].second++;
51+
freq_map[old_freq].remove(key);
52+
if (freq_map[old_freq].empty()) {
53+
freq_map.erase(old_freq);
54+
}
55+
freq_map[cache[key].second].push_front(key);
56+
}
57+
58+
void LFUCache::evict() {
59+
int min_freq = -1;
60+
for(auto const& [freq, keys] : freq_map) {
61+
if(min_freq == -1 || freq < min_freq) {
62+
min_freq = freq;
63+
}
64+
}
65+
if(min_freq != -1) {
66+
int key_to_evict = freq_map[min_freq].back();
67+
freq_map[min_freq].pop_back();
68+
if (freq_map[min_freq].empty()) {
69+
freq_map.erase(min_freq);
70+
}
71+
cache.erase(key_to_evict);
5672
}
5773
}

0 commit comments

Comments
 (0)