@Test public void testChooseTemporalWithoutStatsHouseHour() { final ChooseLocalityPreservingQueryStrategy strategy = new ChooseLocalityPreservingQueryStrategy(); final Iterator<Index> it = getIndices( new HashMap<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>>(), new BasicQueryByClass(createConstraints(HOUSE, HOUSE, HOUR)), strategy); assertTrue(it.hasNext()); assertEquals(indices.get(1).getName(), it.next().getName()); assertFalse(it.hasNext()); }
@Override public CloseableIterator<Index> getIndices( final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats, final QueryConstraints query, final Index[] indices, final DataTypeAdapter<?> adapter, final Map<QueryHint, Object> hints) { return new CloseableIterator<Index>() { Index nextIdx = null; boolean done = false; int i = 0; @Override public boolean hasNext() { double indexMax = -1; Index bestIdx = null; while (!done && (i < indices.length)) { nextIdx = indices[i++]; if (nextIdx.getIndexStrategy().getOrderedDimensionDefinitions().length == 0) { continue; } final List<MultiDimensionalNumericData> queryRanges = query.getIndexConstraints(nextIdx); if (IndexUtils.isFullTableScan(queryRanges)) { if (bestIdx == null) { bestIdx = nextIdx; } } else { 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] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d]; } totalMax += IndexUtils.getDimensionalBitsUsed( nextIdx.getIndexStrategy(), dataRangePerDimension); } if (totalMax > indexMax) { indexMax = totalMax; bestIdx = nextIdx; } } } nextIdx = bestIdx; done = true; return nextIdx != null; } @Override public Index next() throws NoSuchElementException { if (nextIdx == null) { throw new NoSuchElementException(); } final Index returnVal = nextIdx; nextIdx = null; return returnVal; } @Override public void remove() {} @Override public void close() {} }; }
ChooseLocalityPreservingQueryStrategy implements IndexQueryStrategySPI { @Override public CloseableIterator<Index> getIndices( final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats, final QueryConstraints query, final Index[] indices, final DataTypeAdapter<?> adapter, final Map<QueryHint, Object> hints) { return new CloseableIterator<Index>() { Index nextIdx = null; boolean done = false; int i = 0; @Override public boolean hasNext() { double indexMax = -1; Index bestIdx = null; while (!done && (i < indices.length)) { nextIdx = indices[i++]; if (nextIdx.getIndexStrategy().getOrderedDimensionDefinitions().length == 0) { continue; } final List<MultiDimensionalNumericData> queryRanges = query.getIndexConstraints(nextIdx); if (IndexUtils.isFullTableScan(queryRanges)) { if (bestIdx == null) { bestIdx = nextIdx; } } else { 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] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d]; } totalMax += IndexUtils.getDimensionalBitsUsed( nextIdx.getIndexStrategy(), dataRangePerDimension); } if (totalMax > indexMax) { indexMax = totalMax; bestIdx = nextIdx; } } } nextIdx = bestIdx; done = true; return nextIdx != null; } @Override public Index next() throws NoSuchElementException { if (nextIdx == null) { throw new NoSuchElementException(); } final Index returnVal = nextIdx; nextIdx = null; return returnVal; } @Override public void remove() {} @Override public void close() {} }; } }
ChooseLocalityPreservingQueryStrategy implements IndexQueryStrategySPI { @Override public CloseableIterator<Index> getIndices( final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats, final QueryConstraints query, final Index[] indices, final DataTypeAdapter<?> adapter, final Map<QueryHint, Object> hints) { return new CloseableIterator<Index>() { Index nextIdx = null; boolean done = false; int i = 0; @Override public boolean hasNext() { double indexMax = -1; Index bestIdx = null; while (!done && (i < indices.length)) { nextIdx = indices[i++]; if (nextIdx.getIndexStrategy().getOrderedDimensionDefinitions().length == 0) { continue; } final List<MultiDimensionalNumericData> queryRanges = query.getIndexConstraints(nextIdx); if (IndexUtils.isFullTableScan(queryRanges)) { if (bestIdx == null) { bestIdx = nextIdx; } } else { 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] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d]; } totalMax += IndexUtils.getDimensionalBitsUsed( nextIdx.getIndexStrategy(), dataRangePerDimension); } if (totalMax > indexMax) { indexMax = totalMax; bestIdx = nextIdx; } } } nextIdx = bestIdx; done = true; return nextIdx != null; } @Override public Index next() throws NoSuchElementException { if (nextIdx == null) { throw new NoSuchElementException(); } final Index returnVal = nextIdx; nextIdx = null; return returnVal; } @Override public void remove() {} @Override public void close() {} }; }  }
ChooseLocalityPreservingQueryStrategy implements IndexQueryStrategySPI { @Override public CloseableIterator<Index> getIndices( final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats, final QueryConstraints query, final Index[] indices, final DataTypeAdapter<?> adapter, final Map<QueryHint, Object> hints) { return new CloseableIterator<Index>() { Index nextIdx = null; boolean done = false; int i = 0; @Override public boolean hasNext() { double indexMax = -1; Index bestIdx = null; while (!done && (i < indices.length)) { nextIdx = indices[i++]; if (nextIdx.getIndexStrategy().getOrderedDimensionDefinitions().length == 0) { continue; } final List<MultiDimensionalNumericData> queryRanges = query.getIndexConstraints(nextIdx); if (IndexUtils.isFullTableScan(queryRanges)) { if (bestIdx == null) { bestIdx = nextIdx; } } else { 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] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d]; } totalMax += IndexUtils.getDimensionalBitsUsed( nextIdx.getIndexStrategy(), dataRangePerDimension); } if (totalMax > indexMax) { indexMax = totalMax; bestIdx = nextIdx; } } } nextIdx = bestIdx; done = true; return nextIdx != null; } @Override public Index next() throws NoSuchElementException { if (nextIdx == null) { throw new NoSuchElementException(); } final Index returnVal = nextIdx; nextIdx = null; return returnVal; } @Override public void remove() {} @Override public void close() {} }; }  @Override String toString(); @Override CloseableIterator<Index> getIndices(
      final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats,
      final QueryConstraints query,
      final Index[] indices,
      final DataTypeAdapter<?> adapter,
      final Map<QueryHint, Object> hints); @Override boolean requiresStats(); }
