blob: e21f81703c308cb9eb37152034ab2934745ec518 [file] [log] [blame]
/*
* Copyright (C) 2014 The Guava Authors
*
* Licensed 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 com.google.common.collect;
import static com.google.common.truth.Truth.assertThat;
import com.google.common.math.IntMath;
import com.google.common.primitives.Ints;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import junit.framework.TestCase;
/**
* Tests for {@code TopKSelector}.
*
* @author Louis Wasserman
*/
public class TopKSelectorTest extends TestCase {
public void testNegativeK() {
try {
TopKSelector.least(-1);
fail();
} catch (IllegalArgumentException expected) {
}
try {
TopKSelector.greatest(-1);
fail();
} catch (IllegalArgumentException expected) {
}
try {
TopKSelector.least(-1, Ordering.natural());
fail();
} catch (IllegalArgumentException expected) {
}
try {
TopKSelector.greatest(-1, Ordering.natural());
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testZeroK() {
TopKSelector<Integer> top = TopKSelector.least(0);
for (int i = 0; i < 10; i++) {
top.offer(i);
}
assertThat(top.topK()).isEmpty();
}
public void testNoElementsOffered() {
TopKSelector<Integer> top = TopKSelector.least(10);
assertThat(top.topK()).isEmpty();
}
public void testOfferedFewerThanK() {
TopKSelector<Integer> top = TopKSelector.least(10);
top.offer(3);
top.offer(5);
top.offer(2);
assertThat(top.topK()).containsExactly(2, 3, 5).inOrder();
}
public void testOfferedKPlusOne() {
for (List<Integer> list : Collections2.permutations(Ints.asList(1, 2, 3, 4, 5))) {
TopKSelector<Integer> top = TopKSelector.least(4);
top.offerAll(list);
assertThat(top.topK()).containsExactly(1, 2, 3, 4).inOrder();
}
}
public void testOfferedThreeK() {
for (List<Integer> list : Collections2.permutations(Ints.asList(1, 2, 3, 4, 5, 6))) {
TopKSelector<Integer> top = TopKSelector.least(2);
top.offerAll(list);
assertThat(top.topK()).containsExactly(1, 2).inOrder();
}
}
public void testDifferentComparator() {
TopKSelector<String> top = TopKSelector.least(3, String.CASE_INSENSITIVE_ORDER);
top.offerAll(ImmutableList.of("a", "B", "c", "D", "e", "F"));
assertThat(top.topK()).containsExactly("a", "B", "c").inOrder();
}
public void testWorstCase() {
int n = 2000000;
int k = 200000;
final long[] compareCalls = {0};
Comparator<Integer> cmp =
new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
compareCalls[0]++;
return o1.compareTo(o2);
}
};
TopKSelector<Integer> top = TopKSelector.least(k, cmp);
top.offer(1);
for (int i = 1; i < n; i++) {
top.offer(0);
}
assertThat(top.topK()).containsExactlyElementsIn(Collections.nCopies(k, 0));
assertThat(compareCalls[0]).isAtMost(10L * n * IntMath.log2(k, RoundingMode.CEILING));
}
}