Browse Source

HADOOP-2244. Fixes the MapWritable.readFields to clear the instance field variable every time readFields is called. Contributed by Michael Stack.

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/trunk@598984 13f79535-47bb-0310-9956-ffa450edef68
Devaraj Das 17 years ago
parent
commit
a0f4026874

+ 2 - 0
CHANGES.txt

@@ -152,6 +152,8 @@ Trunk (unreleased changes)
     HDFS but not the default filesystem.  HDFS paths returned by the
     listStatus() method are now fully-qualified.  (cutting)
 
+    HADOOP-2244.  Fixes the MapWritable.readFields to clear the instance 
+    field variable every time readFields is called. (Michael Stack via ddas).
 
 Release 0.15.1 - 2007-11-27
 

+ 4 - 0
src/java/org/apache/hadoop/io/MapWritable.java

@@ -144,6 +144,10 @@ public class MapWritable extends AbstractMapWritable
   public void readFields(DataInput in) throws IOException {
     super.readFields(in);
     
+    // First clear the map.  Otherwise we will just accumulate
+    // entries every time this method is called.
+    this.instance.clear();
+    
     // Read the number of entries in the map
     
     int entries = in.readInt();

+ 34 - 0
src/test/org/apache/hadoop/io/TestMapWritable.java

@@ -19,6 +19,10 @@
  */
 package org.apache.hadoop.io;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.util.Map;
 
 import junit.framework.TestCase;
@@ -97,4 +101,34 @@ public class TestMapWritable extends TestCase {
     MapWritable copyOfCopy = new MapWritable(outMap);
     assertEquals(1, copyOfCopy.getNewClasses());
   }
+  
+  /**
+   * Assert MapWritable does not grow across calls to readFields.
+   * @throws Exception
+   * @see <a href="https://issues.apache.org/jira/browse/HADOOP-2244">HADOOP-2244</a>
+   */
+  public void testMultipleCallsToReadFieldsAreSafe() throws Exception {
+    // Create an instance and add a key/value.
+    MapWritable m = new MapWritable();
+    final Text t = new Text(getName());
+    m.put(t, t);
+    // Get current size of map.  Key values are 't'.
+    int count = m.size();
+    // Now serialize... save off the bytes.
+    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+    DataOutputStream dos = new DataOutputStream(baos);
+    m.write(dos);
+    dos.close();
+    // Now add new values to the MapWritable.
+    m.put(new Text("key1"), new Text("value1"));
+    m.put(new Text("key2"), new Text("value2"));
+    // Now deserialize the original MapWritable.  Ensure count and key values
+    // match original state.
+    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+    DataInputStream dis = new DataInputStream(bais);
+    m.readFields(dis);
+    assertEquals(count, m.size());
+    assertTrue(m.get(t).equals(t));
+    dis.close();
+  }
 }