You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by cu...@apache.org on 2011/10/05 20:37:46 UTC

svn commit: r1179372 - in /avro/trunk: ./ lang/java/avro/src/main/java/org/apache/avro/generic/ lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ lang/java/thrift/src/main/java/org/apache/avro/thrift/

Author: cutting
Date: Wed Oct  5 18:37:45 2011
New Revision: 1179372

URL: http://svn.apache.org/viewvc?rev=1179372&view=rev
Log:
AVRO-907. Java: Optimize access to protobuf message fields.

Modified:
    avro/trunk/CHANGES.txt
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
    avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java
    avro/trunk/lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ProtobufData.java
    avro/trunk/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java

Modified: avro/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/avro/trunk/CHANGES.txt?rev=1179372&r1=1179371&r2=1179372&view=diff
==============================================================================
--- avro/trunk/CHANGES.txt (original)
+++ avro/trunk/CHANGES.txt Wed Oct  5 18:37:45 2011
@@ -37,6 +37,8 @@ Avro 1.6.0 (unreleased)
 
     AVRO-853: Java: Cache Schema hash codes. (cutting)
 
+    AVRO-907. Java: Optimize access to protobuf message fields. (cutting)
+
   IMPROVEMENTS
 
     AVRO-836. Python "avro" commandline utility to display and write Avro files.

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java?rev=1179372&r1=1179371&r2=1179372&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericData.java Wed Oct  5 18:37:45 2011
@@ -513,7 +513,7 @@ public class GenericData {
   /** Produce state for repeated calls to {@link
    * #getField(Object,String,int,Object)} and {@link
    * #setField(Object,String,int,Object,Object)} on the same record.*/
-  protected Object getRecordState(Schema schema) { return null; }
+  protected Object getRecordState(Object record, Schema schema) { return null; }
 
   /** Version of {@link #setField} that has state. */
   protected void setField(Object r, String n, int p, Object o, Object state) {

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java?rev=1179372&r1=1179371&r2=1179372&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader.java Wed Oct  5 18:37:45 2011
@@ -164,7 +164,7 @@ public class GenericDatumReader<D> imple
   protected Object readRecord(Object old, Schema expected, 
       ResolvingDecoder in) throws IOException {
     Object r = data.newRecord(old, expected);
-    Object state = data.getRecordState(expected);
+    Object state = data.getRecordState(r, expected);
     
     for (Field f : in.readFieldOrder()) {
       int pos = f.pos();

Modified: avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java?rev=1179372&r1=1179371&r2=1179372&view=diff
==============================================================================
--- avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java (original)
+++ avro/trunk/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumWriter.java Wed Oct  5 18:37:45 2011
@@ -98,7 +98,7 @@ public class GenericDatumWriter<D> imple
    * representations.*/
   protected void writeRecord(Schema schema, Object datum, Encoder out)
     throws IOException {
-    Object state = data.getRecordState(schema);
+    Object state = data.getRecordState(datum, schema);
     for (Field f : schema.getFields()) {
       Object value = data.getField(datum, f.name(), f.pos(), state);
       try {

Modified: avro/trunk/lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ProtobufData.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ProtobufData.java?rev=1179372&r1=1179371&r2=1179372&view=diff
==============================================================================
--- avro/trunk/lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ProtobufData.java (original)
+++ avro/trunk/lang/java/protobuf/src/main/java/org/apache/avro/protobuf/ProtobufData.java Wed Oct  5 18:37:45 2011
@@ -35,6 +35,7 @@ import org.apache.avro.specific.Specific
 import com.google.protobuf.ByteString;
 import com.google.protobuf.Message;
 import com.google.protobuf.Message.Builder;
+import com.google.protobuf.MessageOrBuilder;
 import com.google.protobuf.ProtocolMessageEnum;
 import com.google.protobuf.Descriptors.Descriptor;
 import com.google.protobuf.Descriptors.FieldDescriptor;
@@ -60,9 +61,19 @@ public class ProtobufData extends Generi
   public static ProtobufData get() { return INSTANCE; }
 
   @Override
-  public void setField(Object record, String name, int position, Object o) {
-    Builder b = (Builder)record;
-    FieldDescriptor f = getFieldDescriptor(b.getDescriptorForType(), position);
+  public void setField(Object r, String n, int pos, Object o) {
+    setField(r, n, pos, o, getRecordState(r, getSchema(r.getClass())));
+  }
+
+  @Override
+  public Object getField(Object r, String name, int pos) {
+    return getField(r, name, pos, getRecordState(r, getSchema(r.getClass())));
+  }
+
+  @Override
+  protected void setField(Object r, String n, int pos, Object o, Object state) {
+    Builder b = (Builder)r;
+    FieldDescriptor f = ((FieldDescriptor[])state)[pos];
     switch (f.getType()) {
     case ENUM:
       b.setField(f, ((ProtocolMessageEnum)o).getValueDescriptor());
@@ -78,9 +89,9 @@ public class ProtobufData extends Generi
   }
 
   @Override
-  public Object getField(Object record, String name, int position) {
+  protected Object getField(Object record, String name, int pos, Object state) {
     Message m = (Message)record;
-    FieldDescriptor f = getFieldDescriptor(m.getDescriptorForType(), position);
+    FieldDescriptor f = ((FieldDescriptor[])state)[pos];
     switch (f.getType()) {
     case ENUM:
       Schema s = getSchema(f);
@@ -102,16 +113,17 @@ public class ProtobufData extends Generi
   private final Map<Descriptor,FieldDescriptor[]> fieldCache =
     new ConcurrentHashMap<Descriptor,FieldDescriptor[]>();
 
-  private FieldDescriptor getFieldDescriptor(Descriptor d, int pos) {
+  @Override
+  protected Object getRecordState(Object r, Schema s) {
+    Descriptor d = ((MessageOrBuilder)r).getDescriptorForType();
     FieldDescriptor[] fields = fieldCache.get(d);
     if (fields == null) {                         // cache miss
-      Schema s = getSchema(d);
       fields = new FieldDescriptor[s.getFields().size()];
       for (Field f : s.getFields())
         fields[f.pos()] = d.findFieldByName(f.name());
       fieldCache.put(d, fields);                  // update cache
     }
-    return fields[pos];
+    return fields;
   }
 
   @Override

Modified: avro/trunk/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java
URL: http://svn.apache.org/viewvc/avro/trunk/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java?rev=1179372&r1=1179371&r2=1179372&view=diff
==============================================================================
--- avro/trunk/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java (original)
+++ avro/trunk/lang/java/thrift/src/main/java/org/apache/avro/thrift/ThriftData.java Wed Oct  5 18:37:45 2011
@@ -54,18 +54,15 @@ public class ThriftData extends GenericD
 
   @Override
   public void setField(Object r, String n, int pos, Object o) {
-    setField(r, n, pos, o, getRecordState(getSchema(r.getClass())));
+    setField(r, n, pos, o, getRecordState(r, getSchema(r.getClass())));
   }
 
   @Override
   public Object getField(Object r, String name, int pos) {
-    return getField(r, name, pos, getRecordState(getSchema(r.getClass())));
+    return getField(r, name, pos, getRecordState(r, getSchema(r.getClass())));
   }
 
   @Override
-  protected Object getRecordState(Schema schema) { return getFieldIds(schema); }
-
-  @Override
   protected void setField(Object r, String n, int pos, Object v, Object state) {
     ((TBase)r).setFieldValue(((TFieldIdEnum[])state)[pos], v);
   }
@@ -78,18 +75,16 @@ public class ThriftData extends GenericD
   private final Map<Schema,TFieldIdEnum[]> fieldCache =
     new ConcurrentHashMap<Schema,TFieldIdEnum[]>();
 
-  public TFieldIdEnum[] getFieldIds(Schema s) {
+  @Override
+  protected Object getRecordState(Object r, Schema s) {
     TFieldIdEnum[] fields = fieldCache.get(s);
-    if (fields == null)
-      try {                                       // cache miss
-        fields = new TFieldIdEnum[s.getFields().size()];
-        Class c = Class.forName(SpecificData.getClassName(s));
-        for (TFieldIdEnum f : FieldMetaData.getStructMetaDataMap(c).keySet())
-          fields[s.getField(f.getFieldName()).pos()] = f;
-        fieldCache.put(s, fields);                  // update cache
-      } catch (ClassNotFoundException e) {
-        throw new AvroRuntimeException(e);
-      }
+    if (fields == null) {                           // cache miss
+      fields = new TFieldIdEnum[s.getFields().size()];
+      Class c = r.getClass();
+      for (TFieldIdEnum f : FieldMetaData.getStructMetaDataMap(c).keySet())
+        fields[s.getField(f.getFieldName()).pos()] = f;
+      fieldCache.put(s, fields);                  // update cache
+    }
     return fields;
   }