From 4a1bae3a69a76cae0341b821e3b880e5b8b8f5a3 Mon Sep 17 00:00:00 2001 From: Sam Whited Date: Tue, 28 Oct 2014 12:14:21 -0400 Subject: Subtree merged in minidns --- .../src/main/java/de/measite/minidns/LRUCache.java | 139 +++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 libs/minidns/src/main/java/de/measite/minidns/LRUCache.java (limited to 'libs/minidns/src/main/java/de/measite/minidns/LRUCache.java') diff --git a/libs/minidns/src/main/java/de/measite/minidns/LRUCache.java b/libs/minidns/src/main/java/de/measite/minidns/LRUCache.java new file mode 100644 index 00000000..6b9bbdc1 --- /dev/null +++ b/libs/minidns/src/main/java/de/measite/minidns/LRUCache.java @@ -0,0 +1,139 @@ +package de.measite.minidns; + +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +/** + * LRU based DNSCache backed by a LinkedHashMap. + */ +public class LRUCache implements DNSCache { + + /** + * Internal miss count. + */ + protected long missCount = 0l; + + /** + * Internal expire count (subset of misses that was caused by expire). + */ + protected long expireCount = 0l; + + /** + * Internal hit count. + */ + protected long hitCount = 0l; + + /** + * The internal capacity of the backend cache. + */ + protected int capacity; + + /** + * The upper bound of the ttl. All longer TTLs will be capped by this ttl. + */ + protected long maxTTL; + + /** + * The backend cache. + */ + protected LinkedHashMap backend; + + /** + * Create a new LRUCache with given capacity and upper bound ttl. + * @param capacity The internal capacity. + * @param maxTTL The upper bound for any ttl. + */ + @SuppressWarnings("serial") + public LRUCache(final int capacity, final long maxTTL) { + this.capacity = capacity; + this.maxTTL = maxTTL; + backend = new LinkedHashMap( + Math.min(capacity + (capacity + 3) / 4 + 2, 11), 0.75f, true) + { + @Override + protected boolean removeEldestEntry( + Entry eldest) { + return size() > capacity; + } + }; + } + + /** + * Create a new LRUCache with given capacity. + * @param capacity The capacity of this cache. + */ + public LRUCache(final int capacity) { + this(capacity, Long.MAX_VALUE); + } + + @Override + public synchronized void put(Question q, DNSMessage message) { + if (message.getReceiveTimestamp() <= 0l) { + return; + } + backend.put(q, message); + } + + @Override + public synchronized DNSMessage get(Question q) { + DNSMessage message = backend.get(q); + if (message == null) { + missCount++; + return null; + } + + long ttl = maxTTL; + for (Record r : message.getAnswers()) { + ttl = Math.min(ttl, r.ttl); + } + for (Record r : message.getAdditionalResourceRecords()) { + ttl = Math.min(ttl, r.ttl); + } + if (message.getReceiveTimestamp() + ttl > System.currentTimeMillis()) { + missCount++; + expireCount++; + backend.remove(q); + return null; + } else { + hitCount++; + return message; + } + } + + /** + * Clear all entries in this cache. + */ + public synchronized void clear() { + backend.clear(); + missCount = 0l; + hitCount = 0l; + expireCount = 0l; + } + + /** + * Get the miss count of this cache which is the number of fruitless + * get calls since this cache was last resetted. + * @return The number of cache misses. + */ + public long getMissCount() { + return missCount; + } + + /** + * The number of expires (cache hits that have had a ttl to low to be + * retrieved). + * @return The expire count. + */ + public long getExpireCount() { + return expireCount; + } + + /** + * The cache hit count (all sucessful calls to get). + * @return The hit count. + */ + public long getHitCount() { + return hitCount; + } + +} -- cgit v1.2.3