2024-09-21 11:51:04 +03:00

142 lines
3.8 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:
int tic_number = 0;
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;
if (umap1.find(id) != umap1.end()) { //page is found, nothing to do (fast case)
//std::cout << "id ="<<id<<" TIC!\n";
tic_number++;
//print_info();
return;
} else if (umap2.find(id) != umap2.end()) {
//std::cout << "id ="<<id<<" TIC!\n";
tic_number++;
q2.erase(umap2[id]);
umap2.erase(id);
if (q1.size() < cpct_q1) {
//print_info();
q1.push_front(id);
umap1[id] = q1.begin();
//print_info();
} else {
//print_info();
auto lru_page = q1.back(); //if fast is overflow - delete
umap1.erase(lru_page);
q1.pop_back();
q1.push_front(id);
umap1[id] = q1.begin();
//print_info();
return;
}
} else if (q2.size() < cpct_q2) { //if not in cache put it in slow
//print_info();
q2.push_front(id);
umap2[id] = q2.begin();
//print_info();
return;
} else { //if slow is overflow - pop
//print_info();
int lru_page = q2.back(); //if fast is overflow - delete
umap2.erase(lru_page);
q2.pop_back();
q2.push_front(id);
umap2[id] = q2.begin();
return;
//print_info();
}
}
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