public class TestCompactHilbert {
private CompactHilbertCurve sfc; //space filling curve
private final int DIM;
private final int DEPTH;// = 64;
private TestCompactHilbert(int DIM, int DEPTH) {
this.DIM = DIM;
this.DEPTH = DEPTH;
}
private long toSortableLong(double value) {
//To create a sortable long, we convert the double to a long using the IEEE-754 standard,
//which stores floats in the form <sign><exponent-127><mantissa> .
//This result is properly ordered longs for all positive doubles. Negative values have
//inverse ordering. For negative doubles, we therefore simply invert them to make them
//sortable, however the sign must be inverted again to stay negative.
long r = Double.doubleToRawLongBits(value);
return (r >= 0) ? r : r ^ 0x7FFFFFFFFFFFFFFFL;
}
private BigInteger[][] generateRanges(double[] min, double[] max) {
BigInteger[][] ranges = new BigInteger[DIM][2];
for (int j = 0; j < DIM; ++j) {
ranges[j][0] = BigInteger.valueOf(toSortableLong(min[j]));
ranges[j][1] = BigInteger.valueOf(toSortableLong(max[j]));
}
return ranges;
}
private void order2Query(double[] minD, double[] maxD) {
BigInteger[][] ranges = generateRanges(minD, maxD);
int maxRanges = 1;
queryAndFilterBI(sfc, ranges, maxRanges, null);
}
public static void main(String[] args) {
int DIM = 2;
TestCompactHilbert x = new TestCompactHilbert(DIM, 64);
x.run();
}
private void run() {
int[] dd = new int[DIM];
Arrays.fill(dd, DEPTH);
sfc = new CompactHilbertCurve(new int[]{DEPTH, DEPTH});
//range queries
double[] qDLow = new double[]{0.01, 0.01};
double[] qDUpp = new double[]{0.011, 0.011};
System.out.println("Waiting...");
order2Query(qDLow, qDUpp);
System.out.println("Done!");
}
private static final Logger logger = Logger.getLogger(TestCompactHilbert.class.getSimpleName());
private void queryAndFilterBI(
SpaceFillingCurve sfc, BigInteger[][] ranges,
int maxRanges, Map<Pow2LengthBitSetRange, NodeValue<BigIntegerContent>> rolledupMap) {
List<BigIntegerRange> region = rangesToQueryRegionBI(ranges);
List<FilteredIndexRange<Object, BigIntegerRange>> indexRanges = queryBI(
region, sfc, maxRanges, rolledupMap);
Assert.assertTrue(indexRanges.size() <= maxRanges);
logger.log(Level.INFO, "indexRanges={0}", indexRanges);
}
private List<FilteredIndexRange<Object, BigIntegerRange>> queryBI(
List<BigIntegerRange> region, SpaceFillingCurve sfc, int maxRanges,
Map<Pow2LengthBitSetRange, NodeValue<BigIntegerContent>> rolledupMap) {
List<? extends List<BigIntegerRange>> x = ImmutableList.of(region);
BigIntegerContent zero = new BigIntegerContent(BigInteger.ZERO);
Object filter = "";
BigIntegerContent one = new BigIntegerContent(BigInteger.ONE);
RegionInspector<Object, BigIntegerContent> simpleRegionInspector =
SimpleRegionInspector.create(
x, one, Functions.constant(filter), BigIntegerRangeHome.INSTANCE, zero);
final RegionInspector<Object, BigIntegerContent> regionInspector;
if (rolledupMap == null) {
regionInspector = simpleRegionInspector;
} else {
regionInspector = MapRegionInspector.create(
rolledupMap, simpleRegionInspector, false, zero, one);
}
// Not using using sub-ranges here.
PlainFilterCombiner<Object, BigInteger, BigIntegerContent, BigIntegerRange> combiner =
new PlainFilterCombiner<>(filter);
QueryBuilder<Object, BigIntegerRange> queryBuilder = BacktrackingQueryBuilder.create(
regionInspector, combiner, maxRanges, true, BigIntegerRangeHome.INSTANCE, zero);
sfc.accept(new ZoomingSpaceVisitorAdapter(sfc, queryBuilder));
Query<Object, BigIntegerRange> query = queryBuilder.get();
return query.getFilteredIndexRanges();
}
private static List<BigIntegerRange> rangesToQueryRegionBI(BigInteger[][] ranges) {
List<BigIntegerRange> region = new ArrayList<>();
for (int j = 0; j < ranges.length; ++j) {
region.add(BigIntegerRange.of(ranges[j][0], ranges[j][1]));
}
return region;
}
}