You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by st...@apache.org on 2011/01/07 23:33:25 UTC

svn commit: r1056548 - in /hbase/trunk: CHANGES.txt src/main/java/org/apache/hadoop/hbase/io/HbaseObjectWritable.java src/test/java/org/apache/hadoop/hbase/io/TestHbaseObjectWritable.java

Author: stack
Date: Fri Jan  7 22:33:24 2011
New Revision: 1056548

URL: http://svn.apache.org/viewvc?rev=1056548&view=rev
Log:
HBASE-3429 HBaseObjectWritable should support arrays of any Writable or Serializable, not just Writable[]

Modified:
    hbase/trunk/CHANGES.txt
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/HbaseObjectWritable.java
    hbase/trunk/src/test/java/org/apache/hadoop/hbase/io/TestHbaseObjectWritable.java

Modified: hbase/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/hbase/trunk/CHANGES.txt?rev=1056548&r1=1056547&r2=1056548&view=diff
==============================================================================
--- hbase/trunk/CHANGES.txt (original)
+++ hbase/trunk/CHANGES.txt Fri Jan  7 22:33:24 2011
@@ -46,6 +46,8 @@ Release 0.91.0 - Unreleased
                (Jesse Yates via Stack)
    HBASE-3393  Update Avro gateway to use Avro 1.4.1 and the new
                server.join() method (Jeff Hammerbacher via Stack)
+   HBASE-3429  HBaseObjectWritable should support arrays of any Writable
+               or Serializable, not just Writable[] (Ed Kohlwey via Stack)
 
 
   NEW FEATURES

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/HbaseObjectWritable.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/HbaseObjectWritable.java?rev=1056548&r1=1056547&r2=1056548&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/HbaseObjectWritable.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/io/HbaseObjectWritable.java Fri Jan  7 22:33:24 2011
@@ -84,6 +84,7 @@ import org.apache.hadoop.hbase.regionser
 import org.apache.hadoop.hbase.regionserver.wal.HLog;
 import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Classes;
 import org.apache.hadoop.io.MapWritable;
 import org.apache.hadoop.io.ObjectWritable;
 import org.apache.hadoop.io.Text;
@@ -382,7 +383,9 @@ public class HbaseObjectWritable impleme
       declClass = Writable.class;
     }
     writeClassCode(out, declClass);
-    if (declClass.isArray()) {                // array
+    // used to just be arrays. Now check for ones for which there's a
+    // class code, and let the others get scooped up by serializable.
+    if (declClass.isArray() && CLASS_TO_CODE.get(declClass)!=null) {   // array
       // If bytearray, just dump it out -- avoid the recursion and
       // byte-at-a-time we were previously doing.
       if (declClass.equals(byte [].class)) {
@@ -449,18 +452,27 @@ public class HbaseObjectWritable impleme
       } else {
         writeClassCode(out, c);
       }
-      ByteArrayOutputStream bos = null;
-      ObjectOutputStream oos = null;
-      try{
-        bos = new ByteArrayOutputStream();
-        oos = new ObjectOutputStream(bos);
-        oos.writeObject(instanceObj);
-        byte[] value = bos.toByteArray();
-        out.writeInt(value.length);
-        out.write(value);
-      } finally {
-        if(bos!=null) bos.close();
-        if(oos!=null) oos.close();
+      if(declClass.isArray()){
+        int length = Array.getLength(instanceObj);
+        out.writeInt(length);
+        for (int i = 0; i < length; i++) {
+          writeObject(out, Array.get(instanceObj, i),
+                    declClass.getComponentType(), conf);
+        }
+      } else {
+        ByteArrayOutputStream bos = null;
+        ObjectOutputStream oos = null;
+        try{
+          bos = new ByteArrayOutputStream();
+          oos = new ObjectOutputStream(bos);
+          oos.writeObject(instanceObj);
+          byte[] value = bos.toByteArray();
+          out.writeInt(value.length);
+          out.write(value);
+        } finally {
+          if(bos!=null) bos.close();
+          if(oos!=null) oos.close();
+        }
       }
     } else {
       throw new IOException("Can't write: "+instanceObj+" as "+declClass);
@@ -569,21 +581,29 @@ public class HbaseObjectWritable impleme
           instance = null;
         }
       } else {
-        int length = in.readInt();
-        byte[] objectBytes = new byte[length];
-        in.readFully(objectBytes);
-        ByteArrayInputStream bis = null;
-        ObjectInputStream ois = null;
-        try { 
-          bis = new ByteArrayInputStream(objectBytes);
-          ois = new ObjectInputStream(bis);
-          instance = ois.readObject();
-        } catch (ClassNotFoundException e) {
-          LOG.error("Error in readFields", e);
-          throw new IOException("Error in readFields", e);
-        } finally {
-          if(bis!=null) bis.close();
-          if(ois!=null) ois.close();
+        if(instanceClass.isArray()){
+          int length = in.readInt();
+          instance = Array.newInstance(instanceClass.getComponentType(), length);
+          for(int i = 0; i< length; i++){
+            Array.set(instance, i, HbaseObjectWritable.readObject(in, conf));
+          }
+        } else {
+          int length = in.readInt();
+          byte[] objectBytes = new byte[length];
+          in.readFully(objectBytes);
+          ByteArrayInputStream bis = null;
+          ObjectInputStream ois = null;
+          try { 
+            bis = new ByteArrayInputStream(objectBytes);
+            ois = new ObjectInputStream(bis);
+            instance = ois.readObject();
+          } catch (ClassNotFoundException e) {
+            LOG.error("Error in readFields", e);
+            throw new IOException("Error in readFields", e);
+          } finally {
+            if(bis!=null) bis.close();
+            if(ois!=null) ois.close();
+          }
         }
       }
     }

Modified: hbase/trunk/src/test/java/org/apache/hadoop/hbase/io/TestHbaseObjectWritable.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/test/java/org/apache/hadoop/hbase/io/TestHbaseObjectWritable.java?rev=1056548&r1=1056547&r2=1056548&view=diff
==============================================================================
--- hbase/trunk/src/test/java/org/apache/hadoop/hbase/io/TestHbaseObjectWritable.java (original)
+++ hbase/trunk/src/test/java/org/apache/hadoop/hbase/io/TestHbaseObjectWritable.java Fri Jan  7 22:33:24 2011
@@ -21,6 +21,7 @@ package org.apache.hadoop.hbase.io;
 
 import java.io.*;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 
 import junit.framework.TestCase;
@@ -122,6 +123,20 @@ public class TestHbaseObjectWritable ext
     assertEquals("mykey", ((CustomFilter)child).getKey());
   }
   
