package org.graalvm.compiler.jtt.optimize;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import org.graalvm.compiler.jtt.JTTTest;
import org.graalvm.compiler.lir.hashing.HashFunction;
import org.graalvm.compiler.lir.hashing.Hasher;
import org.junit.Test;
import jdk.vm.ci.meta.JavaConstant;
public class SwitchHashTableTest extends JTTTest {
@Test
public void checkHashFunctionInstances() {
List<String> coveredByTestCases = Arrays.asList("val >> min", "val", "val >> (val & min)", "(val >> min) ^ val", "val - min", "rotateRight(val, prime)", "rotateRight(val, prime) ^ val",
"rotateRight(val, prime) + val", "(val >> min) * val", "(val * prime) >> min");
Set<String> functions = HashFunction.instances().stream().map(Object::toString).collect(Collectors.toSet());
functions.removeAll(coveredByTestCases);
assertTrue("The following hash functions are not covered by the `Switch03` test: " + functions +
". Re-run the `Switch03.TestGenerator.main` and update the test class.", functions.isEmpty());
}
public static int test1(int arg) {
switch (arg) {
case 3080012:
return 3080012;
case 3080017:
return 3080017;
case 3080029:
return 3080029;
case 3080037:
return 3080037;
case 3080040:
return 3080040;
case 3080054:
return 3080054;
case 3080060:
return 3080060;
case 3080065:
return 3080065;
case 3080073:
return 3080073;
case 3080082:
return 3080082;
case 3080095:
return 3080095;
case 3080103:
return 3080103;
case 3080116:
return 3080116;
case 3080127:
return 3080127;
case 3080130:
return 3080130;
default:
return -1;
}
}
@Test
public void run1() throws Throwable {
runTest("test1", 0);
runTest("test1", 3080011);
runTest("test1", 3080012);
runTest("test1", 3080065);
runTest("test1", 3080130);
runTest("test1", 3080131);
runTest("test1", 3080013);
}
public static int test2(int arg) {
switch (arg) {
case 718707335:
return 718707335;
case 718707336:
return 718707336;
case 718707347:
return 718707347;
case 718707359:
return 718707359;
case 718707366:
return 718707366;
case 718707375:
return 718707375;
case 718707378:
return 718707378;
case 718707386:
return 718707386;
case 718707396:
return 718707396;
case 718707401:
return 718707401;
case 718707408:
return 718707408;
case 718707409:
return 718707409;
case 718707420:
return 718707420;
case 718707431:
return 718707431;
case 718707436:
return 718707436;
default:
return -1;
}
}
@Test
public void run2() throws Throwable {
runTest("test2", 0);
runTest("test2", 718707334);
runTest("test2", 718707335);
runTest("test2", 718707386);
runTest("test2", 718707436);
runTest("test2", 718707437);
runTest("test2", 718707337);
}
public static int test3(int arg) {
switch (arg) {
case 880488712:
return 880488712;
case 880488723:
return 880488723;
case 880488737:
return 880488737;
case 880488744:
return 880488744;
case 880488752:
return 880488752;
case 880488757:
return 880488757;
case 880488767:
return 880488767;
case 880488777:
return 880488777;
case 880488781:
return 880488781;
case 880488794:
return 880488794;
case 880488795:
return 880488795;
case 880488807:
return 880488807;
case 880488814:
return 880488814;
case 880488821:
return 880488821;
case 880488831:
return 880488831;
default:
return -1;
}
}
@Test
public void run3() throws Throwable {
runTest("test3", 0);
runTest("test3", 880488711);
runTest("test3", 880488712);
runTest("test3", 880488777);
runTest("test3", 880488831);
runTest("test3", 880488832);
runTest("test3", 880488713);
}
public static int test4(int arg) {
switch (arg) {
case 189404658:
return 189404658;
case 189404671:
return 189404671;
case 189404678:
return 189404678;
case 189404680:
return 189404680;
case 189404687:
return 189404687;
case 189404698:
return 189404698;
case 189404699:
return 189404699;
case 189404711:
return 189404711;
case 189404724:
return 189404724;
case 189404725:
return 189404725;
case 189404732:
return 189404732;
case 189404739:
return 189404739;
case 189404748:
return 189404748;
case 189404754:
return 189404754;
case 189404765:
return 189404765;
default:
return -1;
}
}
@Test
public void run4() throws Throwable {
runTest("test4", 0);
runTest("test4", 189404657);
runTest("test4", 189404658);
runTest("test4", 189404711);
runTest("test4", 189404765);
runTest("test4", 189404766);
runTest("test4", 189404659);
}
public static int test5(int arg) {
switch (arg) {
case 527674226:
return 527674226;
case 527674235:
return 527674235;
case 527674236:
return 527674236;
case 527674247:
return 527674247;
case 527674251:
return 527674251;
case 527674253:
return 527674253;
case 527674257:
return 527674257;
case 527674263:
return 527674263;
case 527674265:
return 527674265;
case 527674272:
return 527674272;
case 527674286:
return 527674286;
case 527674293:
return 527674293;
case 527674294:
return 527674294;
case 527674306:
return 527674306;
case 527674308:
return 527674308;
default:
return -1;
}
}
@Test
public void run5() throws Throwable {
runTest("test5", 0);
runTest("test5", 527674225);
runTest("test5", 527674226);
runTest("test5", 527674263);
runTest("test5", 527674308);
runTest("test5", 527674309);
runTest("test5", 527674227);
}
public static int test6(int arg) {
switch (arg) {
case 676979121:
return 676979121;
case 676979128:
return 676979128;
case 676979135:
return 676979135;
case 676979146:
return 676979146;
case 676979148:
return 676979148;
case 676979156:
return 676979156;
case 676979158:
return 676979158;
case 676979169:
return 676979169;
case 676979175:
return 676979175;
case 676979179:
return 676979179;
case 676979182:
return 676979182;
case 676979194:
return 676979194;
case 676979200:
return 676979200;
case 676979205:
return 676979205;
case 676979219:
return 676979219;
default:
return -1;
}
}
@Test
public void run6() throws Throwable {
runTest("test6", 0);
runTest("test6", 676979120);
runTest("test6", 676979121);
runTest("test6", 676979169);
runTest("test6", 676979219);
runTest("test6", 676979220);
runTest("test6", 676979122);
}
public static int test7(int arg) {
switch (arg) {
case 634218696:
return 634218696;
case 634218710:
return 634218710;
case 634218715:
return 634218715;
case 634218720:
return 634218720;
case 634218724:
return 634218724;
case 634218732:
return 634218732;
case 634218737:
return 634218737;
case 634218749:
return 634218749;
case 634218751:
return 634218751;
case 634218758:
return 634218758;
case 634218767:
return 634218767;
case 634218772:
return 634218772;
case 634218786:
return 634218786;
case 634218792:
return 634218792;
case 634218795:
return 634218795;
default:
return -1;
}
}
@Test
public void run7() throws Throwable {
runTest("test7", 0);
runTest("test7", 634218695);
runTest("test7", 634218696);
runTest("test7", 634218749);
runTest("test7", 634218795);
runTest("test7", 634218796);
runTest("test7", 634218697);
}
public static int test8(int arg) {
switch (arg) {
case 473982403:
return 473982403;
case 473982413:
return 473982413;
case 473982416:
return 473982416;
case 473982425:
return 473982425;
case 473982439:
return 473982439;
case 473982445:
return 473982445;
case 473982459:
return 473982459;
case 473982468:
return 473982468;
case 473982479:
return 473982479;
case 473982482:
return 473982482;
case 473982494:
return 473982494;
case 473982501:
return 473982501;
case 473982505:
return 473982505;
case 473982519:
return 473982519;
case 473982523:
return 473982523;
default:
return -1;
}
}
@Test
public void run8() throws Throwable {
runTest("test8", 0);
runTest("test8", 473982402);
runTest("test8", 473982403);
runTest("test8", 473982468);
runTest("test8", 473982523);
runTest("test8", 473982524);
runTest("test8", 473982404);
}
public static int test9(int arg) {
switch (arg) {
case 15745090:
return 15745090;
case 15745093:
return 15745093;
case 15745102:
return 15745102;
case 15745108:
return 15745108;
case 15745122:
return 15745122;
case 15745131:
return 15745131;
case 15745132:
return 15745132;
case 15745146:
return 15745146;
case 15745151:
return 15745151;
case 15745163:
return 15745163;
case 15745169:
return 15745169;
case 15745182:
return 15745182;
case 15745191:
return 15745191;
case 15745198:
return 15745198;
case 15745207:
return 15745207;
default:
return -1;
}
}
@Test
public void run9() throws Throwable {
runTest("test9", 0);
runTest("test9", 15745089);
runTest("test9", 15745090);
runTest("test9", 15745146);
runTest("test9", 15745207);
runTest("test9", 15745208);
runTest("test9", 15745091);
}
public static int test10(int arg) {
switch (arg) {
case 989358996:
return 989358996;
case 989359010:
return 989359010;
case 989359022:
return 989359022;
case 989359030:
return 989359030;
case 989359038:
return 989359038;
case 989359047:
return 989359047;
case 989359053:
return 989359053;
case 989359059:
return 989359059;
case 989359061:
return 989359061;
case 989359072:
return 989359072;
case 989359073:
return 989359073;
case 989359087:
return 989359087;
case 989359097:
return 989359097;
case 989359099:
return 989359099;
case 989359108:
return 989359108;
default:
return -1;
}
}
@Test
public void run10() throws Throwable {
runTest("test10", 0);
runTest("test10", 989358995);
runTest("test10", 989358996);
runTest("test10", 989359059);
runTest("test10", 989359108);
runTest("test10", 989359109);
runTest("test10", 989358997);
}
public static class TestGenerator {
private static int nextId = 0;
private static final int size = 15;
private static double minDensity = 0.5;
public static void main(String[] args) {
Random r = new Random(0);
Set<String> seen = new HashSet<>();
Set<String> all = HashFunction.instances().stream().map(Object::toString).collect(Collectors.toSet());
println("@Test");
println("public void checkHashFunctionInstances() {");
println(" List<String> coveredByTestCases = Arrays.asList(" + String.join(", ", all.stream().map(s -> "\"" + s + "\"").collect(Collectors.toSet())) + ");");
println(" Set<String> functions = HashFunction.instances().stream().map(Object::toString).collect(Collectors.toSet());");
println(" functions.removeAll(coveredByTestCases);");
println(" assertTrue(\"The following hash functions are not covered by the `Switch03` test: \" + functions +");
println(" \". Re-run the `Switch03.TestGenerator.main` and update the test class.\", functions.isEmpty());");
println("}");
while (seen.size() < all.size()) {
int v = r.nextInt(Integer.MAX_VALUE / 2);
List<Integer> keys = new ArrayList<>();
while (keys.size() < 15) {
keys.add(v);
v += r.nextInt(15);
}
keys.sort(Integer::compare);
double density = ((double) keys.size() + 1) / (keys.get(keys.size() - 1) - keys.get(0));
if (density < minDensity) {
Hasher.forKeys(toConstants(keys), minDensity).ifPresent(h -> {
String f = h.function().toString();
if (!seen.contains(f)) {
gen(keys, h);
seen.add(f);
}
});
}
}
}
private static void gen(List<Integer> keys, Hasher hasher) {
int id = ++nextId;
println("// " + hasher + "");
println("public static int test" + id + "(int arg) {");
println(" switch (arg) {");
for (Integer key : keys) {
println(" case " + key + ": return " + key + ";");
}
println(" default: return -1;");
println(" }");
println("}");
int miss = keys.get(0) + 1;
while (keys.contains(miss)) {
miss++;
}
println("@Test");
println("public void run" + id + "() throws Throwable {");
println(" runTest(\"test" + id + "\", 0); // zero ");
println(" runTest(\"test" + id + "\", " + (keys.get(0) - 1) + "); // bellow ");
println(" runTest(\"test" + id + "\", " + keys.get(0) + "); // first ");
println(" runTest(\"test" + id + "\", " + keys.get(size / 2) + "); // middle ");
println(" runTest(\"test" + id + "\", " + keys.get(size - 1) + "); // last ");
println(" runTest(\"test" + id + "\", " + (keys.get(size - 1) + 1) + "); // above ");
println(" runTest(\"test" + id + "\", " + miss + "); // miss ");
println("}");
}
private static void println(String s) {
System.out.println(s);
}
private static JavaConstant[] toConstants(List<Integer> keys) {
JavaConstant[] ckeys = new JavaConstant[keys.size()];
for (int i = 0; i < keys.size(); i++) {
ckeys[i] = JavaConstant.forInt(keys.get(i));
}
return ckeys;
}
}
}