#include <bits/stdc++.h>
using namespace std;
struct Node {
string key;
string value;
Node* prev;
Node* next;
Node(const string &k, const string &v)
{
key = k;
value = v;
prev = nullptr;
next = nullptr;
}
};
class LRUCache
{
private:
int capacity;
unordered_map<string, Node*> cacheMap;
Node* head;
Node* tail;
void moveToHead(Node* node)
{
if (node == head) return;
if (node->prev) node->prev->next = node->next;
if (node->next) node->next->prev = node->prev;
if (node == tail) tail = node->prev;
node->next = head;
node->prev = nullptr;
if (head) head->prev = node;
head = node;
if (!tail) tail = head;
}
public:
LRUCache(int cap)
{
capacity = cap;
head = nullptr;
tail = nullptr;
}
string get(const string &key)
{
if (cacheMap.count(key))
{
Node* node = cacheMap[key];
moveToHead(node);
cout << "Get: " << key << " -> " << node->value << endl;
return node->value;
}
cout << "Get: " << key << " -> Not found" << endl;
return "";
}
void put(const string &key, const string &value)
{
if (cacheMap.count(key))
{
Node* node = cacheMap[key];
node->value = value;
moveToHead(node);
cout << "Put (update): " << key << " = " << value << endl;
}
else
{
Node* newNode = new Node(key, value);
cacheMap[key] = newNode;
if (head == nullptr) head = tail = newNode;
else
{
newNode->next = head;
head->prev = newNode;
head = newNode;
}
cout << "Put: " << key << " = " << value << endl;
if (cacheMap.size() > capacity)
{
if (tail != nullptr)
{
string evictedKey = tail->key; // Lưu trữ key trước khi xóa
cacheMap.erase(tail->key);
Node* temp = tail;
tail = tail->prev;
if (tail) {
tail->next = nullptr;
} else {
head = nullptr;
}
delete temp;
cout << "Evict: " << evictedKey << endl;
}
else
{
// Trường hợp cache có capacity 1 và đầy
string evictedKey = head->key;
cacheMap.erase(head->key);
delete head;
head = tail = nullptr;
cout << "Evict: " << evictedKey << endl;
}
}
}
}
void printCache() const
{
cout << "Cache: ";
Node* current = head;
while (current) {
cout << "(" << current->key << ":" << current->value << ") ";
current = current->next;
}
cout << endl;
}
~LRUCache()
{
Node* current = head;
while (current) {
Node* next = current->next;
delete current;
current = next;
}
}
};
int main() {
LRUCache lruCache(3);
lruCache.put("1", "one");
lruCache.printCache();
lruCache.put("2", "two");
lruCache.printCache();
lruCache.put("3", "three");
lruCache.printCache();
lruCache.get("2");
lruCache.printCache();
lruCache.put("4", "four");
lruCache.printCache();
lruCache.get("1");
lruCache.printCache();
lruCache.get("3");
lruCache.printCache();
lruCache.put("5", "five");
lruCache.printCache();
LRUCache lruCacheSingle(1);
lruCacheSingle.put("a", "1");
lruCacheSingle.printCache();
lruCacheSingle.put("b", "2");
lruCacheSingle.printCache();
lruCacheSingle.get("b");
lruCacheSingle.printCache();
return 0;
}