+  public void testCustomWritableArray() throws Exception {
+    Configuration conf = HBaseConfiguration.create();
+
+    // test proper serialization of un-encoded custom writables
+    CustomWritable custom1 = new CustomWritable("test phrase");
+    CustomWritable custom2 = new CustomWritable("test phrase2");
+    CustomWritable[] customs = {custom1, custom2};
+    Object obj = doType(conf, customs, CustomWritable[].class);
+    
+    assertTrue("Arrays should match " + Arrays.toString(customs) + ", "
+               + Arrays.toString((Object[]) obj),
+               Arrays.equals(customs, (Object[])obj));
+  }
+  
   public void testCustomSerializable() throws Exception {
     Configuration conf = HBaseConfiguration.create();
 
@@ -132,6 +147,20 @@ public class TestHbaseObjectWritable ext
     assertTrue(obj instanceof CustomSerializable);
     assertEquals("test phrase", ((CustomSerializable)obj).getValue());
   }
+  
+  
+  public void testCustomSerializableArray() throws Exception {
+    Configuration conf = HBaseConfiguration.create();
+
+    // test proper serialization of un-encoded serialized java objects
+    CustomSerializable custom1 = new CustomSerializable("test phrase");
+    CustomSerializable custom2 = new CustomSerializable("test phrase2");
+    CustomSerializable[] custom = {custom1, custom2};
+    Object obj = doType(conf, custom, CustomSerializable[].class);
+    assertTrue("Arrays should match " + Arrays.toString(custom) + ", "
+                   + Arrays.toString((Object[]) obj),
+               Arrays.equals(custom, (Object[]) obj));
+  }
 
   private Object doType(final Configuration conf, final Object value,
       final Class<?> clazz)
@@ -149,7 +178,7 @@ public class TestHbaseObjectWritable ext
   }
   
   public static class CustomSerializable implements Serializable {
-    private static final long serialVersionUID = 1048445561865740632L;
+    private static final long serialVersionUID = 1048445561865740633L;
     private String value = null;
     
     public CustomSerializable() {
@@ -167,6 +196,21 @@ public class TestHbaseObjectWritable ext
       this.value = value;
     }
     
+    @Override
+    public boolean equals(Object obj) {
+      return (obj instanceof CustomSerializable) && ((CustomSerializable)obj).value.equals(value);
+    }
+    
+    @Override
+    public int hashCode() {
+      return value.hashCode();
+    }
+    
+    @Override
+    public String toString() {
+      return "<" + value + ">";
+    }
+    
   }
 
   public static class CustomWritable implements Writable {
@@ -190,6 +234,21 @@ public class TestHbaseObjectWritable ext
     public void readFields(DataInput in) throws IOException {
       this.value = Text.readString(in);
     }
+    
+    @Override
+    public boolean equals(Object obj) {
+      return (obj instanceof CustomWritable) && ((CustomWritable)obj).value.equals(value);
+    }
+    
+    @Override
+    public int hashCode() {
+      return value.hashCode();
+    }
+    
+    @Override
+    public String toString() {
+      return "<" + value + ">";
+    }
   }
 
   public static class CustomFilter extends FilterBase {