mirror of https://github.com/apache/lucene.git
Speedup PriorityQueue a little
Saving some field accesses.
This commit is contained in:
parent
3983fa2c8d
commit
d60183bd17
|
@ -117,26 +117,29 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
* ArrayIndexOutOfBoundsException} is thrown.
|
* ArrayIndexOutOfBoundsException} is thrown.
|
||||||
*/
|
*/
|
||||||
public void addAll(Collection<T> elements) {
|
public void addAll(Collection<T> elements) {
|
||||||
if (this.size + elements.size() > this.maxSize) {
|
int s = size;
|
||||||
|
if (s + elements.size() > this.maxSize) {
|
||||||
throw new ArrayIndexOutOfBoundsException(
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
"Cannot add "
|
"Cannot add "
|
||||||
+ elements.size()
|
+ elements.size()
|
||||||
+ " elements to a queue with remaining capacity: "
|
+ " elements to a queue with remaining capacity: "
|
||||||
+ (maxSize - size));
|
+ (maxSize - s));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Heap with size S always takes first S elements of the array,
|
// Heap with size S always takes first S elements of the array,
|
||||||
// and thus it's safe to fill array further - no actual non-sentinel value will be overwritten.
|
// and thus it's safe to fill array further - no actual non-sentinel value will be overwritten.
|
||||||
Iterator<T> iterator = elements.iterator();
|
Iterator<T> iterator = elements.iterator();
|
||||||
|
var heap = this.heap;
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
this.heap[size + 1] = iterator.next();
|
heap[s + 1] = iterator.next();
|
||||||
this.size++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The loop goes down to 1 as heap is 1-based not 0-based.
|
// The loop goes down to 1 as heap is 1-based not 0-based.
|
||||||
for (int i = (size >>> 1); i >= 1; i--) {
|
for (int i = (s >>> 1); i >= 1; i--) {
|
||||||
downHeap(i);
|
downHeap(i, heap, s);
|
||||||
}
|
}
|
||||||
|
this.size = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,9 +159,10 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
public final T add(T element) {
|
public final T add(T element) {
|
||||||
// don't modify size until we know heap access didn't throw AIOOB.
|
// don't modify size until we know heap access didn't throw AIOOB.
|
||||||
int index = size + 1;
|
int index = size + 1;
|
||||||
|
var heap = this.heap;
|
||||||
heap[index] = element;
|
heap[index] = element;
|
||||||
size = index;
|
size = index;
|
||||||
upHeap(index);
|
upHeap(index, heap);
|
||||||
return heap[1];
|
return heap[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +197,15 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
|
|
||||||
/** Removes and returns the least element of the PriorityQueue in log(size) time. */
|
/** Removes and returns the least element of the PriorityQueue in log(size) time. */
|
||||||
public final T pop() {
|
public final T pop() {
|
||||||
if (size > 0) {
|
int s = size;
|
||||||
|
if (s > 0) {
|
||||||
|
var heap = this.heap;
|
||||||
T result = heap[1]; // save first value
|
T result = heap[1]; // save first value
|
||||||
heap[1] = heap[size]; // move last to first
|
heap[1] = heap[s]; // move last to first
|
||||||
heap[size] = null; // permit GC of objects
|
heap[s] = null; // permit GC of objects
|
||||||
size--;
|
s--;
|
||||||
downHeap(1); // adjust heap
|
size = s;
|
||||||
|
downHeap(1, heap, s); // adjust heap
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -225,7 +232,8 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
* @return the new 'top' element.
|
* @return the new 'top' element.
|
||||||
*/
|
*/
|
||||||
public final T updateTop() {
|
public final T updateTop() {
|
||||||
downHeap(1);
|
var heap = this.heap;
|
||||||
|
downHeap(1, heap, size);
|
||||||
return heap[1];
|
return heap[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +250,8 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
|
|
||||||
/** Removes all entries from the PriorityQueue. */
|
/** Removes all entries from the PriorityQueue. */
|
||||||
public final void clear() {
|
public final void clear() {
|
||||||
for (int i = 0; i <= size; i++) {
|
var heap = this.heap;
|
||||||
|
for (int i = 0, to = size; i <= to; i++) {
|
||||||
heap[i] = null;
|
heap[i] = null;
|
||||||
}
|
}
|
||||||
size = 0;
|
size = 0;
|
||||||
|
@ -254,14 +263,15 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
* constant remove time but the trade-off would be extra cost to all additions/insertions)
|
* constant remove time but the trade-off would be extra cost to all additions/insertions)
|
||||||
*/
|
*/
|
||||||
public final boolean remove(T element) {
|
public final boolean remove(T element) {
|
||||||
for (int i = 1; i <= size; i++) {
|
var heap = this.heap;
|
||||||
|
for (int i = 1, to = size; i <= to; i++) {
|
||||||
if (heap[i] == element) {
|
if (heap[i] == element) {
|
||||||
heap[i] = heap[size];
|
heap[i] = heap[size];
|
||||||
heap[size] = null; // permit GC of objects
|
heap[size] = null; // permit GC of objects
|
||||||
size--;
|
size--;
|
||||||
if (i <= size) {
|
if (i <= size) {
|
||||||
if (!upHeap(i)) {
|
if (!upHeap(i, heap)) {
|
||||||
downHeap(i);
|
downHeap(i, heap, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -270,7 +280,7 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean upHeap(int origPos) {
|
private boolean upHeap(int origPos, T[] heap) {
|
||||||
int i = origPos;
|
int i = origPos;
|
||||||
T node = heap[i]; // save bottom node
|
T node = heap[i]; // save bottom node
|
||||||
int j = i >>> 1;
|
int j = i >>> 1;
|
||||||
|
@ -283,7 +293,7 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
return i != origPos;
|
return i != origPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void downHeap(int i) {
|
private void downHeap(int i, T[] heap, int size) {
|
||||||
T node = heap[i]; // save top node
|
T node = heap[i]; // save top node
|
||||||
int j = i << 1; // find smaller child
|
int j = i << 1; // find smaller child
|
||||||
int k = j + 1;
|
int k = j + 1;
|
||||||
|
@ -313,7 +323,7 @@ public abstract class PriorityQueue<T> implements Iterable<T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
return new Iterator<T>() {
|
return new Iterator<>() {
|
||||||
|
|
||||||
int i = 1;
|
int i = 1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue