blob: 9f2e3ba93b1c44f74c38cc28024ca5cb127e044a [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.lucene.util;
import static org.apache.lucene.util.LongHeap.Order.MAX;
import static org.apache.lucene.util.LongHeap.Order.MIN;
import java.util.ArrayList;
import java.util.Random;
public class TestLongHeap extends LuceneTestCase {
private static class AssertingLongHeap extends LongHeap {
AssertingLongHeap(int count) {
super(count);
}
@Override
public boolean lessThan(long a, long b) {
return (a < b);
}
final void checkValidity() {
long[] heapArray = getHeapArray();
for (int i = 1; i <= size(); i++) {
int parent = i >>> 1;
if (parent > 1) {
if (lessThan(heapArray[parent], heapArray[i]) == false) {
assertEquals(heapArray[parent], heapArray[i]);
}
}
}
}
}
public void testPQ() {
testPQ(atLeast(10000), random());
}
public static void testPQ(int count, Random gen) {
LongHeap pq = LongHeap.create(MIN, count);
long sum = 0, sum2 = 0;
for (int i = 0; i < count; i++) {
long next = gen.nextLong();
sum += next;
pq.push(next);
}
long last = Long.MIN_VALUE;
for (long i = 0; i < count; i++) {
long next = pq.pop();
assertTrue(next >= last);
last = next;
sum2 += last;
}
assertEquals(sum, sum2);
}
public void testClear() {
LongHeap pq = LongHeap.create(MIN, 3);
pq.push(2);
pq.push(3);
pq.push(1);
assertEquals(3, pq.size());
pq.clear();
assertEquals(0, pq.size());
}
public void testExceedBounds() {
LongHeap pq = LongHeap.create(MIN, 1);
pq.push(2);
pq.push(0);
// expectThrows(ArrayIndexOutOfBoundsException.class, () -> pq.push(0));
assertEquals(2, pq.size()); // the heap has been extended to a new max size
assertEquals(0, pq.top());
}
public void testFixedSize() {
LongHeap pq = LongHeap.create(MIN, 3);
pq.insertWithOverflow(2);
pq.insertWithOverflow(3);
pq.insertWithOverflow(1);
pq.insertWithOverflow(5);
pq.insertWithOverflow(7);
pq.insertWithOverflow(1);
assertEquals(3, pq.size());
assertEquals(3, pq.top());
}
public void testFixedSizeMax() {
LongHeap pq = LongHeap.create(MAX, 3);
pq.insertWithOverflow(2);
pq.insertWithOverflow(3);
pq.insertWithOverflow(1);
pq.insertWithOverflow(5);
pq.insertWithOverflow(7);
pq.insertWithOverflow(1);
assertEquals(3, pq.size());
assertEquals(2, pq.top());
}
public void testDuplicateValues() {
LongHeap pq = LongHeap.create(MIN, 3);
pq.push(2);
pq.push(3);
pq.push(1);
assertEquals(1, pq.top());
pq.updateTop(3);
assertEquals(3, pq.size());
assertArrayEquals(new long[] {0, 2, 3, 3}, pq.getHeapArray());
}
public void testInsertions() {
Random random = random();
int numDocsInPQ = TestUtil.nextInt(random, 1, 100);
AssertingLongHeap pq = new AssertingLongHeap(numDocsInPQ);
Long lastLeast = null;
// Basic insertion of new content
ArrayList<Long> sds = new ArrayList<Long>(numDocsInPQ);
for (int i = 0; i < numDocsInPQ * 10; i++) {
long newEntry = Math.abs(random.nextLong());
sds.add(newEntry);
pq.insertWithOverflow(newEntry);
pq.checkValidity();
long newLeast = pq.top();
if ((lastLeast != null) && (newLeast != newEntry) && (newLeast != lastLeast)) {
// If there has been a change of least entry and it wasn't our new
// addition we expect the scores to increase
assertTrue(newLeast <= newEntry);
assertTrue(newLeast >= lastLeast);
}
lastLeast = newLeast;
}
}
public void testInvalid() {
expectThrows(IllegalArgumentException.class, () -> LongHeap.create(MAX, -1));
expectThrows(IllegalArgumentException.class, () -> LongHeap.create(MAX, 0));
expectThrows(
IllegalArgumentException.class, () -> LongHeap.create(MAX, ArrayUtil.MAX_ARRAY_LENGTH));
}
public void testUnbounded() {
int initialSize = random().nextInt(10) + 1;
LongHeap pq = LongHeap.create(MAX, initialSize);
int num = random().nextInt(100) + 1;
long minValue = Long.MAX_VALUE;
int count = 0;
for (int i = 0; i < num; i++) {
long value = random().nextLong();
if (random().nextBoolean()) {
pq.push(value);
count++;
} else {
boolean full = pq.size() >= initialSize;
if (pq.insertWithOverflow(value)) {
if (full == false) {
count++;
}
}
}
minValue = Math.min(minValue, value);
}
assertEquals(count, pq.size());
long last = Long.MAX_VALUE;
while (pq.size() > 0) {
long top = pq.top();
long next = pq.pop();
assertEquals(top, next);
--count;
assertTrue(next <= last);
last = next;
}
assertEquals(0, count);
assertEquals(minValue, last);
}
}