You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2018/09/19 15:09:18 UTC

[1/2] commons-collections git commit: [COLLECTIONS-696] AbstractReferenceMap made easier for subclassing; PR #51.

Repository: commons-collections
Updated Branches:
  refs/heads/master ad442e3c7 -> d6800c606


[COLLECTIONS-696] AbstractReferenceMap made easier for subclassing; PR
#51.

Project: http://git-wip-us.apache.org/repos/asf/commons-collections/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-collections/commit/23747116
Tree: http://git-wip-us.apache.org/repos/asf/commons-collections/tree/23747116
Diff: http://git-wip-us.apache.org/repos/asf/commons-collections/diff/23747116

Branch: refs/heads/master
Commit: 23747116069c150e26e0dd42d61331b1108e1e01
Parents: ad442e3
Author: Maxim Solodovnik <so...@gmail.com>
Authored: Wed Sep 19 09:09:10 2018 -0600
Committer: Gary Gregory <gg...@rocketsoftware.com>
Committed: Wed Sep 19 09:09:10 2018 -0600

----------------------------------------------------------------------
 .../collections4/map/AbstractReferenceMap.java  | 30 +++++++++-
 .../collections4/map/ReferenceMapTest.java      | 62 +++++++++++++++++++-
 2 files changed, 86 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-collections/blob/23747116/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java b/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
index 0eda632..4f4727f 100644
--- a/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
+++ b/src/main/java/org/apache/commons/collections4/map/AbstractReferenceMap.java
@@ -400,13 +400,15 @@ public abstract class AbstractReferenceMap<K, V> extends AbstractHashedMap<K, V>
         HashEntry<K, V> previous = null;
         HashEntry<K, V> entry = data[index];
         while (entry != null) {
-            if (((ReferenceEntry<K, V>) entry).purge(ref)) {
+            ReferenceEntry<K, V> refEntry = (ReferenceEntry<K, V>) entry;
+            if (refEntry.purge(ref)) {
                 if (previous == null) {
                     data[index] = entry.next;
                 } else {
                     previous.next = entry.next;
                 }
                 this.size--;
+                refEntry.onPurge();
                 return;
             }
             previous = entry;
@@ -722,11 +724,17 @@ public abstract class AbstractReferenceMap<K, V> extends AbstractHashedMap<K, V>
         }
 
         /**
+         * This is the callback for custom "after purge" logic
+         */
+        protected void onPurge() {
+        }
+
+        /**
          * Purges the specified reference
          * @param ref  the reference to purge
          * @return true or false
          */
-        boolean purge(final Reference<?> ref) {
+        protected boolean purge(final Reference<?> ref) {
             boolean r = parent.keyType != ReferenceStrength.HARD && key == ref;
             r = r || parent.valueType != ReferenceStrength.HARD && value == ref;
             if (r) {
@@ -736,7 +744,7 @@ public abstract class AbstractReferenceMap<K, V> extends AbstractHashedMap<K, V>
                 if (parent.valueType != ReferenceStrength.HARD) {
                     ((Reference<?>) value).clear();
                 } else if (parent.purgeValues) {
-                    value = null;
+                    nullValue();
                 }
             }
             return r;
@@ -750,6 +758,13 @@ public abstract class AbstractReferenceMap<K, V> extends AbstractHashedMap<K, V>
         protected ReferenceEntry<K, V> next() {
             return (ReferenceEntry<K, V>) next;
         }
+
+        /**
+         * This method can be overriden to provide custom logic to purge value
+         */
+        protected void nullValue() {
+            value = null;
+        }
     }
 
     //-----------------------------------------------------------------------
@@ -1073,4 +1088,13 @@ public abstract class AbstractReferenceMap<K, V> extends AbstractHashedMap<K, V>
     protected boolean isKeyType(final ReferenceStrength type) {
         return this.keyType == type;
     }
+
+    /**
+     * Provided protected read-only access to the value type.
+     * @param type the type to check against.
+     * @return true if valueType has the specified type
+     */
+    protected boolean isValueType(final ReferenceStrength type) {
+        return this.valueType == type;
+    }
 }

http://git-wip-us.apache.org/repos/asf/commons-collections/blob/23747116/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
index 72b108a..35699e0 100644
--- a/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
+++ b/src/test/java/org/apache/commons/collections4/map/ReferenceMapTest.java
@@ -21,15 +21,20 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-
+import java.io.Serializable;
 import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
-
-import junit.framework.Test;
+import java.util.function.Consumer;
 
 import org.apache.commons.collections4.BulkTest;
+import org.apache.commons.collections4.map.AbstractHashedMap.HashEntry;
+import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceEntry;
 import org.apache.commons.collections4.map.AbstractReferenceMap.ReferenceStrength;
 
+import junit.framework.Test;
+
 /**
  * Tests for ReferenceMap.
  *
@@ -255,6 +260,40 @@ public class ReferenceMapTest<K, V> extends AbstractIterableMapTest<K, V> {
         }
     }
 
+    public void testCustomPurge() {
+        List<Integer> expiredValues = new ArrayList<>();
+        @SuppressWarnings("unchecked")
+        final Consumer<Integer> consumer = (Consumer<Integer> & Serializable) v -> expiredValues.add(v);
+        final Map<Integer, Integer> map = new ReferenceMap<Integer, Integer>(ReferenceStrength.WEAK, ReferenceStrength.HARD, false) {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            protected ReferenceEntry<Integer, Integer> createEntry(HashEntry<Integer, Integer> next, int hashCode, Integer key, Integer value) {
+                return new AccessibleEntry<>(this, next, hashCode, key, value, consumer);
+            }
+        };
+        for (int i = 100000; i < 100010; i++) {
+            map.put(Integer.valueOf(i), Integer.valueOf(i));
+        }
+        int iterations = 0;
+        int bytz = 2;
+        while (true) {
+            System.gc();
+            if (iterations++ > 50 || bytz < 0) {
+                fail("Max iterations reached before resource released.");
+            }
+            map.isEmpty();
+            if (!expiredValues.isEmpty()) {
+                break;
+            }
+            // create garbage:
+            @SuppressWarnings("unused")
+            final byte[] b = new byte[bytz];
+            bytz = bytz * 2;
+        }
+        assertFalse("Value should be stored", expiredValues.isEmpty());
+    }
+
     /**
      * Test whether after serialization the "data" HashEntry array is the same size as the original.<p>
      *
@@ -292,4 +331,21 @@ public class ReferenceMapTest<K, V> extends AbstractIterableMapTest<K, V> {
         }
     }
 
+    private static class AccessibleEntry<K, V> extends ReferenceEntry<K, V> {
+        final AbstractReferenceMap<K, V> parent;
+        final Consumer<V> consumer;
+
+        public AccessibleEntry(final AbstractReferenceMap<K, V> parent, final HashEntry<K, V> next, final int hashCode, final K key, final V value, final Consumer<V> consumer) {
+            super(parent, next, hashCode, key, value);
+            this.parent = parent;
+            this.consumer = consumer;
+        }
+
+        @Override
+        protected void onPurge() {
+            if (parent.isValueType(ReferenceStrength.HARD)) {
+                consumer.accept(getValue());
+            }
+        }
+    }
 }


[2/2] commons-collections git commit: [COLLECTIONS-696] AbstractReferenceMap made easier for subclassing; PR #51.

Posted by gg...@apache.org.
[COLLECTIONS-696] AbstractReferenceMap made easier for subclassing; PR
#51.

Project: http://git-wip-us.apache.org/repos/asf/commons-collections/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-collections/commit/d6800c60
Tree: http://git-wip-us.apache.org/repos/asf/commons-collections/tree/d6800c60
Diff: http://git-wip-us.apache.org/repos/asf/commons-collections/diff/d6800c60

Branch: refs/heads/master
Commit: d6800c606c502bb7c1de180dc9ac9686070aad37
Parents: 2374711
Author: Gary Gregory <gg...@rocketsoftware.com>
Authored: Wed Sep 19 09:09:16 2018 -0600
Committer: Gary Gregory <gg...@rocketsoftware.com>
Committed: Wed Sep 19 09:09:16 2018 -0600

----------------------------------------------------------------------
 src/changes/changes.xml | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-collections/blob/d6800c60/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 2aedeac..6bd0534 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -33,6 +33,9 @@
     <action issue="COLLECTIONS-692" dev="ggregory" type="update" due-to="Gary Gregory, Eitan Adler">
       Replace use of deprecated Class#newInstance() PR #49.
     </action>
+    <action issue="COLLECTIONS-696" dev="ggregory" type="add" due-to="Maxim Solodovnik">
+      AbstractReferenceMap made easier for subclassing; PR #51.
+    </action>
   </release>
   <release version="4.2" date="2018-07-11" description="Update from Java 6 to Java 7, bug fixes, and small changes.">
     <action issue="COLLECTIONS-681" dev="kinow" type="add" due-to="Stephan Fuhrmann">