This is an automated email from the ASF dual-hosted git repository. thiru pushed a commit to branch fast-decoder-thiru in repository https://gitbox.apache.org/repos/asf/avro.git
commit cefbf862a7ba5f024e990a987357926a3f8ab2be Author: Thiruvalluvan M G <[email protected]> AuthorDate: Tue Apr 30 19:48:50 2019 -0700 formatting changes --- .../src/main/java/org/apache/avro/Resolver.java | 54 +- .../java/org/apache/avro/generic/Advancer.java | 975 ++++++++++++++------- .../apache/avro/generic/GenericDatumReader2.java | 63 +- 3 files changed, 728 insertions(+), 364 deletions(-) diff --git a/lang/java/avro/src/main/java/org/apache/avro/Resolver.java b/lang/java/avro/src/main/java/org/apache/avro/Resolver.java index 7c9e2c3..a01dfb9 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/Resolver.java +++ b/lang/java/avro/src/main/java/org/apache/avro/Resolver.java @@ -163,11 +163,11 @@ public class Resolver { } /** - * In this case, there's nothing to be done for resolution: the two - * schemas are effectively the same. This action will be generated - * <em>only</em> for primitive types (incl. STRING and BYTES) and - * also for fixed types, and <not>not</not for any other kind of - * schema. */ + * In this case, there's nothing to be done for resolution: the two schemas are + * effectively the same. This action will be generated <em>only</em> for + * primitive types (incl. STRING and BYTES) and also for fixed types, and + * <not>not</not for any other kind of schema. + */ public static class DoNothing extends Action { public DoNothing(Schema w, Schema r, GenericData d) { super(w, r, d, Action.Type.DO_NOTHING); @@ -251,9 +251,7 @@ public class Resolver { */ public static class Promote extends Action { public static enum Promotions { - INT2LONG, INT2FLOAT, INT2DOUBLE, - LONG2FLOAT, LONG2DOUBLE, FLOAT2DOUBLE, - STRING2BYTES, BYTES2STRING + INT2LONG, INT2FLOAT, INT2DOUBLE, LONG2FLOAT, LONG2DOUBLE, FLOAT2DOUBLE, STRING2BYTES, BYTES2STRING } /** The exact promotion being represented. */ @@ -283,9 +281,8 @@ public class Resolver { } /** - * Returns the {@link Promtion} that would resolve schema - * <code>w</code> against <code>r</code>, or null if there is no - * such promotion. + * Returns the {@link Promtion} that would resolve schema <code>w</code> against + * <code>r</code>, or null if there is no such promotion. */ private static Promotions findPromotion(Schema w, Schema r) { if (w.getType() == r.getType()) @@ -294,27 +291,35 @@ public class Resolver { switch (r.getType()) { case LONG: switch (wt) { - case INT: return Promotions.INT2LONG; + case INT: + return Promotions.INT2LONG; } break; case FLOAT: switch (wt) { - case INT: return Promotions.INT2FLOAT; - case LONG: return Promotions.LONG2FLOAT; + case INT: + return Promotions.INT2FLOAT; + case LONG: + return Promotions.LONG2FLOAT; } break; case DOUBLE: switch (wt) { - case INT: return Promotions.INT2DOUBLE; - case LONG: return Promotions.LONG2DOUBLE; - case FLOAT: return Promotions.FLOAT2DOUBLE; + case INT: + return Promotions.INT2DOUBLE; + case LONG: + return Promotions.LONG2DOUBLE; + case FLOAT: + return Promotions.FLOAT2DOUBLE; } break; case BYTES: - if (wt == Schema.Type.STRING) return Promotions.STRING2BYTES; + if (wt == Schema.Type.STRING) + return Promotions.STRING2BYTES; break; case STRING: - if (wt == Schema.Type.STRING) return Promotions.BYTES2STRING; + if (wt == Schema.Type.STRING) + return Promotions.BYTES2STRING; break; } return null; @@ -422,12 +427,11 @@ public class Resolver { public final Action[] fieldActions; /** - * Contains (all of) the reader's fields. The first {@link - * firstDefault} of these are the fields that will be read from - * the writer: these are in the order dictated by writer's - * schema. The remaining fields from {@link firstDefault} to the - * end of the array will be read from default values (actions for - * these default values are found in {@link defaults}. Note that + * Contains (all of) the reader's fields. The first {@link firstDefault} of + * these are the fields that will be read from the writer: these are in the + * order dictated by writer's schema. The remaining fields from + * {@link firstDefault} to the end of the array will be read from default values + * (actions for these default values are found in {@link defaults}. Note that * the default fields are in the order of the reader's schema. */ public final Field[] readerOrder; diff --git a/lang/java/avro/src/main/java/org/apache/avro/generic/Advancer.java b/lang/java/avro/src/main/java/org/apache/avro/generic/Advancer.java index 7c469cb..21bb22a 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/generic/Advancer.java +++ b/lang/java/avro/src/main/java/org/apache/avro/generic/Advancer.java @@ -27,67 +27,108 @@ import org.apache.avro.Schema; import org.apache.avro.io.Decoder; import org.apache.avro.util.Utf8; - -/** An "Advancer" is a tree of objects that apply resolution logic - * while reading values out of a {@link Decoder}. - * - * An Advancer tree is created by calling {@link advancerFor} on a - * {@link Resolver.Action} object. The resulting tree mimics the - * reader schema of that Action object. - * - * A decoder for that reader schema is meant to traverse the schema - * in a depth-first fashion. When it hits a leaf of type - * <code>Xyz</code>, it should call corresponding - * <code>nextXyx</code> on the Advancer. For example, if the reader - * hits a lead indicating that an integer should be read, it should - * call {@link nextInt}, as in <code>a.nextInt(in)</code>, where - * <code>a</code> is the advancer being traversed, and - * <code>in</code> is the Decoder being read from. - * - * When traversing an Array or Map in the reader schema, the decoder - * should call {@link getElementAdvancer} to retrieve the advancer - * object for the contained element-schema or value-schema. See the - * JavaDoc for {@link getElementAdvancer} for instructions on how to - * decode these types. - * - * For unions, the decoder should call {@link nextIndex} to fetch the - * branch and then {@link getBranchAdvancer} to get the advancer of - * that branch. (Calling {@link next} on a union will read the - * index, pick the right advancer based on the index, and then read - * and return the actual value.) - * - * Traversing records, arrays, and maps is more involved. In the - * case of an array or map, call {@link getArrayAdvancer} {@link - * getMapAdvancer} and proceed as described in the documentation for - * {@link Advancer.Container}. For records, best to just look at the - * implementation of {@link GenericDatumReader2}. - **/ +/** + * An "Advancer" is a tree of objects that apply resolution logic while reading + * values out of a {@link Decoder}. + * + * An Advancer tree is created by calling {@link advancerFor} on a + * {@link Resolver.Action} object. The resulting tree mimics the reader schema + * of that Action object. + * + * A decoder for that reader schema is meant to traverse the schema in a + * depth-first fashion. When it hits a leaf of type <code>Xyz</code>, it should + * call corresponding <code>nextXyx</code> on the Advancer. For example, if the + * reader hits a lead indicating that an integer should be read, it should call + * {@link nextInt}, as in <code>a.nextInt(in)</code>, where <code>a</code> is + * the advancer being traversed, and <code>in</code> is the Decoder being read + * from. + * + * When traversing an Array or Map in the reader schema, the decoder should call + * {@link getElementAdvancer} to retrieve the advancer object for the contained + * element-schema or value-schema. See the JavaDoc for + * {@link getElementAdvancer} for instructions on how to decode these types. + * + * For unions, the decoder should call {@link nextIndex} to fetch the branch and + * then {@link getBranchAdvancer} to get the advancer of that branch. (Calling + * {@link next} on a union will read the index, pick the right advancer based on + * the index, and then read and return the actual value.) + * + * Traversing records, arrays, and maps is more involved. In the case of an + * array or map, call {@link getArrayAdvancer} {@link getMapAdvancer} and + * proceed as described in the documentation for {@link Advancer.Container}. For + * records, best to just look at the implementation of + * {@link GenericDatumReader2}. + **/ abstract class Advancer { protected Exception exception() { throw new UnsupportedOperationException(); } - //// API methods of Advancer. Used by decoding methods to + //// API methods of Advancer. Used by decoding methods to //// read values out of Decoder, applying resolution logic - //// in the process. In the base class, these do throw - //// a not-supported exception. Specific subclasses implement + //// in the process. In the base class, these do throw + //// a not-supported exception. Specific subclasses implement //// certain ones, e.g., IntFast (the Advancer used when //// an integer is read with no promotion) overrides just //// readInt. public final Schema writer, reader; - protected Advancer(Schema w, Schema r) { this.writer = w; this.reader = r; } - - public Object next(Decoder in) throws IOException { exception(); return null; } - public Object nextNull(Decoder in) throws IOException { exception(); return null; } - public boolean nextBoolean(Decoder in) throws IOException { exception(); return false; } - public int nextInt(Decoder in) throws IOException { exception(); return 0; } - public long nextLong(Decoder in) throws IOException { exception(); return 0; } - public float nextFloat(Decoder in) throws IOException { exception(); return 0; } - public double nextDouble(Decoder in) throws IOException { exception(); return 0; } - public int nextEnum(Decoder in) throws IOException { exception(); return 0; } - public Utf8 nextString(Decoder in, Utf8 old) throws IOException { exception(); return null; } - public String nextString(Decoder in) throws IOException { exception(); return null; } + + protected Advancer(Schema w, Schema r) { + this.writer = w; + this.reader = r; + } + + public Object next(Decoder in) throws IOException { + exception(); + return null; + } + + public Object nextNull(Decoder in) throws IOException { + exception(); + return null; + } + + public boolean nextBoolean(Decoder in) throws IOException { + exception(); + return false; + } + + public int nextInt(Decoder in) throws IOException { + exception(); + return 0; + } + + public long nextLong(Decoder in) throws IOException { + exception(); + return 0; + } + + public float nextFloat(Decoder in) throws IOException { + exception(); + return 0; + } + + public double nextDouble(Decoder in) throws IOException { + exception(); + return 0; + } + + public int nextEnum(Decoder in) throws IOException { + exception(); + return 0; + } + + public Utf8 nextString(Decoder in, Utf8 old) throws IOException { + exception(); + return null; + } + + public String nextString(Decoder in) throws IOException { + exception(); + return null; + } + public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException { exception(); return null; @@ -103,10 +144,15 @@ abstract class Advancer { } /** Get index for a union. */ - public int nextIndex(Decoder in) throws IOException { exception(); return 0; } + public int nextIndex(Decoder in) throws IOException { + exception(); + return 0; + } - /** Access to contained advancer for unions. You must call {@link - * nextIndex} before calling this method. */ + /** + * Access to contained advancer for unions. You must call {@link nextIndex} + * before calling this method. + */ public Advancer getBranchAdvancer(Decoder in, int branch) throws IOException { exception(); return null; @@ -130,72 +176,92 @@ abstract class Advancer { return null; } - - ////// Here's the builder for Advancer trees. The subclasses used by + ////// Here's the builder for Advancer trees. The subclasses used by ////// this implementation are found below. - /** Build a {@link Advancer} tree that for a given {@link - * Resolver.Action} tree. If input argument (<code>a</code>) is a - * {@link Resolver.RecordAdjust}, the result is guaranteed to be a - * {@link Advancer.Record}. */ + /** + * Build a {@link Advancer} tree that for a given {@link Resolver.Action} tree. + * If input argument (<code>a</code>) is a {@link Resolver.RecordAdjust}, the + * result is guaranteed to be a {@link Advancer.Record}. + */ public static Advancer from(Resolver.Action a) { switch (a.type) { case DO_NOTHING: switch (a.reader.getType()) { - case NULL: return NullFast.instance; - case BOOLEAN: return BooleanFast.instance; - case INT: return IntFast.instance; - case LONG: return LongFast.instance; - case FLOAT: return FloatFast.instance; - case DOUBLE: return DoubleFast.instance; - case STRING: return StringFast.instance; - case BYTES: return BytesFast.instance; - case FIXED: return new FixedFast(a.writer, a.reader); + case NULL: + return NullFast.instance; + case BOOLEAN: + return BooleanFast.instance; + case INT: + return IntFast.instance; + case LONG: + return LongFast.instance; + case FLOAT: + return FloatFast.instance; + case DOUBLE: + return DoubleFast.instance; + case STRING: + return StringFast.instance; + case BYTES: + return BytesFast.instance; + case FIXED: + return new FixedFast(a.writer, a.reader); default: throw new IllegalArgumentException("Unexpected schema for DoNothing:" + a.reader); } case PROMOTE: - switch (((Resolver.Promote)a).promotion) { - case INT2LONG: return LongFromInt.instance; - case INT2FLOAT: return FloatFromInt.instance; - case INT2DOUBLE: return DoubleFromInt.instance; - case LONG2FLOAT: return FloatFromLong.instance; - case LONG2DOUBLE: return DoubleFromLong.instance; - case FLOAT2DOUBLE: return DoubleFromFloat.instance; - case STRING2BYTES: return BytesFromString.instance; - case BYTES2STRING: return StringFromBytes.instance; + switch (((Resolver.Promote) a).promotion) { + case INT2LONG: + return LongFromInt.instance; + case INT2FLOAT: + return FloatFromInt.instance; + case INT2DOUBLE: + return DoubleFromInt.instance; + case LONG2FLOAT: + return FloatFromLong.instance; + case LONG2DOUBLE: + return DoubleFromLong.instance; + case FLOAT2DOUBLE: + return DoubleFromFloat.instance; + case STRING2BYTES: + return BytesFromString.instance; + case BYTES2STRING: + return StringFromBytes.instance; default: throw new IllegalArgumentException("Unexpected promotion:" + a); } case ENUM: - Resolver.EnumAdjust e = (Resolver.EnumAdjust)a; - if (e.noAdjustmentsNeeded) return new EnumFast(a.writer, a.reader); - else return new EnumWithAdjustments(a.writer, a.reader, e.adjustments); + Resolver.EnumAdjust e = (Resolver.EnumAdjust) a; + if (e.noAdjustmentsNeeded) + return new EnumFast(a.writer, a.reader); + else + return new EnumWithAdjustments(a.writer, a.reader, e.adjustments); case CONTAINER: - Advancer ea = Advancer.from(((Resolver.Container)a).elementAction); - if (a.writer.getType() == Schema.Type.ARRAY) - return new Container(a.writer, a.reader, ea); - else return new Map(a.writer, a.reader, ea); + Advancer ea = Advancer.from(((Resolver.Container) a).elementAction); + if (a.writer.getType() == Schema.Type.ARRAY) + return new Container(a.writer, a.reader, ea); + else + return new Map(a.writer, a.reader, ea); case RECORD: - return Advancer.Record.from((Resolver.RecordAdjust)a); + return Advancer.Record.from((Resolver.RecordAdjust) a); case WRITER_UNION: - Resolver.WriterUnion wu = (Resolver.WriterUnion)a; + Resolver.WriterUnion wu = (Resolver.WriterUnion) a; Advancer[] branches = new Advancer[wu.actions.length]; for (int i = 0; i < branches.length; i++) branches[i] = Advancer.from(wu.actions[i]); - if (wu.unionEquiv) return new EquivUnion(a.writer, a.reader, branches); + if (wu.unionEquiv) + return new EquivUnion(a.writer, a.reader, branches); return new WriterUnion(a.writer, a.reader, branches); case READER_UNION: - Resolver.ReaderUnion ru = (Resolver.ReaderUnion)a; - return new ReaderUnion(a.writer, a.reader, - ru.firstMatch, Advancer.from(ru.actualAction)); + Resolver.ReaderUnion ru = (Resolver.ReaderUnion) a; + return new ReaderUnion(a.writer, a.reader, ru.firstMatch, Advancer.from(ru.actualAction)); case ERROR: - return new Error(a.writer,a.reader, a.toString()); + return new Error(a.writer, a.reader, a.toString()); case SKIP: throw new RuntimeException("Internal error. Skip should've been consumed."); default: @@ -215,167 +281,253 @@ abstract class Advancer { } return result; } + private static final Schema[] EMPTY_SCHEMA_ARRAY = new Schema[0]; ////// Subclasses of Advancer -- real work is done in these - /** All methods of <code>this</code> throw {@link - * AvroTypeException} with appropriate message. Used for - * throwing resolution errors in a lazy fashion (i.e., as actual - * data causes the error to manifest). */ + /** + * All methods of <code>this</code> throw {@link AvroTypeException} with + * appropriate message. Used for throwing resolution errors in a lazy fashion + * (i.e., as actual data causes the error to manifest). + */ private static class Error extends Advancer { String msg; - public Error(Schema w, Schema r, String msg) { super(w,r); this.msg = msg; } + + public Error(Schema w, Schema r, String msg) { + super(w, r); + this.msg = msg; + } + protected Exception exception() { throw new AvroTypeException(msg); } } - /** Used for Array. The following fragment illustrates how - * to use to read an array of int: - * - * <pre> - * Advancer.Container c = advancer.getArrayAdvancer(in); - * for(long i = c.firstChunk(in); i != 0; i = c.nextChunk(in)) { - * for (long j = 0; j < i; j++) { - * int element = c.elementAdvancer.readInt(in); - * // .. do something with this element - * } - * } - * </pre> - * See the implementation of {@link GenericDatumReader2} for more - * illustrations. */ + /** + * Used for Array. The following fragment illustrates how to use to read an + * array of int: + * + * <pre> + * Advancer.Container c = advancer.getArrayAdvancer(in); + * for (long i = c.firstChunk(in); i != 0; i = c.nextChunk(in)) { + * for (long j = 0; j < i; j++) { + * int element = c.elementAdvancer.readInt(in); + * // .. do something with this element + * } + * } + * </pre> + * + * See the implementation of {@link GenericDatumReader2} for more illustrations. + */ public static class Container extends Advancer { public final Advancer elementAdvancer; - public Container(Schema w, Schema r, Advancer ea) - { super(w,r); elementAdvancer = ea; } - - public long firstChunk(Decoder in) throws IOException - { return in.readArrayStart(); } - - public long nextChunk(Decoder in) throws IOException - { return in.arrayNext(); } - } - - /** Used for Map. The following fragment illustrates how - * to use to read an array of int: - * - * <pre> - * Advancer.Map c = advancer.getMapAdvancer(in); - * for(long i = c.firstChunk(in); i != 0; i = c.nextChunk(in)) { - * for (long j = 0; j < i; j++) { - * String key = c.keyAdvancer.readString(in); - * int element = c.elementAdvancer.readInt(in); - * // .. do something with this element - * } - * } - * </pre> - * See the implementation of {@link GenericDatumReader2} for more - * illustrations. */ + + public Container(Schema w, Schema r, Advancer ea) { + super(w, r); + elementAdvancer = ea; + } + + public long firstChunk(Decoder in) throws IOException { + return in.readArrayStart(); + } + + public long nextChunk(Decoder in) throws IOException { + return in.arrayNext(); + } + } + + /** + * Used for Map. The following fragment illustrates how to use to read an array + * of int: + * + * <pre> + * Advancer.Map c = advancer.getMapAdvancer(in); + * for (long i = c.firstChunk(in); i != 0; i = c.nextChunk(in)) { + * for (long j = 0; j < i; j++) { + * String key = c.keyAdvancer.readString(in); + * int element = c.elementAdvancer.readInt(in); + * // .. do something with this element + * } + * } + * </pre> + * + * See the implementation of {@link GenericDatumReader2} for more illustrations. + */ public static class Map extends Container { public final Advancer keyAdvancer = StringFast.instance; - public Map(Schema w, Schema r, Advancer ea) { super(w,r,ea); } - public long firstChunk(Decoder in) throws IOException - { return in.readMapStart(); } + public Map(Schema w, Schema r, Advancer ea) { + super(w, r, ea); + } - public long nextChunk(Decoder in) throws IOException - { return in.mapNext(); } + public long firstChunk(Decoder in) throws IOException { + return in.readMapStart(); + } + + public long nextChunk(Decoder in) throws IOException { + return in.mapNext(); + } } //// The following set of subclasses are for when there is no - //// resolution logic to be applied. All that needs to be done + //// resolution logic to be applied. All that needs to be done //// is call the corresponding method on the Decoder. private static class NullFast extends Advancer { public static final NullFast instance = new NullFast(); private static final Schema s = Schema.create(Schema.Type.NULL); - private NullFast() { super(s,s); } + + private NullFast() { + super(s, s); + } + public Object nextNull(Decoder in) throws IOException { - in.readNull(); + in.readNull(); return null; } - public Object next(Decoder in) throws IOException { return nextNull(in); } + + public Object next(Decoder in) throws IOException { + return nextNull(in); + } } private static class BooleanFast extends Advancer { public static final BooleanFast instance = new BooleanFast(); private static final Schema s = Schema.create(Schema.Type.BOOLEAN); - private BooleanFast() { super(s,s); } + + private BooleanFast() { + super(s, s); + } + public boolean nextBoolean(Decoder in) throws IOException { - return in.readBoolean(); + return in.readBoolean(); + } + + public Object next(Decoder in) throws IOException { + return nextBoolean(in); } - public Object next(Decoder in) throws IOException { return nextBoolean(in); } } private static class IntFast extends Advancer { public static final IntFast instance = new IntFast(); private static final Schema s = Schema.create(Schema.Type.INT); - private IntFast() { super(s,s); } + + private IntFast() { + super(s, s); + } + public int nextInt(Decoder in) throws IOException { - return in.readInt(); + return in.readInt(); + } + + public Object next(Decoder in) throws IOException { + return nextInt(in); } - public Object next(Decoder in) throws IOException { return nextInt(in); } } private static class LongFast extends Advancer { public static final LongFast instance = new LongFast(); private static final Schema s = Schema.create(Schema.Type.LONG); - private LongFast() { super(s,s); } + + private LongFast() { + super(s, s); + } + public long nextLong(Decoder in) throws IOException { - return in.readLong(); + return in.readLong(); + } + + public Object next(Decoder in) throws IOException { + return nextLong(in); } - public Object next(Decoder in) throws IOException { return nextLong(in); } } private static class FloatFast extends Advancer { public static final FloatFast instance = new FloatFast(); private static final Schema s = Schema.create(Schema.Type.FLOAT); - private FloatFast() { super(s,s); } + + private FloatFast() { + super(s, s); + } + public float nextFloat(Decoder in) throws IOException { - return in.readFloat(); + return in.readFloat(); + } + + public Object next(Decoder in) throws IOException { + return nextFloat(in); } - public Object next(Decoder in) throws IOException { return nextFloat(in); } } private static class DoubleFast extends Advancer { public static final DoubleFast instance = new DoubleFast(); private static final Schema s = Schema.create(Schema.Type.DOUBLE); - private DoubleFast() { super(s,s); } + + private DoubleFast() { + super(s, s); + } + public double nextDouble(Decoder in) throws IOException { - return in.readDouble(); + return in.readDouble(); + } + + public Object next(Decoder in) throws IOException { + return nextDouble(in); } - public Object next(Decoder in) throws IOException { return nextDouble(in); } } private static class StringFast extends Advancer { public static final StringFast instance = new StringFast(); private static final Schema s = Schema.create(Schema.Type.STRING); - private StringFast() { super(s,s); } - public String nextString(Decoder in) throws IOException { return in.readString(); } + + private StringFast() { + super(s, s); + } + + public String nextString(Decoder in) throws IOException { + return in.readString(); + } + public Utf8 nextString(Decoder in, Utf8 old) throws IOException { return in.readString(old); } - public Object next(Decoder in) throws IOException { return nextString(in); } + + public Object next(Decoder in) throws IOException { + return nextString(in); + } } private static class BytesFast extends Advancer { public static final BytesFast instance = new BytesFast(); private static final Schema s = Schema.create(Schema.Type.BYTES); - private BytesFast() { super(s,s); } + + private BytesFast() { + super(s, s); + } + public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException { return in.readBytes(old); } - public Object next(Decoder in) throws IOException { return nextBytes(in, null); } + + public Object next(Decoder in) throws IOException { + return nextBytes(in, null); + } } private static class FixedFast extends Advancer { private final int len; - private FixedFast(Schema w, Schema r) { super(w,r); this.len = w.getFixedSize(); } + + private FixedFast(Schema w, Schema r) { + super(w, r); + this.len = w.getFixedSize(); + } + public byte[] nextFixed(Decoder in, byte[] bytes, int start, int len) throws IOException { in.readFixed(bytes, start, len); return bytes; } + public Object next(Decoder in) throws IOException { byte[] result = new byte[len]; nextFixed(in, new byte[len]); @@ -384,9 +536,17 @@ abstract class Advancer { } private static class EnumFast extends Advancer { - public EnumFast(Schema w, Schema r) { super(w,r); } - public int nextEnum(Decoder in) throws IOException { return in.readEnum(); } - public Object next(Decoder in) throws IOException { return nextEnum(in); } + public EnumFast(Schema w, Schema r) { + super(w, r); + } + + public int nextEnum(Decoder in) throws IOException { + return in.readEnum(); + } + + public Object next(Decoder in) throws IOException { + return nextEnum(in); + } } //// The following set of subclasses apply promotion logic @@ -394,160 +554,258 @@ abstract class Advancer { private static class LongFromInt extends Advancer { public static final LongFromInt instance = new LongFromInt(); + private LongFromInt() { super(Schema.create(Schema.Type.INT), Schema.create(Schema.Type.LONG)); } + public long nextLong(Decoder in) throws IOException { - return (long) in.readInt(); + return (long) in.readInt(); + } + + public Object next(Decoder in) throws IOException { + return nextLong(in); } - public Object next(Decoder in) throws IOException { return nextLong(in); } } private static class FloatFromInt extends Advancer { public static final FloatFromInt instance = new FloatFromInt(); + private FloatFromInt() { super(Schema.create(Schema.Type.INT), Schema.create(Schema.Type.FLOAT)); } + public float nextFloat(Decoder in) throws IOException { - return (float) in.readInt(); + return (float) in.readInt(); + } + + public Object next(Decoder in) throws IOException { + return nextFloat(in); } - public Object next(Decoder in) throws IOException { return nextFloat(in); } } private static class FloatFromLong extends Advancer { public static final FloatFromLong instance = new FloatFromLong(); + private FloatFromLong() { super(Schema.create(Schema.Type.LONG), Schema.create(Schema.Type.FLOAT)); } + public float nextFloat(Decoder in) throws IOException { - return (long) in.readLong(); + return (long) in.readLong(); + } + + public Object next(Decoder in) throws IOException { + return nextFloat(in); } - public Object next(Decoder in) throws IOException { return nextFloat(in); } } private static class DoubleFromInt extends Advancer { public static final DoubleFromInt instance = new DoubleFromInt(); + private DoubleFromInt() { super(Schema.create(Schema.Type.INT), Schema.create(Schema.Type.DOUBLE)); } + public double nextDouble(Decoder in) throws IOException { - return (double) in.readInt(); + return (double) in.readInt(); + } + + public Object next(Decoder in) throws IOException { + return nextDouble(in); } - public Object next(Decoder in) throws IOException { return nextDouble(in); } } private static class DoubleFromLong extends Advancer { public static final DoubleFromLong instance = new DoubleFromLong(); + private DoubleFromLong() { super(Schema.create(Schema.Type.LONG), Schema.create(Schema.Type.DOUBLE)); } + public double nextDouble(Decoder in) throws IOException { - return (double) in.readLong(); + return (double) in.readLong(); + } + + public Object next(Decoder in) throws IOException { + return nextDouble(in); } - public Object next(Decoder in) throws IOException { return nextDouble(in); } } private static class DoubleFromFloat extends Advancer { public static final DoubleFromFloat instance = new DoubleFromFloat(); + private DoubleFromFloat() { super(Schema.create(Schema.Type.FLOAT), Schema.create(Schema.Type.DOUBLE)); } + public double nextDouble(Decoder in) throws IOException { - return (double) in.readFloat(); + return (double) in.readFloat(); + } + + public Object next(Decoder in) throws IOException { + return nextDouble(in); } - public Object next(Decoder in) throws IOException { return nextDouble(in); } } private static class BytesFromString extends Advancer { public static final BytesFromString instance = new BytesFromString(); + private BytesFromString() { super(Schema.create(Schema.Type.STRING), Schema.create(Schema.Type.BYTES)); } + public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException { Utf8 s = in.readString(null); return ByteBuffer.wrap(s.getBytes(), 0, s.getByteLength()); } - public Object next(Decoder in) throws IOException { return nextBytes(in, null); } + + public Object next(Decoder in) throws IOException { + return nextBytes(in, null); + } } private static class StringFromBytes extends Advancer { public static final StringFromBytes instance = new StringFromBytes(); + private StringFromBytes() { super(Schema.create(Schema.Type.BYTES), Schema.create(Schema.Type.STRING)); } + public String nextString(Decoder in) throws IOException { return new String(in.readBytes(null).array(), StandardCharsets.UTF_8); } + public Utf8 nextString(Decoder in, Utf8 old) throws IOException { return new Utf8(in.readBytes(null).array()); } - public Object next(Decoder in) throws IOException { return nextString(in); } - } + public Object next(Decoder in) throws IOException { + return nextString(in); + } + } //// This last set of advancers are used when more sophisticated //// adjustmentds are needed private static class EnumWithAdjustments extends Advancer { private final int[] adjustments; + public EnumWithAdjustments(Schema w, Schema r, int[] adjustments) { - super(w,r); + super(w, r); this.adjustments = adjustments; } + public int nextEnum(Decoder in) throws IOException { return adjustments[in.readInt()]; } - public Object next(Decoder in) throws IOException { return nextEnum(in); } + + public Object next(Decoder in) throws IOException { + return nextEnum(in); + } } - /** In this case, the writer has a union by the reader doesn't, so we - * consume the tag ourself and call the corresponding advancer. */ + /** + * In this case, the writer has a union by the reader doesn't, so we consume the + * tag ourself and call the corresponding advancer. + */ private static class WriterUnion extends Advancer { private Advancer[] branches; - public WriterUnion(Schema w, Schema r, Advancer[] b) { super(w,r); branches = b; } - private final Advancer b(Decoder in) throws IOException - { return branches[in.readIndex()]; } + public WriterUnion(Schema w, Schema r, Advancer[] b) { + super(w, r); + branches = b; + } - public Object next(Decoder in) throws IOException { return b(in).next(in); } - public Object nextNull(Decoder in) throws IOException { return b(in).nextNull(in); } - public boolean nextBoolean(Decoder in) throws IOException { return b(in).nextBoolean(in); } - public int nextInt(Decoder in) throws IOException { return b(in).nextInt(in); } - public long nextLong(Decoder in) throws IOException { return b(in).nextLong(in); } - public float nextFloat(Decoder in) throws IOException { return b(in).nextFloat(in); } - public double nextDouble(Decoder in) throws IOException { return b(in).nextDouble(in); } - public int nextEnum(Decoder in) throws IOException { return b(in).nextEnum(in); } - public String nextString(Decoder in) throws IOException { return b(in).nextString(in); } - public Utf8 nextString(Decoder in, Utf8 old) throws IOException - { return b(in).nextString(in, old); } + private final Advancer b(Decoder in) throws IOException { + return branches[in.readIndex()]; + } - public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException - { return b(in).nextBytes(in, old); } + public Object next(Decoder in) throws IOException { + return b(in).next(in); + } - public byte[] nextFixed(Decoder in, byte[] bytes, int start, int length) throws IOException - { return b(in).nextFixed(in, bytes, start, length); } + public Object nextNull(Decoder in) throws IOException { + return b(in).nextNull(in); + } - public int nextIndex(Decoder in) throws IOException { return b(in).nextIndex(in); } - public Advancer getBranchAdvancer(Decoder in, int branch) throws IOException - { return b(in).getBranchAdvancer(in, branch); } + public boolean nextBoolean(Decoder in) throws IOException { + return b(in).nextBoolean(in); + } + + public int nextInt(Decoder in) throws IOException { + return b(in).nextInt(in); + } + + public long nextLong(Decoder in) throws IOException { + return b(in).nextLong(in); + } + + public float nextFloat(Decoder in) throws IOException { + return b(in).nextFloat(in); + } - public Container getArrayAdvancer(Decoder in) throws IOException - { return b(in).getArrayAdvancer(in); } + public double nextDouble(Decoder in) throws IOException { + return b(in).nextDouble(in); + } - public Map getMapAdvancer(Decoder in) throws IOException - { return b(in).getMapAdvancer(in); } + public int nextEnum(Decoder in) throws IOException { + return b(in).nextEnum(in); + } - public Record getRecordAdvancer(Decoder in) throws IOException - { return b(in).getRecordAdvancer(in); } + public String nextString(Decoder in) throws IOException { + return b(in).nextString(in); + } + + public Utf8 nextString(Decoder in, Utf8 old) throws IOException { + return b(in).nextString(in, old); + } + + public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException { + return b(in).nextBytes(in, old); + } + + public byte[] nextFixed(Decoder in, byte[] bytes, int start, int length) throws IOException { + return b(in).nextFixed(in, bytes, start, length); + } + + public int nextIndex(Decoder in) throws IOException { + return b(in).nextIndex(in); + } + + public Advancer getBranchAdvancer(Decoder in, int branch) throws IOException { + return b(in).getBranchAdvancer(in, branch); + } + + public Container getArrayAdvancer(Decoder in) throws IOException { + return b(in).getArrayAdvancer(in); + } + + public Map getMapAdvancer(Decoder in) throws IOException { + return b(in).getMapAdvancer(in); + } + + public Record getRecordAdvancer(Decoder in) throws IOException { + return b(in).getRecordAdvancer(in); + } } - /** In this case, reader and writer have the same union, so let the decoder - * consume it as a regular union. */ + /** + * In this case, reader and writer have the same union, so let the decoder + * consume it as a regular union. + */ private static class EquivUnion extends Advancer { private final Advancer[] branches; - public EquivUnion(Schema w, Schema r, Advancer[] b) {super(w,r); branches = b; } - public int nextIndex(Decoder in) throws IOException { return in.readIndex(); } + public EquivUnion(Schema w, Schema r, Advancer[] b) { + super(w, r); + branches = b; + } + + public int nextIndex(Decoder in) throws IOException { + return in.readIndex(); + } + public Advancer getBranchAdvancer(Decoder in, int branch) throws IOException { return branches[branch]; } @@ -556,59 +814,67 @@ abstract class Advancer { private static class ReaderUnion extends Advancer { private int branch; private Advancer advancer; - public ReaderUnion(Schema w, Schema r, int b, Advancer a) - { super(w,r); branch = b; advancer = a; } - public int nextIndex(Decoder in) { return branch; } + public ReaderUnion(Schema w, Schema r, int b, Advancer a) { + super(w, r); + branch = b; + advancer = a; + } + + public int nextIndex(Decoder in) { + return branch; + } public Advancer getBranchAdvancer(Decoder in, int b) { if (b != this.branch) - throw new IllegalArgumentException("Branch much be " + branch + ", got " + b); + throw new IllegalArgumentException("Branch much be " + branch + ", got " + b); return advancer; } } - - - //// Records are particularly intricate because we may have to skip //// fields, read fields out of order, and use default values. - /** Advancer for records. The {@link advancers} array contains an - * advancer for each field, ordered according writer (which - * determines the order in which data must be read). The {@link - * readerOrder} array tells you how those advancers line up with the - * reader's fields. Thus, the following is how to read a record: - * <pre> - * for (int i = 0; i < a.advancers.length; i++) { - * dataum.set(a.readerOrder[i].pos(), a.advancers[i].next(in)); - * } - * a.done(in); - * </pre> - * Note that a decoder <em>must</em> call {@link done} after interpreting - * all the elemnts in {@link advancers}. - * - * As a convenience, {@link inOrder} is set to true iff the reader - * and writer order agrees (i.e., iff <code>readerOrder[i].pos() == - * i</code> for all i). Generated code can use this to optimize this - * common case. */ + /** + * Advancer for records. The {@link advancers} array contains an advancer for + * each field, ordered according writer (which determines the order in which + * data must be read). The {@link readerOrder} array tells you how those + * advancers line up with the reader's fields. Thus, the following is how to + * read a record: + * + * <pre> + * for (int i = 0; i < a.advancers.length; i++) { + * dataum.set(a.readerOrder[i].pos(), a.advancers[i].next(in)); + * } + * a.done(in); + * </pre> + * + * Note that a decoder <em>must</em> call {@link done} after interpreting all + * the elemnts in {@link advancers}. + * + * As a convenience, {@link inOrder} is set to true iff the reader and writer + * order agrees (i.e., iff <code>readerOrder[i].pos() == + * i</code> for all i). Generated code can use this to optimize this common + * case. + */ public static class Record extends Advancer { public final Advancer[] advancers; private Schema[] finalSkips; public final Schema.Field[] readerOrder; public final boolean inOrder; - private Record(Schema w, Schema r, Advancer[] advancers, Schema[] finalSkips, - Schema.Field[] readerOrder, boolean inOrder) - { - super(w,r); + private Record(Schema w, Schema r, Advancer[] advancers, Schema[] finalSkips, Schema.Field[] readerOrder, + boolean inOrder) { + super(w, r); this.advancers = advancers; this.finalSkips = finalSkips; this.readerOrder = readerOrder; this.inOrder = inOrder; } - public Record getRecordAdvancer(Decoder in) { return this; } + public Record getRecordAdvancer(Decoder in) { + return this; + } /** Must be called after consuming all elements of {@link advancers}. */ public void done(Decoder in) throws IOException { @@ -631,7 +897,7 @@ abstract class Advancer { int nrf = 0; // (Insertion) index into fieldAdvs // Deal with fields to be read - for ( ; rf < ra.firstDefault; rf++, nrf++) { + for (; rf < ra.firstDefault; rf++, nrf++) { Schema[] toSkip = collectSkips(ra.fieldActions, i); i += toSkip.length; Advancer fieldAdv = Advancer.from(ra.fieldActions[i++]); @@ -653,8 +919,8 @@ abstract class Advancer { // decoders to have an optimized path for the common case of a // record's field order not changing. boolean inOrder = true; - for (int k = 0; k < ra.firstDefault-1; k++) - inOrder &= (readOrder[k].pos() < readOrder[k+1].pos()); + for (int k = 0; k < ra.firstDefault - 1; k++) + inOrder &= (readOrder[k].pos() < readOrder[k + 1].pos()); if (inOrder) { Advancer[] newAdvancers = new Advancer[fieldAdvs.length]; Schema.Field[] newReadOrder = new Schema.Field[fieldAdvs.length]; @@ -678,79 +944,140 @@ abstract class Advancer { private static class RecordField extends Advancer { private final Schema[] toSkip; private final Advancer field; + public RecordField(Schema w, Schema r, Schema[] toSkip, Advancer field) { - super(w,r); + super(w, r); this.toSkip = toSkip; this.field = field; } - public Object nextNull(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextNull(in); } + public Object nextNull(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextNull(in); + } - public boolean nextBoolean(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextBoolean(in); } + public boolean nextBoolean(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextBoolean(in); + } - public int nextInt(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextInt(in); } + public int nextInt(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextInt(in); + } - public long nextLong(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextLong(in); } + public long nextLong(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextLong(in); + } - public float nextFloat(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextFloat(in); } + public float nextFloat(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextFloat(in); + } - public double nextDouble(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextDouble(in); } + public double nextDouble(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextDouble(in); + } - public int nextEnum(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextEnum(in); } + public int nextEnum(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextEnum(in); + } - public String nextString(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextString(in); } + public String nextString(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextString(in); + } - public Utf8 nextString(Decoder in, Utf8 old) throws IOException - { ignore(toSkip, in); return field.nextString(in, old); } + public Utf8 nextString(Decoder in, Utf8 old) throws IOException { + ignore(toSkip, in); + return field.nextString(in, old); + } - public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException - { ignore(toSkip, in); return field.nextBytes(in, old); } + public ByteBuffer nextBytes(Decoder in, ByteBuffer old) throws IOException { + ignore(toSkip, in); + return field.nextBytes(in, old); + } - public byte[] nextFixed(Decoder in, byte[] bytes, int start, int len) throws IOException - { ignore(toSkip, in); return field.nextFixed(in, bytes, start, len); } + public byte[] nextFixed(Decoder in, byte[] bytes, int start, int len) throws IOException { + ignore(toSkip, in); + return field.nextFixed(in, bytes, start, len); + } - public int nextIndex(Decoder in) throws IOException - { ignore(toSkip, in); return field.nextIndex(in); } + public int nextIndex(Decoder in) throws IOException { + ignore(toSkip, in); + return field.nextIndex(in); + } - public Advancer getBranchAdvancer(Decoder in, int branch) throws IOException - { ignore(toSkip, in); return field.getBranchAdvancer(in, branch); } + public Advancer getBranchAdvancer(Decoder in, int branch) throws IOException { + ignore(toSkip, in); + return field.getBranchAdvancer(in, branch); + } - public Container getArrayAdvancer(Decoder in) throws IOException - { ignore(toSkip, in); return field.getArrayAdvancer(in); } + public Container getArrayAdvancer(Decoder in) throws IOException { + ignore(toSkip, in); + return field.getArrayAdvancer(in); + } - public Map getMapAdvancer(Decoder in) throws IOException - { ignore(toSkip, in); return field.getMapAdvancer(in); } + public Map getMapAdvancer(Decoder in) throws IOException { + ignore(toSkip, in); + return field.getMapAdvancer(in); + } - public Record getRecordAdvancer(Decoder in) throws IOException - { ignore(toSkip, in); return field.getRecordAdvancer(in); } + public Record getRecordAdvancer(Decoder in) throws IOException { + ignore(toSkip, in); + return field.getRecordAdvancer(in); + } } private static class Default extends Advancer { protected final Object val; - private Default(Schema s, Object v) { super(s,s); val = v; } - public Object next(Decoder in) { return val; } - public Object nextNull(Decoder in) { return val; } - public boolean nextBoolean(Decoder in) { return (Boolean) val; } - public int nextInt(Decoder in) { return (Integer) val; } - public long nextLong(Decoder in) { return (Long) val; } - public float nextFloat(Decoder in) { return (Float) val; } - public double nextDouble(Decoder in) { return (Double) val; } - public int nextEnum(Decoder in) { return (Integer) val; } + private Default(Schema s, Object v) { + super(s, s); + val = v; + } + + public Object next(Decoder in) { + return val; + } + + public Object nextNull(Decoder in) { + return val; + } + + public boolean nextBoolean(Decoder in) { + return (Boolean) val; + } + + public int nextInt(Decoder in) { + return (Integer) val; + } + + public long nextLong(Decoder in) { + return (Long) val; + } + + public float nextFloat(Decoder in) { + return (Float) val; + } + + public double nextDouble(Decoder in) { + return (Double) val; + } + + public int nextEnum(Decoder in) { + return (Integer) val; + } // TODO -- finish for the rest of the types } private static void ignore(Schema[] toIgnore, Decoder in) throws IOException { - for (Schema s: toIgnore) skip(s, in); + for (Schema s : toIgnore) + skip(s, in); } // Probably belongs someplace else, although Decoder doesn't reference @@ -758,33 +1085,55 @@ abstract class Advancer { // new dependencies... public static void skip(Schema s, Decoder in) throws IOException { switch (s.getType()) { - case NULL: in.readNull(); break; - case BOOLEAN: in.readBoolean(); break; - case INT: in.readInt(); break; - case LONG: in.readLong(); break; - case FLOAT: in.readFloat(); break; - case DOUBLE: in.readDouble(); break; - case STRING: in.skipString(); break; - case BYTES: in.skipBytes(); break; - case FIXED: in.skipFixed(s.getFixedSize()); break; - case ENUM: in.readEnum(); break; - case UNION: skip(s.getTypes().get(in.readInt()), in); break; + case NULL: + in.readNull(); + break; + case BOOLEAN: + in.readBoolean(); + break; + case INT: + in.readInt(); + break; + case LONG: + in.readLong(); + break; + case FLOAT: + in.readFloat(); + break; + case DOUBLE: + in.readDouble(); + break; + case STRING: + in.skipString(); + break; + case BYTES: + in.skipBytes(); + break; + case FIXED: + in.skipFixed(s.getFixedSize()); + break; + case ENUM: + in.readEnum(); + break; + case UNION: + skip(s.getTypes().get(in.readInt()), in); + break; case RECORD: - for (Schema.Field f: s.getFields()) + for (Schema.Field f : s.getFields()) skip(f.schema(), in); break; case ARRAY: for (long i = in.skipArray(); i != 0; i = in.skipArray()) - for (long j = 0; j < i; j++) - skip(s.getElementType(), in); - break; + for (long j = 0; j < i; j++) + skip(s.getElementType(), in); + break; case MAP: for (long k = in.skipArray(); k != 0; k = in.skipArray()) - for (long l = 0; l < k; l++) { - in.skipString(); // Key - skip(s.getValueType(), in); + for (long l = 0; l < k; l++) { + in.skipString(); // Key + skip(s.getValueType(), in); } - break; + break; default: throw new IllegalArgumentException("Unknown type for schema: " + s); } diff --git a/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader2.java b/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader2.java index cbfcff7..5ff9e50 100644 --- a/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader2.java +++ b/lang/java/avro/src/main/java/org/apache/avro/generic/GenericDatumReader2.java @@ -37,32 +37,39 @@ public class GenericDatumReader2<D> implements DatumReader<D> { data = d; } - /** ... Document how we use <code>d:</code> to create fixed, array, - * map, and record objects. - */ + /** + * ... Document how we use <code>d:</code> to create fixed, array, map, and + * record objects. + */ public static GenericDatumReader2 getReaderFor(Schema writer, Schema reader, GenericData d) { // TODO: add caching Resolver.Action a = Resolver.resolve(writer, reader, d); - Advancer.Record r = (Advancer.Record)Advancer.from(a); + Advancer.Record r = (Advancer.Record) Advancer.from(a); return new GenericDatumReader2(r, d); } public D read(D reuse, Decoder in) throws IOException { - return null; + return null; } - public Object read(Object reuse, Advancer a, Decoder in) - throws IOException - { + public Object read(Object reuse, Advancer a, Decoder in) throws IOException { switch (a.reader.getType()) { - case NULL: return a.nextNull(in); - case BOOLEAN: return (Boolean) a.nextBoolean(in); - case INT: return (Integer) a.nextInt(in); - case LONG: return (Long) a.nextLong(in); - case FLOAT: return (Float) a.nextFloat(in); - case DOUBLE: return (Double) a.nextDouble(in); - case STRING: return (String) a.nextString(in); - case BYTES: return a.nextBytes(in, (ByteBuffer)reuse); + case NULL: + return a.nextNull(in); + case BOOLEAN: + return (Boolean) a.nextBoolean(in); + case INT: + return (Integer) a.nextInt(in); + case LONG: + return (Long) a.nextLong(in); + case FLOAT: + return (Float) a.nextFloat(in); + case DOUBLE: + return (Double) a.nextDouble(in); + case STRING: + return (String) a.nextString(in); + case BYTES: + return a.nextBytes(in, (ByteBuffer) reuse); case FIXED: { GenericFixed fixed = (GenericFixed) data.createFixed(reuse, a.reader); a.nextFixed(in, fixed.bytes()); @@ -77,10 +84,11 @@ public class GenericDatumReader2<D> implements DatumReader<D> { ((GenericArray) reuse).reset(); } else if (reuse instanceof Collection) { ((Collection) reuse).clear(); - } else reuse = new GenericData.Array((int)i, a.reader); + } else + reuse = new GenericData.Array((int) i, a.reader); - Collection array = (Collection)reuse; - for( ; i != 0; i = c.nextChunk(in)) + Collection array = (Collection) reuse; + for (; i != 0; i = c.nextChunk(in)) for (long j = 0; j < i; j++) { Object v = read(null, ec, in); // TODO -- logical type conversion @@ -89,7 +97,7 @@ public class GenericDatumReader2<D> implements DatumReader<D> { if (array instanceof GenericArray<?>) ((GenericArray<?>) array).prune(); } - + case MAP: { Advancer.Map c = advancer.getMapAdvancer(in); Advancer kc = c.keyAdvancer; @@ -97,9 +105,10 @@ public class GenericDatumReader2<D> implements DatumReader<D> { long i = c.firstChunk(in); if (reuse instanceof Map) { ((Map) reuse).clear(); - } else reuse = new HashMap<Object,Object>((int)i); - Map map = (Map)reuse; - for ( ; i != 0; i = c.nextChunk(in)) + } else + reuse = new HashMap<Object, Object>((int) i); + Map map = (Map) reuse; + for (; i != 0; i = c.nextChunk(in)) for (int j = 0; j < i; j++) { Object key = kc.nextString(in); Object val = read(null, ec, in); @@ -113,7 +122,7 @@ public class GenericDatumReader2<D> implements DatumReader<D> { Object r = data.newRecord(reuse, ra.reader); for (int i = 0; i < ra.advancers.length; i++) { int p = ra.readerOrder[i].pos(); - ((IndexedRecord)reuse).put(p, read(null, ra.advancers[i], in)); + ((IndexedRecord) reuse).put(p, read(null, ra.advancers[i], in)); } ra.done(in); return r; @@ -127,8 +136,10 @@ public class GenericDatumReader2<D> implements DatumReader<D> { } } - /** Throws {@link UnsupportedOperationException}. (In retrospect, making - * DatumReaders mutable wasn't a good idea...) */ + /** + * Throws {@link UnsupportedOperationException}. (In retrospect, making + * DatumReaders mutable wasn't a good idea...) + */ public void setSchema(Schema s) { throw new UnsupportedOperationException(); }
