LRU
是最近最少使用頁面置換算法(Least Recently Used),也就是首先淘汰最長時間未被使用的頁面!node
LFU
是最近最不經常使用頁面置換算法(Least Frequently Used),也就是淘汰必定時期內被訪問次數最少的頁!ios
咱們維護一個有序單鏈表,越靠近鏈表尾部的結點是越早以前訪問的。當有一個新的數據被訪問時,咱們從鏈表頭開始順序遍歷鏈表。web
若是此數據以前已經被緩存在鏈表中了,咱們遍歷獲得這個數據對應的結點,並將其從原來的位置刪除,而後再插入到鏈表的頭部。算法
若是此數據沒有在緩存鏈表中,又能夠分爲兩種狀況:緩存
#include <iostream> #include <list> #include <vector> #include <algorithm> using namespace std; void print(list<int> &physical_block) { for (auto tmp : physical_block) cout << tmp << " "; cout << endl; } int main(void) { // 規定緩存中放置的頁面不超過 4 (也就是list不超過 4) list<int> physical_block; vector<int> pages = {7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2, 1, 2, 0, 1, 7, 0, 1}; for (auto i : pages) //依次訪問頁面 { /*先看在沒在緩存中*/ auto it = std::find(physical_block.begin(), physical_block.end(), i); if (it != physical_block.end()) { cout << i << "在緩存中" << endl; physical_block.erase(it); physical_block.push_front(i); } /*沒在*/ else { cout << i << "不在緩存中" << endl; /*頁面滿了就得刪除並添加*/ if (physical_block.size() >= 4) physical_block.pop_back(); physical_block.push_front(i); } /*打印緩存中的頁面*/ print(physical_block); cout << "********************************" << endl; } }
#include <iostream> #include <list> #include <vector> #include <algorithm> #include <string> #include <functional> #include <unordered_map> using namespace std; class Node { public: Node(std::string str) : data_(str) {} std::string data_; }; namespace std { template <> class hash<Node> { public: int operator()(const Node &s) const { return stoi(s.data_); } }; } // namespace std class LruCache { public: LruCache() : capacity_(0) {} // cpu 訪問數據,須要動態更新緩存 bool PutCache(std::string &str) { Node node(str); int key = hash_fn_(node); auto it = hash_table_.find(key); if (it != hash_table_.end()) { auto list_iter = it->second; cout << node.data_ << "數據已經在內存中...." << endl; double_list_.splice(double_list_.begin(), double_list_, list_iter); } else { cout << node.data_ << "數據未在內存中...." << endl; /*頁面滿了就得刪除並添加*/ if (capacity_ >= 4) { int key = hash_fn_(double_list_.back()); double_list_.pop_back(); hash_table_.erase(key); capacity_--; } double_list_.push_front(node); hash_table_.insert({key, double_list_.begin()}); capacity_++; } for (auto &tt : double_list_) cout << tt.data_ << " "; cout << endl; } private: std::hash<Node> hash_fn_; int capacity_ = 0; //cache capacity,其實就是 list 的容量 //注意是:只用了一條 std::list //對於list中只有元素的刪除操做會致使指向該元素的迭代器失效,其餘元素迭代器不受影響,當刪除元素時,將迭代器置爲空就好了 //或者直接在 hash_map 中 erase 便可 std::list<Node> double_list_; std::unordered_map<int, std::list<Node>::iterator> hash_table_; }; int main(void) { std::string str[] = {"7", "0", "1", "2", "0", "3", "0", "4", "2", "3", "0", "3", "2", "1", "2", "0", "1", "7", "0"}; std::vector<std::string> pages(str, str + 19); LruCache lru; for (auto tt : pages) { lru.PutCache(tt); } }
組織結構以下:
svg