Author: cutting
Date: Fri Jan 8 20:36:04 2010
New Revision: 897319
URL: http://svn.apache.org/viewvc?rev=897319&view=rev
Log:
AVRO-278. Change GenericRecord's API and implementation to be array-based
rather than Map-based.
Modified:
hadoop/avro/trunk/CHANGES.txt
hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericData.java
hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumReader.java
hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumWriter.java
hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericRecord.java
hadoop/avro/trunk/src/java/org/apache/avro/reflect/ReflectDatumReader.java
hadoop/avro/trunk/src/java/org/apache/avro/specific/SpecificDatumReader.java
hadoop/avro/trunk/src/test/java/org/apache/avro/TestProtocolGeneric.java
Modified: hadoop/avro/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/CHANGES.txt?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/CHANGES.txt (original)
+++ hadoop/avro/trunk/CHANGES.txt Fri Jan 8 20:36:04 2010
@@ -24,6 +24,9 @@
format now permits streaming but no longer supports multiple
schemas per file. Java API for reading is iterator-based.
+ AVRO-278. Changed GenericRecord API and implementation to be
+ array-based rather than Map-based. (cutting)
+
NEW FEATURES
AVRO-151. Validating Avro schema parser for C (massie)
Modified: hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericData.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericData.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericData.java
(original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericData.java Fri Jan
8 20:36:04 2010
@@ -18,9 +18,7 @@
package org.apache.avro.generic;
import java.nio.ByteBuffer;
-import java.util.HashMap;
import java.util.Iterator;
-import java.util.LinkedHashMap;
import java.util.Arrays;
import java.util.Map;
@@ -43,17 +41,23 @@
protected GenericData() {}
/** Default implementation of {...@link GenericRecord}. */
- @SuppressWarnings(value="unchecked")
- public static class Record
- extends HashMap<String,Object>
- implements GenericRecord, Comparable<Record> {
+ public static class Record implements GenericRecord, Comparable<Record> {
private final Schema schema;
+ private final Object[] values;
public Record(Schema schema) {
- super(schema.getFields().size());
this.schema = schema;
+ this.values = new Object[schema.getFields().size()];
}
- public Schema getSchema() { return schema; }
- public boolean equals(Object o) {
+ @Override public Schema getSchema() { return schema; }
+ @Override public void put(String key, Object value) {
+ values[schema.getFields().get(key).pos()] = value;
+ }
+ @Override public void put(int i, Object v) { values[i] = v; }
+ @Override public Object get(String key) {
+ return values[schema.getFields().get(key).pos()];
+ }
+ @Override public Object get(int i) { return values[i]; }
+ @Override public boolean equals(Object o) {
if (o == this) return true; // identical object
if (!(o instanceof Record)) return false; // not a record
Record that = (Record)o;
@@ -61,12 +65,15 @@
return false; // not the same schema
return this.compareTo(that) == 0;
}
- public int hashCode() {
+ @Override public int hashCode() {
return GenericData.get().hashCode(this, schema);
}
- public int compareTo(Record that) {
+ @Override public int compareTo(Record that) {
return GenericData.get().compare(this, that, schema);
}
+ @Override public String toString() {
+ return GenericData.get().toString(this);
+ }
}
/** Default implementation of {...@link GenericArray}. */
@@ -166,9 +173,11 @@
case RECORD:
if (!(datum instanceof GenericRecord)) return false;
GenericRecord fields = (GenericRecord)datum;
- for (Map.Entry<String, Schema> entry : schema.getFieldSchemas())
- if (!validate(entry.getValue(), fields.get(entry.getKey())))
+ for (Map.Entry<String, Field> entry : schema.getFields().entrySet()) {
+ Field f = entry.getValue();
+ if (!validate(f.schema(), fields.get(f.pos())))
return false;
+ }
return true;
case ENUM:
return schema.getEnumSymbols().contains(datum);
@@ -217,11 +226,12 @@
buffer.append("{");
int count = 0;
GenericRecord record = (GenericRecord)datum;
- for (Map.Entry<String,Object> entry : record.entrySet()) {
- toString(entry.getKey(), buffer);
+ for (Map.Entry<String,Field> e :
+ record.getSchema().getFields().entrySet()) {
+ toString(e.getKey(), buffer);
buffer.append(": ");
- toString(entry.getValue(), buffer);
- if (++count < record.size())
+ toString(record.get(e.getValue().pos()), buffer);
+ if (++count < record.getSchema().getFields().size())
buffer.append(", ");
}
buffer.append("}");
@@ -267,11 +277,7 @@
/** Create a schema given an example datum. */
public Schema induce(Object datum) {
if (datum instanceof GenericRecord) {
- GenericRecord record = (GenericRecord)datum;
- LinkedHashMap<String,Field> fields = new LinkedHashMap<String,Field>();
- for (Map.Entry<String,Object> entry : record.entrySet())
- fields.put(entry.getKey(), new Field(induce(entry.getValue()), null,
null));
- return Schema.createRecord(fields);
+ return ((GenericRecord)datum).getSchema();
} else if (datum instanceof GenericArray) {
Schema elementType = null;
for (Object element : (GenericArray)datum) {
@@ -407,8 +413,7 @@
Field f = e.getValue();
if (f.order() == Field.Order.IGNORE)
continue;
- String name = e.getKey();
- hashCode = hashCodeAdd(hashCode, r.get(name), f.schema());
+ hashCode = hashCodeAdd(hashCode, r.get(f.pos()), f.schema());
}
return hashCode;
case ARRAY:
@@ -446,8 +451,8 @@
Field f = e.getValue();
if (f.order() == Field.Order.IGNORE)
continue; // ignore this field
- String name = e.getKey();
- int compare = compare(r1.get(name), r2.get(name), f.schema());
+ int pos = f.pos();
+ int compare = compare(r1.get(pos), r2.get(pos), f.schema());
if (compare != 0) // not equal
return f.order() == Field.Order.DESCENDING ? -compare : compare;
}
Modified:
hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumReader.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumReader.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumReader.java
(original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumReader.java
Fri Jan 8 20:36:04 2010
@@ -151,7 +151,7 @@
int fieldPosition = expectedField.pos();
Object oldDatum =
(old != null) ? getField(record, fieldName, fieldPosition) : null;
- addField(record, fieldName, fieldPosition,
+ setField(record, fieldName, fieldPosition,
read(oldDatum,actualField.schema(),expectedField.schema(), in));
size++;
}
@@ -164,7 +164,7 @@
JsonNode json = f.defaultValue();
if (json == null) // no default
throw new AvroTypeException("No default value for: "+fieldName);
- addField(record, fieldName, f.pos(), // add default
+ setField(record, fieldName, f.pos(), // set default
defaultFieldValue(old, f.schema(), json));
}
}
@@ -172,18 +172,18 @@
return record;
}
- /** Called by the default implementation of {...@link #readRecord} to add a
+ /** Called by the default implementation of {...@link #readRecord} to set a
* record fields value to a record instance. The default implementation is
* for {...@link GenericRecord}.*/
- protected void addField(Object record, String name, int position, Object o) {
- ((GenericRecord) record).put(name, o);
+ protected void setField(Object record, String name, int position, Object o) {
+ ((GenericRecord)record).put(position, o);
}
/** Called by the default implementation of {...@link #readRecord} to
retrieve a
* record field value from a reused instance. The default implementation is
* for {...@link GenericRecord}.*/
protected Object getField(Object record, String name, int position) {
- return ((GenericRecord) record).get(name);
+ return ((GenericRecord)record).get(position);
}
/** Called by the default implementation of {...@link #readRecord} to
construct
@@ -201,7 +201,7 @@
if (v == null)
throw new AvroTypeException("No default value for: "+name);
Object o = old != null ? getField(old, name, f.pos()) : null;
- addField(record, name, f.pos(), defaultFieldValue(o, f.schema(), v));
+ setField(record, name, f.pos(), defaultFieldValue(o, f.schema(), v));
}
return record;
case ENUM:
Modified:
hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumWriter.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumWriter.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumWriter.java
(original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericDatumWriter.java
Fri Jan 8 20:36:04 2010
@@ -95,7 +95,7 @@
* a record field value. The default implementation is for {...@link
* GenericRecord}.*/
protected Object getField(Object record, String field, int position) {
- return ((GenericRecord) record).get(field);
+ return ((GenericRecord) record).get(position);
}
/** Called to write an enum value. May be overridden for alternate enum
Modified: hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericRecord.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericRecord.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericRecord.java
(original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/generic/GenericRecord.java Fri
Jan 8 20:36:04 2010
@@ -17,8 +17,14 @@
*/
package org.apache.avro.generic;
-import java.util.Map;
-
-/** A set of fields, each a name/value pair.*/
-public interface GenericRecord extends Map<String,Object>, GenericContainer {
+/** An instance of a record schema.*/
+public interface GenericRecord extends GenericContainer {
+ /** Set the value of a field given its name. */
+ void put(String key, Object v);
+ /** Set the value of a field given its position in the schema. */
+ void put(int i, Object v);
+ /** Return the value of a field given its name. */
+ Object get(String key);
+ /** Return the value of a field given its position in the schema. */
+ Object get(int i);
}
Modified:
hadoop/avro/trunk/src/java/org/apache/avro/reflect/ReflectDatumReader.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/reflect/ReflectDatumReader.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/src/java/org/apache/avro/reflect/ReflectDatumReader.java
(original)
+++ hadoop/avro/trunk/src/java/org/apache/avro/reflect/ReflectDatumReader.java
Fri Jan 8 20:36:04 2010
@@ -45,7 +45,7 @@
}
@Override
- protected void addField(Object record, String name, int position, Object o) {
+ protected void setField(Object record, String name, int position, Object o) {
try {
ReflectData.getField(record.getClass(), name).set(record, o);
} catch (IllegalAccessException e) {
Modified:
hadoop/avro/trunk/src/java/org/apache/avro/specific/SpecificDatumReader.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/java/org/apache/avro/specific/SpecificDatumReader.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
---
hadoop/avro/trunk/src/java/org/apache/avro/specific/SpecificDatumReader.java
(original)
+++
hadoop/avro/trunk/src/java/org/apache/avro/specific/SpecificDatumReader.java
Fri Jan 8 20:36:04 2010
@@ -43,7 +43,7 @@
}
@Override
- protected void addField(Object record, String name, int position, Object o) {
+ protected void setField(Object record, String name, int position, Object o) {
((SpecificRecord)record).set(position, o);
}
@Override
Modified:
hadoop/avro/trunk/src/test/java/org/apache/avro/TestProtocolGeneric.java
URL:
http://svn.apache.org/viewvc/hadoop/avro/trunk/src/test/java/org/apache/avro/TestProtocolGeneric.java?rev=897319&r1=897318&r2=897319&view=diff
==============================================================================
--- hadoop/avro/trunk/src/test/java/org/apache/avro/TestProtocolGeneric.java
(original)
+++ hadoop/avro/trunk/src/test/java/org/apache/avro/TestProtocolGeneric.java
Fri Jan 8 20:36:04 2010
@@ -43,7 +43,6 @@
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
-import java.util.Map;
import java.util.Random;
public class TestProtocolGeneric {
@@ -155,7 +154,7 @@
error = e;
}
assertNotNull(error);
- assertEquals("an error",
((Map)error.getValue()).get("message").toString());
+ assertEquals("an error",
((GenericRecord)error.getValue()).get("message").toString());
}
@Test