Author: jason.greene(a)jboss.com
Date: 2008-06-10 22:00:37 -0400 (Tue, 10 Jun 2008)
New Revision: 5970
Modified:
pojo/trunk/src/main/java/org/jboss/cache/pojo/util/ConcurrentReferenceHashMap.java
Log:
Merge 5969
Modified:
pojo/trunk/src/main/java/org/jboss/cache/pojo/util/ConcurrentReferenceHashMap.java
===================================================================
---
pojo/trunk/src/main/java/org/jboss/cache/pojo/util/ConcurrentReferenceHashMap.java 2008-06-11
01:45:40 UTC (rev 5969)
+++
pojo/trunk/src/main/java/org/jboss/cache/pojo/util/ConcurrentReferenceHashMap.java 2008-06-11
02:00:37 UTC (rev 5970)
@@ -262,6 +262,7 @@
static interface KeyReference {
int keyHash();
+ Object keyRef();
}
/**
@@ -269,13 +270,17 @@
*/
static final class WeakKeyReference<K> extends WeakReference<K>
implements KeyReference {
final int hash;
- WeakKeyReference(K key, int hash, ReferenceQueue<K> refQueue) {
+ WeakKeyReference(K key, int hash, ReferenceQueue<Object> refQueue) {
super(key, refQueue);
this.hash = hash;
}
public final int keyHash() {
return hash;
}
+
+ public final Object keyRef() {
+ return this;
+ }
}
/**
@@ -283,15 +288,54 @@
*/
static final class SoftKeyReference<K> extends SoftReference<K>
implements KeyReference {
final int hash;
- SoftKeyReference(K key, int hash, ReferenceQueue<K> refQueue) {
+ SoftKeyReference(K key, int hash, ReferenceQueue<Object> refQueue) {
super(key, refQueue);
this.hash = hash;
}
public final int keyHash() {
return hash;
}
+
+ public final Object keyRef() {
+ return this;
+ }
}
+ static final class WeakValueReference<V> extends WeakReference<V>
implements KeyReference {
+ final Object keyRef;
+ final int hash;
+ WeakValueReference(V value, Object keyRef, int hash, ReferenceQueue<Object>
refQueue) {
+ super(value, refQueue);
+ this.keyRef = keyRef;
+ this.hash = hash;
+ }
+
+ public final int keyHash() {
+ return hash;
+ }
+
+ public final Object keyRef() {
+ return keyRef;
+ }
+ }
+
+ static final class SoftValueReference<V> extends SoftReference<V>
implements KeyReference {
+ final Object keyRef;
+ final int hash;
+ SoftValueReference(V value, Object keyRef, int hash, ReferenceQueue<Object>
refQueue) {
+ super(value, refQueue);
+ this.keyRef = keyRef;
+ this.hash = hash;
+ }
+ public final int keyHash() {
+ return hash;
+ }
+
+ public final Object keyRef() {
+ return keyRef;
+ }
+ }
+
/**
* ConcurrentReferenceHashMap list entry. Note that this is never exported
* out as a user-visible Map.Entry.
@@ -312,15 +356,15 @@
HashEntry(K key, int hash, HashEntry<K,V> next, V value,
ReferenceType keyType, ReferenceType valueType,
- ReferenceQueue<K> refQueue) {
- this.keyRef = newKeyReference(key, keyType, hash, refQueue);
+ ReferenceQueue<Object> refQueue) {
this.hash = hash;
this.next = next;
- this.valueRef = newValueReference(value, valueType);
+ this.keyRef = newKeyReference(key, keyType, refQueue);
+ this.valueRef = newValueReference(value, valueType, refQueue);
}
- final Object newKeyReference(K key, ReferenceType keyType, int hash,
- ReferenceQueue<K> refQueue) {
+ final Object newKeyReference(K key, ReferenceType keyType,
+ ReferenceQueue<Object> refQueue) {
if (keyType == ReferenceType.WEAK)
return new WeakKeyReference<K>(key, hash, refQueue);
if (keyType == ReferenceType.SOFT)
@@ -329,11 +373,12 @@
return key;
}
- final Object newValueReference(V value, ReferenceType valueType) {
+ final Object newValueReference(V value, ReferenceType valueType,
+ ReferenceQueue<Object> refQueue) {
if (valueType == ReferenceType.WEAK)
- return new WeakReference<V>(value);
+ return new WeakValueReference<V>(value, keyRef, hash, refQueue);
if (valueType == ReferenceType.SOFT)
- return new SoftReference<V>(value);
+ return new SoftValueReference<V>(value, keyRef, hash, refQueue);
return value;
}
@@ -358,8 +403,8 @@
return (V) value;
}
- final void setValue(V value, ReferenceType valueType) {
- this.valueRef = newValueReference(value, valueType);
+ final void setValue(V value, ReferenceType valueType,
ReferenceQueue<Object> refQueue) {
+ this.valueRef = newValueReference(value, valueType, refQueue);
}
@SuppressWarnings("unchecked")
@@ -452,7 +497,7 @@
* The collected weak-key reference queue for this segment.
* This should be (re)initialized whenever table is assigned,
*/
- transient volatile ReferenceQueue<K> refQueue;
+ transient volatile ReferenceQueue<Object> refQueue;
final ReferenceType keyType;
@@ -485,7 +530,7 @@
void setTable(HashEntry<K,V>[] newTable) {
threshold = (int)(newTable.length * loadFactor);
table = newTable;
- refQueue = new ReferenceQueue<K>();
+ refQueue = new ReferenceQueue<Object>();
}
/**
@@ -581,7 +626,7 @@
boolean replaced = false;
if (e != null && oldValue.equals(e.value())) {
replaced = true;
- e.setValue(newValue, valueType);
+ e.setValue(newValue, valueType, refQueue);
}
return replaced;
} finally {
@@ -600,7 +645,7 @@
V oldValue = null;
if (e != null) {
oldValue = e.value();
- e.setValue(newValue, valueType);
+ e.setValue(newValue, valueType, refQueue);
}
return oldValue;
} finally {
@@ -631,7 +676,7 @@
if (e != null) {
oldValue = e.value();
if (!onlyIfAbsent)
- e.setValue(value, valueType);
+ e.setValue(value, valueType, refQueue);
}
else {
oldValue = null;
@@ -718,19 +763,19 @@
/**
* Remove; match on key only if value null, else match both.
*/
- V remove(Object key, int hash, Object value, boolean weakRemove) {
+ V remove(Object key, int hash, Object value, boolean refRemove) {
lock();
try {
- if (!weakRemove)
+ if (!refRemove)
removeStale();
int c = count - 1;
HashEntry<K,V>[] tab = table;
int index = hash & (tab.length - 1);
HashEntry<K,V> first = tab[index];
HashEntry<K,V> e = first;
- // a weak remove operation compares the WeakReference instance
- while (e != null && (!weakRemove || key != e.keyRef)
- && (e.hash != hash || !keyEq(key, e.key())))
+ // a ref remove operation compares the Reference instance
+ while (e != null && key != e.keyRef
+ && (refRemove || hash != e.hash || !keyEq(key,
e.key())))
e = e.next;
V oldValue = null;
@@ -763,12 +808,9 @@
}
final void removeStale() {
- if (keyType == ReferenceType.STRONG)
- return;
-
KeyReference ref;
while ((ref = (KeyReference) refQueue.poll()) != null) {
- remove(ref, ref.keyHash(), null, true);
+ remove(ref.keyRef(), ref.keyHash(), null, true);
}
}
@@ -781,7 +823,7 @@
tab[i] = null;
++modCount;
// replace the reference queue to avoid unnecessary stale cleanups
- refQueue = new ReferenceQueue<K>();
+ refQueue = new ReferenceQueue<Object>();
count = 0; // write-volatile
} finally {
unlock();