/** Restores the heap after inserting a new object */ private void heapValueUpwards() { int a = size(); int c = a / 2; PriorityQueueElement recentlyInsertedElement = (PriorityQueueElement) queue.get(a - 1); while (c > 0 && getPriority(c - 1) < recentlyInsertedElement.getPriority()) { queue.set(a - 1, queue.get(c - 1)); // shift parent-node down a = c; // (c <= 0) => no parent-node remains c = a / 2; } queue.set(a - 1, recentlyInsertedElement); }
/** Restores the heap after removing the next element */ private void heapValueDownwards() { int a = 1; int c = 2 * a; // descendant PriorityQueueElement priorityQueueElement = (PriorityQueueElement) queue.get(a - 1); if (c < size() && (getPriority(c) > getPriority(c - 1))) c++; while (c <= size() && getPriority(c - 1) > priorityQueueElement.getPriority()) { queue.set(a - 1, queue.get(c - 1)); a = c; c = 2 * a; if (c < size() && (getPriority(c) > getPriority(c - 1))) c++; } queue.set(a - 1, priorityQueueElement); }
protected void checkPriorityQueue() throws HyracksDataException, IndexException { while (!outputPriorityQueue.isEmpty() || needPush == true) { if (!outputPriorityQueue.isEmpty()) { PriorityQueueElement checkElement = outputPriorityQueue.peek(); if (proceed && !searchCallback.proceed(checkElement.getTuple())) { if (includeMemComponent) { PriorityQueueElement inMemElement = null; boolean inMemElementFound = false; // scan the PQ for the in-memory component's element Iterator<PriorityQueueElement> it = outputPriorityQueue.iterator(); while (it.hasNext()) { inMemElement = it.next(); if (inMemElement.getCursorIndex() == 0) { inMemElementFound = true; it.remove(); break; } } if (inMemElementFound) { // copy the in-mem tuple if (tupleBuilder == null) { tupleBuilder = new ArrayTupleBuilder(cmp.getKeyFieldCount()); } TupleUtils.copyTuple(tupleBuilder, inMemElement.getTuple(), cmp.getKeyFieldCount()); copyTuple.reset(tupleBuilder.getFieldEndOffsets(), tupleBuilder.getByteArray()); // unlatch/unpin rangeCursors[0].reset(); // reconcile if (checkElement.getCursorIndex() == 0) { searchCallback.reconcile(copyTuple); } else { searchCallback.reconcile(checkElement.getTuple()); } // retraverse reusablePred.setLowKey(copyTuple, true); memBTreeAccessor.search(rangeCursors[0], reusablePred); pushIntoPriorityQueue(inMemElement); if (cmp.compare(copyTuple, inMemElement.getTuple()) != 0) { searchCallback.cancel(copyTuple); continue; } } else { // the in-memory cursor is exhausted searchCallback.reconcile(checkElement.getTuple()); } } else { searchCallback.reconcile(checkElement.getTuple()); } } // If there is no previous tuple or the previous tuple can be ignored if (outputElement == null) { if (isDeleted(checkElement)) { // 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(); searchCallback.cancel(checkElement.getTuple()); needPush = true; proceed = 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(); pushIntoPriorityQueue(e); } else { // If the previous tuple and the head tuple are different // the info of previous tuple is useless if (needPush == true) { pushIntoPriorityQueue(outputElement); needPush = false; } proceed = true; outputElement = null; } } } else { // the priority queue is empty and needPush pushIntoPriorityQueue(outputElement); needPush = false; outputElement = null; proceed = true; } } }