Package avrobase

Source Code of avrobase.Row

package avrobase;

import org.apache.avro.Schema;
import org.apache.avro.io.Decoder;
import org.apache.avro.io.DecoderFactory;
import org.apache.avro.io.Encoder;
import org.apache.avro.io.EncoderFactory;
import org.apache.avro.specific.SpecificDatumReader;
import org.apache.avro.specific.SpecificDatumWriter;
import org.apache.avro.specific.SpecificRecord;

import java.io.ByteArrayOutputStream;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

/**
* Row value wrapper for the associated metadata.  Wouldn't Java be great if you could add metadata to any instance
* in a typed fashion?
* <p/>
* User: sam
* Date: Jun 9, 2010
* Time: 12:07:47 PM
*/
public class Row<T extends SpecificRecord, K> implements Externalizable, Cloneable {

  private static EncoderFactory encoderFactory = new EncoderFactory();
  private static DecoderFactory decoderFactory = new DecoderFactory();

  public T value;
  public K row;
  public long version;

  public Row() {}

  public Row(T value, K row) {
    this(value, row, -1);
  }

  public Row(T value, K row, long version) {
    this.value = value;
    this.row = row;
    this.version = version;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Row row = (Row) o;
    return !(value != null ? !value.equals(row.value) : row.value != null);
  }

  @Override
  public int hashCode() {
    return value != null ? value.hashCode() : 0;
  }

  @Override
  public String toString() {
    return "[" + row + ", " + version + ", " + value + "]";
  }

  public void writeExternal(ObjectOutput objectOutput) throws IOException {
    // row
    objectOutput.writeObject(row);
    // version
    objectOutput.writeLong(version);
    // schema
    objectOutput.writeUTF(value.getSchema().toString());
    Schema schema = value.getSchema();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    Encoder be = encoderFactory.binaryEncoder(baos, null);
    SpecificDatumWriter<T> sdw = new SpecificDatumWriter<T>(schema);
    sdw.write(value, be);
    be.flush();
    byte[] bytes = baos.toByteArray();
    // length
    objectOutput.writeInt(bytes.length);
    // bytes
    objectOutput.write(bytes);
  }

  public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
    // row
    row = (K) objectInput.readObject();
    // version
    version = objectInput.readLong();
    // schema
    Schema schema = Schema.parse(objectInput.readUTF());
    // length
    byte[] bytes = new byte[objectInput.readInt()];
    // bytes
    objectInput.readFully(bytes);
    Decoder d = decoderFactory.binaryDecoder(bytes, 0, bytes.length, null);
    SpecificDatumReader<T> sdr = new SpecificDatumReader<T>(schema);
    value = sdr.read(null, d);
  }

  public Row<T, K> clone() {
    Schema schema = value.getSchema();
    T newvalue;
    try {
      newvalue = (T) Class.forName(schema.getFullName()).newInstance();
    } catch (Exception e) {
      throw new AvroBaseException("Could not clone row", e);
    }
    for (Schema.Field field : schema.getFields()) {
      int pos = field.pos();
      newvalue.put(pos, value.get(pos));
    }
    return new Row<T, K>(newvalue, row, version);
  }
}
TOP

Related Classes of avrobase.Row

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.