/** @return an array of min values associated with each dimension */ @Override public double[] getMinValuesPerDimension() { return indexRanges.getMinValuesPerDimension(); }
private static int getRanges(final MultiDimensionalNumericData indexedData) { final double[] mins = indexedData.getMinValuesPerDimension(); final double[] maxes = indexedData.getMaxValuesPerDimension(); int ranges = 0; for (int d = 0; d < mins.length; d++) { if (!FloatCompareUtils.checkDoublesEqual(mins[d], maxes[d])) { ranges++; } } return ranges; }
@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; }
/** * Returns all of the insertion ids for the range. Since this index strategy doensn't use binning, * it will return the ByteArrayId of every value in the range (i.e. if you are storing a range * using this index strategy, your data will be replicated for every integer value in the range). * * <p> {@inheritDoc} */ @Override public InsertionIds getInsertionIds( final MultiDimensionalNumericData indexedData, final int maxEstimatedDuplicateIds) { final long min = (long) indexedData.getMinValuesPerDimension()[0]; final long max = (long) Math.ceil(indexedData.getMaxValuesPerDimension()[0]); final List<byte[]> insertionIds = new ArrayList<>((int) (max - min) + 1); for (long i = min; i <= max; i++) { insertionIds.add(lexicoder.toByteArray(cast(i))); } return new InsertionIds(insertionIds); }
/** Returns an insertion id selected round-robin from a predefined pool */ @Override public byte[][] getInsertionPartitionKeys(final MultiDimensionalNumericData insertionData) { final long hashCode; if (insertionData.isEmpty()) { hashCode = insertionData.hashCode(); } else { hashCode = Math.abs( hashCode( insertionData.getMaxValuesPerDimension(), hashCode(insertionData.getMinValuesPerDimension(), 1))); } final int position = (int) (hashCode % keys.length); return new byte[][] {keys[position]}; }
final double[] queryMins = query.getMinValuesPerDimension(); final double[] queryMaxes = query.getMaxValuesPerDimension(); for (int i = 0; i < dimensionCount; i++) {
/** * 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); }
/** * {@inheritDoc} */ @Override public RangeDecomposition decomposeRange( final MultiDimensionalNumericData query, final boolean overInclusiveOnEdge, int maxFilteredIndexedRanges) { if (maxFilteredIndexedRanges == -1) { maxFilteredIndexedRanges = Integer.MAX_VALUE; } final QueryCacheKey key = new QueryCacheKey( query.getMinValuesPerDimension(), query.getMaxValuesPerDimension(), overInclusiveOnEdge, maxFilteredIndexedRanges); RangeDecomposition rangeDecomp = queryDecompositionCache.get(key); if (rangeDecomp == null) { rangeDecomp = decomposeQueryOperations.decomposeRange( query.getDataPerDimension(), compactHilbertCurve, dimensionDefinitions, totalPrecision, maxFilteredIndexedRanges, REMOVE_VACUUM, overInclusiveOnEdge); queryDecompositionCache.put(key, rangeDecomp); } return rangeDecomp; }
public static InsertionIds trimIndexIds( InsertionIds rawIds, Geometry geom, NumericIndexStrategy index) { for (final SinglePartitionInsertionIds insertionId : rawIds.getPartitionKeys()) { final byte[] partitionKey = insertionId.getPartitionKey(); final int size = insertionId.getSortKeys().size(); if (size > 3) { final Iterator<byte[]> it = insertionId.getSortKeys().iterator(); while (it.hasNext()) { final byte[] sortKey = it.next(); MultiDimensionalNumericData keyTile = index.getRangeForId(partitionKey, sortKey); Envelope other = new Envelope(); other.init( keyTile.getMinValuesPerDimension()[0], keyTile.getMaxValuesPerDimension()[0], keyTile.getMinValuesPerDimension()[1], keyTile.getMaxValuesPerDimension()[1]); Polygon rect = JTS.toGeometry(other); if (!RectangleIntersects.intersects(rect, geom)) { it.remove(); } } } } return rawIds; }
/** * Always returns a single range since this is a 1-dimensional index. The sort-order of the bytes * is the same as the sort order of values, so an indexedRange can be represented by a single * contiguous ByteArrayRange. {@inheritDoc} */ @Override public QueryRanges getQueryRanges( final MultiDimensionalNumericData indexedRange, final int maxEstimatedRangeDecomposition, final IndexMetaData... hints) { final T min = cast(indexedRange.getMinValuesPerDimension()[0]); final byte[] start = lexicoder.toByteArray(min); final T max = cast(Math.ceil(indexedRange.getMaxValuesPerDimension()[0])); final byte[] end = lexicoder.toByteArray(max); final ByteArrayRange range = new ByteArrayRange(start, end); final SinglePartitionQueryRanges partitionRange = new SinglePartitionQueryRanges(Collections.singletonList(range)); return new QueryRanges(Collections.singletonList(partitionRange)); }
protected boolean validateConstraints( final BasicQueryCompareOp op, final MultiDimensionalNumericData queryRange, final MultiDimensionalNumericData dataRange) { final NumericData[] queryRangePerDimension = queryRange.getDataPerDimension(); final double[] minPerDimension = dataRange.getMinValuesPerDimension(); final double[] maxPerDimension = dataRange.getMaxValuesPerDimension(); boolean ok = true; for (int d = 0; (d < dimensionFields.length) && ok; d++) { ok &= op.compare( minPerDimension[d], maxPerDimension[d], queryRangePerDimension[d].getMin(), queryRangePerDimension[d].getMax()); } return ok; }
index.getIndexStrategy().getOrderedDimensionDefinitions(); final double[] minsPerDimension = indexRange.getMinValuesPerDimension(); final double[] maxesPerDimension = indexRange.getMaxValuesPerDimension(); Double minX = null;
final double[] minValuesPerDimension = bounds.getMinValuesPerDimension(); for (int d = 0; d < tileRangePerDimension.length; d++) { tileRangePerDimension[d] =
for (int d = 0; d < dataRangePerDimension.length; d++) { dataRangePerDimension[d] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d];
final double[] minValuesPerDimension = fullBounds.getMinValuesPerDimension(); final double[] maxValuesPerDimension = fullBounds.getMaxValuesPerDimension(); for (int i = 0; i < dimension; i++) {
protected static Filter getFilter( final GeotoolsFeatureDataAdapter adapter, final QueryConstraints delegateConstraints) { final List<MultiDimensionalNumericData> constraints = delegateConstraints.getIndexConstraints(new TemporalIndexBuilder().createIndex()); if (adapter.getTimeDescriptors().getTime() != null) { return constraintsToFilter( constraints, data -> TimeUtils.toDuringFilter( (long) data.getMinValuesPerDimension()[0], (long) data.getMaxValuesPerDimension()[0], adapter.getTimeDescriptors().getTime().getLocalName())); } else if ((adapter.getTimeDescriptors().getStartRange() != null) && (adapter.getTimeDescriptors().getEndRange() != null)) { return constraintsToFilter( constraints, data -> TimeUtils.toFilter( (long) data.getMinValuesPerDimension()[0], (long) data.getMaxValuesPerDimension()[0], adapter.getTimeDescriptors().getStartRange().getLocalName(), adapter.getTimeDescriptors().getEndRange().getLocalName())); } return null; }
for (int d = 0; d < dataRangePerDimension.length; d++) { dataRangePerDimension[d] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d];
/** * {@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)}); }
if (dimensions[d] instanceof LatitudeDefinition) { latitudeIndex = d; minDP[1] = originalBounds.getMinValuesPerDimension()[d]; maxDP[1] = originalBounds.getMaxValuesPerDimension()[d]; } else if (dimensions[d] instanceof LongitudeDefinition) { longitudeIndex = d; minDP[0] = originalBounds.getMinValuesPerDimension()[d]; maxDP[0] = originalBounds.getMaxValuesPerDimension()[d]; } else if (dimensions[d] instanceof CustomCRSSpatialDimension) { minDP[d] = originalBounds.getMinValuesPerDimension()[d]; maxDP[d] = originalBounds.getMaxValuesPerDimension()[d]; final double[] minsPerDimension = rangePerDimension.getMinValuesPerDimension(); final double[] maxesPerDimension = rangePerDimension.getMaxValuesPerDimension(); final ReferencedEnvelope mapExtent = final double[] mins = rangePerDimension.getMinValuesPerDimension(); final NumericRange[] ranges = new NumericRange[centroids.length]; for (int d = 0; d < centroids.length; d++) {