1-
1+ /* ******************************************************************************
2+ *
3+ * /\ | _ _ ._ o _|_ |_ ._ _ _
4+ * /--\ | (_| (_) | | |_ | | | | | _>
5+ * _|
6+ *
7+ * Least Recently Used (LRU):
8+ * discards the least recently used items first. This algorithm requires
9+ * keeping track of what was used when, which is expensive if one wants to make
10+ * sure the algorithm always discards the least recently used item. General
11+ * implementations of this technique require keeping "age bits" for cache-lines
12+ * and track the "Least Recently Used" cache-line based on age-bits. In such an
13+ * implementation, every time a cache-line is used,
14+ * the age of all other cache-lines changes
15+ *
16+ * We use this double list to store the cache like this:
17+ *
18+ * NodeHead <==> Node1 <==> Node2 <==> ... ... <==> NodeN <==>NodeNear
19+ *
20+ * the "NodeHead" and "NodeNear" have no data , them just for head and near.
21+ *
22+ * Two Interface:
23+ * getValue : get the value by key ,and put the Node to first
24+ * putValue : add or update the Node's Key and Value, and then,
25+ * put the Node to first
26+ *
27+ * http://en.wikipedia.org/wiki/LRU_cache#Least_Recently_Used
28+ *
29+ ******************************************************************************/
230
331#ifndef _LRUCACHE_
432#define _LRUCACHE_
533
6-
734#include < iostream>
835#include < string>
936#include < stdio.h>
1037#include < stdlib.h>
1138#include < string.h>
1239
13- using namespace std ;
14-
15- typedef struct _Node_ {
16-
17- int key;
18- int value;
19-
20- struct _Node_ *next;
21- struct _Node_ *pre ;
22-
23- }CacheNode;
24-
25-
26-
27- class LRUCache {
28-
29- public:
30-
31- LRUCache (int cache_size=10 )
32- {
33- cache_size_=cache_size;
34- cache_real_size_=0 ;
35- p_cache_list_head=new CacheNode ();
36- p_cache_list_near=new CacheNode ();
37- p_cache_list_head->next =p_cache_list_near;
38- p_cache_list_head->pre =NULL ;
39- p_cache_list_near->pre =p_cache_list_head;
40- p_cache_list_near->next =NULL ;
41-
40+ namespace alg {
41+ class LRUCache {
42+ typedef struct _Node_ {
43+ int key;
44+ int value;
45+
46+ struct _Node_ *next;
47+ struct _Node_ *pre ;
48+
49+ } CacheNode;
50+
51+ public:
52+ LRUCache (int cache_size=10 ) {
53+ cache_size_ = cache_size;
54+ cache_real_size_ = 0 ;
55+ p_cache_list_head = new CacheNode ();
56+ p_cache_list_near = new CacheNode ();
57+ p_cache_list_head->next = p_cache_list_near;
58+ p_cache_list_head->pre = NULL ;
59+ p_cache_list_near->pre = p_cache_list_head;
60+ p_cache_list_near->next = NULL ;
4261}
43- ~LRUCache ()
44- {
62+
63+ ~LRUCache () {
4564CacheNode *p;
46- p=p_cache_list_head->next ;
47- while (p!=NULL )
48- {
65+ p = p_cache_list_head->next ;
66+ while (p!=NULL ) {
4967delete p->pre ;
5068p=p->next ;
5169}
5270
5371delete p_cache_list_near;
5472}
5573
56-
57- int getValue (int key)
58- {
74+ int getValue (int key) {
5975CacheNode *p=p_cache_list_head->next ;
60- while (p->next !=NULL )
61- {
62-
63- if (p->key == key) // catch node
64- {
65-
76+ while (p->next !=NULL ) {
77+ if (p->key == key) { // catch node
6678detachNode (p);
6779addToFront (p);
6880return p->value ;
@@ -72,87 +84,68 @@ class LRUCache{
7284return -1 ;
7385}
7486
75- bool putValue (int key,int value)
76- {
87+ bool putValue (int key,int value) {
7788CacheNode *p=p_cache_list_head->next ;
78- while (p->next !=NULL )
79- {
80-
81-
82- if (p->key == key) // catch node
83- {
89+ while (p->next !=NULL ) {
90+ if (p->key == key) { // catch node
8491p->value =value;
8592getValue (key);
8693return true ;
8794}
8895p=p->next ;
8996}
90-
91-
92- if (cache_real_size_ >= cache_size_)
93- {
94- cout << " free" <<endl;
97+
98+ if (cache_real_size_ >= cache_size_) {
99+ std::cout << " free" <<std::endl;
95100p=p_cache_list_near->pre ->pre ;
96101delete p->next ;
97102p->next =p_cache_list_near;
98103p_cache_list_near->pre =p;
99104}
100-
101- p= new CacheNode ();// (CacheNode *)malloc(sizeof(CacheNode));
102-
103- if (p==NULL )
105+
106+ p = new CacheNode ();// (CacheNode *)malloc(sizeof(CacheNode));
107+
108+ if (p==NULL )
104109return false ;
105110
106111addToFront (p);
107112p->key =key;
108113p->value =value;
109-
114+
110115cache_real_size_++;
111-
116+
112117return true ;
113118}
114- void displayNodes ()
115- {
119+
120+ void displayNodes () {
116121CacheNode *p=p_cache_list_head->next ;
117-
118- while (p->next !=NULL )
119- {
120- cout << " Key : " << p->key << " Value : " << p->value << endl;
122+
123+ while (p->next !=NULL ) {
124+ std::cout << " Key : " << p->key << " Value : " << p->value << std::endl;
121125p=p->next ;
122-
126+
123127}
124- cout << endl;
125-
128+ std::cout << std::endl;
126129}
127-
128-
129- private:
130-
131- int cache_size_;
132- int cache_real_size_;
133- CacheNode *p_cache_list_head;
134- CacheNode *p_cache_list_near;
135-
136- void detachNode (CacheNode *node)
137- {
130+
131+ private:
132+ int cache_size_;
133+ int cache_real_size_;
134+ CacheNode *p_cache_list_head;
135+ CacheNode *p_cache_list_near;
136+
137+ void detachNode (CacheNode *node) {
138138node->pre ->next =node->next ;
139139node->next ->pre =node->pre ;
140140}
141- void addToFront (CacheNode *node)
142- {
143-
141+
142+ void addToFront (CacheNode *node) {
144143node->next =p_cache_list_head->next ;
145144p_cache_list_head->next ->pre =node;
146145p_cache_list_head->next =node;
147146node->pre =p_cache_list_head;
148-
149147}
150-
151- };
152-
153-
148+ };
149+ }
154150
155151#endif
156-
157-
158-
0 commit comments