Skip to content

Commit 0a0b7d3

Browse files
LFU cache
1 parent c56394b commit 0a0b7d3

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package package1;
2+
3+
import java.util.Comparator;
4+
import java.util.HashMap;
5+
import java.util.List;
6+
import java.util.Map;
7+
import java.util.Map.Entry;
8+
import java.util.PriorityQueue;
9+
import java.util.Queue;
10+
import java.util.TreeMap;
11+
import java.util.TreeSet;
12+
13+
public class LFUCache {
14+
/**
15+
* Wikipedia: The simplest method to employ an LFU algorithm is to assign a counter to every
16+
* block that is loaded into the cache. Each time a reference is made to that block the counter
17+
* is increased by one. When the cache reaches capacity and has a new block waiting to be
18+
* inserted the system will search for the block with the lowest counter and remove it from the
19+
* cache.
20+
*
21+
* Policy to handle frequency ties: based on timestamp, the entries that get set into cache earlier will be evicted first.
22+
*/
23+
24+
class FreqKeyValueTimestamp {
25+
int freq;
26+
int key;
27+
int value;
28+
long timestamp;
29+
}
30+
31+
Map<Integer, FreqKeyValueTimestamp> map;
32+
TreeSet<FreqKeyValueTimestamp> set;
33+
int max;
34+
35+
public LFUCache(int capacity) {
36+
max = capacity;
37+
map = new HashMap<Integer, FreqKeyValueTimestamp>();
38+
set = new TreeSet<FreqKeyValueTimestamp>(new Comparator<FreqKeyValueTimestamp>(){
39+
40+
@Override
41+
public int compare(FreqKeyValueTimestamp o1, FreqKeyValueTimestamp o2) {
42+
if(o1.freq != o2.freq) return o1.freq - o2.freq;
43+
else return (int) (o1.timestamp - o2.timestamp);//it's guaranteed that timestamp will never have two to be the same
44+
}
45+
46+
});
47+
}
48+
49+
public int get(int key) {
50+
if(!map.containsKey(key)) return -1;
51+
else {
52+
FreqKeyValueTimestamp valueObj = map.get(key);
53+
set.remove(valueObj);
54+
valueObj.freq += 1;
55+
valueObj.timestamp = System.currentTimeMillis();
56+
map.put(key, valueObj);
57+
return map.get(key).value;
58+
}
59+
}
60+
61+
public void set(int key, int value) {
62+
if(!map.containsKey(key)){
63+
while(set.size() >= max){
64+
FreqKeyValueTimestamp valueObj = set.pollFirst();
65+
map.remove(valueObj.key);
66+
}
67+
FreqKeyValueTimestamp valueObj = new FreqKeyValueTimestamp();
68+
valueObj.key = key;
69+
valueObj.timestamp = System.currentTimeMillis();
70+
valueObj.value = value;
71+
valueObj.freq = 1;
72+
map.put(key, valueObj);
73+
set.add(valueObj);
74+
}
75+
}
76+
77+
78+
public static void main(String...args){
79+
int capacity = 2;
80+
LFUCache test = new LFUCache(capacity);
81+
test.set(1, 11);
82+
test.set(2, 22);
83+
System.out.println(test.get(1));
84+
test.set(3, 33);
85+
System.out.println(test.get(2));
86+
System.out.println(test.get(3));
87+
}
88+
89+
}

0 commit comments

Comments
 (0)