From 7e0f7b441fc84f8dc2e2dfb025bc75d80e1d1bc9 Mon Sep 17 00:00:00 2001 From: "Eric J. Bowersox" Date: Wed, 14 Nov 2001 06:00:35 +0000 Subject: [PATCH] first cleanup of cache code - implemented a new CacheMap which uses SoftReferences --- .../util/{cachemap => cache}/CacheMap.java | 119 +++++++++++++++--- .../{cachemap => cache}/CacheMapEntry.java | 93 ++++++++------ .../{cachemap => cache}/CacheMapStrategy.java | 2 +- .../venice/core/impl/AdvertisementImpl.java | 14 +-- .../venice/servlets/format/StaticRender.java | 2 +- 5 files changed, 168 insertions(+), 62 deletions(-) rename src/com/silverwrist/util/{cachemap => cache}/CacheMap.java (81%) rename src/com/silverwrist/util/{cachemap => cache}/CacheMapEntry.java (65%) rename src/com/silverwrist/util/{cachemap => cache}/CacheMapStrategy.java (96%) diff --git a/src/com/silverwrist/util/cachemap/CacheMap.java b/src/com/silverwrist/util/cache/CacheMap.java similarity index 81% rename from src/com/silverwrist/util/cachemap/CacheMap.java rename to src/com/silverwrist/util/cache/CacheMap.java index 7aea300..69e0633 100644 --- a/src/com/silverwrist/util/cachemap/CacheMap.java +++ b/src/com/silverwrist/util/cache/CacheMap.java @@ -15,8 +15,9 @@ * * Contributor(s): */ -package com.silverwrist.util.cachemap; +package com.silverwrist.util.cache; +import java.lang.ref.*; import java.util.*; public class CacheMap implements Map @@ -92,6 +93,7 @@ public class CacheMap implements Map private CacheMapStrategy strategy; // strategy routine to use to purge entries private HashMap base_map; // maps keys to CacheMapEntry values private ArrayList element_list; // the actual elements + private ReferenceQueue rq; // holds references that the garbage collector has cleared /*-------------------------------------------------------------------------------- * Constructors @@ -112,6 +114,7 @@ public class CacheMap implements Map this.strategy = strategy; this.base_map = new HashMap(10); this.element_list = new ArrayList(10); + this.rq = new ReferenceQueue(); } // end constructor @@ -127,6 +130,66 @@ public class CacheMap implements Map } // end constructor + /*-------------------------------------------------------------------------------- + * Internal operations + *-------------------------------------------------------------------------------- + */ + + private void doSweep() + { + Reference r = rq.poll(); + ArrayList ditch = new ArrayList(); + Iterator it; + + while (r!=null) + { // look for the dead reference in the element list + it = element_list.iterator(); + while (it.hasNext()) + { // check each cache map entry in return + CacheMapEntry ntry = (CacheMapEntry)(it.next()); + if (ntry.matchReference(r)) + { // remove the offending entry and save it in the temporary list + it.remove(); + ditch.add(ntry); + break; + + } // end if + + } // end while + + r = rq.poll(); // get next dead reference + + } // end while + + if (ditch.isEmpty()) + return; // nothing to prune + + it = ditch.iterator(); + while (it.hasNext()) + { // clear all entries from the base hashmap as well + CacheMapEntry ntry = (CacheMapEntry)(it.next()); + base_map.remove(ntry.getKey()); + ntry.discard(); + + } // end while + + } // end doSweep + + public synchronized void doShrink(int num_remove) + { + // Sort the element list to figure out which elements to remove. + Collections.sort(element_list,new CacheOrdering(strategy)); + + // The elements we want to remove are at the end of the array, so start from there. + for (int i=0; i capacity) - shrink(); + int nover = (map.size() + base_map.size()) - capacity; + if (nover>0) + doShrink(nover); } // end synchronized block @@ -258,6 +332,14 @@ public class CacheMap implements Map public synchronized void clear() { base_map.clear(); + Iterator it = element_list.iterator(); + while (it.hasNext()) + { // discard all entries we have + CacheMapEntry cme = (CacheMapEntry)(it.next()); + cme.discard(); + + } // end while + element_list.clear(); } // end clear @@ -270,13 +352,13 @@ public class CacheMap implements Map public Collection values() { - return null; // not implemented + throw new UnsupportedOperationException("CacheMap.values() is not implemented"); } // end values public Set entrySet() { - return null; // not implemented + throw new UnsupportedOperationException("CacheMap.entrySet() is not implemented"); } // end entrySet @@ -284,6 +366,7 @@ public class CacheMap implements Map { if ((o==null) || !(o instanceof Map)) return false; // not a map + doSweep(); Map other = (Map)o; if (other.size()!=base_map.size()) return false; // size does matter! @@ -314,6 +397,7 @@ public class CacheMap implements Map public int hashCode() { + doSweep(); int rc = 0; Iterator it = base_map.values().iterator(); while (it.hasNext()) @@ -384,17 +468,16 @@ public class CacheMap implements Map // Figure out how many elements to remove. int num_remove = (element_list.size() * shrink_percentage) / 100; - // Sort the element list to figure out which elements to remove. - Collections.sort(element_list,new CacheOrdering(strategy)); - - // The elements we want to remove are at the end of the array, so start from there. - for (int i=0; i