package tap.core.io;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import tap.core.io.avro.BinaryKeyDatumWriter;
public class BinaryKey {
private byte[] buf;
private int length;
private int groupLength;
private ReuseByteArrayOutputStream stream;
private GenericData.Record record;
private boolean dirty;
public static final int KEY_BYTES_OFFSET = Bytes.SIZEOF_INT * 2; // length, group length
public BinaryKey() {}
public void set(byte[] buf, int length) {
this.buf = buf;
this.length = length;
this.groupLength = Bytes.toInt(this.buf, Bytes.SIZEOF_INT, SortOrder.ASCENDING);
this.dirty = false;
}
public byte[] getBuffer() {
serializeIfNecessary();
return buf;
}
public int getLength() {
serializeIfNecessary();
return length;
}
public int keyBytesLength() {
serializeIfNecessary();
return getLength() - KEY_BYTES_OFFSET;
}
public int groupBytesLength() {
serializeIfNecessary();
return groupLength;
}
public void setSchema(Schema schema) {
record = new GenericData.Record(schema);
}
public void setField(String name, Object value) {
record.put(name, value);
dirty = true;
}
public void dirty()
{
dirty=true;
}
private void serializeIfNecessary() {
if(dirty == false)
return;
if(stream == null)
stream = new ReuseByteArrayOutputStream(128);
else
stream.reset();
try {
BinaryKeyDatumWriter.serialize(record, stream);
} catch(IOException e) {
throw new RuntimeException(e);
}
this.buf = stream.getBuffer();
this.length = stream.getCount();
this.groupLength = Bytes.toInt(this.buf, Bytes.SIZEOF_INT, SortOrder.ASCENDING);
dirty = false;
}
}