blob: 38262d3e8141a73dbca7614bfe0451e23326574f [file] [log] [blame]
package edu.uci.ics.asterix.dataflow.data.nontagged.serde;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import edu.uci.ics.asterix.builders.OrderedListBuilder;
import edu.uci.ics.asterix.common.exceptions.AsterixException;
import edu.uci.ics.asterix.formats.nontagged.AqlSerializerDeserializerProvider;
import edu.uci.ics.asterix.om.base.AOrderedList;
import edu.uci.ics.asterix.om.base.IAObject;
import edu.uci.ics.asterix.om.types.AOrderedListType;
import edu.uci.ics.asterix.om.types.ATypeTag;
import edu.uci.ics.asterix.om.types.EnumDeserializer;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
import edu.uci.ics.hyracks.api.dataflow.value.ISerializerDeserializer;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.data.std.util.ArrayBackedValueStorage;
public class AOrderedListSerializerDeserializer implements ISerializerDeserializer<AOrderedList> {
private static final long serialVersionUID = 1L;
public static final AOrderedListSerializerDeserializer SCHEMALESS_INSTANCE = new AOrderedListSerializerDeserializer();
private IAType itemType;
@SuppressWarnings("unchecked")
private ISerializerDeserializer serializer;
@SuppressWarnings("unchecked")
private ISerializerDeserializer deserializer;
private AOrderedListType orderedlistType;
private AOrderedListSerializerDeserializer() {
this.itemType = null;
this.orderedlistType = null;
}
public AOrderedListSerializerDeserializer(AOrderedListType orderedlistType) {
this.itemType = orderedlistType.getItemType();
this.orderedlistType = orderedlistType;
serializer = AqlSerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(itemType);
deserializer = itemType.getTypeTag() == ATypeTag.ANY ? AqlSerializerDeserializerProvider.INSTANCE
.getSerializerDeserializer(itemType) : AqlSerializerDeserializerProvider.INSTANCE
.getNonTaggedSerializerDeserializer(itemType);
}
@Override
public AOrderedList deserialize(DataInput in) throws HyracksDataException {
// TODO: schemaless ordered list deserializer
try {
boolean fixedSize = false;
ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(in.readByte());
switch (typeTag) {
case STRING:
case RECORD:
case ORDEREDLIST:
case UNORDEREDLIST:
case ANY:
fixedSize = false;
break;
default:
fixedSize = true;
break;
}
in.readInt(); // list size
int numberOfitems;
numberOfitems = in.readInt();
ArrayList<IAObject> items = new ArrayList<IAObject>();
if (numberOfitems > 0) {
if (!fixedSize) {
for (int i = 0; i < numberOfitems; i++)
in.readInt();
}
for (int i = 0; i < numberOfitems; i++) {
IAObject v = (IAObject) deserializer.deserialize(in);
items.add(v);
}
}
AOrderedListType type = new AOrderedListType(itemType, "orderedlist");
return new AOrderedList(type, items);
} catch (IOException e) {
throw new HyracksDataException(e);
}
}
@SuppressWarnings("unchecked")
@Override
public void serialize(AOrderedList instance, DataOutput out) throws HyracksDataException {
// TODO: schemaless ordered list serializer
OrderedListBuilder listBuilder = new OrderedListBuilder();
listBuilder.reset(orderedlistType);
ArrayBackedValueStorage itemValue = new ArrayBackedValueStorage();
for (int i = 0; i < instance.size(); i++) {
itemValue.reset();
serializer.serialize(instance.getItem(i), itemValue.getDataOutput());
listBuilder.addItem(itemValue);
}
listBuilder.write(out, false);
}
public static final int getOrderedListLength(byte[] serOrderedList, int offset) {
return AInt32SerializerDeserializer.getInt(serOrderedList, offset + 1);
}
public static int getNumberOfItems(byte[] serOrderedList) {
return getNumberOfItems(serOrderedList, 0);
}
public static int getNumberOfItems(byte[] serOrderedList, int offset) {
if (serOrderedList[offset] == ATypeTag.ORDEREDLIST.serialize())
// 6 = tag (1) + itemTag (1) + list size (4)
return AInt32SerializerDeserializer.getInt(serOrderedList, offset + 6);
else
return -1;
}
public static int getItemOffset(byte[] serOrderedList, int offset, int itemIndex) throws AsterixException {
if (serOrderedList[offset] == ATypeTag.ORDEREDLIST.serialize()) {
ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(serOrderedList[offset + 1]);
switch (typeTag) {
case STRING:
case RECORD:
case ORDEREDLIST:
case UNORDEREDLIST:
case ANY:
return offset + AInt32SerializerDeserializer.getInt(serOrderedList, offset + 10 + (4 * itemIndex));
default:
int length = NonTaggedFormatUtil.getFieldValueLength(serOrderedList, offset + 1, typeTag, true);
return offset + 10 + (length * itemIndex);
}
// 10 = tag (1) + itemTag (1) + list size (4) + number of items (4)
} else
return -1;
}
public static int getItemOffset(byte[] serOrderedList, int itemIndex) throws AsterixException {
return getItemOffset(serOrderedList, 0, itemIndex);
}
}