2024-09-17 12:21:53 +03:00

85 lines
2.7 KiB
C++

#ifndef _2Q_CACHE_H_
#define _2Q_CACHE_H_
#include <iostream>
#include <unordered_map>
#include <list>
class TwoCache {
private:
//2 LRU caches
size_t cpct_q1;
std::unordered_map<int, std::list<int>::iterator> umap1;
std::list <int> q1; //fast queue - the most popular pages
size_t cpct_q2;
std::unordered_map<int, std::list<int>::iterator> umap2;
std::list <int> q2; //slow queue - if page asked at the first time put it to q2, if itasked from q2 it put it to q1,
public:
TwoCache(size_t q1sz, size_t q2sz): cpct_q1(q1sz), cpct_q2(q2sz) {} //ctor
void put_page(int id) {
if (umap1.find(id) != umap1.end()) { //page is found, nothing to do (fast case)
return;
} else if (umap2.find(id) != umap2.end()) {
q2.erase(umap2[id]); //if page is in slow put it in fast
if (q1.size() < cpct_q1) {
q1.push_front(id);
umap1[id] = q1.begin();
} else {
int lru_page = q1.back(); //if fast is overflow - delete
q1.pop_back();
umap1.erase(lru_page);
q1.push_front(id);
umap1[id] = q1.begin();
}
return;
} else if (q2.size() < cpct_q2) { //if not in cache put it in slow
q2.push_front(id);
umap2[id] = q2.begin();
return;
} else { //if slow is overflow - pop
int lru_page = q2.back();
q2.pop_back();
umap2.erase(lru_page);
q2.push_front(id);
umap2[id] = q2.begin();
return;
}
}
void print_info() {
std::cout << "\nq1 (the most usable): ";
for (auto i = q1.begin(); i != q1.end(); i++) {
std::cout << *i << " ";
}
std::cout << "\nq2 (Less usable): ";
for (auto i = q2.begin(); i != q2.end(); i++) {
std::cout << *i << " ";
}
std::cout << std::endl;
}
std::string string_info () { //to easy compare with tests;
std::string answer;
for (auto i = q1.begin(); i != q1.end(); i++) {
answer += std::to_string(*i) + " ";
}
for (auto i = q2.begin(); i != q2.end(); i++) {
answer += std::to_string(*i) + " ";
}
answer.pop_back(); //delete last space
return answer;
}
};
#endif