CAY-2351 Remove dependency on commons-collection
  performance optimizations of Weak- and SoftValueMap


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/7f7aca81
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/7f7aca81
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/7f7aca81

Branch: refs/heads/master
Commit: 7f7aca813d3eba5eedb9c75567d7f42320a1529b
Parents: bc7399a
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Mon Aug 14 17:41:41 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Thu Aug 17 12:41:58 2017 +0300

----------------------------------------------------------------------
 .../org/apache/cayenne/util/ReferenceMap.java   | 38 ++++++++++----------
 1 file changed, 20 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/7f7aca81/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java 
b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
index 530ea30..8e177f1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ReferenceMap.java
@@ -30,6 +30,7 @@ import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
@@ -76,11 +77,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
      */
     protected transient Map<K, R> map;
 
-    /**
-     * This is aux storage to faster remove cleared references
-     */
-    protected transient Map<R, K> reverseMap;
-
     protected transient ReferenceQueue<V> referenceQueue;
 
     /**
@@ -90,13 +86,11 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
 
     public ReferenceMap() {
         map = new HashMap<>();
-        reverseMap = new HashMap<>();
         referenceQueue = new ReferenceQueue<>();
     }
 
     public ReferenceMap(int initialCapacity) {
         map = new HashMap<>(initialCapacity);
-        reverseMap = new HashMap<>(initialCapacity);
         referenceQueue = new ReferenceQueue<>();
     }
 
@@ -154,7 +148,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
         checkReferenceQueue();
         R refValue = newReference(value);
         R oldValue = map.put(key, refValue);
-        reverseMap.put(refValue, key);
         if(oldValue == null) {
             return null;
         }
@@ -168,7 +161,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
         if(oldValue == null) {
             return null;
         }
-        reverseMap.remove(oldValue);
         return oldValue.get();
     }
 
@@ -178,14 +170,12 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
         for(Map.Entry<? extends K, ? extends V> entry : m.entrySet()) {
             R value = newReference(entry.getValue());
             map.put(entry.getKey(), value);
-            reverseMap.put(value, entry.getKey());
         }
     }
 
     @Override
     public void clear() {
         map.clear();
-        reverseMap.clear();
         resetReferenceQueue();
     }
 
@@ -224,13 +214,28 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
      * Cleanup all references collected by GC so far
      */
     protected void checkReferenceQueue() {
+        Collection<Reference<? extends V>> valuesToRemove = null;
         Reference<? extends V> reference;
-
         while((reference = referenceQueue.poll()) != null) {
-            K keyToRemove = reverseMap.remove(reference);
-            if(keyToRemove != null) {
-                map.remove(keyToRemove);
+            if(valuesToRemove == null) {
+                valuesToRemove = new HashSet<>();
             }
+            valuesToRemove.add(reference);
+        }
+
+        if(valuesToRemove == null) {
+            return;
+        }
+
+        Collection<K> keysToRemove = new ArrayList<>(valuesToRemove.size());
+        for(Map.Entry<K, R> entry : map.entrySet()) {
+            if(valuesToRemove.contains(entry.getValue())) {
+                keysToRemove.add(entry.getKey());
+            }
+        }
+
+        for(K keyToRemove : keysToRemove) {
+            map.remove(keyToRemove);
         }
     }
 
@@ -271,10 +276,8 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
         @SuppressWarnings("unchecked")
         Map<K, V> replacement = (Map<K, V>) in.readObject();
         map = new HashMap<>(replacement.size());
-        reverseMap = new HashMap<>(replacement.size());
         referenceQueue = new ReferenceQueue<>();
         putAll(replacement);
-        map.forEach((k, v) -> reverseMap.put(v, k));
     }
 
     /**
@@ -333,7 +336,6 @@ abstract class ReferenceMap<K, V, R extends Reference<V>> 
extends AbstractMap<K,
         public V setValue(V value) {
             R newRef = newReference(value);
             R oldRef = refEntry.setValue(newRef);
-            reverseMap.put(newRef, reverseMap.remove(oldRef));
             if(oldRef != null) {
                 return oldRef.get();
             }

Reply via email to