Skip to content

Commit

Permalink
Improve LRUCache implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
javadev committed Apr 26, 2018
1 parent ad89c68 commit 7bc6fec
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 69 deletions.
1 change: 0 additions & 1 deletion pom.xml
Expand Up @@ -158,7 +158,6 @@
<option>-keep public class com.github.underscore.lodash.*$ParseException { *; }</option>
<option>-keep public class com.github.underscore.lodash.*$FetchResponse { *; }</option>
<option>-keep public class com.github.underscore.lodash.*$LRUCache { *; }</option>
<option>-keep public class com.github.underscore.lodash.*$Node { *; }</option>
<option>-keepclassmembers class * { *** newArrayList(); *** newLinkedHashSet(); *** newHashSet(java.lang.Iterable); *** newLinkedHashMap(); }</option>
<option>-dontnote com.github.underscore.*$ClassForName</option>
</options>
Expand Down
76 changes: 12 additions & 64 deletions src/main/java/com/github/underscore/lodash/$.java
Expand Up @@ -2827,79 +2827,27 @@ public List<String> words() {
}

public static class LRUCache<K, V> {
private int capacity;
private Map<K, Node<K, V>> map = new HashMap<K, Node<K, V>>();
private Node head;
private Node end;
private static final boolean SORT_BY_ACCESS = true;
private static final float LOAD_FACTOR = 0.75F;
private final LinkedHashMap<K, V> lruCacheMap;
private final int capacity;

public LRUCache(int capacity) {
this.capacity = capacity;
this.lruCacheMap = new LinkedHashMap<K, V>(capacity, LOAD_FACTOR, SORT_BY_ACCESS);
}

public V get(K key) {
if (map.containsKey(key)) {
Node<K, V> node = map.get(key);
remove(node);
setHead(node);
return node.value;
}
return null;
}

public void remove(Node node) {
if (node.pre != null) {
node.pre.next = node.next;
} else {
head = node.next;
}
if (node.next != null) {
node.next.pre = node.pre;
} else {
end = node.pre;
}
return lruCacheMap.get(key);
}

public void setHead(Node node) {
node.next = head;
node.pre = null;
if (head != null) {
head.pre = node;
public void put(K key, V value) {
if (lruCacheMap.containsKey(key)) {
lruCacheMap.remove(key);
} else if (lruCacheMap.size() >= capacity) {
lruCacheMap.remove(lruCacheMap.keySet().iterator().next());
}
head = node;
if (end == null) {
end = head;
}
}

public void set(K key, V value) {
if (map.containsKey(key)) {
Node<K, V> old = map.get(key);
old.value = value;
remove(old);
setHead(old);
} else {
Node<K, V> created = new Node<K, V>(key, value);
if (map.size() >= capacity) {
map.remove(end.key);
remove(end);
setHead(created);
} else {
setHead(created);
}
map.put(key, created);
}
}
}

public static class Node<K, V> {
private K key;
private V value;
private Node pre;
private Node next;

public Node(K key, V value) {
this.key = key;
this.value = value;
lruCacheMap.put(key, value);
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/test/java/com/github/underscore/lodash/MathTest.java
Expand Up @@ -199,14 +199,14 @@ public void sumOfInt() {
public void createLRUCache() {
new $.LRUCache<Integer, String>(0);
$.LRUCache<Integer, String> cache = $.createLRUCache(2);
cache.set(0, "Value 0");
cache.put(0, "Value 0");
assertEquals("Value 0", cache.get(0));
assertNull(cache.get(1));
cache.set(1, "Value 1");
cache.put(1, "Value 1");
assertEquals("Value 1", cache.get(1));
cache.set(1, "Value 1+");
cache.put(1, "Value 1+");
assertEquals("Value 1+", cache.get(1));
cache.set(2, "Value 2");
cache.put(2, "Value 2");
assertEquals("Value 2", cache.get(2));
}

Expand Down

0 comments on commit 7bc6fec

Please sign in to comment.