package mil.nga.giat.geowave.core.store.query;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.ByteArrayRange;
import mil.nga.giat.geowave.core.index.Coordinate;
import mil.nga.giat.geowave.core.index.IndexMetaData;
import mil.nga.giat.geowave.core.index.MultiDimensionalCoordinateRanges;
import mil.nga.giat.geowave.core.index.MultiDimensionalCoordinates;
import mil.nga.giat.geowave.core.index.NumericIndexStrategy;
import mil.nga.giat.geowave.core.index.dimension.NumericDimensionDefinition;
import mil.nga.giat.geowave.core.index.dimension.bin.BinRange;
import mil.nga.giat.geowave.core.index.sfc.data.BasicNumericDataset;
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.data.CommonIndexedPersistenceEncoding;
import mil.nga.giat.geowave.core.store.data.PersistentDataset;
import mil.nga.giat.geowave.core.store.data.field.FieldReader;
import mil.nga.giat.geowave.core.store.data.field.FieldWriter;
import mil.nga.giat.geowave.core.store.dimension.NumericDimensionField;
import mil.nga.giat.geowave.core.store.filter.QueryFilter;
import mil.nga.giat.geowave.core.store.index.BasicIndexModel;
import mil.nga.giat.geowave.core.store.index.CommonIndexModel;
import mil.nga.giat.geowave.core.store.index.CommonIndexValue;
import mil.nga.giat.geowave.core.store.index.CustomIdIndex;
import mil.nga.giat.geowave.core.store.index.PrimaryIndex;
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 org.junit.Test;
public class BasicQueryTest
{
final SimpleDateFormat df = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssz");
@Test
public void testIsSupported() {
final ConstraintSet cs1 = new ConstraintSet();
PrimaryIndex index = new CustomIdIndex(
new ExampleNumericIndexStrategy(),
new BasicIndexModel(
new NumericDimensionField[] {
new ExampleDimensionOne(),
new ExampleDimensionTwo()
}),
new ByteArrayId(
"22"));
assertTrue(cs1.isSupported(index));
cs1.addConstraint(
ExampleDimensionOne.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
true));
cs1.addConstraint(
ExampleDimensionTwo.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
true));
assertTrue(cs1.isSupported(index));
cs1.addConstraint(
ExampleDimensionThree.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
true));
assertTrue(cs1.isSupported(index));
final ConstraintSet cs2 = new ConstraintSet();
cs2.addConstraint(
ExampleDimensionThree.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
false));
assertFalse(cs2.isSupported(index));
}
@Test
public void testIntersectCasesWithPersistence() {
final List<MultiDimensionalNumericData> expectedResults = new ArrayList<MultiDimensionalNumericData>();
expectedResults.add(new BasicNumericDataset(
new NumericData[] {
new ConstrainedIndexValue(
0.3,
0.5),
new ConstrainedIndexValue(
0.1,
0.7)
}));
final ConstraintSet cs1 = new ConstraintSet();
cs1.addConstraint(
ExampleDimensionOne.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
true));
cs1.addConstraint(
ExampleDimensionTwo.class,
new ConstraintData(
new ConstrainedIndexValue(
0.4,
0.7),
true));
final ConstraintSet cs2a = new ConstraintSet();
cs2a.addConstraint(
ExampleDimensionTwo.class,
new ConstraintData(
new ConstrainedIndexValue(
0.1,
0.2),
true));
final Constraints constraints = new Constraints(
Arrays.asList(cs2a)).merge(Collections.singletonList(cs1));
assertEquals(
expectedResults,
constraints.getIndexConstraints(new ExampleNumericIndexStrategy()));
final byte[] image = new BasicQuery(
constraints).toBinary();
final BasicQuery query = new BasicQuery();
query.fromBinary(image);
assertEquals(
expectedResults,
query.getIndexConstraints(new ExampleNumericIndexStrategy()));
}
@Test
public void testDisjointCasesWithPersistence() {
final List<MultiDimensionalNumericData> expectedResults = new ArrayList<MultiDimensionalNumericData>();
expectedResults.add(new BasicNumericDataset(
new NumericData[] {
new ConstrainedIndexValue(
0.3,
0.7),
new ConstrainedIndexValue(
0.1,
2.3)
}));
expectedResults.add(new BasicNumericDataset(
new NumericData[] {
new ConstrainedIndexValue(
0.3,
0.7),
new ConstrainedIndexValue(
3.4,
3.7)
}));
final ConstraintSet cs1 = new ConstraintSet();
cs1.addConstraint(
ExampleDimensionOne.class,
new ConstraintData(
new ConstrainedIndexValue(
0.3,
0.5),
true));
cs1.addConstraint(
ExampleDimensionOne.class,
new ConstraintData(
new ConstrainedIndexValue(
0.4,
0.7),
true));
final ConstraintSet cs2a = new ConstraintSet();
cs2a.addConstraint(
ExampleDimensionTwo.class,
new ConstraintData(
new ConstrainedIndexValue(
0.1,
0.2),
true));
cs2a.addConstraint(
ExampleDimensionTwo.class,
new ConstraintData(
new ConstrainedIndexValue(
2.1,
2.3),
true));
final ConstraintSet cs2b = new ConstraintSet();
cs2b.addConstraint(
ExampleDimensionTwo.class,
new ConstraintData(
new ConstrainedIndexValue(
3.4,
3.7),
true));
final Constraints constraints = new Constraints(
Arrays.asList(
cs2a,
cs2b)).merge(Collections.singletonList(cs1));
assertEquals(
expectedResults,
constraints.getIndexConstraints(new ExampleNumericIndexStrategy()));
final byte[] image = new BasicQuery(
constraints).toBinary();
final BasicQuery query = new BasicQuery();
query.fromBinary(image);
assertEquals(
expectedResults,
query.getIndexConstraints(new ExampleNumericIndexStrategy()));
final List<QueryFilter> filters = query.createFilters(new BasicIndexModel(
new NumericDimensionField[] {
new ExampleDimensionOne(),
new ExampleDimensionTwo()
}));
assertEquals(
1,
filters.size());
final Map<ByteArrayId, ConstrainedIndexValue> fieldIdToValueMap = new HashMap<ByteArrayId, ConstrainedIndexValue>();
fieldIdToValueMap.put(
new ByteArrayId(
"one"),
new ConstrainedIndexValue(
0.4,
0.4));
fieldIdToValueMap.put(
new ByteArrayId(
"two"),
new ConstrainedIndexValue(
0.5,
0.5));
final CommonIndexModel model = null;
assertTrue(filters.get(
0).accept(
model,
new CommonIndexedPersistenceEncoding(
new ByteArrayId(
"adapter"),
new ByteArrayId(
"data"),
new ByteArrayId(
"index"),
1, // duplicate count
new PersistentDataset(
fieldIdToValueMap),
null)));
fieldIdToValueMap.put(
new ByteArrayId(
"one"),
new ConstrainedIndexValue(
0.1,
0.1));
assertFalse(filters.get(
0).accept(
model,
new CommonIndexedPersistenceEncoding(
new ByteArrayId(
"adapter"),
new ByteArrayId(
"data"),
new ByteArrayId(
"index"),
1, // duplicate count
new PersistentDataset(
fieldIdToValueMap),
null)));
fieldIdToValueMap.put(
new ByteArrayId(
"one"),
new ConstrainedIndexValue(
0.4,
0.4));
fieldIdToValueMap.put(
new ByteArrayId(
"two"),
new ConstrainedIndexValue(
5.0,
5.0));
assertFalse(filters.get(
0).accept(
model,
new CommonIndexedPersistenceEncoding(
new ByteArrayId(
"adapter"),
new ByteArrayId(
"data"),
new ByteArrayId(
"index"),
1, // duplicate count
new PersistentDataset(
fieldIdToValueMap),
null)));
/**
* Tests the 'OR' Case
*/
fieldIdToValueMap.put(
new ByteArrayId(
"two"),
new ConstrainedIndexValue(
3.5,
3.5));
assertTrue(filters.get(
0).accept(
model,
new CommonIndexedPersistenceEncoding(
new ByteArrayId(
"adapter"),
new ByteArrayId(
"data"),
new ByteArrayId(
"index"),
1, // duplicate count
new PersistentDataset(
fieldIdToValueMap),
null)));
}
public static class ExampleNumericIndexStrategy implements
NumericIndexStrategy
{
@Override
public byte[] toBinary() {
return null;
}
@Override
public void fromBinary(
final byte[] bytes ) {}
@Override
public List<ByteArrayRange> getQueryRanges(
final MultiDimensionalNumericData indexedRange,
final IndexMetaData... hints ) {
return null;
}
@Override
public List<ByteArrayRange> getQueryRanges(
final MultiDimensionalNumericData indexedRange,
final int maxEstimatedRangeDecomposition,
final IndexMetaData... hints ) {
return null;
}
@Override
public List<ByteArrayId> getInsertionIds(
final MultiDimensionalNumericData indexedData ) {
return null;
}
@Override
public List<ByteArrayId> getInsertionIds(
final MultiDimensionalNumericData indexedData,
final int maxEstimatedDuplicateIds ) {
return null;
}
@Override
public MultiDimensionalNumericData getRangeForId(
final ByteArrayId insertionId ) {
return null;
}
@Override
public MultiDimensionalCoordinates getCoordinatesPerDimension(
final ByteArrayId insertionId ) {
return null;
}
@Override
public NumericDimensionDefinition[] getOrderedDimensionDefinitions() {
return new NumericDimensionDefinition[] {
new ExampleDimensionOne(),
new ExampleDimensionTwo()
};
}
@Override
public String getId() {
return "test-bqt";
}
@Override
public double[] getHighestPrecisionIdRangePerDimension() {
return null;
}
@Override
public Set<ByteArrayId> getNaturalSplits() {
return null;
}
@Override
public int getByteOffsetFromDimensionalIndex() {
// TODO Auto-generated method stub
return 0;
}
@Override
public List<IndexMetaData> createMetaData() {
return Collections.emptyList();
}
@Override
public MultiDimensionalCoordinateRanges[] getCoordinateRangesPerDimension(
MultiDimensionalNumericData dataRange,
IndexMetaData... hints ) {
// TODO Auto-generated method stub
return null;
}
}
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;
}
}
public static class ExampleDimensionOne implements
NumericDimensionField<ConstrainedIndexValue>
{
public ExampleDimensionOne() {
}
@Override
public double getRange() {
return 10;
}
@Override
public double normalize(
final double value ) {
return value;
}
@Override
public double denormalize(
final double value ) {
return value;
}
@Override
public BinRange[] getNormalizedRanges(
final NumericData range ) {
return new BinRange[] {
new BinRange(
range.getMin(),
range.getMax())
};
}
@Override
public NumericRange getDenormalizedRange(
final BinRange range ) {
return new NumericRange(
range.getNormalizedMin(),
range.getNormalizedMax());
}
@Override
public int getFixedBinIdSize() {
return 0;
}
@Override
public NumericRange getBounds() {
return null;
}
@Override
public NumericData getFullRange() {
return new NumericRange(
0,
10);
}
@Override
public byte[] toBinary() {
return new byte[0];
}
@Override
public void fromBinary(
final byte[] bytes ) {}
@Override
public NumericData getNumericData(
final ConstrainedIndexValue dataElement ) {
return dataElement;
}
@Override
public ByteArrayId getFieldId() {
return new ByteArrayId(
"one");
}
@Override
public FieldWriter<?, ConstrainedIndexValue> getWriter() {
return null;
}
@Override
public FieldReader<ConstrainedIndexValue> getReader() {
return null;
}
@Override
public NumericDimensionDefinition getBaseDefinition() {
return this;
}
}
public static class ExampleDimensionTwo extends
ExampleDimensionOne
{
public ExampleDimensionTwo() {
super();
}
@Override
public ByteArrayId getFieldId() {
return new ByteArrayId(
"two");
}
}
public static class ExampleDimensionThree extends
ExampleDimensionOne
{
public ExampleDimensionThree() {
super();
}
@Override
public ByteArrayId getFieldId() {
return new ByteArrayId(
"three");
}
}
}