private static boolean queryRangeDimensionsMatch( final int indexDimensions, final List<MultiDimensionalNumericData> queryRanges) { for (final MultiDimensionalNumericData qr : queryRanges) { if (qr.getDimensionCount() != indexDimensions) { return false; } } return true; } }
/** @return the number of total dimensions */ @Override public int getDimensionCount() { return indexRanges.getDimensionCount(); }
@Override public BigInteger getEstimatedIdCount(final MultiDimensionalNumericData data) { final double[] mins = data.getMinValuesPerDimension(); final double[] maxes = data.getMaxValuesPerDimension(); BigInteger estimatedIdCount = BigInteger.valueOf(1); for (int d = 0; d < data.getDimensionCount(); d++) { final double binMin = dimensionDefs[d].normalize(mins[d]) * binsPerDimension; final double binMax = dimensionDefs[d].normalize(maxes[d]) * binsPerDimension; estimatedIdCount = estimatedIdCount.multiply(BigInteger.valueOf((long) (Math.abs(binMax - binMin) + 1))); } return estimatedIdCount; }
@Override public BigInteger getEstimatedIdCount( final MultiDimensionalNumericData data, final SFCDimensionDefinition[] dimensionDefinitions) { final double[] mins = data.getMinValuesPerDimension(); final double[] maxes = data.getMaxValuesPerDimension(); BigInteger estimatedIdCount = BigInteger.valueOf(1); for (int d = 0; d < data.getDimensionCount(); d++) { final BigInteger binMin = normalizeDimension(dimensionDefinitions[d], mins[d], binsPerDimension[d], true, false); BigInteger binMax = normalizeDimension(dimensionDefinitions[d], maxes[d], binsPerDimension[d], false, false); if (binMin.compareTo(binMax) > 0) { // if they're both equal, which is possible because we treat max // as exclusive, set bin max to bin min (ie. treat it as // inclusive in this case) binMax = binMin; } estimatedIdCount = estimatedIdCount.multiply(binMax.subtract(binMin).abs().add(BigInteger.ONE)); } return estimatedIdCount; }
/** * {@inheritDoc} */ @Override public RangeDecomposition decomposeRange( final MultiDimensionalNumericData query, final boolean overInclusiveOnEdge, final int maxFilteredIndexedRanges) { // TODO: Because the research and benchmarking show Hilbert to // outperform Z-Order // the optimization of full query decomposition is not implemented at // the moment for Z-Order final double[] queryMins = query.getMinValuesPerDimension(); final double[] queryMaxes = query.getMaxValuesPerDimension(); final double[] normalizedMins = new double[query.getDimensionCount()]; final double[] normalizedMaxes = new double[query.getDimensionCount()]; for (int d = 0; d < query.getDimensionCount(); d++) { normalizedMins[d] = dimensionDefs[d].normalize(queryMins[d]); normalizedMaxes[d] = dimensionDefs[d].normalize(queryMaxes[d]); } final byte[] minZorder = ZOrderUtils.encode(normalizedMins, cardinalityPerDimension, query.getDimensionCount()); final byte[] maxZorder = ZOrderUtils.encode(normalizedMaxes, cardinalityPerDimension, query.getDimensionCount()); return new RangeDecomposition(new ByteArrayRange[] {new ByteArrayRange(minZorder, maxZorder)}); }
/** * The estimated ID count is the cross product of normalized range of all dimensions per the bits * of precision provided by the dimension definitions. */ @Override public BigInteger getEstimatedIdCount( final MultiDimensionalNumericData data, final SFCDimensionDefinition[] dimensionDefinitions) { final double[] mins = data.getMinValuesPerDimension(); final double[] maxes = data.getMaxValuesPerDimension(); long estimatedIdCount = 1L; for (int d = 0; d < data.getDimensionCount(); d++) { final long binMin = normalizeDimension(dimensionDefinitions[d], mins[d], binsPerDimension[d], true, false); long binMax = normalizeDimension(dimensionDefinitions[d], maxes[d], binsPerDimension[d], false, false); if (binMin > binMax) { // if they're both equal, which is possible because we treat max // as exclusive, set bin max to bin min (ie. treat it as // inclusive in this case) binMax = binMin; } estimatedIdCount *= (Math.abs(binMax - binMin) + 1); } return BigInteger.valueOf(estimatedIdCount); }
@Override public byte[] toBinary() { int byteBufferLength = VarintUtils.unsignedIntByteLength(compareOp.ordinal()); final int dimensions = Math.min(constraints.getDimensionCount(), dimensionFields.length); byteBufferLength += VarintUtils.unsignedIntByteLength(dimensions); final byte[][] lengthDimensionAndQueryBinaries = new byte[dimensions][]; final NumericData[] dataPerDimension = constraints.getDataPerDimension(); for (int d = 0; d < dimensions; d++) { final NumericDimensionField<?> dimension = dimensionFields[d]; final NumericData data = dataPerDimension[d]; final byte[] dimensionBinary = PersistenceUtils.toBinary(dimension); final int currentDimensionByteBufferLength = (16 + dimensionBinary.length + VarintUtils.unsignedIntByteLength(dimensionBinary.length)); final ByteBuffer buf = ByteBuffer.allocate(currentDimensionByteBufferLength); VarintUtils.writeUnsignedInt(dimensionBinary.length, buf); buf.putDouble(data.getMin()); buf.putDouble(data.getMax()); buf.put(dimensionBinary); byteBufferLength += currentDimensionByteBufferLength; lengthDimensionAndQueryBinaries[d] = buf.array(); } final ByteBuffer buf = ByteBuffer.allocate(byteBufferLength); VarintUtils.writeUnsignedInt(compareOp.ordinal(), buf); VarintUtils.writeUnsignedInt(dimensions, buf); for (final byte[] binary : lengthDimensionAndQueryBinaries) { buf.put(binary); } return buf.array(); }
final double[] tileRangePerDimension = new double[bounds.getDimensionCount()]; final double[] maxValuesPerDimension = bounds.getMaxValuesPerDimension(); final double[] minValuesPerDimension = bounds.getMinValuesPerDimension();
double totalMax = 0; for (final MultiDimensionalNumericData qr : queryRanges) { final double[] dataRangePerDimension = new double[qr.getDimensionCount()]; for (int d = 0; d < dataRangePerDimension.length; d++) { dataRangePerDimension[d] =
/** * Tool can be used custom index strategies to check if the tiles actual intersect with the * provided bounding box. * * @param boxRangeData * @param innerTile * @return */ private boolean checkCoverage( final MultiDimensionalNumericData boxRangeData, final MultiDimensionalNumericData innerTile) { for (int i = 0; i < boxRangeData.getDimensionCount(); i++) { final double i1 = innerTile.getDataPerDimension()[i].getMin(); final double i2 = innerTile.getDataPerDimension()[i].getMax(); final double j1 = boxRangeData.getDataPerDimension()[i].getMin(); final double j2 = boxRangeData.getDataPerDimension()[i].getMax(); final boolean overlaps = ((i1 < j2) || DoubleMath.fuzzyEquals(i1, j2, DOUBLE_TOLERANCE)) && ((i2 > j1) || DoubleMath.fuzzyEquals(i2, j1, DOUBLE_TOLERANCE)); if (!overlaps) { return false; } } return true; }
final double[] dataRangePerDimension = new double[qr.getDimensionCount()]; for (int d = 0; d < dataRangePerDimension.length; d++) { dataRangePerDimension[d] =