use of org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder in project asterixdb by apache.
the class LSMInvertedIndexTestUtils method compareActualAndExpectedIndexesRangeSearch.
/**
* Compares actual and expected indexes using the rangeSearch() method of the inverted-index accessor.
*/
public static void compareActualAndExpectedIndexesRangeSearch(LSMInvertedIndexTestContext testCtx) throws HyracksDataException {
IInvertedIndex invIndex = (IInvertedIndex) testCtx.getIndex();
int tokenFieldCount = invIndex.getTokenTypeTraits().length;
int invListFieldCount = invIndex.getInvListTypeTraits().length;
IInvertedIndexAccessor invIndexAccessor = (IInvertedIndexAccessor) invIndex.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
IIndexCursor invIndexCursor = invIndexAccessor.createRangeSearchCursor();
MultiComparator tokenCmp = MultiComparator.create(invIndex.getTokenCmpFactories());
IBinaryComparatorFactory[] tupleCmpFactories = new IBinaryComparatorFactory[tokenFieldCount + invListFieldCount];
for (int i = 0; i < tokenFieldCount; i++) {
tupleCmpFactories[i] = invIndex.getTokenCmpFactories()[i];
}
for (int i = 0; i < invListFieldCount; i++) {
tupleCmpFactories[tokenFieldCount + i] = invIndex.getInvListCmpFactories()[i];
}
MultiComparator tupleCmp = MultiComparator.create(tupleCmpFactories);
RangePredicate nullPred = new RangePredicate(null, null, true, true, tokenCmp, tokenCmp);
invIndexAccessor.rangeSearch(invIndexCursor, nullPred);
// Helpers for generating a serialized inverted-list element from a CheckTuple from the expected index.
ISerializerDeserializer[] fieldSerdes = testCtx.getFieldSerdes();
ArrayTupleBuilder expectedBuilder = new ArrayTupleBuilder(fieldSerdes.length);
ArrayTupleReference expectedTuple = new ArrayTupleReference();
Iterator<CheckTuple> expectedIter = testCtx.getCheckTuples().iterator();
// Compare index elements.
try {
while (invIndexCursor.hasNext() && expectedIter.hasNext()) {
invIndexCursor.next();
ITupleReference actualTuple = invIndexCursor.getTuple();
CheckTuple expected = expectedIter.next();
OrderedIndexTestUtils.createTupleFromCheckTuple(expected, expectedBuilder, expectedTuple, fieldSerdes);
if (tupleCmp.compare(actualTuple, expectedTuple) != 0) {
fail("Index entries differ for token '" + expected.getField(0) + "'.");
}
}
if (expectedIter.hasNext()) {
fail("Indexes do not match. Actual index is missing entries.");
}
if (invIndexCursor.hasNext()) {
fail("Indexes do not match. Actual index contains too many entries.");
}
} finally {
invIndexCursor.close();
}
}
use of org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder in project asterixdb by apache.
the class TupleUtils method createDoubleTuple.
public static ITupleReference createDoubleTuple(final double... fields) throws HyracksDataException {
ArrayTupleBuilder tupleBuilder = new ArrayTupleBuilder(fields.length);
ArrayTupleReference tuple = new ArrayTupleReference();
createDoubleTuple(tupleBuilder, tuple, fields);
return tuple;
}
use of org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder in project asterixdb by apache.
the class TupleUtils method copyTuple.
public static ITupleReference copyTuple(ITupleReference tuple) throws HyracksDataException {
ArrayTupleBuilder tupleBuilder = new ArrayTupleBuilder(tuple.getFieldCount());
for (int i = 0; i < tuple.getFieldCount(); i++) {
tupleBuilder.addField(tuple.getFieldData(i), tuple.getFieldStart(i), tuple.getFieldLength(i));
}
ArrayTupleReference tupleCopy = new ArrayTupleReference();
tupleCopy.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
return tupleCopy;
}
use of org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder in project asterixdb by apache.
the class TupleUtils method createIntegerTuple.
public static ITupleReference createIntegerTuple(boolean filtered, final int... fields) throws HyracksDataException {
ArrayTupleBuilder tupleBuilder = filtered ? new ArrayTupleBuilder(fields.length + 1) : new ArrayTupleBuilder(fields.length);
ArrayTupleReference tuple = new ArrayTupleReference();
createIntegerTuple(tupleBuilder, tuple, fields);
return tuple;
}
use of org.apache.hyracks.dataflow.common.comm.io.ArrayTupleBuilder in project asterixdb by apache.
the class LSMBTreeRangeSearchCursor method checkPriorityQueue.
/**
* Checks the priority queue and resets and the top element if required.
* PriorityQueue can hold one element from each cursor.
* The boolean variable canCallProceedMethod controls whether we can call proceed() method for this element.
* i.e. it can return this element if proceed() succeeds.
* If proceed fails, that is most-likely that there is ongoing operations in the in-memory component.
* After resolving in-memory component issue, it progresses again.
* Also, in order to not release the same element again, it keeps the previous output and checks it
* against the current head in the queue.
*/
@Override
protected void checkPriorityQueue() throws HyracksDataException {
while (!outputPriorityQueue.isEmpty() || needPushElementIntoQueue == true) {
if (!outputPriorityQueue.isEmpty()) {
PriorityQueueElement checkElement = outputPriorityQueue.peek();
if (canCallProceed) {
resultOfSearchCallBackProceed = searchCallback.proceed(checkElement.getTuple());
if (!resultOfSearchCallBackProceed) {
// we can't simply use this element since there might be a change.
if (includeMutableComponent) {
PriorityQueueElement mutableElement = null;
boolean mutableElementFound = false;
// Scans the PQ for the mutable component's element and delete it
// since it can be changed.
// (i.e. we can't ensure that the element is the most current one.)
Iterator<PriorityQueueElement> it = outputPriorityQueue.iterator();
while (it.hasNext()) {
mutableElement = it.next();
if (mutableElement.getCursorIndex() == 0) {
mutableElementFound = true;
it.remove();
break;
}
}
if (mutableElementFound) {
// Copies the in-memory tuple.
if (tupleBuilder == null) {
tupleBuilder = new ArrayTupleBuilder(cmp.getKeyFieldCount());
}
TupleUtils.copyTuple(tupleBuilder, mutableElement.getTuple(), cmp.getKeyFieldCount());
copyTuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray());
// Unlatches/unpins the leaf page of the index.
rangeCursors[0].reset();
// Tries to reconcile.
if (checkElement.getCursorIndex() == 0) {
searchCallback.reconcile(copyTuple);
} else {
// If this element is from the disk component, we can call complete()
// after reconcile() since we can guarantee that there is no change.
searchCallback.reconcile(checkElement.getTuple());
searchCallback.complete(checkElement.getTuple());
}
// Re-traverses the index.
reusablePred.setLowKey(copyTuple, true);
btreeAccessors[0].search(rangeCursors[0], reusablePred);
boolean isNotExhaustedCursor = pushIntoQueueFromCursorAndReplaceThisElement(mutableElement);
if (checkElement.getCursorIndex() == 0) {
if (!isNotExhaustedCursor || cmp.compare(copyTuple, mutableElement.getTuple()) != 0) {
// The searched key no longer exists. We call cancel() to
// reverse the effect of reconcile() method.
searchCallback.cancel(copyTuple);
continue;
}
// The searched key is still there.
// TODO: do we need to call or not call complete() in this case?
searchCallback.complete(copyTuple);
}
} else {
// The mutable cursor is exhausted and it couldn't find the element.
// The failed element did not come from the in-memory component.
searchCallback.reconcile(checkElement.getTuple());
}
} else {
// proceed() failed. However, there is no in-memory component.
// So just call reconcile.
searchCallback.reconcile(checkElement.getTuple());
}
}
}
// This check is needed not to release the same tuple again.
if (outputElement == null) {
if (isDeleted(checkElement) && !returnDeletedTuples) {
// If the key has been deleted then pop it and set needPush to true.
// We cannot push immediately because the tuple may be
// modified if hasNext() is called
outputElement = outputPriorityQueue.poll();
if (!resultOfSearchCallBackProceed) {
searchCallback.cancel(checkElement.getTuple());
}
needPushElementIntoQueue = true;
canCallProceed = false;
} else {
break;
}
} else {
// Compare the previous tuple and the head tuple in the PQ
if (compare(cmp, outputElement.getTuple(), checkElement.getTuple()) == 0) {
// If the previous tuple and the head tuple are
// identical
// then pop the head tuple and push the next tuple from
// the tree of head tuple
// the head element of PQ is useless now
PriorityQueueElement e = outputPriorityQueue.poll();
pushIntoQueueFromCursorAndReplaceThisElement(e);
} else {
// the info of previous tuple is useless
if (needPushElementIntoQueue == true) {
pushIntoQueueFromCursorAndReplaceThisElement(outputElement);
needPushElementIntoQueue = false;
}
canCallProceed = true;
outputElement = null;
}
}
} else {
// the priority queue is empty and needPush
pushIntoQueueFromCursorAndReplaceThisElement(outputElement);
needPushElementIntoQueue = false;
outputElement = null;
canCallProceed = true;
}
}
}
Aggregations