[jbosscache-commits] JBoss Cache SVN: r5970 - pojo/trunk/src/main/java/org/jboss/cache/pojo/util.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Tue Jun 10 22:00:38 EDT 2008


Author: jason.greene at 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();




More information about the jbosscache-commits mailing list