Pārlūkot izejas kodu

HADOOP-689. Add GenericWritable, to facilitate polymorphism in MapReduce, SequenceFile, etc. Contributed by Feng Jiang.

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/trunk@480294 13f79535-47bb-0310-9956-ffa450edef68
Doug Cutting 18 gadi atpakaļ
vecāks
revīzija
081a4f0a54
2 mainītis faili ar 112 papildinājumiem un 0 dzēšanām
  1. 3 0
      CHANGES.txt
  2. 109 0
      src/java/org/apache/hadoop/io/GenericWritable.java

+ 3 - 0
CHANGES.txt

@@ -137,6 +137,9 @@ Trunk (unreleased changes)
 40. HADOOP-698.  Fix HDFS client not to retry the same datanode on
     read failures.  (Milind Bhandarkar via cutting)
 
+41. HADOOP-689. Add GenericWritable, to facilitate polymorphism in
+    MapReduce, SequenceFile, etc. (Feng Jiang via cutting)
+
 
 Release 0.8.0 - 2006-11-03
 

+ 109 - 0
src/java/org/apache/hadoop/io/GenericWritable.java

@@ -0,0 +1,109 @@
+package org.apache.hadoop.io;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * A wrapper for Writable instances.
+ * <p>
+ * When two sequence files, which have same Key type but different Value
+ * types, are mapped out to reduce, multiple Value types is not allowed.
+ * In this case, this class can help you wrap instances with different types.
+ * </p>
+ * 
+ * <p>
+ * Compared with <code>ObjectWritable</code>, this class is much more effective,
+ * because <code>ObjectWritable</code> will append the class declaration as a String 
+ * into the output file in every Key-Value pair.
+ * </p>
+ * 
+ * how to use it: <br>
+ * 1. Write your own class, such as GenericObject, which extends GenericWritable.<br> 
+ * 2. Implements the abstract method <code>getTypes()</code>, defines 
+ *    the classes which will be wrapped in GenericObject in application.
+ *    Attention: this classes defined in <code>getTypes()</code> method, must
+ *    implement <code>Writable</code> interface.
+ * <br><br>
+ * 
+ * The code looks like this:
+ * <blockquote><pre>
+ * public class GenericObject extends GenericWritable {
+ * 
+ *   private static Class[] CLASSES = {
+ *               ClassType1.class, 
+ *               ClassType2.class,
+ *               ClassType3.class,
+ *               };
+ *
+ *   protected Class[] getTypes() {
+ *       return CLASSES;
+ *   }
+ *
+ * }
+ * </pre></blockquote>
+ * 
+ * @author Feng Jiang (Feng.a.Jiang@gmail.com)
+ * @since Nov 8, 2006
+ */
+public abstract class GenericWritable implements Writable {
+
+  private static final byte NOT_SET = -1;
+
+  private byte type = NOT_SET;
+
+  private Writable instance;
+
+  /**
+   * Set the instance that is wrapped.
+   * 
+   * @param obj
+   */
+  public void set(Writable obj) {
+    instance = obj;
+    Class[] clazzes = getTypes();
+    for (int i = 0; i < clazzes.length; i++) {
+      Class clazz = clazzes[i];
+      if (clazz.isInstance(instance)) {
+        type = (byte) i;
+        return;
+      }
+    }
+    throw new RuntimeException("The type of instance is: "
+                + instance.getClass() + ", which is NOT registered.");
+  }
+
+  /**
+   * Return the wrapped instance.
+   */
+  public Writable get() {
+    return instance;
+  }
+
+  public void readFields(DataInput in) throws IOException {
+    type = in.readByte();
+    Class clazz = getTypes()[type];
+    try {
+      instance = (Writable) clazz.newInstance();
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw new IOException("Cannot initialize the class: " + clazz);
+    }
+    instance.readFields(in);
+  }
+
+  public void write(DataOutput out) throws IOException {
+    if (type == NOT_SET || instance == null)
+      throw new IOException("The GenericWritable has NOT been set correctly. type="
+                            + type + ", instance=" + instance);
+    out.writeByte(type);
+    instance.write(out);
+  }
+
+  /**
+   * Return all classes that may be wrapped.  Subclasses should implement this
+   * to return a constant array of classes.
+   */
+  abstract protected Class[] getTypes();
+
+}