commit 3ef1bc3ab9cbe63bbdf55d293326baa5feaa5a16 Author: ag Date: Fri Sep 13 07:02:36 2024 +0300 initial commit diff --git a/2Q_cache.cpp b/2Q_cache.cpp new file mode 100644 index 0000000..55dc869 --- /dev/null +++ b/2Q_cache.cpp @@ -0,0 +1,85 @@ + +#include +#include +#include "2Q_cache.h" + +class TwoCache { +private: + //2 LRU caches + + size_t cpct_q1; + std::unordered_map::iterator> umap1; + std::list q1; //fast queue - the most popular pages + + size_t cpct_q2; + std::unordered_map::iterator> umap2; + std::list 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 + + int get_page(int id) { //get_page() - returns if page is found, and -1 if not + if(umap1.find(id) != umap1.end()) { + q1.splice(q1.begin(), q1, umap1[id]); //if page did not find in the end of fast(q1) queue - put it in the begin + + return id; + } + + if (umap2.find(id) != umap2.end()) { //if page was not found in the end of slow queue - put is from slow(q2) to begin fast(q1) + auto it = umap2[id]; + + q2.splice(q2.begin(), q2, it); //put this page from queue to the slow + umap2.erase(id); //delete it from slow queue + + if (q1.size() == cpct_q1) { //if q1 is overflowed delete oldest element from fast(q1) + umap1.erase(q1.back()); + q1.pop_back(); + } + q1.push_front(id); //if it is not overflowed put it at the begin + umap2[id] = q1.begin(); + + return id; + } else return -1; //page was not found - return PAGE_DID_NOT_FOUND = -1 + } + + void put_page(int id) { //puts page in cache + if (umap1.find(id) != umap1.end()) { //if page is q1 + return; + } + + if (umap2.find(id) != umap2.end()) { //I know that in this case there will be 2 loops in get_page() i will think about it... + get_page(id); + return; + } + + if (q1.size() == cpct_q1) { //if overflow + umap1.erase(q1.back()); + q1.pop_back(); + } + + if (q2.size() == cpct_q2) { + umap2.erase(q2.back()); + q2.pop_back(); + } + + q1.push_front(id); //in the end push page in cache + umap1[id] = q1.begin(); + } + + + + + + 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 << " "; + } + std::cout << "\ncapacity q1: " << cpct_q1 + << "\ncapacity q2: " << cpct_q2 << std::endl; + } +}; \ No newline at end of file diff --git a/2Q_cache.h b/2Q_cache.h new file mode 100644 index 0000000..5dd716a --- /dev/null +++ b/2Q_cache.h @@ -0,0 +1,14 @@ +#ifndef _2Q_CACHE_H_ +#define _2Q_CACHE_H_ +#include +#include +#include + +class TwoCache { +public: + TwoCache(size_t q1sz, size_t q2sz); + int get_page(int id); + void put_page(int id); + void info(); +}; +#endif \ No newline at end of file diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..d6466b5 --- /dev/null +++ b/main.cpp @@ -0,0 +1,23 @@ +#include + +#include "2Q_cache.h" + + +int main() { + TwoCache cache(2, 4); + cache.put_page(1); + cache.put_page(2); + std::cout << cache.get_page(1) << std::endl; // Вывод: 1 + cache.put_page(1); + cache.put_page(2); + cache.put_page(1); + cache.put_page(2); + cache.put_page(1); + cache.put_page(2); + cache.put_page(3); + std::cout << cache.get_page(2) << std::endl; // Вывод: 2 + cache.put_page(4); // Теперь 4 будет в Q1 + std::cout << cache.get_page(3) << std::endl; // Вывод: -1 (3 нет в кэше) + + return 0; +} \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..08ef223 --- /dev/null +++ b/makefile @@ -0,0 +1,26 @@ + +TARGET = Q2 + +CXX = g++ + +CXXFLAGS = -Wall -Wextra -std=c++11 + +SRCS = 2Q_cache.cpp main.cpp + +OBJS = $(SRCS:.cpp=.o) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) -o $@ $^ + +%.o: %.cpp + $(CXX) $(CXXFLAGS) -c $< -o $@ + +clean: + rm -f $(OBJS) $(TARGET) + +run: $(TARGET) + ./$(TARGET) + +.PHONY: all clean run \ No newline at end of file