diff --git a/src/java/org/apache/commons/collections/ReferenceMap.java b/src/java/org/apache/commons/collections/ReferenceMap.java
index 2580ad164..97c1eec1c 100644
--- a/src/java/org/apache/commons/collections/ReferenceMap.java
+++ b/src/java/org/apache/commons/collections/ReferenceMap.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/ReferenceMap.java,v 1.10 2003/05/06 11:19:26 rdonkin Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/ReferenceMap.java,v 1.11 2003/05/07 09:18:57 rdonkin Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -116,7 +116,7 @@ import java.util.Set;
* @see java.lang.ref.Reference
*
* @since Commons Collections 2.1
- * @version $Revision: 1.10 $ $Date: 2003/05/06 11:19:26 $
+ * @version $Revision: 1.11 $ $Date: 2003/05/07 09:18:57 $
*
* @author Paul Jack
*/
@@ -175,6 +175,11 @@ public class ReferenceMap extends AbstractMap {
* @serial
*/
private float loadFactor;
+
+ /**
+ * Should the value be automatically purged when the associated key has been collected?
+ */
+ private boolean purgeValues = false;
// -- Non-serialized instance variables
@@ -237,6 +242,21 @@ public class ReferenceMap extends AbstractMap {
this(HARD, SOFT);
}
+ /**
+ * Constructs a new ReferenceMap
that will
+ * use the specified types of references.
+ *
+ * @param keyType the type of reference to use for keys;
+ * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
+ * @param valueType the type of reference to use for values;
+ * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
+ * @param purgeValues should the value be automatically purged when the
+ * key is garbage collected
+ */
+ public ReferenceMap(int keyType, int valueType, boolean purgeValues) {
+ this(keyType, valueType);
+ this.purgeValues = purgeValues;
+ }
/**
* Constructs a new ReferenceMap
that will
@@ -251,6 +271,29 @@ public class ReferenceMap extends AbstractMap {
this(keyType, valueType, 16, 0.75f);
}
+ /**
+ * Constructs a new ReferenceMap
with the
+ * specified reference types, load factor and initial
+ * capacity.
+ *
+ * @param keyType the type of reference to use for keys;
+ * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
+ * @param valueType the type of reference to use for values;
+ * must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
+ * @param capacity the initial capacity for the map
+ * @param loadFactor the load factor for the map
+ * @param purgeValues should the value be automatically purged when the
+ * key is garbage collected
+ */
+ public ReferenceMap(
+ int keyType,
+ int valueType,
+ int capacity,
+ float loadFactor,
+ boolean purgeValues) {
+ this(keyType, valueType, capacity, loadFactor);
+ this.purgeValues = purgeValues;
+ }
/**
* Constructs a new ReferenceMap
with the
@@ -778,7 +821,11 @@ public class ReferenceMap extends AbstractMap {
r = r || ((valueType > HARD) && (value == ref));
if (r) {
if (keyType > HARD) ((Reference)key).clear();
- if (valueType > HARD) ((Reference)value).clear();
+ if (valueType > HARD) {
+ ((Reference)value).clear();
+ } else if (purgeValues) {
+ value = null;
+ }
}
return r;
}
diff --git a/src/test/org/apache/commons/collections/TestReferenceMap.java b/src/test/org/apache/commons/collections/TestReferenceMap.java
index c82119cb0..f194eea90 100644
--- a/src/test/org/apache/commons/collections/TestReferenceMap.java
+++ b/src/test/org/apache/commons/collections/TestReferenceMap.java
@@ -1,7 +1,7 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestReferenceMap.java,v 1.7 2003/05/06 11:19:26 rdonkin Exp $
- * $Revision: 1.7 $
- * $Date: 2003/05/06 11:19:26 $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestReferenceMap.java,v 1.8 2003/05/07 09:18:58 rdonkin Exp $
+ * $Revision: 1.8 $
+ * $Date: 2003/05/07 09:18:58 $
*
* ====================================================================
*
@@ -61,6 +61,8 @@
package org.apache.commons.collections;
+import java.lang.ref.WeakReference;
+
import java.util.Map;
import junit.framework.Test;
@@ -70,7 +72,7 @@ import junit.framework.Test;
* Tests for ReferenceMap.
*
* @author Paul Jack
- * @version $Id: TestReferenceMap.java,v 1.7 2003/05/06 11:19:26 rdonkin Exp $
+ * @version $Id: TestReferenceMap.java,v 1.8 2003/05/07 09:18:58 rdonkin Exp $
*/
public class TestReferenceMap extends TestMap {
@@ -186,5 +188,44 @@ public class TestReferenceMap extends TestMap {
return "2.1";
}
-
+ /** Tests whether purge values setting works */
+ public void testPurgeValues() throws Exception {
+ // many thanks to Juozas Baliuka for suggesting this method
+ Object key = new Object();
+ Object value = new Object();
+
+ WeakReference keyReference = new WeakReference(key);
+ WeakReference valueReference = new WeakReference(value);
+
+ Map testMap = new ReferenceMap(ReferenceMap.WEAK, ReferenceMap.HARD, true);
+ testMap.put(key, value);
+
+ assertEquals("In map", value, testMap.get(key));
+ assertNotNull("Weak reference released early (1)", keyReference.get());
+ assertNotNull("Weak reference released early (2)", valueReference.get());
+
+ // dereference strong references
+ key = null;
+ value = null;
+
+ int iterations = 0;
+ int bytz = 2;
+ while(true) {
+ System.gc();
+ if(iterations++ > 50){
+ fail("Max iterations reached before resource released.");
+ }
+ testMap.isEmpty();
+ if(
+ keyReference.get() == null &&
+ valueReference.get() == null) {
+ break;
+
+ } else {
+ // create garbage:
+ byte[] b = new byte[bytz];
+ bytz = bytz * 2;
+ }
+ }
+ }
}