Added ability to make referenced value purgable. This allows an instance to be constructed with weak referenced keys whose values are purged when the keys are garbage collected.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/collections/trunk@131042 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Burrell Donkin 2003-05-07 09:18:58 +00:00
parent 9e9541ec69
commit 1ebd856d1f
2 changed files with 96 additions and 8 deletions

View File

@ -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 <Code>ReferenceMap</Code> 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 <Code>ReferenceMap</Code> that will
@ -251,6 +271,29 @@ public class ReferenceMap extends AbstractMap {
this(keyType, valueType, 16, 0.75f);
}
/**
* Constructs a new <Code>ReferenceMap</Code> 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 <Code>ReferenceMap</Code> 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;
}

View File

@ -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;
}
}
}
}