Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit36e23bb

Browse files
committed
Added LFU cache implementation
1 parentbf223bb commit36e23bb

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
packagecom.caching;
2+
3+
importjava.util.HashMap;
4+
importjava.util.NoSuchElementException;
5+
importjava.util.TreeMap;
6+
7+
/**
8+
* Your LFUCache object can be instantiated and called as such: LFUCache
9+
* lfuCache = new LFUCache(capacity); lfuCache.put(key,value); int param_1 =
10+
* lfuCache.get(key);
11+
*/
12+
classLFUCache<T> {
13+
// internal Node to store cache element
14+
privateclassNode {
15+
intkey;
16+
Tvalue;
17+
intfreq;
18+
Nodenext;
19+
Nodepre;
20+
21+
publicNode(intkey,Tvalue,intfreq) {
22+
this.key =key;
23+
this.value =value;
24+
this.freq =freq;
25+
next =pre =null;
26+
}
27+
28+
publicStringtoString() {
29+
return" Key: " +key +"Value: " +value +"Freq: " +freq;
30+
}
31+
32+
}
33+
34+
// internal Doubly Linked List to store cache nodes
35+
privateclassDLL {
36+
Nodehead;
37+
Nodetail;
38+
intlen;
39+
40+
publicDLL() {
41+
head =newNode(-1,null, -1);
42+
tail =newNode(-1,null, -1);
43+
head.next =tail;
44+
tail.pre =head;
45+
len =0;
46+
}
47+
48+
publicvoidaddToHead(Nodenode) {
49+
node.next =head.next;
50+
head.next.pre =node;
51+
head.next =node;
52+
node.pre =head;
53+
len++;
54+
}
55+
56+
publicvoiddeleteNode(Nodenode) {
57+
node.pre.next =node.next;
58+
node.next.pre =node.pre;
59+
len--;
60+
}
61+
62+
}
63+
64+
privateintcapacity;
65+
privateintsize;
66+
privateTreeMap<Integer,DLL>freq;
67+
privateHashMap<Integer,Node>map;
68+
69+
/**
70+
* instantiates LFUCache with fixed capacity
71+
*
72+
* @param capacity The capacity of the cache. Once the cache reaches capacity,
73+
* new elements will replace old elements in LFU manner
74+
*/
75+
publicLFUCache(intcapacity) {
76+
this.capacity =capacity;
77+
size =0;
78+
freq =newTreeMap<Integer,DLL>();
79+
map =newHashMap<Integer,Node>();
80+
System.out.println("LFUCache initialised with capacity: " +capacity);
81+
}
82+
83+
/**
84+
* To get the cached value for given key
85+
*
86+
* @param key The key (int) of the expected value
87+
* @return corresponding value for input key
88+
* @throws NoSuchElementException if key is absent
89+
*/
90+
publicTget(intkey) {
91+
// Cache hit condition
92+
if (map.containsKey(key)) {
93+
Nodenode =map.get(key);
94+
System.out.println("Returning value from cache:" +node.toString());
95+
DLLdll =freq.get(node.freq);
96+
dll.deleteNode(node);
97+
if (dll.len ==0)
98+
freq.remove(node.freq);
99+
node.freq +=1;
100+
dll =freq.computeIfAbsent(node.freq,k ->newDLL());
101+
dll.addToHead(node);
102+
returnnode.value;
103+
}
104+
// Cache miss condition
105+
thrownewNoSuchElementException("No element for key: " +key);
106+
}
107+
108+
/**
109+
* To put a value in LFU cache with corresponding key
110+
*
111+
* @param key The key (int)
112+
* @param value The value to be cached
113+
*/
114+
publicvoidput(intkey,Tvalue) {
115+
if (capacity ==0) {
116+
System.out.println("Cache set to 0 capacity. No element will be cached");
117+
return;
118+
}
119+
if (map.containsKey(key)) {
120+
System.out.println("Key " +key +" already present in cache.Value will be replaced");
121+
Nodenode =map.get(key);
122+
node.value =value;
123+
DLLdll =freq.get(node.freq);
124+
dll.deleteNode(node);
125+
if (dll.len ==0)
126+
freq.remove(node.freq);
127+
node.freq +=1;
128+
dll =freq.computeIfAbsent(node.freq,k ->newDLL());
129+
dll.addToHead(node);
130+
}else {
131+
System.out.println("Adding new key " +key +" to cache");
132+
Nodenode =newNode(key,value,1);
133+
map.put(key,node);
134+
135+
if (size <capacity) {
136+
size++;
137+
DLLdll =freq.computeIfAbsent(1,k ->newDLL());
138+
dll.addToHead(node);
139+
}else {
140+
System.out.println("Cache at peak capacity.Old values will be removed in LFU fashion");
141+
Integerlowest =freq.firstKey();
142+
DLLdll =freq.get(lowest);
143+
map.remove(dll.tail.pre.key);
144+
System.out.println("Value removed:" +dll.tail.pre.value.toString());
145+
dll.deleteNode(dll.tail.pre);
146+
if (dll.len ==0 &&lowest !=1)
147+
freq.remove(lowest);
148+
DLLfreq_one =freq.computeIfAbsent(1,k ->newDLL());
149+
freq_one.addToHead(node);
150+
}
151+
}
152+
153+
}
154+
155+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
packagecom.caching;
2+
3+
importjava.util.NoSuchElementException;
4+
5+
importorg.junit.jupiter.api.Assertions;
6+
importorg.junit.jupiter.api.Test;
7+
8+
publicclassLFUCacheTest {
9+
10+
@Test
11+
publicvoidtestLFUCache() {
12+
LFUCache<Integer>cache =newLFUCache<Integer>(2/* capacity */ );
13+
14+
cache.put(1,1);
15+
cache.put(2,2);
16+
Assertions.assertEquals(1,cache.get(1));// returns 1
17+
cache.put(3,3);// evicts key 2
18+
Assertions.assertThrows(NoSuchElementException.class, () ->cache.get(2));// throws exception
19+
Assertions.assertEquals(3,cache.get(3));// returns 3.
20+
cache.put(4,4);// evicts key 1.
21+
Assertions.assertThrows(NoSuchElementException.class, () ->cache.get(1));// throws exception
22+
Assertions.assertEquals(3,cache.get(3));// returns 3
23+
Assertions.assertEquals(4,cache.get(4));// returns 4
24+
}
25+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp