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">