address part of Alex's comments
git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_opentype@370 eaa15691-b419-025a-1212-ee371bd00084
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 87e1bdd..32498c3 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,7 +8,7 @@
import edu.uci.ics.asterix.om.types.ARecordType;
import edu.uci.ics.asterix.om.types.IAType;
import edu.uci.ics.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import edu.uci.ics.asterix.runtime.pointables.ARecordPointable;
+import edu.uci.ics.asterix.runtime.pointables.PointableAllocator;
import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
import edu.uci.ics.asterix.runtime.pointables.cast.ACastVisitor;
import edu.uci.ics.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -58,8 +58,10 @@
final IEvaluator recEvaluator = recordEvalFactory.createEvaluator(recordBuffer);
return new IEvaluator() {
- final ARecordPointable recAccessor = new ARecordPointable(inputType);
- final ARecordPointable resultAccessor = new ARecordPointable(reqType);
+ // pointable allocator
+ private PointableAllocator allocator = new PointableAllocator();
+ final IVisitablePointable recAccessor = allocator.allocateRecordValue(inputType);
+ final IVisitablePointable resultAccessor = allocator.allocateRecordValue(reqType);
final ACastVisitor castVisitor = new ACastVisitor();
final Triple<IVisitablePointable, IAType, Boolean> arg = new Triple<IVisitablePointable, IAType, Boolean>(
resultAccessor, reqType, Boolean.FALSE);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AFlatValuePointable.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AFlatValuePointable.java
index b879d8c..2416cc4 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AFlatValuePointable.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AFlatValuePointable.java
@@ -24,12 +24,19 @@
public class AFlatValuePointable extends AbstractVisitablePointable {
- public static IElementFactory<IVisitablePointable, IAType> FACTORY = new IElementFactory<IVisitablePointable, IAType>() {
+ /**
+ * DO NOT allow to create AFlatValuePointable object arbitrarily, force to
+ * use object pool based allocator
+ */
+ static IElementFactory<IVisitablePointable, IAType> FACTORY = new IElementFactory<IVisitablePointable, IAType>() {
public AFlatValuePointable createElement(IAType type) {
return new AFlatValuePointable();
}
};
+ /**
+ * private constructor, to prevent arbitrary creation
+ */
private AFlatValuePointable() {
}
@@ -38,16 +45,23 @@
public boolean equals(Object o) {
if (!(o instanceof IValueReference))
return false;
+
+ // get right raw data
IValueReference ivf = (IValueReference) o;
byte[] odata = ivf.getByteArray();
int ostart = ivf.getStartOffset();
int olen = ivf.getLength();
+ // get left raw data
byte[] data = getByteArray();
int start = getStartOffset();
int len = getLength();
+
+ // bytes length should be equal
if (len != olen)
return false;
+
+ // check each byte
for (int i = 0; i < len; i++) {
if (data[start + i] != odata[ostart + i])
return false;
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java
index 41669304..558ec58 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/AListPointable.java
@@ -28,13 +28,16 @@
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
import edu.uci.ics.asterix.runtime.pointables.visitor.IVisitablePointableVisitor;
-import edu.uci.ics.asterix.runtime.util.PointableAllocator;
import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
import edu.uci.ics.asterix.runtime.util.container.IElementFactory;
public class AListPointable extends AbstractVisitablePointable {
- public static IElementFactory<IVisitablePointable, IAType> FACTORY = new IElementFactory<IVisitablePointable, IAType>() {
+ /**
+ * DO NOT allow to create AListPointable object arbitrarily, force to use
+ * object pool based allocator, in order to have object reuse
+ */
+ static IElementFactory<IVisitablePointable, IAType> FACTORY = new IElementFactory<IVisitablePointable, IAType>() {
public IVisitablePointable createElement(IAType type) {
return new AListPointable((AbstractCollectionType) type);
}
@@ -52,6 +55,12 @@
private final ResettableByteArrayOutputStream dataBos = new ResettableByteArrayOutputStream();
private final DataOutputStream dataDos = new DataOutputStream(dataBos);
+ /**
+ * private constructor, to prevent constructing it
+ *
+ * @param inputType
+ * , the input type
+ */
private AListPointable(AbstractCollectionType inputType) {
if (inputType != null && inputType.getItemType() != null) {
itemType = inputType.getItemType();
@@ -98,7 +107,7 @@
if (typedItemList) {
for (int i = 0; i < numberOfitems; i++) {
itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, false);
- IVisitablePointable tag = allocator.allocateFieldType();
+ IVisitablePointable tag = allocator.allocateEmpty();
IVisitablePointable item = allocator.allocateFieldValue(itemType);
// set item type tag
@@ -121,7 +130,7 @@
for (int i = 0; i < numberOfitems; i++) {
itemTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[itemOffset]);
itemLength = NonTaggedFormatUtil.getFieldValueLength(b, itemOffset, itemTag, true) + 1;
- IVisitablePointable tag = allocator.allocateFieldType();
+ IVisitablePointable tag = allocator.allocateEmpty();
IVisitablePointable item = allocator.allocateFieldValue(itemType);
// set item type tag
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/ARecordPointable.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/ARecordPointable.java
index 72023e2..75a3737 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/ARecordPointable.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/ARecordPointable.java
@@ -31,14 +31,17 @@
import edu.uci.ics.asterix.om.util.NonTaggedFormatUtil;
import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
import edu.uci.ics.asterix.runtime.pointables.visitor.IVisitablePointableVisitor;
-import edu.uci.ics.asterix.runtime.util.PointableAllocator;
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 ARecordPointable extends AbstractVisitablePointable {
- public static IElementFactory<IVisitablePointable, IAType> FACTORY = new IElementFactory<IVisitablePointable, IAType>() {
+ /**
+ * DO NOT allow to create ARecordPointable object arbitrarily, force to use
+ * object pool based allocator, in order to have object reuse
+ */
+ static IElementFactory<IVisitablePointable, IAType> FACTORY = new IElementFactory<IVisitablePointable, IAType>() {
public IVisitablePointable createElement(IAType type) {
return new ARecordPointable((ARecordType) type);
}
@@ -49,7 +52,7 @@
private List<IVisitablePointable> fieldTypeTags = new ArrayList<IVisitablePointable>();
private List<IVisitablePointable> fieldValues = new ArrayList<IVisitablePointable>();
- // accessor allocator
+ // pointable allocator
private PointableAllocator allocator = new PointableAllocator();
private byte[] typeBuffer = new byte[32768];
@@ -69,7 +72,13 @@
private ATypeTag typeTag;
private IVisitablePointable nullReference = AFlatValuePointable.FACTORY.createElement(null);
- public ARecordPointable(ARecordType inputType) {
+ /**
+ * private constructor, to prevent constructing it
+ *
+ * @param inputType
+ * , the input type
+ */
+ private ARecordPointable(ARecordType inputType) {
this.inputRecType = inputType;
IAType[] fieldTypes = inputType.getFieldTypes();
String[] fieldNameStrs = inputType.getFieldNames();
@@ -224,13 +233,13 @@
dataDos.writeByte(ATypeTag.STRING.serialize());
dataDos.write(b, fieldOffset, fieldValueLength);
int fnend = dataBos.size();
- IVisitablePointable fieldName = allocator.allocateFieldName();
+ IVisitablePointable fieldName = allocator.allocateEmpty();
fieldName.set(dataBuffer, fnstart, fnend - fnstart);
fieldNames.add(fieldName);
fieldOffset += fieldValueLength;
// set the field type tag
- IVisitablePointable fieldTypeTag = allocator.allocateFieldType();
+ IVisitablePointable fieldTypeTag = allocator.allocateEmpty();
fieldTypeTag.set(b, fieldOffset, 1);
fieldTypeTags.add(fieldTypeTag);
typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(b[fieldOffset]);
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/PointableAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/PointableAllocator.java
new file mode 100644
index 0000000..2b654db
--- /dev/null
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/PointableAllocator.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package edu.uci.ics.asterix.runtime.pointables;
+
+import edu.uci.ics.asterix.om.types.ATypeTag;
+import edu.uci.ics.asterix.om.types.IAType;
+import edu.uci.ics.asterix.runtime.pointables.base.DefaultOpenFieldType;
+import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
+import edu.uci.ics.asterix.runtime.util.container.IElementAllocator;
+import edu.uci.ics.asterix.runtime.util.container.ListElementAllocator;
+
+public class PointableAllocator {
+
+ private IElementAllocator<IVisitablePointable, IAType> flatValueAllocator = new ListElementAllocator<IVisitablePointable, IAType>(
+ AFlatValuePointable.FACTORY);
+ private IElementAllocator<IVisitablePointable, IAType> recordValueAllocator = new ListElementAllocator<IVisitablePointable, IAType>(
+ ARecordPointable.FACTORY);
+ private IElementAllocator<IVisitablePointable, IAType> listValueAllocator = new ListElementAllocator<IVisitablePointable, IAType>(
+ AListPointable.FACTORY);
+
+ public IVisitablePointable allocateEmpty() {
+ return flatValueAllocator.allocate(null);
+ }
+
+ /**
+ * allocate closed part value pointable
+ *
+ * @param type
+ * @return the pointable object
+ */
+ public IVisitablePointable allocateFieldValue(IAType type) {
+ if (type == null)
+ return flatValueAllocator.allocate(null);
+ else if (type.getTypeTag().equals(ATypeTag.RECORD))
+ return recordValueAllocator.allocate(type);
+ else if (type.getTypeTag().equals(ATypeTag.UNORDEREDLIST) || type.getTypeTag().equals(ATypeTag.ORDEREDLIST))
+ return listValueAllocator.allocate(type);
+ else
+ return flatValueAllocator.allocate(null);
+ }
+
+ /**
+ * allocate open part value pointable
+ *
+ * @param typeTag
+ * @return the pointable object
+ */
+ public IVisitablePointable allocateFieldValue(ATypeTag typeTag) {
+ if (typeTag == null)
+ return flatValueAllocator.allocate(null);
+ else if (typeTag.equals(ATypeTag.RECORD))
+ return recordValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ else if (typeTag.equals(ATypeTag.UNORDEREDLIST))
+ return listValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
+ else if (typeTag.equals(ATypeTag.ORDEREDLIST))
+ return listValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
+ else
+ return flatValueAllocator.allocate(null);
+ }
+
+ public IVisitablePointable allocateListValue(IAType type) {
+ return listValueAllocator.allocate(type);
+ }
+
+ public IVisitablePointable allocateRecordValue(IAType type) {
+ return recordValueAllocator.allocate(type);
+ }
+
+ public void reset() {
+ flatValueAllocator.reset();
+ recordValueAllocator.reset();
+ listValueAllocator.reset();
+ }
+}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java
index e1bad50..930bb8b 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/AListCaster.java
@@ -29,8 +29,8 @@
import edu.uci.ics.asterix.om.types.AbstractCollectionType;
import edu.uci.ics.asterix.om.types.EnumDeserializer;
import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.asterix.runtime.pointables.AFlatValuePointable;
import edu.uci.ics.asterix.runtime.pointables.AListPointable;
+import edu.uci.ics.asterix.runtime.pointables.PointableAllocator;
import edu.uci.ics.asterix.runtime.pointables.base.DefaultOpenFieldType;
import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
@@ -39,7 +39,11 @@
class AListCaster {
private IAType reqItemType;
- private IVisitablePointable itemTempReference = AFlatValuePointable.FACTORY.createElement(null);
+ // pointable allocator
+ private PointableAllocator allocator = new PointableAllocator();
+
+ // for storing the cast result
+ private IVisitablePointable itemTempReference = allocator.allocateEmpty();
private Triple<IVisitablePointable, IAType, Boolean> itemVisitorArg = new Triple<IVisitablePointable, IAType, Boolean>(
itemTempReference, null, null);
@@ -54,8 +58,8 @@
}
- public void castList(AListPointable listAccessor, IVisitablePointable resultAccessor, AbstractCollectionType reqType,
- ACastVisitor visitor) throws IOException, AsterixException {
+ public void castList(AListPointable listAccessor, IVisitablePointable resultAccessor,
+ AbstractCollectionType reqType, ACastVisitor visitor) throws IOException, AsterixException {
if (reqType.getTypeTag().equals(ATypeTag.UNORDEREDLIST)) {
unOrderedListBuilder.reset((AUnorderedListType) reqType);
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ARecordCaster.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ARecordCaster.java
index e68cdf4..52aab9d 100644
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ARecordCaster.java
+++ b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/pointables/cast/ARecordCaster.java
@@ -30,8 +30,8 @@
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.asterix.runtime.pointables.AFlatValuePointable;
import edu.uci.ics.asterix.runtime.pointables.ARecordPointable;
+import edu.uci.ics.asterix.runtime.pointables.PointableAllocator;
import edu.uci.ics.asterix.runtime.pointables.base.DefaultOpenFieldType;
import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
import edu.uci.ics.asterix.runtime.util.ResettableByteArrayOutputStream;
@@ -44,6 +44,9 @@
class ARecordCaster {
+ // pointable allocator
+ private PointableAllocator allocator = new PointableAllocator();
+
// describe closed fields in the required type
private int[] fieldPermutation;
private boolean[] optionalFields;
@@ -62,8 +65,8 @@
private DataOutputStream dos = new DataOutputStream(bos);
private RecordBuilder recBuilder = new RecordBuilder();
- private IVisitablePointable nullReference = AFlatValuePointable.FACTORY.createElement(null);
- private IVisitablePointable nullTypeTag = AFlatValuePointable.FACTORY.createElement(null);
+ private IVisitablePointable nullReference = allocator.allocateEmpty();
+ private IVisitablePointable nullTypeTag = allocator.allocateEmpty();
private int numInputFields = 0;
private IBinaryComparator fieldNameComparator = PointableBinaryComparatorFactory.of(UTF8StringPointable.FACTORY)
@@ -73,7 +76,7 @@
private ResettableByteArrayOutputStream outputBos = new ResettableByteArrayOutputStream();
private DataOutputStream outputDos = new DataOutputStream(outputBos);
- private IVisitablePointable fieldTempReference = AFlatValuePointable.FACTORY.createElement(null);
+ private IVisitablePointable fieldTempReference = allocator.allocateEmpty();
private Triple<IVisitablePointable, IAType, Boolean> nestedVisitorArg = new Triple<IVisitablePointable, IAType, Boolean>(
fieldTempReference, null, null);
@@ -155,7 +158,7 @@
int tagStart = bos.size();
dos.writeByte(ftypeTag.serialize());
int tagEnd = bos.size();
- IVisitablePointable typeTagPointable = AFlatValuePointable.FACTORY.createElement(null);
+ IVisitablePointable typeTagPointable = allocator.allocateEmpty();
typeTagPointable.set(buffer, tagStart, tagEnd - tagStart);
reqFieldTypeTags.add(typeTagPointable);
@@ -164,7 +167,7 @@
dos.write(ATypeTag.STRING.serialize());
dos.writeUTF(fname);
int nameEnd = bos.size();
- IVisitablePointable typeNamePointable = AFlatValuePointable.FACTORY.createElement(null);
+ IVisitablePointable typeNamePointable = allocator.allocateEmpty();
typeNamePointable.set(buffer, nameStart, nameEnd - nameStart);
reqFieldNames.add(typeNamePointable);
}
diff --git a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/PointableAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/PointableAllocator.java
deleted file mode 100644
index fe0499a..0000000
--- a/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/PointableAllocator.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2009-2010 by The Regents of the University of California
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * you may obtain a copy of the License from
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package edu.uci.ics.asterix.runtime.util;
-
-import edu.uci.ics.asterix.om.types.ATypeTag;
-import edu.uci.ics.asterix.om.types.IAType;
-import edu.uci.ics.asterix.runtime.pointables.AFlatValuePointable;
-import edu.uci.ics.asterix.runtime.pointables.AListPointable;
-import edu.uci.ics.asterix.runtime.pointables.ARecordPointable;
-import edu.uci.ics.asterix.runtime.pointables.base.DefaultOpenFieldType;
-import edu.uci.ics.asterix.runtime.pointables.base.IVisitablePointable;
-import edu.uci.ics.asterix.runtime.util.container.IElementAllocator;
-import edu.uci.ics.asterix.runtime.util.container.ListElementAllocator;
-
-public class PointableAllocator {
-
- private IElementAllocator<IVisitablePointable, IAType> flatArtifactAllocator = new ListElementAllocator<IVisitablePointable, IAType>(
- AFlatValuePointable.FACTORY);
- private IElementAllocator<IVisitablePointable, IAType> nestedRecValueAllocator = new ListElementAllocator<IVisitablePointable, IAType>(
- ARecordPointable.FACTORY);
- private IElementAllocator<IVisitablePointable, IAType> nestedListValueAllocator = new ListElementAllocator<IVisitablePointable, IAType>(
- AListPointable.FACTORY);
-
- public IVisitablePointable allocateFieldName() {
- return flatArtifactAllocator.allocate(null);
- }
-
- public IVisitablePointable allocateFieldType() {
- return flatArtifactAllocator.allocate(null);
- }
-
- public IVisitablePointable allocateFieldValue(IAType type) {
- if(type == null)
- return flatArtifactAllocator.allocate(null);
- else 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 IVisitablePointable allocateFieldValue(ATypeTag typeTag) {
- if(typeTag == null)
- return flatArtifactAllocator.allocate(null);
- else if (typeTag.equals(ATypeTag.RECORD))
- return nestedRecValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
- else if (typeTag.equals(ATypeTag.UNORDEREDLIST))
- return nestedListValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE);
- else if(typeTag.equals(ATypeTag.ORDEREDLIST))
- return nestedListValueAllocator.allocate(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE);
- else
- return flatArtifactAllocator.allocate(null);
- }
-
- public IVisitablePointable 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/util/container/ListElementAllocator.java b/asterix-runtime/src/main/java/edu/uci/ics/asterix/runtime/util/container/ListElementAllocator.java
index d4ae0a4..a2b2273 100644
--- 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
@@ -18,17 +18,38 @@
import java.util.ArrayList;
import java.util.List;
+import org.apache.hadoop.io.BooleanWritable;
+
/**
- * ListElementAllocator<E, T> is an element-reusable list or a element pool in other words, however
- * elements in the list should be exactly the same class, this is forced by IElementFactory<E, T> factory
- * as a parameter to the constructor once a ListElementAllocator is constructed, it can only store
+ * ListElementAllocator<E, T> is an element-reusable list or a element pool in
+ * other words, however elements in the list should be exactly the same class,
+ * this is forced by IElementFactory<E, T> factory as a parameter to the
+ * constructor once a ListElementAllocator is constructed, it can only store
* objects of the same class
*/
public class ListElementAllocator<E, T> implements IElementAllocator<E, T> {
private IElementFactory<E, T> factory;
+
+ /**
+ * element reusable object pool
+ */
private List<E> pool = new ArrayList<E>();
- private int cursor = -1;
+
+ /**
+ * args that are used to create each element in the pool
+ */
+ private List<T> args = new ArrayList<T>();
+
+ /**
+ * bits indicating which element is in use
+ */
+ private List<BooleanWritable> usedBits = new ArrayList<BooleanWritable>();
+
+ /**
+ * the start index for searching
+ */
+ private int minStartIndex = 0;
public ListElementAllocator(IElementFactory<E, T> factory) {
this.factory = factory;
@@ -36,18 +57,48 @@
@Override
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;
+ boolean continuous = true;
+ for (int i = minStartIndex; i < pool.size(); i++) {
+ if (!usedBits.get(i).get()) {
+ boolean match = false;
+
+ // the two cases where an element in the pool is a match
+ if ((arg == null && args.get(i) == null)
+ || (arg != null && args.get(i) != null && arg.equals(args.get(i))))
+ match = true;
+
+ if (match) {
+ // the element is not used and the arg is the same as input
+ // arg
+ if (continuous)
+ minStartIndex++;
+
+ usedBits.get(i).set(true);
+ return pool.get(i);
+ } else {
+ // a unmatched element blocked
+ // free slots are not continuous from the beginning free
+ // slot
+ continuous = false;
+ }
+ } else {
+ if (continuous)
+ minStartIndex++;
+ }
}
+
+ // if not find a reusable object, allocate a new element
+ E element = factory.createElement(arg);
+ pool.add(element);
+ args.add(arg);
+ usedBits.add(new BooleanWritable(true));
+ return element;
}
@Override
public void reset() {
- cursor = -1;
+ for (int i = 0; i < usedBits.size(); i++)
+ usedBits.get(i).set(false);
+ minStartIndex = 0;
}
}