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:
parent
9e9541ec69
commit
1ebd856d1f
|
@ -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
|
||||
*/
|
||||
|
@ -176,6 +176,11 @@ public class ReferenceMap extends AbstractMap {
|
|||
*/
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue