132 lines
4.1 KiB
C++
132 lines
4.1 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) {
|
|
std::cout << "id: " << id << std::endl;
|
|
//std::cout <<__LINE__ << " " << __FILE__<< std::endl;
|
|
|
|
if (umap1.find(id) != umap1.end()) { //page is found, nothing to do (fast case)
|
|
std::cout << "id ="<<id<<" TIC!\n";
|
|
|
|
print_info();
|
|
|
|
return;
|
|
} else if (umap2.find(id) != umap2.end()) {
|
|
std::cout << "id ="<<id<<" TIC!\n";
|
|
|
|
print_info();
|
|
|
|
q2.erase(umap2[id]);
|
|
//if page is in slow put it in fast
|
|
std::cout <<__LINE__ << " " << __FILE__<< std::endl;
|
|
if (q1.size() < cpct_q1) {
|
|
|
|
print_info();
|
|
|
|
q1.push_front(id);
|
|
umap1[id] = q1.begin();
|
|
|
|
} else {
|
|
print_info();
|
|
|
|
int lru_page = q1.back(); //if fast is overflow - delete
|
|
q1.pop_back();
|
|
auto p = umap1.find(lru_page);
|
|
umap1.erase(p);
|
|
// std::cout << "ERASING " << lru_page << "\n";
|
|
// umap1.erase(lru_page);
|
|
// std::cout << "KAAAAl"`<<*(umap1[lru_page]) << "\n";
|
|
q1.push_front(id);
|
|
umap1[id] = q1.begin();
|
|
}
|
|
|
|
} else if (q2.size() < cpct_q2) { //if not in cache put it in slow
|
|
|
|
print_info();
|
|
|
|
q2.push_front(id);
|
|
umap2[id] = q2.begin();
|
|
|
|
|
|
return;
|
|
} else { //if slow is overflow - pop
|
|
|
|
print_info();
|
|
int lru_page = q2.back(); //if fast is overflow - delete
|
|
q2.pop_back();
|
|
auto p = umap2.find(lru_page);
|
|
std::cout<< "ERASING " << *(umap2[lru_page]) <<std::endl;
|
|
umap2.erase(p);
|
|
q2.push_front(id);
|
|
umap2[id] = q2.begin();
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
void print_info() {
|
|
std::cout <<__LINE__ << " " << __FILE__<< std::endl;
|
|
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::cout << "Umap1:\n";
|
|
|
|
for (auto it = umap1.begin(); it != umap1.end(); ++it) {
|
|
std::cout << "Key: " << (it->first) << ", Val: " << *(it->second) << " ";
|
|
}
|
|
|
|
std::cout << std::endl;
|
|
|
|
std::cout << "Umap2:\n";
|
|
|
|
for (auto it = umap2.begin(); it != umap2.end(); ++it) {
|
|
std::cout << "Key: " << it->first << ", Val: " << *(it->second) << " ";
|
|
}
|
|
|
|
std::cout << std::endl<<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 |