From b4830319021c7db441352da22f5adc9974e9b3ed Mon Sep 17 00:00:00 2001 From: ray Date: Fri, 18 Oct 2002 01:43:46 +0000 Subject: [PATCH] LRU hashmap with rudimentary performance tracking code. git-svn-id: https://samskivert.googlecode.com/svn/trunk@873 6335cc39-0255-0410-8fd6-9bcaacd3b74c --- .../java/com/samskivert/util/LRUHashMap.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 projects/samskivert/src/java/com/samskivert/util/LRUHashMap.java diff --git a/projects/samskivert/src/java/com/samskivert/util/LRUHashMap.java b/projects/samskivert/src/java/com/samskivert/util/LRUHashMap.java new file mode 100644 index 00000000..b465cf37 --- /dev/null +++ b/projects/samskivert/src/java/com/samskivert/util/LRUHashMap.java @@ -0,0 +1,99 @@ +// +// $Id: LRUHashMap.java,v 1.1 2002/10/18 01:43:46 ray Exp $ + +package com.samskivert.util; + +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * A HashMap with LRU functionality and rudimentary performance tracking + * facilities. + */ +public class LRUHashMap extends LinkedHashMap +{ + /** + * Construct a LRUHashMap with the specified maximum size. + */ + public LRUHashMap (int maxSize) + { + super(Math.min(1024, Math.max(16, maxSize)), .75f, true); + _maxSize = maxSize; + } + + /** + * Turn performance tracking on/off. + */ + public void setTracking (boolean track) + { + if (track != _tracking) { + _tracking = track; + if (track) { + _seenKeys = new HashSet(); + _misses = _hits = 0; + + // oh boy, but to properly track we need to clear the hash + clear(); + } else { + _seenKeys = null; + } + } + } + + /** + * Return a measure of the effectiveness of this cache, the ratio of + * hits to misses. + * + * @return an array containing {hits, misses} + */ + public int[] getTrackedEffectiveness () + { + return new int[] {_hits, _misses}; + } + + // documentation inherited + public Object get (Object key) + { + Object result = super.get(key); + + if (_tracking) { + if (result == null) { + if (_seenKeys.contains(key)) { + // only count a miss if we've seen the key before + _misses++; + } + } else { + _hits++; + } + } + + return result; + } + + // documentation inherited + public Object put (Object key, Object value) + { + Object result = super.put(key, value); + + if (_tracking) { + _seenKeys.add(key); + } + + return result; + } + + // documentation inherited + protected boolean removeEldestEntry (Map.Entry eldest) + { + return size() > _maxSize; + } + + /** The maximum size of this cache. */ + protected int _maxSize; + + /** Tracking info. */ + protected boolean _tracking; + protected HashSet _seenKeys; + protected int _hits, _misses; +}