package edu.brown.costmodel; import java.util.Random; import edu.brown.BaseTestCase; import edu.brown.rand.RandomDistribution; import edu.brown.statistics.Histogram; import edu.brown.statistics.ObjectHistogram; /** * @author pavlo */ public class TestSkewFactorUtil extends BaseTestCase { private static final int NUM_PARTITIONS = 300; private static final int QUERIES_PER_PARTITION = 1000; private final Random rand = new Random(100); /** * testPartitionCounts */ public void testPartitionCounts() throws Exception { // Simple check to make sure varying numbers of partitions with slight randomness // always works and gives us expected results for (int num_partitions = 2; num_partitions < NUM_PARTITIONS; num_partitions++) { Histogram<Integer> h = new ObjectHistogram<Integer>(); for (int i = 0; i < num_partitions; i++) { int count = 1000 + (rand.nextInt(20) - 10); // +/- 10 h.put(i, count); } // FOR // Just check that it's slightly higher than the best skew value double skew = SkewFactorUtil.calculateSkew(num_partitions, h.getSampleCount(), h); // System.err.println(String.format("[%03d] %.05f", num_partitions, skew)); // System.err.println(h); assert(skew < 0.1) : "Invalid skew value " + skew; assert(skew > 0.0) : "Invalid skew value " + skew; } } /** * testSanityCheck */ public void testSanityCheck() throws Exception { // Add a bunch of partitions and then make sure that making one of the partitions zero // and making one of the partitions having an ass load both have worst cost Histogram<Integer> h = new ObjectHistogram<Integer>(); for (int i = 0; i < NUM_PARTITIONS; i++) { h.put(i, QUERIES_PER_PARTITION); } double base_skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, h.getSampleCount(), h); h.dec(0, QUERIES_PER_PARTITION); double skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, h.getSampleCount(), h); assert(base_skew < skew) : "Invalid skew value " + skew; h.put(0, QUERIES_PER_PARTITION * 3); skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, h.getSampleCount(), h); assert(base_skew < skew) : "Invalid skew value " + skew; } /** * testAlternating */ public void testAlternating() throws Exception { Histogram<Integer> h = new ObjectHistogram<Integer>(); int delta = (int)Math.round(QUERIES_PER_PARTITION * 0.50); for (int i = 0; i < NUM_PARTITIONS; i++) { int count = QUERIES_PER_PARTITION + (i % 2 == 0 ? -delta : delta); h.put(i, count); } // System.err.println(h); double expected = 0.40d; double skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, h.getSampleCount(), h); // System.err.println("skew = " + skew); assert(skew < 1.0) : "Invalid skew value " + skew; assert(skew >= expected) : "Invalid skew value " + skew; } /** * testCalculateSkewZipf */ public void testCalculateSkewZipf() throws Exception { int rounds = 5; Double last = null; double sigma = 1.0000001d; // For each round, increase the sigma value. We are checking that our skew value // gets worse as the distribution of the histogram gets more skewed while (--rounds > 0) { Histogram<Integer> h = new ObjectHistogram<Integer>(); RandomDistribution.Zipf zipf = new RandomDistribution.Zipf(this.rand, 0, NUM_PARTITIONS, sigma); for (int i = 0, cnt = (NUM_PARTITIONS * QUERIES_PER_PARTITION); i < cnt; i++) { h.put(zipf.nextInt()); } // FOR double skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, h.getSampleCount(), h); assert(skew >= 0.0) : "Invalid skew value " + skew; assert(skew <= 1.0) : "Invalid skew value " + skew; if (last != null) assert(last < skew) : last + " < " + skew; last = skew; sigma += 1d; // System.err.println(h); // System.err.println("[" + sigma + "] skew: " + skew); // System.err.println("-------------------------------------"); } // WHILE } /** * testCalculateSkewBest */ public void testCalculateSkewBest() throws Exception { Histogram<Integer> h = new ObjectHistogram<Integer>(); int num_queries = NUM_PARTITIONS * QUERIES_PER_PARTITION; for (int partition = 0; partition < NUM_PARTITIONS; partition++) { h.put(partition, QUERIES_PER_PARTITION); } // FOR double skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, num_queries, h); assertEquals("Invalid skew value " + skew, 0.0, skew); } /** * testCalculateSkewWorst */ public void testCalculateSkewWorst() throws Exception { Histogram<Integer> h = new ObjectHistogram<Integer>(); int num_queries = QUERIES_PER_PARTITION; for (int partition = 0; partition < NUM_PARTITIONS; partition++) { h.put(partition, (partition == 0 ? QUERIES_PER_PARTITION : 0)); } // FOR double skew = SkewFactorUtil.calculateSkew(NUM_PARTITIONS, num_queries, h); assertEquals("Invalid skew value " + skew, 1.0, skew, 0.000001); } }