[Arakhnę-Dev] [33] Reimplement AbstractWeakSoftValueMap to avoid exceptions. |
[ Thread Index |
Date Index
| More arakhne.org/dev Archives
]
Revision: 33
Author: galland
Date: 2009-02-03 13:37:00 +0100 (Tue, 03 Feb 2009)
Log Message:
-----------
Reimplement AbstractWeakSoftValueMap to avoid exceptions.
Modified Paths:
--------------
trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
trunk/arakhneRefs/src/main/resources/Changelog
trunk/arakhneRefs/src/main/resources/VERSION
trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
trunk/pom.xml
Modified: trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java
===================================================================
--- trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java 2009-02-03 09:58:11 UTC (rev 32)
+++ trunk/arakhneRefs/src/main/java/org/arakhne/util/ref/AbstractWeakSoftValueMap.java 2009-02-03 12:37:00 UTC (rev 33)
@@ -23,13 +23,11 @@
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
-import java.lang.ref.WeakReference;
import java.util.AbstractMap;
-import java.util.AbstractSet;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.NoSuchElementException;
import java.util.Set;
/**
@@ -83,7 +81,6 @@
private boolean autoExpurge = false;
private final HashMap<K,WeakSoftValue<K,V>> map;
private final ReferenceQueue<V> queue = new ReferenceQueue<V>();
- private final EntrySet entrySet;
/**
* Constructs an empty <tt>HashMap</tt> with the specified initial
@@ -96,7 +93,6 @@
*/
public AbstractWeakSoftValueMap(int initialCapacity, float loadFactor) {
this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity, loadFactor);
- this.entrySet = new EntrySet();
}
/**
@@ -108,7 +104,6 @@
*/
public AbstractWeakSoftValueMap(int initialCapacity) {
this.map = new HashMap<K,WeakSoftValue<K,V>>(initialCapacity);
- this.entrySet = new EntrySet();
}
/**
@@ -117,7 +112,6 @@
*/
public AbstractWeakSoftValueMap() {
this.map = new HashMap<K,WeakSoftValue<K,V>>();
- this.entrySet = new EntrySet();
}
/**
@@ -131,7 +125,6 @@
*/
public AbstractWeakSoftValueMap(Map<? extends K, ? extends V> m) {
this.map = new HashMap<K,WeakSoftValue<K,V>>();
- this.entrySet = new EntrySet();
putAll(m);
}
@@ -222,6 +215,17 @@
*/
protected abstract WeakSoftValue<K,V> makeValue(K k, V v, ReferenceQueue<V> queue);
+ /** Create a storage object that permits to put the specified
+ * elements inside this map.
+ *
+ * @param k is the key associated to the value
+ * @param v is the value
+ * @return the new storage object
+ */
+ protected final WeakSoftValue<K,V> makeValue(K k, V v) {
+ return makeValue(k, v, this.queue);
+ }
+
/**
* {@inheritDoc}
*/
@@ -239,7 +243,7 @@
@Override
public final Set<Entry<K,V>> entrySet() {
expurgeNow();
- return this.entrySet;
+ return new InnerEntrySet();
}
/**
@@ -259,100 +263,233 @@
expurgeNow();
return hashCode();
}
+
+ /**
+ * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
+ * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
+ */
+ protected interface WeakSoftValue<K,V> extends Entry<K,V> {
+
+ /**
+ * @return if the value is enqueued into a reference queue.
+ */
+ public boolean isEnqueued();
+
+ /**
+ * @return the weak/soft reference.
+ */
+ public V get();
- /**
+ /**
+ * @return if the value was enqueued
+ */
+ public boolean enqueue();
+
+ /**
+ */
+ public void clear();
+
+ }
+
+ /**
* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
* @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
*/
- private class RealEntry implements Entry<K,V> {
+ @SuppressWarnings("synthetic-access")
+ private class InnerEntrySet implements Set<Entry<K,V>> {
- private final WeakReference<WeakSoftValue<K,V>> realEntry;
- private final K key;
- private V value;
-
- public RealEntry(WeakSoftValue<K,V> rEntry, V rValue) {
- this.value = rValue;
- this.key = rEntry.getKey();
- this.realEntry = new WeakReference<WeakSoftValue<K,V>>(rEntry);
+ public InnerEntrySet() {
+ //
}
-
+
@Override
- public K getKey() {
- return this.key;
+ public final boolean add(java.util.Map.Entry<K, V> e) {
+ K key = e.getKey();
+ V value = e.getValue();
+ return AbstractWeakSoftValueMap.this.map.put(key,
+ makeValue(key, value)) == null;
}
@Override
- public V getValue() {
- return this.value;
+ public final boolean addAll(Collection<? extends java.util.Map.Entry<K, V>> c) {
+ boolean ok = true;
+ for(java.util.Map.Entry<K, V> entry : c) {
+ ok = add(entry) && ok;
+ }
+ return ok;
}
@Override
- public V setValue(V value) {
- V oldValue = this.value;
-
- this.value = value;
-
- WeakSoftValue<K,V> rEntry = this.realEntry.get();
-
- if (rEntry!=null) {
- if (value==null) rEntry.clear();
- else rEntry.setValue(value);
+ public final void clear() {
+ AbstractWeakSoftValueMap.this.map.clear();
+ }
+
+ @Override
+ public final boolean contains(Object o) {
+ if (o instanceof Entry) {
+ try {
+ expurgeNow();
+ return AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+ }
+ catch(Throwable _) {
+ //
+ }
}
+ return false;
+ }
+
+ @Override
+ public final boolean containsAll(Collection<?> c) {
+ boolean ok;
+ expurgeNow();
+ for(Object o : c) {
+ ok = false;
+ if (o instanceof Entry) {
+ try {
+ ok = AbstractWeakSoftValueMap.this.map.containsKey(((Entry<?,?>)o).getKey());
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ if (!ok) return false;
+ }
+ return true;
+ }
+
+ @Override
+ public final boolean isEmpty() {
+ expurgeNow();
+ return AbstractWeakSoftValueMap.this.map.isEmpty();
+ }
+
+ @Override
+ public final Iterator<java.util.Map.Entry<K, V>> iterator() {
+ return new InnerIterator();
+ }
+
+ @Override
+ public final boolean remove(Object o) {
+ if (o instanceof Entry) {
+ try {
+ return AbstractWeakSoftValueMap.this.map.remove(((Entry<?,?>)o).getKey())!=null;
+ }
+ catch(Throwable _) {
+ //
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public final boolean removeAll(Collection<?> c) {
+ boolean ok = true;
+ for(Object o : c) {
+ ok = remove(o) && ok;
+ }
+ return ok;
+ }
+
+ @Override
+ public final boolean retainAll(Collection<?> c) {
+ expurgeNow();
+ Collection<K> keys = AbstractWeakSoftValueMap.this.map.keySet();
+ Iterator<K> iterator = keys.iterator();
+ K key;
+ boolean changed = false;
+ while (iterator.hasNext()) {
+ key = iterator.next();
+ if (!c.contains(key)) {
+ iterator.remove();
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ @Override
+ public final int size() {
+ expurgeNow();
+ return AbstractWeakSoftValueMap.this.map.size();
+ }
+
+ @Override
+ public final Object[] toArray() {
+ expurgeNow();
+ Object[] tab = new Object[AbstractWeakSoftValueMap.this.map.size()];
+ return toArray(tab);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public final <T> T[] toArray(T[] a) {
+ Entry[] tab;
+ expurgeNow();
+ int count = AbstractWeakSoftValueMap.this.map.size();
+ if (a==null || a.length<count) {
+ tab = new Entry[count];
+ }
+ else {
+ tab = (Entry[])a;
+ }
+
+ Iterator<java.util.Map.Entry<K, V>> iterator = iterator();
+ int i = 0;
+ while (i<tab.length && iterator.hasNext()) {
+ tab[i] = iterator.next();
+ }
- return oldValue;
+ return (T[])tab;
}
}
-
+
/**
* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
* @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
*/
- private class EntrySetIterator implements Iterator<Entry<K,V>> {
+ private class InnerIterator implements Iterator<Entry<K,V>> {
+
+ private final Iterator<Entry<K,WeakSoftValue<K,V>>> originalIterator;
+ private Entry<K,V> next;
- private final Iterator<Entry<K,WeakSoftValue<K,V>>> iter;
- private RealEntry lastReplied;
- private RealEntry next;
-
- public EntrySetIterator(Iterator<Entry<K,WeakSoftValue<K,V>>> iter) {
- this.iter = iter;
- expurgeNow();
- this.lastReplied = null;
+ @SuppressWarnings("synthetic-access")
+ public InnerIterator() {
+ this.originalIterator = AbstractWeakSoftValueMap.this.map.entrySet().iterator();
this.next = searchNext();
}
- private RealEntry searchNext() {
- Entry<K,WeakSoftValue<K,V>> entry;
- WeakSoftValue<K,V> val;
- V value;
- while (this.iter.hasNext()) {
- entry = this.iter.next();
- if (entry==null) throw new NoSuchElementException();
- val = entry.getValue();
- if (val==null) throw new NoSuchElementException();
- value = val.getValue();
- if (value!=null) {
- return new RealEntry(val, value);
+ private Entry<K,V> searchNext() {
+ Entry<K,WeakSoftValue<K,V>> originalNext;
+ WeakSoftValue<K,V> wValue;
+ Entry<K,V> next = null;
+ while (next==null && this.originalIterator.hasNext()) {
+ originalNext = this.originalIterator.next();
+ if (originalNext!=null) {
+ wValue = originalNext.getValue();
+ if (wValue!=null) {
+ next = new InnerEntry(wValue.getValue(), originalNext);
+ }
}
}
- return null;
+ return next;
}
- public boolean hasNext() {
- this.lastReplied = null;
- return (this.next!=null);
+ @Override
+ public boolean hasNext() {
+ return this.next!=null;
}
-
- public Entry<K,V> next() {
- this.lastReplied = this.next;
- if (this.lastReplied==null) throw new NoSuchElementException();
+
+ @Override
+ public java.util.Map.Entry<K, V> next() {
+ Entry<K,V> next = this.next;
this.next = searchNext();
- return this.lastReplied;
+ return next;
}
-
+
+ @Override
public void remove() {
- if (this.lastReplied==null) throw new NoSuchElementException();
- this.lastReplied.setValue(null);
+ this.originalIterator.remove();
}
}
@@ -361,65 +498,32 @@
* @author Stéphane GALLAND <galland@xxxxxxxxxxx>
* @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
*/
- private class EntrySet extends AbstractSet<Entry<K,V>> implements Set<Entry<K,V>> {
+ private class InnerEntry implements Entry<K,V> {
+
+ private final Entry<K,WeakSoftValue<K,V>> original;
+ private V value;
- /**
- *
- */
- public EntrySet() {
- //
+ public InnerEntry(V v, Entry<K,WeakSoftValue<K,V>> o) {
+ this.original = o;
+ this.value = v;
}
- /**
- * {@inheritDoc}
- *
- * @return {@inheritDoc}
- */
- @SuppressWarnings("synthetic-access")
@Override
- public Iterator<Entry<K, V>> iterator() {
- return new EntrySetIterator(AbstractWeakSoftValueMap.this.map.entrySet().iterator());
+ public K getKey() {
+ return this.original.getKey();
}
- /**
- * {@inheritDoc}
- *
- * @return {@inheritDoc}
- */
- @SuppressWarnings("synthetic-access")
@Override
- public int size() {
- expurgeNow();
- return AbstractWeakSoftValueMap.this.map.size();
+ public V getValue() {
+ return this.value;
}
-
- }
-
- /**
- * @author Stéphane GALLAND <galland@xxxxxxxxxxx>
- * @version $Name: $ $Revision: 1.1 $ $Date: 2007-02-20 08:52:37 $
- */
- protected interface WeakSoftValue<K,V> extends Entry<K,V> {
-
- /**
- * @return if the value is enqueued into a reference queue.
- */
- public boolean isEnqueued();
-
- /**
- * @return the weak/soft reference.
- */
- public V get();
- /**
- * @return if the value was enqueued
- */
- public boolean enqueue();
+ @Override
+ public V setValue(V value) {
+ this.value = value;
+ return this.original.getValue().setValue(value);
+ }
- /**
- */
- public void clear();
-
}
-
+
}
Modified: trunk/arakhneRefs/src/main/resources/Changelog
===================================================================
--- trunk/arakhneRefs/src/main/resources/Changelog 2009-02-03 09:58:11 UTC (rev 32)
+++ trunk/arakhneRefs/src/main/resources/Changelog 2009-02-03 12:37:00 UTC (rev 33)
@@ -1,3 +1,10 @@
+arakhneRefs-5.0
+
+ * Reimplement the AbstractWeakSoftValueMap to avoid execeptions.
+
+ -- Stephane GALLAND <galland@xxxxxxxxxxx> 2009-02-03
+
+
arakhneRefs-4.1
* Bug fix: avoid IllegalStateException from internal HashMap.
Modified: trunk/arakhneRefs/src/main/resources/VERSION
===================================================================
--- trunk/arakhneRefs/src/main/resources/VERSION 2009-02-03 09:58:11 UTC (rev 32)
+++ trunk/arakhneRefs/src/main/resources/VERSION 2009-02-03 12:37:00 UTC (rev 33)
@@ -1 +1 @@
-arakhneRefs 4.1
+arakhneRefs 5.0
Modified: trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java
===================================================================
--- trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java 2009-02-03 09:58:11 UTC (rev 32)
+++ trunk/arakhneRefs/src/test/java/org/arakhne/util/ref/WeakValueMapTest.java 2009-02-03 12:37:00 UTC (rev 33)
@@ -64,7 +64,62 @@
this.reference.clear();
}
- public void testWeakValueMapMap() {
+ public void testEntryIterator() {
+ WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
+ test.setDeeplyExpurge(true);
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(this.reference.containsKey(e.getKey()));
+ assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
+ }
+ }
+
+ // Remove elements
+ Map<String,String> baseElements = new HashMap<String,String>(this.reference);
+ removeElementsFromReference();
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertNotDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(baseElements.containsKey(e.getKey()));
+ assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
+ }
+ }
+
+ // Clear the list of removed elements, which will cause collecting
+ baseElements.clear();
+ baseElements = null;
+
+ // Collects the objects
+ collect();
+
+ // Test the content
+ {
+ assertDeepSimilars(this.reference, test);
+ Entry<String,String> e;
+ Iterator<Entry<String,String>> iter = test.entrySet().iterator();
+ while (iter.hasNext()) {
+ e = iter.next();
+ assertTrue(this.reference.containsKey(e.getKey()));
+ assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
+ }
+ }
+ }
+
+ public void testWeakValueMapMap() {
WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
assertDeepSimilars(this.reference, test);
}
@@ -189,61 +244,6 @@
}
}
- public void testEntryIterator() {
- WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
- test.setDeeplyExpurge(true);
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(this.reference.containsKey(e.getKey()));
- assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
- }
- }
-
- // Remove elements
- Map<String,String> baseElements = new HashMap<String,String>(this.reference);
- removeElementsFromReference();
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertNotDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(baseElements.containsKey(e.getKey()));
- assertEquals(baseElements.get(e.getKey()),baseElements.get(e.getKey()));
- }
- }
-
- // Clear the list of removed elements, which will cause collecting
- baseElements.clear();
- baseElements = null;
-
- // Collects the objects
- collect();
-
- // Test the content
- {
- assertDeepSimilars(this.reference, test);
- Entry<String,String> e;
- Iterator<Entry<String,String>> iter = test.entrySet().iterator();
- while (iter.hasNext()) {
- e = iter.next();
- assertTrue(this.reference.containsKey(e.getKey()));
- assertEquals(this.reference.get(e.getKey()),this.reference.get(e.getKey()));
- }
- }
- }
-
public void testKeyIterator() {
WeakValueMap<String,String> test = new WeakValueMap<String,String>(this.reference);
test.setDeeplyExpurge(true);
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2009-02-03 09:58:11 UTC (rev 32)
+++ trunk/pom.xml 2009-02-03 12:37:00 UTC (rev 33)
@@ -18,7 +18,7 @@
<properties>
<version_myjdk>1.6</version_myjdk>
<version_arakhnelogger>1.1-SNAPSHOT</version_arakhnelogger>
- <version_arakhnerefs>4.0-SNAPSHOT</version_arakhnerefs>
+ <version_arakhnerefs>5.0-SNAPSHOT</version_arakhnerefs>
<version_arakhnevmutils>2.1-SNAPSHOT</version_arakhnevmutils>
</properties>