@Test
 public void testSampleRange() {
   Histogram h = new Histogram(40, 2);
   double base = 1;
   for (int i = 0; i < 40; i++) {
     //            System.out.println(i);
     assertEquals(i * 4 + 0, h.sample(base));
     assertEquals(i * 4 + 1, h.sample(base * 1.25));
     assertEquals(i * 4 + 2, h.sample(base * 1.5));
     assertEquals(i * 4 + 3, h.sample(base * 1.75));
     base *= 2;
   }
   //        System.out.println(base);
 }
 @Test
 public void testSamples() {
   Histogram h = new Histogram(7, 5);
   for (int i = 1; i <= 100; i++) h.sample(i);
   assertEquals(101, h.percentile(1), 0);
   assertEquals(95, h.percentile(0.95), 0);
   assertEquals(91, h.percentile(0.90), 0);
   assertEquals(85, h.percentile(0.85), 0);
   assertEquals(81, h.percentile(0.80), 0);
   assertEquals(71, h.percentile(0.71), 0);
   assertEquals(62, (long) h.percentile(0.62), 0);
   assertEquals(50, (long) h.percentile(0.50), 0);
   assertEquals(40, (long) h.percentile(0.40), 0);
   assertEquals(30, (long) h.percentile(0.30), 0);
 }
  @Test
  @Ignore("Long running")
  public void testManySamples() throws IOException {
    //        try (FileOutputStream cpu_dma_latency = new FileOutputStream("/dev/cpu_dma_latency"))
    // {
    //            cpu_dma_latency.write('0');

    Affinity.setAffinity(2);
    System.out.println("Cpu: " + Affinity.getAffinity());
    ITicker instance = Ticker.INSTANCE;
    for (int t = 0; t < 5; t++) {
      Histogram h = new Histogram(32, 4);
      long start = instance.ticks(), prev = start;
      for (int i = 0; i <= 1000_000_000; i++) {
        long now = instance.ticks();
        long time = now - prev;
        h.sample(time);
        prev = now;
      }
      System.out.println(h.toLongMicrosFormat(instance::toMicros));
    }
    //        }
  }
  // TODO test passes but is under development.
  public static void main(String... ignored) throws IOException {
    AffinityLock lock = AffinityLock.acquireCore();
    File file = File.createTempFile("testCHMLatency", "deleteme");
    //        File file = new File("testCHMLatency.deleteme");
    file.delete();
    ChronicleMap<LongValue, LongValue> countersMap =
        ChronicleMapBuilder.of(LongValue.class, LongValue.class)
            .entries(KEYS)
            .createPersistedTo(file);

    // add keys
    LongValue key = Values.newHeapInstance(LongValue.class);
    LongValue value = Values.newNativeReference(LongValue.class);
    for (long i = 0; i < KEYS; i++) {
      key.setValue(i);
      countersMap.acquireUsing(key, value);
      value.setValue(0);
    }
    System.out.println("Keys created");
    //        Monitor monitor = new Monitor();
    LongValue value2 = Values.newNativeReference(LongValue.class);
    for (int t = 0; t < 5; t++) {
      for (int rate :
          new int[] {
            2 * 1000 * 1000, 1000 * 1000, 500 * 1000 /*, 250 * 1000, 100 * 1000, 50 * 1000*/
          }) {
        Histogram times = new Histogram();
        int u = 0;
        long start = System.nanoTime();
        long delay = 1000 * 1000 * 1000L / rate;
        long next = start + delay;
        for (long j = 0; j < RUN_TIME * rate; j += KEYS) {
          int stride = Math.max(1, KEYS / (RUN_TIME * rate));
          // the timed part
          for (int i = 0; i < KEYS && u < RUN_TIME * rate; i += stride) {
            // busy wait for next time.
            while (System.nanoTime() < next - 12) ;
            //                        monitor.sample = System.nanoTime();
            long start0 = next;

            // start the update.
            key.setValue(i);
            LongValue using = countersMap.getUsing(key, value2);
            if (using == null) assertNotNull(using);
            value2.addAtomicValue(1);

            // calculate the time using the time it should have started, not when it was able.
            long elapse = System.nanoTime() - start0;
            times.sample(elapse);
            next += delay;
          }
          //                    monitor.sample = Long.MAX_VALUE;
        }
        System.out.printf("run %d %,9d : ", t, rate);
        times.printPercentiles(" micro-seconds.");
      }
      System.out.println();
    }
    //        monitor.running = false;
    countersMap.close();
    file.delete();
  }