LRU(Least Recently Used)
出發點:在頁式存儲管理中,如果一頁很長時間未被訪問,則它在最近一段時間內也不會被訪問,即時間局部性,那我們就把它調出(置換出)內存,相反的,如果一個數據剛剛被訪問過,那么該數據很大概率會在未來一段時間內訪問。
可以使用棧、隊列、鏈表來簡單實現,在InnoDB中,使用適應性hash,來實現熱點頁的查找(因為快速)。
1. 用棧(數組模擬)簡單實現訪頁邏輯:
1 #include <iostream> 2 using namespace std; 3 4 void conduct(int Size, int Num, int A[100]);//處理函數 5 void print(int a[], int num);//輸出函數 6 7 int main() 8 { 9 int stack_size, num, i, acess[100]; 10 cout << "輸入棧空間:" ; 11 cin >> stack_size; 12 cout << "輸入進程數(Max=100):" ; 13 cin >> num; 14 15 cout << "輸入進程訪頁順序:" ; 16 for(i=0; i<num; i++) 17 { 18 cin >> acess[i]; 19 } 20 21 conduct(stack_size, num, acess); 22 23 return 0; 24 } 25 26 void conduct(int Size, int Num, int A[100]) 27 { 28 int j, k, Stack[Size]; 29 for(j=0; j<Size; j++) 30 { 31 cout << "進入:" << A[j] <<endl; 32 Stack[j]=A[j];//先處理前幾個元素 33 } 34 int locate;bool flag; 35 for(j=Size; j<Num; j++) 36 { 37 flag=false; 38 for(k=0; k<Size; k++) 39 { 40 if(Stack[k]==A[j]) 41 { 42 flag=true; 43 locate=k; 44 } 45 } 46 if(flag==true)//有重復 47 { 48 cout << "重復進程:" << A[j] <<endl; 49 cout << "取出再壓棧" <<endl; 50 int tempp; 51 for(k=locate; k<Size; k++) 52 { 53 Stack[k]=Stack[k+1]; 54 } 55 Stack[Size-1]=A[j]; 56 cout << "壓棧完成" <<endl; 57 cout << "當前順序:"; 58 59 print(Stack, Size); 60 } 61 else 62 { 63 cout << "非重復,壓棧:" << A[j] <<endl; 64 for(k=0; k<Size-1; k++) 65 { 66 Stack[k]=Stack[k+1]; 67 } 68 Stack[Size-1]=A[j]; 69 cout << "置換完成。" <<endl; 70 cout << "當前順序:"; 71 print(Stack, Size); 72 } 73 } 74 } 75 76 void print(int a[], int num) 77 { 78 int k; 79 for(k=0; k<num; k++) 80 { 81 cout << a[k] << " "; 82 } 83 cout << endl; 84 }
Code::Blocks 17.12 運行通過!
結果:
2. 使用lis容器實現LRU邏輯
1 #include <iostream> 2 #include <list> 3 #include <vector> 4 using namespace std; 5 6 class LRU 7 { 8 public: 9 LRU(); 10 ~LRU(); 11 void insret(int x); 12 void printQ(); 13 private: 14 list<int> lst; 15 int count;//當前頁數 16 int max_size = 5;//最大容納頁數 17 }; 18 19 LRU::LRU() 20 { 21 this->count = 0; 22 } 23 24 LRU::~LRU() 25 { 26 } 27 28 //插入算法,先查找,找到先刪除再插入;未找到,直接插入 29 void LRU::insret(int x) 30 { 31 cout << "訪頁:" << x << " "; 32 auto res = find(lst.begin(), lst.end(), x); 33 if (res != lst.end()) 34 { 35 cout << "(exist)" << " "; 36 lst.erase(res); 37 lst.push_front(x); 38 } 39 else 40 { 41 lst.push_front(x); 42 this->count++; 43 } 44 if (this->count > this->max_size) 45 { 46 lst.pop_back(); 47 this->count--; 48 } 49 50 printQ(); 51 } 52 53 //打印list 54 void LRU::printQ() 55 { 56 list<int>::iterator it = this->lst.begin(); 57 cout << "當前隊列/熱點頁:"; 58 for (; it != lst.end(); it++) 59 { 60 cout << *it << " "; 61 } 62 cout << "\ndone. size -- " << this->count << " " << " max_size -- " << this->max_size << endl << endl; 63 } 64 65 int main() 66 { 67 LRU lru; 68 vector<int> test = {1, 3, 2, 4, 2, 3, 1, 5, 6, 7, 1, 7, 3, 2, 1, 3}; 69 for (int i : test) 70 lru.insret(i); 71 return 0; 72 }
結果: