Skip to content

Commit 0a0130a

Browse files
authored
Adaptive Replacement Cache (ARC)
It aims to provide better performance compared to traditional caching algorithms like LRU (Least Recently Used) and LFU (Least Frequently Used).
1 parent 4882024 commit 0a0130a

File tree

1 file changed

+103
-0
lines changed
  • src/main/java/com/thealgorithms/datastructures/caches

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package com.thealgorithms.datastructures.caches;
2+
3+
import java.util.LinkedHashMap;
4+
import java.util.Map;
5+
/**
6+
* Adaptive Replacement Cache (ARC)
7+
* <p>
8+
* dynamically adjusts cache size based on recent access patterns.
9+
* It aims to provide better performance compared to traditional caching algorithms
10+
* like LRU (Least Recently Used) and LFU (Least Frequently Used).
11+
* It combines elements of LRU (Least Recently Used) and LFU (Least Frequently Used) algorithms
12+
* to efficiently manage frequently accessed and recently used items,
13+
* optimizing cache performance in changing workload scenarios.
14+
* <a href="https://en.wikipedia.org/wiki/Adaptive_replacement_cache">...</a>
15+
* @author Adarsh Pandey (<a href="https://github.com/devxadarsh">...</a>)
16+
*
17+
* @param <K> key type
18+
* @param <V> value type
19+
*/
20+
21+
public class ARCCache<K, V> {
22+
private final int capacity;
23+
private final Map<K, V> cache;
24+
private final LinkedHashMap<K, Integer> usageCounts;
25+
private final int p;
26+
private int totalCount;
27+
28+
public ARCCache(int capacity) {
29+
this.capacity = capacity;
30+
this.cache = new LinkedHashMap<>();
31+
this.usageCounts = new LinkedHashMap<>();
32+
this.p = capacity / 2;
33+
this.totalCount = 0;
34+
}
35+
36+
// Function to get data from cache corresponding to the key passed as parameter
37+
public V get(K key) {
38+
if (cache.containsKey(key)) {
39+
usageCounts.put(key, usageCounts.getOrDefault(key, 0) + 1);
40+
return cache.get(key);
41+
}
42+
return null;
43+
}
44+
45+
// Function to put the data in the cache corresponding to the key passed as parameter
46+
public void put(K key, V value) {
47+
if (cache.size() >= capacity) {
48+
evict();
49+
}
50+
cache.put(key, value);
51+
usageCounts.put(key, 1);
52+
totalCount++;
53+
}
54+
55+
// Function to implement the logic of ARCCache
56+
private void evict() {
57+
if (!cache.isEmpty()) {
58+
K keyToRemove = null;
59+
int minUsageCount = Integer.MAX_VALUE;
60+
for (Map.Entry<K, Integer> entry : usageCounts.entrySet()) {
61+
if (entry.getValue() < minUsageCount) {
62+
keyToRemove = entry.getKey();
63+
minUsageCount = entry.getValue();
64+
}
65+
}
66+
cache.remove(keyToRemove);
67+
usageCounts.remove(keyToRemove);
68+
totalCount--;
69+
}
70+
}
71+
72+
public static void main(String[] args) {
73+
74+
// Defining capacity of cache Using Map
75+
ARCCache<String, Integer> cache = new ARCCache<>(5);
76+
cache.put("A", 1);
77+
cache.put("B", 2);
78+
cache.put("C", 3);
79+
cache.put("D", 4);
80+
cache.put("E", 5);
81+
82+
// Printing Cache contents using enhanced for loop
83+
System.out.println("Cache contents:");
84+
for (Map.Entry<String, Integer> entry : cache.cache.entrySet()) {
85+
System.out.println(entry.getKey() + ": " + entry.getValue());
86+
}
87+
88+
// Accessing an existing key
89+
System.out.println("Value of key 'B': " + cache.get("B"));
90+
91+
// Adding a new key
92+
cache.put("F", 6);
93+
94+
// Printing Cache contents after adding Key using enhanced for loop
95+
System.out.println("Cache contents after adding key 'F':");
96+
for (Map.Entry<String, Integer> entry : cache.cache.entrySet()) {
97+
System.out.println(entry.getKey() + ": " + entry.getValue());
98+
}
99+
100+
// Accessing a non existing key
101+
System.out.println("Value of key 'A': " + cache.get("A"));
102+
}
103+
}

0 commit comments

Comments
 (0)