refactoring accessor allocation
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype@315 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
index fe8b656..130d597 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AFlatValueAccessor.java
@@ -16,8 +16,10 @@
package edu.uci.ics.asterix.runtime.accessors;
import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.IValueReference;
public class AFlatValueAccessor implements IBinaryAccessor {
@@ -26,6 +28,16 @@
private int start;
private int len;
+ public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+ public AFlatValueAccessor createElement(IAType type) {
+ return new AFlatValueAccessor();
+ }
+ };
+
+ private AFlatValueAccessor() {
+
+ }
+
@Override
public void reset(byte[] data, int start, int len) {
this.data = data;
@@ -67,7 +79,7 @@
}
@Override
- public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException{
+ public <R, T> R accept(IBinaryAccessorVisitor<R, T> vistor, T tag) throws AsterixException {
return vistor.visit(this, tag);
}
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
index 60d6a2e..2aa4152 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AListAccessor.java
@@ -1,11 +1,23 @@
package edu.uci.ics.asterix.runtime.accessors;
import edu.uci.ics.asterix.common.exceptions.AsterixException;
+import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
public class AListAccessor implements IBinaryAccessor {
+ public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+ public IBinaryAccessor createElement(IAType type) {
+ return new AListAccessor();
+ }
+ };
+
+ private AListAccessor() {
+
+ }
+
@Override
public byte[] getBytes() {
// TODO Auto-generated method stub
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
index e8e85ac..6bd798d 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/ARecordAccessor.java
@@ -32,14 +32,25 @@
import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
+import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
import edu.uci.ics.hyracks.api.dataflow.value.INullWriter;
public class ARecordAccessor implements IBinaryAccessor {
+ public static IElementFactory<IBinaryAccessor, IAType> FACTORY = new IElementFactory<IBinaryAccessor, IAType>() {
+ public IBinaryAccessor createElement(IAType type) {
+ return new ARecordAccessor((ARecordType) type);
+ }
+ };
+
+ // access results: field names, field types, and field values
private List<IBinaryAccessor> fieldNames = new ArrayList<IBinaryAccessor>();
private List<IBinaryAccessor> fieldTypeTags = new ArrayList<IBinaryAccessor>();
private List<IBinaryAccessor> fieldValues = new ArrayList<IBinaryAccessor>();
+ // accessor allocator
+ AccessorAllocator allocator = new AccessorAllocator();
+
private byte[] typeBuffer = new byte[32768];
private ResettableByteArrayOutputStream typeBos = new ResettableByteArrayOutputStream();
private DataOutputStream typeDos = new DataOutputStream(typeBos);
@@ -54,14 +65,18 @@
private int numberOfSchemaFields;
private int offsetArrayOffset;
private int[] fieldOffsets;
- private int fieldCursor = -1;
private ATypeTag typeTag;
- private AFlatValueAccessor nullReference = new AFlatValueAccessor();
+ private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
private byte[] data;
private int start;
private int len;
+ // nested open field rec type
+ // private static ARecordType nestedOpenRecType = new
+ // ARecordType("nested-open", new String[] {}, new IAType[] {},
+ // true);
+
public ARecordAccessor(ARecordType inputType) {
this.inputRecType = inputType;
IAType[] fieldTypes = inputType.getFieldTypes();
@@ -79,7 +94,7 @@
int tagStart = typeBos.size();
typeDos.writeByte(ftypeTag.serialize());
int tagEnd = typeBos.size();
- AFlatValueAccessor typeTagReference = new AFlatValueAccessor();
+ IBinaryAccessor typeTagReference = AFlatValueAccessor.FACTORY.createElement(null);
typeTagReference.reset(typeBuffer, tagStart, tagEnd - tagStart);
fieldTypeTags.add(typeTagReference);
@@ -88,7 +103,7 @@
typeDos.writeByte(ATypeTag.STRING.serialize());
typeDos.writeUTF(fieldNameStrs[i]);
int nameEnd = typeBos.size();
- AFlatValueAccessor typeNameReference = new AFlatValueAccessor();
+ IBinaryAccessor typeNameReference = AFlatValueAccessor.FACTORY.createElement(null);
typeNameReference.reset(typeBuffer, nameStart, nameEnd - nameStart);
fieldNames.add(typeNameReference);
}
@@ -109,7 +124,14 @@
private void reset() {
typeBos.setByteArray(typeBuffer, closedPartTypeInfoSize);
dataBos.setByteArray(dataBuffer, 0);
- fieldCursor = -1;
+ allocator.reset();
+
+ //clean up the returned containers
+ for (int i = fieldNames.size() - 1; i >= numberOfSchemaFields; i--)
+ fieldNames.remove(i);
+ for (int i = fieldTypeTags.size() - 1; i >= numberOfSchemaFields; i--)
+ fieldTypeTags.remove(i);
+ fieldValues.clear();
}
public void reset(byte[] b, int start, int len) {
@@ -156,14 +178,12 @@
offsetArrayOffset += 4;
}
for (int fieldNumber = 0; fieldNumber < numberOfSchemaFields; fieldNumber++) {
- next();
if (hasNullableFields) {
byte b1 = b[nullBitMapOffset + fieldNumber / 8];
int p = 1 << (7 - (fieldNumber % 8));
if ((b1 & p) == 0) {
// set null value (including type tag inside)
- nextFieldValue().reset(nullReference.getBytes(), nullReference.getStartIndex(),
- nullReference.getLength());
+ fieldValues.add(nullReference);
continue;
}
}
@@ -187,14 +207,15 @@
dataDos.writeByte(typeTag.serialize());
dataDos.write(b, fieldOffsets[fieldNumber], fieldValueLength);
int fend = dataBos.size();
- nextFieldValue().reset(dataBuffer, fstart, fend - fstart);
+ IBinaryAccessor fieldValue = allocator.allocateFieldValue(fieldTypes[fieldNumber]);
+ fieldValue.reset(dataBuffer, fstart, fend - fstart);
+ fieldValues.add(fieldValue);
}
}
if (isExpanded) {
int numberOfOpenFields = AInt32SerializerDeserializer.getInt(b, openPartOffset);
int fieldOffset = openPartOffset + 4 + (8 * numberOfOpenFields);
for (int i = 0; i < numberOfOpenFields; i++) {
- next();
// set the field name (including a type tag, which is
// astring)
int fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, ATypeTag.STRING,
@@ -203,16 +224,22 @@
dataDos.writeByte(ATypeTag.STRING.serialize());
dataDos.write(b, fieldOffset, fieldValueLength);
int fnend = dataBos.size();
- nextFieldName().reset(dataBuffer, fnstart, fnend - fnstart);
+ IBinaryAccessor fieldName = allocator.allocateFieldName();
+ fieldName.reset(dataBuffer, fnstart, fnend - fnstart);
+ fieldNames.add(fieldName);
fieldOffset += fieldValueLength;
// set the field type tag
- nextFieldType().reset(b, fieldOffset, 1);
+ IBinaryAccessor fieldTypeTag = allocator.allocateFieldType();
+ fieldTypeTag.reset(b, fieldOffset, 1);
+ fieldTypeTags.add(fieldTypeTag);
typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[fieldOffset]);
// set the field value (already including type tag)
fieldValueLength = NonTaggedFormatUtil.getFieldValueLength(b, fieldOffset, typeTag, true) + 1;
- nextFieldValue().reset(b, fieldOffset, fieldValueLength);
+ IBinaryAccessor fieldValueAccessor = allocator.allocateFieldName();
+ fieldValueAccessor.reset(b, fieldOffset, fieldValueLength);
+ fieldValues.add(fieldValueAccessor);
fieldOffset += fieldValueLength;
}
}
@@ -221,44 +248,6 @@
}
}
- private void next() {
- fieldCursor++;
- }
-
- private IBinaryAccessor nextFieldName() {
- if (fieldCursor < fieldNames.size()) {
- return fieldNames.get(fieldCursor);
- } else {
- AFlatValueAccessor fieldNameReference = new AFlatValueAccessor();
- fieldNames.add(fieldNameReference);
- return fieldNameReference;
- }
- }
-
- private IBinaryAccessor nextFieldType() {
- if (fieldCursor < fieldTypeTags.size()) {
- return fieldTypeTags.get(fieldCursor);
- } else {
- AFlatValueAccessor fieldTypeReference = new AFlatValueAccessor();
- fieldTypeTags.add(fieldTypeReference);
- return fieldTypeReference;
- }
- }
-
- private IBinaryAccessor nextFieldValue() {
- if (fieldCursor < fieldValues.size()) {
- return fieldValues.get(fieldCursor);
- } else {
- AFlatValueAccessor fieldValueReference = new AFlatValueAccessor();
- fieldValues.add(fieldValueReference);
- return fieldValueReference;
- }
- }
-
- public int getCursor() {
- return fieldCursor;
- }
-
public List<IBinaryAccessor> getFieldNames() {
return fieldNames;
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java
new file mode 100644
index 0000000..a3fd0d7
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/AccessorAllocator.java
@@ -0,0 +1,44 @@
+package edu.uci.ics.asterix.runtime.accessors;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
+import edu.uci.ics.asterix.runtime.util.container.IElementAllocator;
+import edu.uci.ics.asterix.runtime.util.container.ListElementAllocator;
+
+public class AccessorAllocator {
+
+ private IElementAllocator<IBinaryAccessor, IAType> flatArtifactAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+ AFlatValueAccessor.FACTORY);
+ private IElementAllocator<IBinaryAccessor, IAType> nestedRecValueAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+ ARecordAccessor.FACTORY);
+ private IElementAllocator<IBinaryAccessor, IAType> nestedListValueAllocator = new ListElementAllocator<IBinaryAccessor, IAType>(
+ AListAccessor.FACTORY);
+
+ public IBinaryAccessor allocateFieldName() {
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateFieldType() {
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateFieldValue(IAType type) {
+ if (type.getTypeTag().equals(ATypeTag.RECORD))
+ return nestedRecValueAllocator.allocate(type);
+ else if (type.getTypeTag().equals(ATypeTag.UNORDEREDLIST) || type.getTypeTag().equals(ATypeTag.ORDEREDLIST))
+ return nestedListValueAllocator.allocate(type);
+ else
+ return flatArtifactAllocator.allocate(null);
+ }
+
+ public IBinaryAccessor allocateNestedListValue(IAType type) {
+ return nestedListValueAllocator.allocate(type);
+ }
+
+ public void reset() {
+ flatArtifactAllocator.reset();
+ nestedRecValueAllocator.reset();
+ nestedListValueAllocator.reset();
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
index 6e874cf..c84f28e 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ACastVisitor.java
@@ -9,20 +9,21 @@
import edu.uci.ics.asterix.runtime.accessors.AFlatValueAccessor;
import edu.uci.ics.asterix.runtime.accessors.AListAccessor;
import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
import edu.uci.ics.asterix.runtime.accessors.visitor.IBinaryAccessorVisitor;
import edu.uci.ics.hyracks.algebricks.common.utils.Triple;
-public class ACastVisitor implements IBinaryAccessorVisitor<Void, Triple<ARecordAccessor, IAType, Boolean>> {
+public class ACastVisitor implements IBinaryAccessorVisitor<Void, Triple<IBinaryAccessor, IAType, Boolean>> {
- private Map<ARecordAccessor, ARecordCaster> raccessorToCaster = new HashMap<ARecordAccessor, ARecordCaster>();
+ private Map<IBinaryAccessor, ARecordCaster> raccessorToCaster = new HashMap<IBinaryAccessor, ARecordCaster>();
@Override
- public Void visit(AListAccessor accessor, Triple<ARecordAccessor, IAType, Boolean> arg) {
+ public Void visit(AListAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) {
return null;
}
@Override
- public Void visit(ARecordAccessor accessor, Triple<ARecordAccessor, IAType, Boolean> arg) throws AsterixException {
+ public Void visit(ARecordAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) throws AsterixException {
ARecordCaster caster = raccessorToCaster.get(accessor);
if (caster == null) {
caster = new ARecordCaster();
@@ -37,7 +38,9 @@
}
@Override
- public Void visit(AFlatValueAccessor accessor, Triple<ARecordAccessor, IAType, Boolean> arg) {
+ public Void visit(AFlatValueAccessor accessor, Triple<IBinaryAccessor, IAType, Boolean> arg) {
+ //set the pointer for result
+ arg.first.reset(accessor.getBytes(), accessor.getStartIndex(), accessor.getLength());
return null;
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
index e7a35bd..8073c91 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/accessors/cast/ARecordCaster.java
@@ -58,8 +58,8 @@
private DataOutputStream dos = new DataOutputStream(bos);
private RecordBuilder recBuilder = new RecordBuilder();
- private AFlatValueAccessor nullReference = new AFlatValueAccessor();
- private AFlatValueAccessor nullTypeTag = new AFlatValueAccessor();
+ private IBinaryAccessor nullReference = AFlatValueAccessor.FACTORY.createElement(null);
+ private IBinaryAccessor nullTypeTag = AFlatValueAccessor.FACTORY.createElement(null);
private int numInputFields = 0;
private IBinaryComparator fieldNameComparator = PointableBinaryComparatorFactory.of(UTF8StringPointable.FACTORY)
@@ -86,12 +86,12 @@
}
}
- public void castRecord(ARecordAccessor recordAccessor, ARecordAccessor resultAccessor, ARecordType reqType,
+ public void castRecord(ARecordAccessor recordAccessor, IBinaryAccessor resultAccessor, ARecordType reqType,
ACastVisitor visitor) throws IOException {
List<IBinaryAccessor> fieldNames = recordAccessor.getFieldNames();
List<IBinaryAccessor> fieldTypeTags = recordAccessor.getFieldTypeTags();
List<IBinaryAccessor> fieldValues = recordAccessor.getFieldValues();
- numInputFields = recordAccessor.getCursor() + 1;
+ numInputFields = fieldNames.size();
if (openFields == null || numInputFields > openFields.length) {
openFields = new boolean[numInputFields];
@@ -147,7 +147,7 @@
int tagStart = bos.size();
dos.writeByte(ftypeTag.serialize());
int tagEnd = bos.size();
- AFlatValueAccessor typeTagPointable = new AFlatValueAccessor();
+ IBinaryAccessor typeTagPointable = AFlatValueAccessor.FACTORY.createElement(null);
typeTagPointable.reset(buffer, tagStart, tagEnd - tagStart);
reqFieldTypeTags.add(typeTagPointable);
@@ -156,7 +156,7 @@
dos.write(ATypeTag.STRING.serialize());
dos.writeUTF(fname);
int nameEnd = bos.size();
- AFlatValueAccessor typeNamePointable = new AFlatValueAccessor();
+ IBinaryAccessor typeNamePointable = AFlatValueAccessor.FACTORY.createElement(null);
typeNamePointable.reset(buffer, nameStart, nameEnd - nameStart);
reqFieldNames.add(typeNamePointable);
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
index d193e85..c82bb9b 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/evaluators/functions/CastRecordDescriptor.java
@@ -8,6 +8,7 @@
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.runtime.accessors.ARecordAccessor;
+import edu.uci.ics.asterix.runtime.accessors.base.IBinaryAccessor;
import edu.uci.ics.asterix.runtime.accessors.cast.ACastVisitor;
import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -60,7 +61,7 @@
final ARecordAccessor recAccessor = new ARecordAccessor(inputType);
final ARecordAccessor resultAccessor = new ARecordAccessor(reqType);
final ACastVisitor castVisitor = new ACastVisitor();
- final Triple<ARecordAccessor, IAType, Boolean> arg = new Triple<ARecordAccessor, IAType, Boolean>(
+ final Triple<IBinaryAccessor, IAType, Boolean> arg = new Triple<IBinaryAccessor, IAType, Boolean>(
resultAccessor, reqType, Boolean.FALSE);
@Override
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java
new file mode 100644
index 0000000..bb98374
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementAllocator.java
@@ -0,0 +1,8 @@
+package edu.uci.ics.asterix.runtime.util.container;
+
+public interface IElementAllocator<E, T> {
+
+ public E allocate(T arg);
+
+ public void reset();
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java
new file mode 100644
index 0000000..bc1b525
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/IElementFactory.java
@@ -0,0 +1,6 @@
+package edu.uci.ics.asterix.runtime.util.container;
+
+public interface IElementFactory<E, T> {
+
+ public E createElement(T arg);
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
new file mode 100644
index 0000000..442f4cb
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
@@ -0,0 +1,30 @@
+package edu.uci.ics.asterix.runtime.util.container;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ListElementAllocator<E, T> implements IElementAllocator<E, T> {
+
+ private IElementFactory<E, T> factory;
+ private List<E> pool = new ArrayList<E>();
+ private int cursor = -1;
+
+ public ListElementAllocator(IElementFactory<E, T> factory) {
+ this.factory = factory;
+ }
+
+ public E allocate(T arg) {
+ cursor++;
+ if (cursor < pool.size()) {
+ return pool.get(cursor);
+ } else {
+ E element = factory.createElement(arg);
+ pool.add(element);
+ return element;
+ }
+ }
+
+ public void reset() {
+ cursor = -1;
+ }
+}