forked from fishercoder1534/Leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLFUCache.java
84 lines (72 loc) · 2.71 KB
/
LFUCache.java
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
package com.fishercoder.solutions;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;
public class LFUCache {
/**
* Wikipedia: The simplest method to employ an LFU algorithm is to assign a counter to every
* block that is loaded into the cache. Each time a reference is made to that block the counter
* is increased by one. When the cache reaches capacity and has a new block waiting to be
* inserted the system will search for the block with the lowest counter and remove it from the
* cache.
*
* Policy to handle frequency ties: based on timestamp, the entries that get set into cache earlier will be evicted first.
*/
class FreqKeyValueTimestamp {
int freq;
int key;
int value;
long timestamp;
}
Map<Integer, FreqKeyValueTimestamp> map;
TreeSet<FreqKeyValueTimestamp> set;
int max;
public LFUCache(int capacity) {
max = capacity;
map = new HashMap<Integer, FreqKeyValueTimestamp>();
set = new TreeSet<FreqKeyValueTimestamp>(new Comparator<FreqKeyValueTimestamp>(){
@Override
public int compare(FreqKeyValueTimestamp o1, FreqKeyValueTimestamp o2) {
if(o1.freq != o2.freq) return o1.freq - o2.freq;
else return (int) (o1.timestamp - o2.timestamp);//it's guaranteed that timestamp will never have two to be the same
}
});
}
public int get(int key) {
if(!map.containsKey(key)) return -1;
else {
FreqKeyValueTimestamp valueObj = map.get(key);
set.remove(valueObj);
valueObj.freq += 1;
valueObj.timestamp = System.currentTimeMillis();
map.put(key, valueObj);
return map.get(key).value;
}
}
public void set(int key, int value) {
if(!map.containsKey(key)){
while(set.size() >= max){
FreqKeyValueTimestamp valueObj = set.pollFirst();
map.remove(valueObj.key);
}
FreqKeyValueTimestamp valueObj = new FreqKeyValueTimestamp();
valueObj.key = key;
valueObj.timestamp = System.currentTimeMillis();
valueObj.value = value;
valueObj.freq = 1;
map.put(key, valueObj);
set.add(valueObj);
}
}
public static void main(String...args){
int capacity = 2;
LFUCache test = new LFUCache(capacity);
test.set(1, 11);
test.set(2, 22);
System.out.println(test.get(1));
test.set(3, 33);
System.out.println(test.get(2));
System.out.println(test.get(3));
}
}