package mil.nga.giat.geowave.adapter.vector.index;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.Closeable;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import mil.nga.giat.geowave.core.geotime.index.dimension.LatitudeDefinition;
import mil.nga.giat.geowave.core.geotime.index.dimension.LongitudeDefinition;
import mil.nga.giat.geowave.core.geotime.index.dimension.TimeDefinition;
import mil.nga.giat.geowave.core.geotime.ingest.SpatialDimensionalityTypeProvider.SpatialIndexBuilder;
import mil.nga.giat.geowave.core.geotime.ingest.SpatialTemporalDimensionalityTypeProvider.SpatialTemporalIndexBuilder;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.ByteArrayRange;
import mil.nga.giat.geowave.core.index.NumericIndexStrategy;
import mil.nga.giat.geowave.core.index.sfc.data.MultiDimensionalNumericData;
import mil.nga.giat.geowave.core.index.sfc.data.NumericData;
import mil.nga.giat.geowave.core.index.sfc.data.NumericRange;
import mil.nga.giat.geowave.core.store.CloseableIteratorWrapper;
import mil.nga.giat.geowave.core.store.adapter.statistics.DataStatistics;
import mil.nga.giat.geowave.core.store.adapter.statistics.RowRangeHistogramStatistics;
import mil.nga.giat.geowave.core.store.adapter.statistics.histogram.FixedBinNumericHistogram.FixedBinNumericHistogramFactory;
import mil.nga.giat.geowave.core.store.base.DataStoreEntryInfo;
import mil.nga.giat.geowave.core.store.base.DataStoreEntryInfo.FieldInfo;
import mil.nga.giat.geowave.core.store.dimension.NumericDimensionField;
import mil.nga.giat.geowave.core.store.index.CommonIndexValue;
import mil.nga.giat.geowave.core.store.index.Index;
import mil.nga.giat.geowave.core.store.index.NullIndex;
import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
import mil.nga.giat.geowave.core.store.query.BasicQuery;
import mil.nga.giat.geowave.core.store.query.BasicQuery.ConstraintData;
import mil.nga.giat.geowave.core.store.query.BasicQuery.ConstraintSet;
import mil.nga.giat.geowave.core.store.query.BasicQuery.Constraints;
import mil.nga.giat.geowave.core.store.util.DataStoreUtils;
import org.junit.Test;
import org.opengis.feature.simple.SimpleFeature;
public class ChooseBestMatchIndexQueryStrategyTest
{
final PrimaryIndex IMAGE_CHIP_INDEX1 = new NullIndex(
"IMAGERY_CHIPS1");
final PrimaryIndex IMAGE_CHIP_INDEX2 = new NullIndex(
"IMAGERY_CHIPS2");
@Test
public void testChooseSpatialWithStats() {
final PrimaryIndex temporalindex = new SpatialTemporalIndexBuilder().createIndex();
final PrimaryIndex spatialIndex = new SpatialIndexBuilder().createIndex();
final RowRangeHistogramStatistics<SimpleFeature> rangeTempStats = new RowRangeHistogramStatistics<SimpleFeature>(
temporalindex.getId(),
temporalindex.getId(),
new FixedBinNumericHistogramFactory(),
1024);
final RowRangeHistogramStatistics<SimpleFeature> rangeStats = new RowRangeHistogramStatistics<SimpleFeature>(
spatialIndex.getId(),
spatialIndex.getId(),
new FixedBinNumericHistogramFactory(),
1024);
final Map<ByteArrayId, DataStatistics<SimpleFeature>> statsMap = new HashMap<ByteArrayId, DataStatistics<SimpleFeature>>();
statsMap.put(
RowRangeHistogramStatistics.composeId(spatialIndex.getId()),
rangeStats);
statsMap.put(
RowRangeHistogramStatistics.composeId(temporalindex.getId()),
rangeTempStats);
final ChooseBestMatchIndexQueryStrategy strategy = new ChooseBestMatchIndexQueryStrategy();
final ConstraintSet cs1 = new ConstraintSet();
cs1.addConstraint(
LatitudeDefinition.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
true));
cs1.addConstraint(
LongitudeDefinition.class,
new ConstraintData(
new ConstrainedIndexValue(
0.4,
0.7),
true));
final ConstraintSet cs2a = new ConstraintSet();
cs2a.addConstraint(
TimeDefinition.class,
new ConstraintData(
new ConstrainedIndexValue(
0.1,
0.2),
true));
final Constraints constraints = new Constraints(
Arrays.asList(cs2a)).merge(Collections.singletonList(cs1));
final BasicQuery query = new BasicQuery(
constraints);
final NumericIndexStrategy temporalIndexStrategy = new SpatialTemporalIndexBuilder()
.createIndex()
.getIndexStrategy();
final List<MultiDimensionalNumericData> tempConstraints = query.getIndexConstraints(temporalIndexStrategy);
final List<ByteArrayRange> temporalRanges = DataStoreUtils.constraintsToByteArrayRanges(
tempConstraints,
temporalIndexStrategy,
5000);
for (final ByteArrayRange range : temporalRanges) {
rangeTempStats.entryIngested(
new DataStoreEntryInfo(
new byte[] {
1
},
Arrays.asList(range.getStart()),
Arrays.asList(range.getStart()),
Collections.<FieldInfo<?>> emptyList()),
null);
rangeTempStats.entryIngested(
new DataStoreEntryInfo(
new byte[] {
1
},
Arrays.asList(range.getEnd()),
Arrays.asList(range.getEnd()),
Collections.<FieldInfo<?>> emptyList()),
null);
}
final NumericIndexStrategy indexStrategy = new SpatialTemporalIndexBuilder().createIndex().getIndexStrategy();
final List<MultiDimensionalNumericData> spatialConstraints = query.getIndexConstraints(indexStrategy);
final List<ByteArrayRange> spatialRanges = DataStoreUtils.constraintsToByteArrayRanges(
spatialConstraints,
indexStrategy,
5000);
for (final ByteArrayRange range : spatialRanges) {
rangeStats.entryIngested(
new DataStoreEntryInfo(
new byte[] {
1
},
Arrays.asList(range.getStart()),
Arrays.asList(range.getStart()),
Collections.<FieldInfo<?>> emptyList()),
null);
}
final Iterator<Index<?, ?>> it = getIndices(
statsMap,
query,
strategy);
assertTrue(it.hasNext());
assertEquals(
spatialIndex.getId(),
it.next().getId());
assertFalse(it.hasNext());
}
/*
* @Test public void testChooseTemporalWithoutStats() { final PrimaryIndex
* temporalindex = new SpatialTemporalIndexBuilder().createIndex(); final
* ChooseBestMatchIndexQueryStrategy strategy = new
* ChooseBestMatchIndexQueryStrategy();
*
* final ConstraintSet cs1 = new ConstraintSet(); cs1.addConstraint(
* LatitudeDefinition.class, new ConstraintData( new ConstrainedIndexValue(
* 0.3, 0.5), true));
*
* cs1.addConstraint( LongitudeDefinition.class, new ConstraintData( new
* ConstrainedIndexValue( 0.4, 0.7), true));
*
* final ConstraintSet cs2a = new ConstraintSet(); cs2a.addConstraint(
* TimeDefinition.class, new ConstraintData( new ConstrainedIndexValue( 0.1,
* 0.2), true));
*
* final Constraints constraints = new Constraints(
* Arrays.asList(cs2a)).merge(Collections.singletonList(cs1));
*
* final BasicQuery query = new BasicQuery( constraints);
*
* final Iterator<Index<?, ?>> it = getIndices( new HashMap<ByteArrayId,
* DataStatistics<SimpleFeature>>(), query, strategy);
* assertTrue(it.hasNext()); assertEquals( temporalindex.getId(),
* it.next().getId()); assertFalse(it.hasNext());
*
* }
*
* @Test public void testChooseSpatialWithoutStats() { final PrimaryIndex
* spatialIndex = new SpatialIndexBuilder().createIndex(); final
* ChooseBestMatchIndexQueryStrategy strategy = new
* ChooseBestMatchIndexQueryStrategy();
*
* final ConstraintSet cs1 = new ConstraintSet(); cs1.addConstraint(
* LatitudeDefinition.class, new ConstraintData( new ConstrainedIndexValue(
* 0.3, 0.5), true));
*
* cs1.addConstraint( LongitudeDefinition.class, new ConstraintData( new
* ConstrainedIndexValue( 0.4, 0.7), true));
*
* final Constraints constraints = new Constraints(
* Collections.singletonList(cs1));
*
* final BasicQuery query = new BasicQuery( constraints);
*
* final Iterator<Index<?, ?>> it = getIndices( new HashMap<ByteArrayId,
* DataStatistics<SimpleFeature>>(), query, strategy);
* assertTrue(it.hasNext()); assertEquals( spatialIndex.getId(),
* it.next().getId()); assertFalse(it.hasNext());
*
* }
*/
public Iterator<Index<?, ?>> getIndices(
final Map<ByteArrayId, DataStatistics<SimpleFeature>> stats,
final BasicQuery query,
final ChooseBestMatchIndexQueryStrategy strategy ) {
return strategy.getIndices(
stats,
query,
new PrimaryIndex[] {
IMAGE_CHIP_INDEX1,
new SpatialTemporalIndexBuilder().createIndex(),
new SpatialIndexBuilder().createIndex(),
IMAGE_CHIP_INDEX2
});
}
public static class ConstrainedIndexValue extends
NumericRange implements
CommonIndexValue
{
/**
*
*/
private static final long serialVersionUID = 1L;
public ConstrainedIndexValue(
final double min,
final double max ) {
super(
min,
max);
//
}
@Override
public byte[] getVisibility() {
return new byte[0];
}
@Override
public void setVisibility(
final byte[] visibility ) {
}
@Override
public boolean overlaps(
final NumericDimensionField[] field,
final NumericData[] rangeData ) {
return false;
}
}
}