-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlru.cpp
130 lines (116 loc) · 2.32 KB
/
lru.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef struct Node{
int key;
int val;
struct Node* prev;
struct Node* next;
}Node;
const int MAX_CACHE_SIZE = 5;
//circular doubly linked list
static Node head;
static map<int, Node*> cache;
void list_init()
{
head.key = head.val = 0;
head.prev = head.next = &head;
}
Node* new_node(int key, int val)
{
Node* np = new Node;
np->key = key;
np->val = val;
np->prev = np->next = np; //point to itself
return np;
}
Node* find(int key)
{
map<int, Node*>::iterator iter= cache.find(key);
if(iter == cache.end())
return NULL;
return iter->second;
}
void remove_from_list(Node* node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
//put it to the front
void promote(Node* node)
{
if(node->prev != node && node->next != node){
//not a new node, already in the list, remove it from the list
remove_from_list(node);
}
//insert node in the front
node->next = head.next;
node->prev = &head;
node->prev->next = node;
node->next->prev = node;
}
void set(int key, int val)
{
Node* node = find(key);
if(!node){
node = new_node(key, val);
if(cache.size() >= MAX_CACHE_SIZE){
//evict an entry according to LRU policy (from list tail)
Node* tmp = head.prev;
remove_from_list(tmp);
cache.erase(tmp->key);
delete tmp;
}
//store the address in the cache
cache[key] = node;
}else
node->val = val; //set the value
//put it in list front
promote(node);
}
Node* get(int key)
{
Node* node = find(key);
if(node){
//put it in list front
promote(node);
}
return node;
}
int main()
{
string cmd;
int key, val;
list_init();
while(1){
cout<<"please input command:"<<endl;
cin>>cmd;
if(cmd == "get"){
cin>>key;
Node* np = get(key);
if(np)
cout<<"("<<np->key<<", "<<np->val<<")"<<endl;
else
cout<<"null"<<endl;
}else if(cmd == "set"){
cin>>key>>val;
set(key, val);
}else{
return 0;
}
cout<<"current cache status:"<<endl;
for(Node* np=head.next; np!=&head; np=np->next){
cout<<"("<<np->key<<", "<<np->val<<") ";
}
cout<<endl;
/*
cout<<"current cache status from map:"<<endl;
for(map<int, Node*>::iterator iter= cache.begin(); iter!=cache.end(); iter++){
cout<<"("<<iter->first<<", "<<iter->second->key<<", "<<iter->second->val<<") ";
}
cout<<endl;
*/
}
return 0;
}