package org.davidmoten.hilbert;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.infra.Blackhole;

public class Benchmarks {

    private static final int BITS = 10;
    private static final long N = 1L << BITS - 1;
    private static final int DIMENSIONS = 5;
    private static final HilbertCurve c = HilbertCurve.bits(BITS).dimensions(DIMENSIONS);
    private static final SmallHilbertCurve small = HilbertCurve.small().bits(BITS)
            .dimensions(DIMENSIONS);
    private static final long[] point = new long[DIMENSIONS];
    private static final List<long[]> points = createPoints();

//    @Benchmark
    public void roundTripTimes512(Blackhole b) {
        for (long i = 0; i < N; i++) {
            long[] point = c.point(i);
            b.consume(c.index(point).longValue());
        }
    }

//    @Benchmark
    public void toIndexTimes512(Blackhole b) {
        for (int i = 0; i < N; i++) {
            b.consume(c.index(points.get(i)).longValue());
        }
    }

//    @Benchmark
    public void toIndexTimes512Small(Blackhole b) {
        for (int i = 0; i < N; i++) {
            b.consume(small.index(points.get(i)));
        }
    }

//    @Benchmark
    public void pointTimes512(Blackhole b) {
        for (long i = 0; i < N; i++) {
            b.consume(c.point(i));
        }
    }

//    @Benchmark
    public void roundTripSmallTimes512(Blackhole b) {
        for (long i = 0; i < N; i++) {
            long[] point = small.point(i);
            b.consume(small.index(point));
        }
    }

//    @Benchmark
    public void pointSmallTimes512(Blackhole b) {
        for (long i = 0; i < N; i++) {
            b.consume(small.point(i));
        }
    }

//    @Benchmark
    public void roundTripTimes512LowAllocation(Blackhole b) {
        for (long i = 0; i < N; i++) {
            c.point(i, point);
            b.consume(c.index(point).longValue());
        }
    }

//    @Benchmark
    public void pointTimes512LowAllocation(Blackhole b) {
        for (long i = 0; i < N; i++) {
            c.point(i, point);
            b.consume(point);
        }
    }

//    @Benchmark
    public void roundTripSmallTimes512LowAllocation(Blackhole b) {
        for (long i = 0; i < N; i++) {
            small.point(i, point);
            b.consume(small.index(point));
        }
    }

//    @Benchmark
    public void pointSmallTimes512LowAllocation(Blackhole b) {
        for (long i = 0; i < N; i++) {
            small.point(i, point);
            b.consume(point);
        }
    }

    private static final Query query = new Query();

    @Benchmark
    public Ranges querySydney() {
        return query.query();
    }

    private static final class Query {
        float lat1 = -33.806477f;
        float lon1 = 151.181767f;
        long minTime = 1510779675000L;
        long maxTime = 1510876800000L;
        long t1 = minTime + (maxTime - minTime) / 2;
        float lat2 = -33.882896f;
        float lon2 = 151.281330f;
        long t2 = t1 + TimeUnit.HOURS.toMillis(1);
        int bits = 10;
        int dimensions = 3;
        SmallHilbertCurve h = HilbertCurve.small().bits(bits).dimensions(dimensions);
        long maxOrdinates = 1L << bits;
        long[] point1 = GeoUtil.scalePoint(lat1, lon1, t1, minTime, maxTime, maxOrdinates);
        long[] point2 = GeoUtil.scalePoint(lat2, lon2, t2, minTime, maxTime, maxOrdinates);

        Ranges query() {
            return h.query(point1, point2);
        }
    }

    private static List<long[]> createPoints() {
        List<long[]> list = new ArrayList<>((int) N);
        for (long i = 0; i < N; i++) {
            list.add(c.point(i));
        }
        return list;
    }
}
@@ -701,18 +701,16 @@
 nts();%0A%0A
-//
     @Ben
@@ -708,32 +708,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -903,34 +903,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -918,32 +918,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -1079,34 +1079,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -1094,32 +1094,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -1252,34 +1252,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -1267,32 +1267,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -1403,34 +1403,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -1418,32 +1418,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -1614,34 +1614,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -1629,32 +1629,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -1774,34 +1774,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -1789,32 +1789,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -1989,34 +1989,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -2004,32 +2004,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -2179,34 +2179,32 @@
        %7D%0A    %7D%0A%0A
-//
     @Benchmark%0A 
@@ -2194,32 +2194,32 @@
 %0A    @Benchmark%0A
+
     public void 
@@ -2407,10 +2407,8 @@
  %7D%0A%0A
-//
     

revert benchmarks