Skip to content

Commit d883de9

Browse files
authored
LRU Generic Cache Algorithm
LRU Generic Cache Algorithm using Java generics
1 parent b82cdf7 commit d883de9

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

LRU Generic Cache Algoritm

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
2+
package com.company;
3+
4+
import java.util.LinkedHashMap;
5+
import java.util.Map;
6+
7+
public class Main {
8+
9+
public class LRUCache<K, V> {
10+
11+
private final int capacity;
12+
private final DoublyLinkedList<K, V> cacheList;
13+
private final HashMap<K, Node<K, V>> cacheMap;
14+
15+
public LRUCache(int capacity) {
16+
this.capacity = capacity;
17+
this.cacheList = new DoublyLinkedList<>();
18+
this.cacheMap = new HashMap<>();
19+
}
20+
21+
public V get(K key) {
22+
Node<K, V> node = cacheMap.get(key);
23+
if (node == null) {
24+
return null;
25+
}
26+
27+
moveToHead(node);
28+
return node.value;
29+
}
30+
31+
public void put(K key, V value) {
32+
Node<K, V> existingNode = cacheMap.get(key);
33+
if (existingNode != null) {
34+
existingNode.value = value;
35+
moveToHead(existingNode);
36+
return;
37+
}
38+
39+
Node<K, V> newNode = new Node<>(key, value);
40+
cacheList.addFirst(newNode);
41+
cacheMap.put(key, newNode);
42+
43+
if (cacheList.size() > capacity) {
44+
removeLeastRecentlyUsed();
45+
}
46+
}
47+
48+
private void moveToHead(Node<K, V> node) {
49+
cacheList.remove(node);
50+
cacheList.addFirst(node);
51+
}
52+
53+
private void removeLeastRecentlyUsed() {
54+
Node<K, V> tail = cacheList.removeLast();
55+
cacheMap.remove(tail.key);
56+
}
57+
58+
private static class Node<K, V> {
59+
final K key;
60+
V value;
61+
Node<K, V> prev;
62+
Node<K, V> next;
63+
64+
public Node(K key, V value) {
65+
this.key = key;
66+
this.value = value;
67+
}
68+
}
69+
70+
private static class DoublyLinkedList<K, V> {
71+
72+
private Node<K, V> head;
73+
private Node<K, V> tail;
74+
75+
public void addFirst(Node<K, V> node) {
76+
if (isEmpty()) {
77+
head = tail = node;
78+
} else {
79+
node.next = head;
80+
head.prev = node;
81+
head = node;
82+
}
83+
}
84+
85+
public void remove(Node<K, V> node) {
86+
if (node == head) {
87+
head = head.next;
88+
} else if (node == tail) {
89+
tail = tail.prev;
90+
}
91+
92+
if (node.prev != null) {
93+
node.prev.next = node.next;
94+
}
95+
if (node.next != null) {
96+
node.next.prev = node.prev;
97+
}
98+
}
99+
100+
public Node<K, V> removeLast() {
101+
if (isEmpty()) {
102+
throw new IllegalStateException("List is empty");
103+
}
104+
105+
Node<K, V> last = tail;
106+
remove(last);
107+
return last;
108+
}
109+
110+
public boolean isEmpty() {
111+
return head == null;
112+
}
113+
114+
public int size() {
115+
int size = 0;
116+
Node<K, V> current = head;
117+
while (current != null) {
118+
size++;
119+
current = current.next;
120+
}
121+
return size;
122+
}
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)