scolebourne 2004/03/31 15:18:56
Modified: collections RELEASE-NOTES.html
collections/src/test/org/apache/commons/collections/map
TestFlat3Map.java
collections/src/java/org/apache/commons/collections/map
Flat3Map.java
Added: collections/data/test Flat3Map.fullCollection.version3.1.obj
Flat3Map.emptyCollection.version3.1.obj
Log:
Make Flat3Map serializable
bug 27946
Add clone() to Flat3Map
Revision Changes Path
1.1
jakarta-commons/collections/data/test/Flat3Map.fullCollection.version3.1.obj
<<Binary file>>
1.1
jakarta-commons/collections/data/test/Flat3Map.emptyCollection.version3.1.obj
<<Binary file>>
1.20 +4 -2 jakarta-commons/collections/RELEASE-NOTES.html
Index: RELEASE-NOTES.html
===================================================================
RCS file: /home/cvs/jakarta-commons/collections/RELEASE-NOTES.html,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- RELEASE-NOTES.html 31 Mar 2004 22:06:12 -0000 1.19
+++ RELEASE-NOTES.html 31 Mar 2004 23:18:56 -0000 1.20
@@ -30,12 +30,14 @@
<center><h3>ENHANCEMENTS</h3></center>
<ul>
+<li>Fast3Map - Make Serializable [27946]</li>
+<li>Fast3Map - Add clone() method</li>
<li>MultiKey - Add getKey(index) and size() methods and make constructor public</li>
+<li>MultiHashMap - Add five methods to improve the API</li>
<li>AbstractHashedMap,AbstractLinkedMap - Add methods to access entry methods when
protected scope blocks</li>
<li>Functors - Add get methods to retrieve internal state [27515]</li>
-<li>MultiHashMap - Add five methods to improve the API</li>
-<li>CollectionUtils - Add size(Object) method to find the size of various
collection-like objects [27909]</li>
<li>Functors - Add additional getInstance() methods for consistency
[27856,27857]</li>
+<li>CollectionUtils - Add size(Object) method to find the size of various
collection-like objects [27909]</li>
</ul>
<center><h3>BUG FIXES</h3></center>
1.7 +155 -1
jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestFlat3Map.java
Index: TestFlat3Map.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/map/TestFlat3Map.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TestFlat3Map.java 18 Feb 2004 01:20:37 -0000 1.6
+++ TestFlat3Map.java 31 Mar 2004 23:18:56 -0000 1.7
@@ -15,6 +15,10 @@
*/
package org.apache.commons.collections.map;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.Map;
import junit.framework.Test;
@@ -33,6 +37,11 @@
*/
public class TestFlat3Map extends AbstractTestIterableMap {
+ private static final Integer ONE = new Integer(1);
+ private static final Integer TWO = new Integer(2);
+ private static final String TEN = "10";
+ private static final String TWENTY = "20";
+
public TestFlat3Map(String testName) {
super(testName);
}
@@ -50,6 +59,136 @@
}
//-----------------------------------------------------------------------
+ public void testClone2() {
+ Flat3Map map = new Flat3Map();
+ assertEquals(0, map.size());
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+ assertEquals(2, map.size());
+ assertEquals(true, map.containsKey(ONE));
+ assertEquals(true, map.containsKey(TWO));
+ assertSame(TEN, map.get(ONE));
+ assertSame(TWENTY, map.get(TWO));
+
+ // clone works (size = 2)
+ Flat3Map cloned = (Flat3Map) map.clone();
+ assertEquals(2, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+
+ // change original doesn't change clone
+ map.put(TEN, ONE);
+ map.put(TWENTY, TWO);
+ assertEquals(4, map.size());
+ assertEquals(2, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+ }
+ public void testClone4() {
+ Flat3Map map = new Flat3Map();
+ assertEquals(0, map.size());
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+ map.put(TEN, ONE);
+ map.put(TWENTY, TWO);
+
+ // clone works (size = 4)
+ Flat3Map cloned = (Flat3Map) map.clone();
+ assertEquals(4, map.size());
+ assertEquals(4, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertEquals(true, cloned.containsKey(TEN));
+ assertEquals(true, cloned.containsKey(TWENTY));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+ assertSame(ONE, cloned.get(TEN));
+ assertSame(TWO, cloned.get(TWENTY));
+
+ // change original doesn't change clone
+ map.clear();
+ assertEquals(0, map.size());
+ assertEquals(4, cloned.size());
+ assertEquals(true, cloned.containsKey(ONE));
+ assertEquals(true, cloned.containsKey(TWO));
+ assertEquals(true, cloned.containsKey(TEN));
+ assertEquals(true, cloned.containsKey(TWENTY));
+ assertSame(TEN, cloned.get(ONE));
+ assertSame(TWENTY, cloned.get(TWO));
+ assertSame(ONE, cloned.get(TEN));
+ assertSame(TWO, cloned.get(TWENTY));
+ }
+
+ public void testSerialisation0() throws Exception {
+ Flat3Map map = new Flat3Map();
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(map);
+ byte[] bytes = bout.toByteArray();
+ out.close();
+ ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+ ObjectInputStream in = new ObjectInputStream(bin);
+ Flat3Map ser = (Flat3Map) in.readObject();
+ in.close();
+ assertEquals(0, map.size());
+ assertEquals(0, ser.size());
+ }
+
+ public void testSerialisation2() throws Exception {
+ Flat3Map map = new Flat3Map();
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(map);
+ byte[] bytes = bout.toByteArray();
+ out.close();
+ ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+ ObjectInputStream in = new ObjectInputStream(bin);
+ Flat3Map ser = (Flat3Map) in.readObject();
+ in.close();
+ assertEquals(2, map.size());
+ assertEquals(2, ser.size());
+ assertEquals(true, ser.containsKey(ONE));
+ assertEquals(true, ser.containsKey(TWO));
+ assertEquals(TEN, ser.get(ONE));
+ assertEquals(TWENTY, ser.get(TWO));
+ }
+
+ public void testSerialisation4() throws Exception {
+ Flat3Map map = new Flat3Map();
+ map.put(ONE, TEN);
+ map.put(TWO, TWENTY);
+ map.put(TEN, ONE);
+ map.put(TWENTY, TWO);
+
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bout);
+ out.writeObject(map);
+ byte[] bytes = bout.toByteArray();
+ out.close();
+ ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
+ ObjectInputStream in = new ObjectInputStream(bin);
+ Flat3Map ser = (Flat3Map) in.readObject();
+ in.close();
+ assertEquals(4, map.size());
+ assertEquals(4, ser.size());
+ assertEquals(true, ser.containsKey(ONE));
+ assertEquals(true, ser.containsKey(TWO));
+ assertEquals(true, ser.containsKey(TEN));
+ assertEquals(true, ser.containsKey(TWENTY));
+ assertEquals(TEN, ser.get(ONE));
+ assertEquals(TWENTY, ser.get(TWO));
+ assertEquals(ONE, ser.get(TEN));
+ assertEquals(TWO, ser.get(TWENTY));
+ }
+
+ //-----------------------------------------------------------------------
public BulkTest bulkTestMapIterator() {
return new TestFlatMapIterator();
}
@@ -96,4 +235,19 @@
TestFlat3Map.this.verify();
}
}
+
+ public String getCompatibilityVersion() {
+ return "3.1";
+ }
+
+// public void testCreate() throws Exception {
+// resetEmpty();
+// writeExternalFormToDisk(
+// (java.io.Serializable) map,
+//
"D:/dev/collections/data/test/Flat3Map.emptyCollection.version3.1.obj");
+// resetFull();
+// writeExternalFormToDisk(
+// (java.io.Serializable) map,
+//
"D:/dev/collections/data/test/Flat3Map.fullCollection.version3.1.obj");
+// }
}
1.14 +76 -15
jakarta-commons/collections/src/java/org/apache/commons/collections/map/Flat3Map.java
Index: Flat3Map.java
===================================================================
RCS file:
/home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/map/Flat3Map.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- Flat3Map.java 18 Feb 2004 01:13:19 -0000 1.13
+++ Flat3Map.java 31 Mar 2004 23:18:56 -0000 1.14
@@ -15,6 +15,10 @@
*/
package org.apache.commons.collections.map;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
import java.util.AbstractCollection;
import java.util.AbstractSet;
import java.util.Collection;
@@ -60,30 +64,33 @@
*
* @author Stephen Colebourne
*/
-public class Flat3Map implements IterableMap {
+public class Flat3Map implements IterableMap, Serializable, Cloneable {
+
+ /** Serialization version */
+ private static final long serialVersionUID = -6701087419741928296L;
/** The size of the map, used while in flat mode */
- private int size;
+ private transient int size;
/** Hash, used while in flat mode */
- private int hash1;
+ private transient int hash1;
/** Hash, used while in flat mode */
- private int hash2;
+ private transient int hash2;
/** Hash, used while in flat mode */
- private int hash3;
+ private transient int hash3;
/** Key, used while in flat mode */
- private Object key1;
+ private transient Object key1;
/** Key, used while in flat mode */
- private Object key2;
+ private transient Object key2;
/** Key, used while in flat mode */
- private Object key3;
+ private transient Object key3;
/** Value, used while in flat mode */
- private Object value1;
+ private transient Object value1;
/** Value, used while in flat mode */
- private Object value2;
+ private transient Object value2;
/** Value, used while in flat mode */
- private Object value3;
+ private transient Object value3;
/** Map, used while in delegate mode */
- private HashedMap delegateMap;
+ private transient HashedMap delegateMap;
/**
* Constructor.
@@ -344,7 +351,7 @@
* Converts the flat map data to a HashMap.
*/
private void convertToMap() {
- delegateMap = new HashedMap();
+ delegateMap = createDelegateMap();
switch (size) { // drop through
case 3:
delegateMap.put(key3, value3);
@@ -361,6 +368,16 @@
}
/**
+ * Create an instance of the map used for storage when in delegation mode.
+ * This can be overridden by subclasses.
+ *
+ * @return a new HashedMap or subclass
+ */
+ protected HashedMap createDelegateMap() {
+ return new HashedMap();
+ }
+
+ /**
* Removes the specified mapping from this map.
*
* @param key the mapping to remove
@@ -945,8 +962,52 @@
return getValue();
}
}
-
+
+ //-----------------------------------------------------------------------
+ /**
+ * Write the map out using a custom routine.
+ */
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeInt(size());
+ for (MapIterator it = mapIterator(); it.hasNext();) {
+ out.writeObject(it.next()); // key
+ out.writeObject(it.getValue()); // value
+ }
+ }
+
+ /**
+ * Read the map in using a custom routine.
+ */
+ private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
+ in.defaultReadObject();
+ int count = in.readInt();
+ if (count > 3) {
+ delegateMap = createDelegateMap();
+ }
+ for (int i = count; i > 0; i--) {
+ put(in.readObject(), in.readObject());
+ }
+ }
+
//-----------------------------------------------------------------------
+ /**
+ * Clones the map without cloning the keys or values.
+ *
+ * @return a shallow clone
+ */
+ public Object clone() {
+ try {
+ Flat3Map cloned = (Flat3Map) super.clone();
+ if (cloned.delegateMap != null) {
+ cloned.delegateMap = (HashedMap) cloned.delegateMap.clone();
+ }
+ return cloned;
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
/**
* Compares this map with another.
*
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]