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;
|
import java.util.List;
|
||||||
|
|
||||||
class MultiwayLongMerger {
|
class MultiwayLongMerger {
|
||||||
private static final long UNSET = Long.MIN_VALUE;
|
private static final long UNSET = Long.MAX_VALUE;
|
||||||
|
|
||||||
private static class LongQueue {
|
private static class LongQueue {
|
||||||
|
private static final LongQueue EMPTY = new LongQueue(LongList.of());
|
||||||
|
|
||||||
final LongList wrapped;
|
final LongList wrapped;
|
||||||
|
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@@ -32,13 +34,17 @@ class MultiwayLongMerger {
|
|||||||
return wrapped.get(offset);
|
return wrapped.get(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long peekLast() {
|
||||||
|
return wrapped.get(wrapped.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return wrapped.sublist(offset).toString();
|
return wrapped.sublist(offset).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int size() {
|
public int size() {
|
||||||
return wrapped.size()-offset;
|
return wrapped.size() - offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,13 +56,13 @@ class MultiwayLongMerger {
|
|||||||
boolean hasValueUNSET = initQueues(longLists, queues);
|
boolean hasValueUNSET = initQueues(longLists, queues);
|
||||||
|
|
||||||
final LongList result = new LongList();
|
final LongList result = new LongList();
|
||||||
if (hasValueUNSET) {
|
|
||||||
result.add(UNSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!queues.isEmpty()) {
|
if (!queues.isEmpty()) {
|
||||||
mergeQueues(queues, result);
|
mergeQueues(queues, result);
|
||||||
}
|
}
|
||||||
|
if (hasValueUNSET) {
|
||||||
|
result.add(UNSET);
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -76,16 +82,14 @@ class MultiwayLongMerger {
|
|||||||
|
|
||||||
private static boolean initQueues(Collection<LongList> longLists, final List<LongQueue> queues) {
|
private static boolean initQueues(Collection<LongList> longLists, final List<LongQueue> queues) {
|
||||||
boolean hasValueUNSET = false;
|
boolean hasValueUNSET = false;
|
||||||
for (LongList longList : longLists) {
|
for (final LongList longList : longLists) {
|
||||||
if (!longList.isEmpty()) {
|
if (!longList.isEmpty()) {
|
||||||
final LongQueue queue = new LongQueue(longList);
|
final LongQueue queue = new LongQueue(longList);
|
||||||
while (!queue.isEmpty() && queue.peek() == UNSET) {
|
if (!queue.isEmpty() && queue.peekLast() == UNSET) {
|
||||||
queue.pop();
|
|
||||||
hasValueUNSET = true;
|
hasValueUNSET = true;
|
||||||
}
|
}
|
||||||
if (!queue.isEmpty()) {
|
|
||||||
queues.add(queue);
|
queues.add(queue);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hasValueUNSET;
|
return hasValueUNSET;
|
||||||
@@ -125,6 +129,14 @@ class MultiwayLongMerger {
|
|||||||
firstLeafIndex = heap.length / 2;
|
firstLeafIndex = heap.length / 2;
|
||||||
|
|
||||||
Arrays.fill(heap, UNSET);
|
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();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +151,9 @@ class MultiwayLongMerger {
|
|||||||
*/
|
*/
|
||||||
public long pop() {
|
public long pop() {
|
||||||
long result = heap[0];
|
long result = heap[0];
|
||||||
fillWithMinOfChildren(0);
|
if (result != UNSET) {
|
||||||
|
fillWithMinOfChildren(0);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,37 +211,23 @@ class MultiwayLongMerger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void fillWithMinOfChildren(int index) {
|
private void fillWithMinOfChildren(int index) {
|
||||||
final int leftChildIndex = index * 2 + 1; //leftChildIndex(index);
|
final int leftChildIndex = index * 2 + 1; // leftChildIndex(index);
|
||||||
final int rightChildIndex = leftChildIndex+1;//rightChildIndex(index);
|
final int rightChildIndex = leftChildIndex + 1;// rightChildIndex(index);
|
||||||
|
|
||||||
final long valueOfLeftChild = heap[leftChildIndex];
|
final long valueOfLeftChild = heap[leftChildIndex];
|
||||||
final long valueOfRightChild = heap[rightChildIndex];
|
final long valueOfRightChild = heap[rightChildIndex];
|
||||||
|
|
||||||
final int chosenValue;
|
final int chosenValue;
|
||||||
|
|
||||||
if (valueOfLeftChild == UNSET) {
|
|
||||||
if (valueOfRightChild == UNSET) {
|
if (valueOfLeftChild < valueOfRightChild) {
|
||||||
heap[index] = UNSET;
|
// left < right
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
//left < right
|
|
||||||
heap[index] = valueOfRightChild;
|
|
||||||
chosenValue = rightChildIndex;
|
|
||||||
}
|
|
||||||
} else if (valueOfRightChild == UNSET) {
|
|
||||||
// left > right
|
|
||||||
heap[index] = valueOfLeftChild;
|
heap[index] = valueOfLeftChild;
|
||||||
chosenValue = leftChildIndex;
|
chosenValue = leftChildIndex;
|
||||||
} else {
|
} else {
|
||||||
if (valueOfLeftChild < valueOfRightChild) {
|
// left >= right
|
||||||
// left < right
|
heap[index] = valueOfRightChild;
|
||||||
heap[index] = valueOfLeftChild;
|
chosenValue = rightChildIndex;
|
||||||
chosenValue = leftChildIndex;
|
|
||||||
} else {
|
|
||||||
// left >= right
|
|
||||||
heap[index] = valueOfRightChild;
|
|
||||||
chosenValue = rightChildIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
refillValue(chosenValue);
|
refillValue(chosenValue);
|
||||||
@@ -235,7 +235,7 @@ class MultiwayLongMerger {
|
|||||||
|
|
||||||
private void refillValue(int index) {
|
private void refillValue(int index) {
|
||||||
if (isLeaf(index)) {
|
if (isLeaf(index)) {
|
||||||
final int listIndex = index - firstLeafIndex; //leafIndexToListIndex(index);
|
final int listIndex = index - firstLeafIndex; // leafIndexToListIndex(index);
|
||||||
final LongQueue queue = longQueues.get(listIndex);
|
final LongQueue queue = longQueues.get(listIndex);
|
||||||
heap[index] = queue.isEmpty() ? UNSET : queue.pop();
|
heap[index] = queue.isEmpty() ? UNSET : queue.pop();
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user