ChooseLocalityPreservingQueryStrategy implements IndexQueryStrategySPI { @Override public CloseableIterator<Index> getIndices( final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats, final QueryConstraints query, final Index[] indices, final DataTypeAdapter<?> adapter, final Map<QueryHint, Object> hints) { return new CloseableIterator<Index>() { Index nextIdx = null; boolean done = false; int i = 0; @Override public boolean hasNext() { double indexMax = -1; Index bestIdx = null; while (!done && (i < indices.length)) { nextIdx = indices[i++]; if (nextIdx.getIndexStrategy().getOrderedDimensionDefinitions().length == 0) { continue; } final List<MultiDimensionalNumericData> queryRanges = query.getIndexConstraints(nextIdx); if (IndexUtils.isFullTableScan(queryRanges)) { if (bestIdx == null) { bestIdx = nextIdx; } } else { 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] = qr.getMaxValuesPerDimension()[d] - qr.getMinValuesPerDimension()[d]; } totalMax += IndexUtils.getDimensionalBitsUsed( nextIdx.getIndexStrategy(), dataRangePerDimension); } if (totalMax > indexMax) { indexMax = totalMax; bestIdx = nextIdx; } } } nextIdx = bestIdx; done = true; return nextIdx != null; } @Override public Index next() throws NoSuchElementException { if (nextIdx == null) { throw new NoSuchElementException(); } final Index returnVal = nextIdx; nextIdx = null; return returnVal; } @Override public void remove() {} @Override public void close() {} }; }  @Override String toString(); @Override CloseableIterator<Index> getIndices(
      final Map<StatisticsId, InternalDataStatistics<SimpleFeature, ?, ?>> stats,
      final QueryConstraints query,
      final Index[] indices,
      final DataTypeAdapter<?> adapter,
      final Map<QueryHint, Object> hints); @Override boolean requiresStats(); static final String NAME; }