blob: e8dbc2999a5af4feea8c9c433461e1fce8ca8c11 [file] [log] [blame]
package edu.uci.ics.asterix.builders;
import java.io.ByteArrayOutputStream;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import edu.uci.ics.asterix.dataflow.data.nontagged.serde.SerializerDeserializerUtil;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.AUnorderedListType;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.api.IValueReference;
public class UnorderedListBuilder implements IAUnorderedListBuilder {
/**
*
*/
private ByteArrayOutputStream outputStream;
private ArrayList<Short> offsets;
private int metadataInfoSize;
private byte[] offsetArray;
private int offsetPosition;
private int headerSize;
private ATypeTag itemTypeTag;
private byte serNullTypeTag = ATypeTag.NULL.serialize();
private final static byte UNORDEREDLIST_TYPE_TAG = ATypeTag.UNORDEREDLIST.serialize();
private boolean fixedSize = false;
private int numberOfItems;
public UnorderedListBuilder() {
this.outputStream = new ByteArrayOutputStream();
this.offsets = new ArrayList<Short>();
this.metadataInfoSize = 0;
this.offsetArray = null;
this.offsetPosition = 0;
}
@Override
public void reset(AUnorderedListType unorderedlistType) throws HyracksDataException {
this.outputStream.reset();
this.offsetArray = null;
this.offsets.clear();
this.offsetPosition = 0;
this.numberOfItems = 0;
if (unorderedlistType == null || unorderedlistType.getItemType() == null) {
this.itemTypeTag = ATypeTag.ANY;
fixedSize = false;
} else {
this.itemTypeTag = unorderedlistType.getItemType().getTypeTag();
fixedSize = NonTaggedFormatUtil.isFixedSizedCollection(unorderedlistType.getItemType());
}
headerSize = 2;
metadataInfoSize = 8;
// 8 = 4 (# of items) + 4 (the size of the list)
}
@Override
public void addItem(IValueReference item) throws HyracksDataException {
if (!fixedSize)
this.offsets.add((short) outputStream.size());
if (itemTypeTag == ATypeTag.ANY) {
this.numberOfItems++;
this.outputStream.write(item.getByteArray(), item.getStartOffset(), item.getLength());
} else if (item.getByteArray()[0] != serNullTypeTag) {
this.numberOfItems++;
this.outputStream.write(item.getByteArray(), item.getStartOffset() + 1, item.getLength() - 1);
}
}
@Override
public void write(DataOutput out, boolean writeTypeTag) throws HyracksDataException {
try {
if (!fixedSize)
metadataInfoSize += offsets.size() * 4;
if (offsetArray == null || offsetArray.length < metadataInfoSize)
offsetArray = new byte[metadataInfoSize];
SerializerDeserializerUtil.writeIntToByteArray(offsetArray,
headerSize + metadataInfoSize + outputStream.size(), offsetPosition);
SerializerDeserializerUtil.writeIntToByteArray(offsetArray, this.numberOfItems, offsetPosition + 4);
if (!fixedSize) {
offsetPosition += 8;
for (int i = 0; i < offsets.size(); i++) {
SerializerDeserializerUtil.writeIntToByteArray(offsetArray, offsets.get(i) + metadataInfoSize
+ headerSize, offsetPosition);
offsetPosition += 4;
}
}
if (writeTypeTag) {
out.writeByte(UNORDEREDLIST_TYPE_TAG);
}
out.writeByte(itemTypeTag.serialize());
out.write(offsetArray, 0, metadataInfoSize);
out.write(outputStream.toByteArray(), 0, outputStream.size());
} catch (IOException e) {
throw new HyracksDataException(e);
}
}
}