changed the value of UNSET from Long.MIN_VALUE to LONG.MAX_VALUE
That made the code in fillWithMinOfChildren() easier. We lost an early out, though. But that should be negligible.
This commit is contained in:
@@ -6,9 +6,11 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
class MultiwayLongMerger {
|
||||
private static final long UNSET = Long.MIN_VALUE;
|
||||
private static final long UNSET = Long.MAX_VALUE;
|
||||
|
||||
private static class LongQueue {
|
||||
private static final LongQueue EMPTY = new LongQueue(LongList.of());
|
||||
|
||||
final LongList wrapped;
|
||||
|
||||
int offset = 0;
|
||||
@@ -32,31 +34,35 @@ class MultiwayLongMerger {
|
||||
return wrapped.get(offset);
|
||||
}
|
||||
|
||||
public long peekLast() {
|
||||
return wrapped.get(wrapped.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return wrapped.sublist(offset).toString();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return wrapped.size()-offset;
|
||||
return wrapped.size() - offset;
|
||||
}
|
||||
}
|
||||
|
||||
static LongList unionSorted(Collection<LongList> longLists) {
|
||||
|
||||
assertAllListsAreSorted(longLists);
|
||||
|
||||
|
||||
final List<LongQueue> queues = new ArrayList<LongQueue>();
|
||||
boolean hasValueUNSET = initQueues(longLists, queues);
|
||||
|
||||
final LongList result = new LongList();
|
||||
if (hasValueUNSET) {
|
||||
result.add(UNSET);
|
||||
}
|
||||
|
||||
if (!queues.isEmpty()) {
|
||||
mergeQueues(queues, result);
|
||||
}
|
||||
if (hasValueUNSET) {
|
||||
result.add(UNSET);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -76,16 +82,14 @@ class MultiwayLongMerger {
|
||||
|
||||
private static boolean initQueues(Collection<LongList> longLists, final List<LongQueue> queues) {
|
||||
boolean hasValueUNSET = false;
|
||||
for (LongList longList : longLists) {
|
||||
for (final LongList longList : longLists) {
|
||||
if (!longList.isEmpty()) {
|
||||
final LongQueue queue = new LongQueue(longList);
|
||||
while (!queue.isEmpty() && queue.peek() == UNSET) {
|
||||
queue.pop();
|
||||
if (!queue.isEmpty() && queue.peekLast() == UNSET) {
|
||||
hasValueUNSET = true;
|
||||
}
|
||||
if (!queue.isEmpty()) {
|
||||
queues.add(queue);
|
||||
}
|
||||
|
||||
queues.add(queue);
|
||||
}
|
||||
}
|
||||
return hasValueUNSET;
|
||||
@@ -125,6 +129,14 @@ class MultiwayLongMerger {
|
||||
firstLeafIndex = heap.length / 2;
|
||||
|
||||
Arrays.fill(heap, UNSET);
|
||||
|
||||
// fill the longQueues list with empty queues, so that we
|
||||
// have a queue for every leaf in the heap. This makes fillWithMinOfChildren()
|
||||
// easier, because it removes special cases.
|
||||
for (int i = size ; i < nextPowOfTwo(size); i++) {
|
||||
this.longQueues.add(LongQueue.EMPTY);
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -139,7 +151,9 @@ class MultiwayLongMerger {
|
||||
*/
|
||||
public long pop() {
|
||||
long result = heap[0];
|
||||
fillWithMinOfChildren(0);
|
||||
if (result != UNSET) {
|
||||
fillWithMinOfChildren(0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -197,37 +211,23 @@ class MultiwayLongMerger {
|
||||
}
|
||||
|
||||
private void fillWithMinOfChildren(int index) {
|
||||
final int leftChildIndex = index * 2 + 1; //leftChildIndex(index);
|
||||
final int rightChildIndex = leftChildIndex+1;//rightChildIndex(index);
|
||||
final int leftChildIndex = index * 2 + 1; // leftChildIndex(index);
|
||||
final int rightChildIndex = leftChildIndex + 1;// rightChildIndex(index);
|
||||
|
||||
final long valueOfLeftChild = heap[leftChildIndex];
|
||||
final long valueOfRightChild = heap[rightChildIndex];
|
||||
|
||||
final int chosenValue;
|
||||
|
||||
|
||||
if (valueOfLeftChild == UNSET) {
|
||||
if (valueOfRightChild == UNSET) {
|
||||
heap[index] = UNSET;
|
||||
return;
|
||||
} else {
|
||||
//left < right
|
||||
heap[index] = valueOfRightChild;
|
||||
chosenValue = rightChildIndex;
|
||||
}
|
||||
} else if (valueOfRightChild == UNSET) {
|
||||
// left > right
|
||||
if (valueOfLeftChild < valueOfRightChild) {
|
||||
// left < right
|
||||
heap[index] = valueOfLeftChild;
|
||||
chosenValue = leftChildIndex;
|
||||
} else {
|
||||
if (valueOfLeftChild < valueOfRightChild) {
|
||||
// left < right
|
||||
heap[index] = valueOfLeftChild;
|
||||
chosenValue = leftChildIndex;
|
||||
} else {
|
||||
// left >= right
|
||||
heap[index] = valueOfRightChild;
|
||||
chosenValue = rightChildIndex;
|
||||
}
|
||||
// left >= right
|
||||
heap[index] = valueOfRightChild;
|
||||
chosenValue = rightChildIndex;
|
||||
}
|
||||
|
||||
refillValue(chosenValue);
|
||||
@@ -235,7 +235,7 @@ class MultiwayLongMerger {
|
||||
|
||||
private void refillValue(int index) {
|
||||
if (isLeaf(index)) {
|
||||
final int listIndex = index - firstLeafIndex; //leafIndexToListIndex(index);
|
||||
final int listIndex = index - firstLeafIndex; // leafIndexToListIndex(index);
|
||||
final LongQueue queue = longQueues.get(listIndex);
|
||||
heap[index] = queue.isEmpty() ? UNSET : queue.pop();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user