Skip to content

Commit b72d466

Browse files
authored
Create ARCCache.java
1 parent ac598e2 commit b72d466

File tree

1 file changed

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

1 file changed

+105
-0
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
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+
* </p>
15+
* <a href="https://en.wikipedia.org/wiki/Adaptive_replacement_cache">...</a>
16+
* @author Adarsh Pandey (<a href="https://github.com/devxadarsh">...</a>)
17+
*
18+
* @param <K> key type
19+
* @param <V> value type
20+
*/
21+
22+
public class ARCCache<K, V> {
23+
private final int capacity;
24+
private final Map<K, V> cache;
25+
private final LinkedHashMap<K, Integer> usageCounts;
26+
private final int p;
27+
private int totalCount;
28+
29+
public ARCCache(int capacity) {
30+
this.capacity = capacity;
31+
this.cache = new LinkedHashMap<>();
32+
this.usageCounts = new LinkedHashMap<>();
33+
this.p = capacity / 2;
34+
this.totalCount = 0;
35+
}
36+
37+
// Function to get data from cache corresponding to the key passed as parameter
38+
public V get(K key) {
39+
if (cache.containsKey(key)) {
40+
usageCounts.put(key, usageCounts.getOrDefault(key, 0) + 1);
41+
return cache.get(key);
42+
}
43+
return null;
44+
}
45+
46+
// Function to put the data in the cache corresponding to the key passed as parameter
47+
public void put(K key, V value) {
48+
if (cache.size() >= capacity) {
49+
evict();
50+
}
51+
cache.put(key, value);
52+
usageCounts.put(key, 1);
53+
totalCount++;
54+
}
55+
56+
// Function to implement the logic of ARCCache
57+
private void evict() {
58+
if (!cache.isEmpty()) {
59+
K keyToRemove = null;
60+
int minUsageCount = Integer.MAX_VALUE;
61+
for (Map.Entry<K, Integer> entry : usageCounts.entrySet()) {
62+
if (entry.getValue() < minUsageCount) {
63+
keyToRemove = entry.getKey();
64+
minUsageCount = entry.getValue();
65+
}
66+
}
67+
cache.remove(keyToRemove);
68+
usageCounts.remove(keyToRemove);
69+
totalCount--;
70+
}
71+
}
72+
73+
74+
public static void main(String[] args) {
75+
76+
// Defining capacity of cache Using Map
77+
ARCCache<String, Integer> cache = new ARCCache<>(5);
78+
cache.put("A", 1);
79+
cache.put("B", 2);
80+
cache.put("C", 3);
81+
cache.put("D", 4);
82+
cache.put("E", 5);
83+
84+
// Printing Cache contents using enhanced for loop
85+
System.out.println("Cache contents:");
86+
for (Map.Entry<String, Integer> entry : cache.cache.entrySet()) {
87+
System.out.println(entry.getKey() + ": " + entry.getValue());
88+
}
89+
90+
// Accessing an existing key
91+
System.out.println("Value of key 'B': " + cache.get("B"));
92+
93+
// Adding a new key
94+
cache.put("F", 6);
95+
96+
// Printing Cache contents after adding Key using enhanced for loop
97+
System.out.println("Cache contents after adding key 'F':");
98+
for (Map.Entry<String, Integer> entry : cache.cache.entrySet()) {
99+
System.out.println(entry.getKey() + ": " + entry.getValue());
100+
}
101+
102+
// Accessing a non existing key
103+
System.out.println("Value of key 'A': " + cache.get("A"));
104+
}
105+
}

0 commit comments

Comments
 (0)