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 << " done. 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 }
结果: