70 lines
2.3 KiB
C++
70 lines
2.3 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 in fast queue in the end, nothing to do (fast case)
|
|
std::cout<<"fast case\n";
|
|
|
|
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 info() {
|
|
std::cout << "q1 (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 << " ";
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif |