package mil.nga.giat.geowave.core.index;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.Test;
import mil.nga.giat.geowave.core.index.dimension.BasicDimensionDefinition;
import mil.nga.giat.geowave.core.index.dimension.NumericDimensionDefinition;
import mil.nga.giat.geowave.core.index.sfc.SFCFactory.SFCType;
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.index.sfc.tiered.TieredSFCIndexFactory;
public class CompoundIndexStrategyTest
{
private static final NumericDimensionDefinition[] DIMENSIONS = new NumericDimensionDefinition[] {
new BasicDimensionDefinition(
0,
1000)
};
private static final NumericIndexStrategy simpleIndexStrategy = TieredSFCIndexFactory.createSingleTierStrategy(
DIMENSIONS,
new int[] {
16
},
SFCType.HILBERT);
private static final NumericDimensionDefinition[] SPATIAL_DIMENSIONS = new NumericDimensionDefinition[] {
new BasicDimensionDefinition(
-180,
180),
new BasicDimensionDefinition(
-90,
90)
};
private static final NumericIndexStrategy sfcIndexStrategy = TieredSFCIndexFactory.createSingleTierStrategy(
SPATIAL_DIMENSIONS,
new int[] {
16,
16
},
SFCType.HILBERT);
private static final CompoundIndexStrategy compoundIndexStrategy = new CompoundIndexStrategy(
simpleIndexStrategy,
sfcIndexStrategy);
private static final NumericRange dimension1Range = new NumericRange(
2,
4);
private static final NumericRange dimension2Range = new NumericRange(
50.0,
50.025);
private static final NumericRange dimension3Range = new NumericRange(
-20.5,
-20.455);
private static final MultiDimensionalNumericData simpleIndexedRange = new BasicNumericDataset(
new NumericData[] {
dimension1Range,
});
private static final MultiDimensionalNumericData sfcIndexedRange = new BasicNumericDataset(
new NumericData[] {
dimension2Range,
dimension3Range
});
private static final MultiDimensionalNumericData compoundIndexedRange = new BasicNumericDataset(
new NumericData[] {
dimension1Range,
dimension2Range,
dimension3Range
});
@Test
public void testBinaryEncoding() {
final byte[] bytes = PersistenceUtils.toBinary(compoundIndexStrategy);
final CompoundIndexStrategy deserializedStrategy = PersistenceUtils.fromBinary(
bytes,
CompoundIndexStrategy.class);
final byte[] bytes2 = PersistenceUtils.toBinary(deserializedStrategy);
Assert.assertArrayEquals(
bytes,
bytes2);
}
@Test
public void testNumberOfDimensionsPerIndexStrategy() {
final int[] numDimensionsPerStrategy = compoundIndexStrategy.getNumberOfDimensionsPerIndexStrategy();
Assert.assertEquals(
1,
numDimensionsPerStrategy[0]);
Assert.assertEquals(
2,
numDimensionsPerStrategy[1]);
}
@Test
public void testGetNumberOfDimensions() {
final int numDimensions = compoundIndexStrategy.getNumberOfDimensions();
Assert.assertEquals(
3,
numDimensions);
}
@Test
public void testCompositionOfByteArrayId() {
final ByteArrayId id1 = new ByteArrayId(
"hello");
final ByteArrayId id2 = new ByteArrayId(
"world!!");
final ByteArrayId compoundId = compoundIndexStrategy.composeByteArrayId(
id1,
id2);
final ByteArrayId[] decomposedId = compoundIndexStrategy.decomposeByteArrayId(compoundId);
Assert.assertArrayEquals(
id1.getBytes(),
decomposedId[0].getBytes());
Assert.assertArrayEquals(
id2.getBytes(),
decomposedId[1].getBytes());
}
@Test
public void testGetQueryRangesWithMaximumNumberOfRanges() {
final List<ByteArrayRange> simpleIndexRanges = simpleIndexStrategy.getQueryRanges(simpleIndexedRange);
final List<ByteArrayRange> sfcIndexRanges = sfcIndexStrategy.getQueryRanges(sfcIndexedRange);
final List<ByteArrayRange> ranges = new ArrayList<>();
for (final ByteArrayRange r1 : simpleIndexRanges) {
for (final ByteArrayRange r2 : sfcIndexRanges) {
final ByteArrayId start = compoundIndexStrategy.composeByteArrayId(
r1.getStart(),
r2.getStart());
final ByteArrayId end = compoundIndexStrategy.composeByteArrayId(
r1.getEnd(),
r2.getEnd());
ranges.add(new ByteArrayRange(
start,
end));
}
}
final Set<ByteArrayRange> testRanges = new HashSet<>(
ranges);
final Set<ByteArrayRange> compoundIndexRanges = new HashSet<>(
compoundIndexStrategy.getQueryRanges(compoundIndexedRange));
Assert.assertTrue(testRanges.containsAll(compoundIndexRanges));
Assert.assertTrue(compoundIndexRanges.containsAll(testRanges));
}
@Test
public void testGetQueryRanges() {
final List<ByteArrayRange> simpleIndexRanges = simpleIndexStrategy.getQueryRanges(
simpleIndexedRange,
3);
final int maxRangesStrategy2 = 8 / simpleIndexRanges.size();
final List<ByteArrayRange> sfcIndexRanges = sfcIndexStrategy.getQueryRanges(
sfcIndexedRange,
maxRangesStrategy2);
final List<ByteArrayRange> ranges = new ArrayList<>(
simpleIndexRanges.size() * sfcIndexRanges.size());
for (final ByteArrayRange r1 : simpleIndexRanges) {
for (final ByteArrayRange r2 : sfcIndexRanges) {
final ByteArrayId start = compoundIndexStrategy.composeByteArrayId(
r1.getStart(),
r2.getStart());
final ByteArrayId end = compoundIndexStrategy.composeByteArrayId(
r1.getEnd(),
r2.getEnd());
ranges.add(new ByteArrayRange(
start,
end));
}
}
final Set<ByteArrayRange> testRanges = new HashSet<>(
ranges);
final Set<ByteArrayRange> compoundIndexRanges = new HashSet<>(
compoundIndexStrategy.getQueryRanges(
compoundIndexedRange,
8));
Assert.assertTrue(testRanges.containsAll(compoundIndexRanges));
Assert.assertTrue(compoundIndexRanges.containsAll(testRanges));
}
@Test
public void testGetInsertionIds() {
final List<ByteArrayId> ids = new ArrayList<>();
final List<ByteArrayId> ids1 = simpleIndexStrategy.getInsertionIds(
simpleIndexedRange,
3);
final int maxEstDuplicatesStrategy2 = 8 / ids1.size();
final List<ByteArrayId> ids2 = sfcIndexStrategy.getInsertionIds(
sfcIndexedRange,
maxEstDuplicatesStrategy2);
for (final ByteArrayId id1 : ids1) {
for (final ByteArrayId id2 : ids2) {
ids.add(compoundIndexStrategy.composeByteArrayId(
id1,
id2));
}
}
final Set<ByteArrayId> testIds = new HashSet<>(
ids);
final Set<ByteArrayId> compoundIndexIds = new HashSet<>(
compoundIndexStrategy.getInsertionIds(
compoundIndexedRange,
8));
Assert.assertTrue(testIds.containsAll(compoundIndexIds));
Assert.assertTrue(compoundIndexIds.containsAll(testIds));
}
@Test
public void testGetCoordinatesPerDimension() {
final ByteArrayId compoundIndexInsertionId = new ByteArrayId(
new byte[] {
16,
0,
-125,
16,
-46,
-93,
-110,
-31,
0,
0,
0,
3
});
final ByteArrayId[] insertionIds = compoundIndexStrategy.decomposeByteArrayId(compoundIndexInsertionId);
final MultiDimensionalCoordinates simpleIndexCoordinatesPerDim = simpleIndexStrategy
.getCoordinatesPerDimension(insertionIds[0]);
final MultiDimensionalCoordinates sfcIndexCoordinatesPerDim = sfcIndexStrategy
.getCoordinatesPerDimension(insertionIds[1]);
final MultiDimensionalCoordinates coordinatesPerDim = compoundIndexStrategy
.getCoordinatesPerDimension(compoundIndexInsertionId);
Assert.assertTrue(Long.compare(
simpleIndexCoordinatesPerDim.getCoordinate(
0).getCoordinate(),
coordinatesPerDim.getCoordinate(
0).getCoordinate()) == 0);
Assert.assertTrue(Long.compare(
sfcIndexCoordinatesPerDim.getCoordinate(
0).getCoordinate(),
coordinatesPerDim.getCoordinate(
1).getCoordinate()) == 0);
Assert.assertTrue(Long.compare(
sfcIndexCoordinatesPerDim.getCoordinate(
1).getCoordinate(),
coordinatesPerDim.getCoordinate(
2).getCoordinate()) == 0);
}
@Test
public void testGetRangeForId() {
final ByteArrayId compoundIndexInsertionId = new ByteArrayId(
new byte[] {
16,
0,
-125,
16,
-46,
-93,
-110,
-31,
0,
0,
0,
3
});
final ByteArrayId[] insertionIds = compoundIndexStrategy.decomposeByteArrayId(compoundIndexInsertionId);
final MultiDimensionalNumericData simpleIndexRange = simpleIndexStrategy.getRangeForId(insertionIds[0]);
final MultiDimensionalNumericData sfcIndexRange = sfcIndexStrategy.getRangeForId(insertionIds[1]);
final MultiDimensionalNumericData range = compoundIndexStrategy.getRangeForId(compoundIndexInsertionId);
Assert.assertEquals(
simpleIndexRange.getDimensionCount(),
1);
Assert.assertEquals(
sfcIndexRange.getDimensionCount(),
2);
Assert.assertEquals(
range.getDimensionCount(),
3);
Assert.assertTrue(Double.compare(
simpleIndexRange.getMinValuesPerDimension()[0],
range.getMinValuesPerDimension()[0]) == 0);
Assert.assertTrue(Double.compare(
sfcIndexRange.getMinValuesPerDimension()[0],
range.getMinValuesPerDimension()[1]) == 0);
Assert.assertTrue(Double.compare(
sfcIndexRange.getMinValuesPerDimension()[1],
range.getMinValuesPerDimension()[2]) == 0);
Assert.assertTrue(Double.compare(
simpleIndexRange.getMaxValuesPerDimension()[0],
range.getMaxValuesPerDimension()[0]) == 0);
Assert.assertTrue(Double.compare(
sfcIndexRange.getMaxValuesPerDimension()[0],
range.getMaxValuesPerDimension()[1]) == 0);
Assert.assertTrue(Double.compare(
sfcIndexRange.getMaxValuesPerDimension()[1],
range.getMaxValuesPerDimension()[2]) == 0);
}
@Test
public void testGetHighestPrecisionIdRangePerDimension() {
final double[] simpleIndexPrecision = simpleIndexStrategy.getHighestPrecisionIdRangePerDimension();
final double[] sfcIndexPrecision = sfcIndexStrategy.getHighestPrecisionIdRangePerDimension();
final double[] precisionPerDim = compoundIndexStrategy.getHighestPrecisionIdRangePerDimension();
Assert.assertTrue(Double.compare(
precisionPerDim[0],
simpleIndexPrecision[0]) == 0);
Assert.assertTrue(Double.compare(
precisionPerDim[1],
sfcIndexPrecision[0]) == 0);
Assert.assertTrue(Double.compare(
precisionPerDim[2],
sfcIndexPrecision[1]) == 0);
}
@Test
public void testHints() {
final List<ByteArrayId> ids = compoundIndexStrategy.getInsertionIds(
compoundIndexedRange,
8);
List<IndexMetaData> metaData = compoundIndexStrategy.createMetaData();
for (IndexMetaData imd : metaData) {
imd.insertionIdsAdded(ids);
}
final List<ByteArrayRange> simpleIndexRanges = simpleIndexStrategy.getQueryRanges(simpleIndexedRange);
final List<ByteArrayRange> sfcIndexRanges = sfcIndexStrategy.getQueryRanges(sfcIndexedRange);
final List<ByteArrayRange> ranges = new ArrayList<>();
for (final ByteArrayRange r1 : simpleIndexRanges) {
for (final ByteArrayRange r2 : sfcIndexRanges) {
final ByteArrayId start = compoundIndexStrategy.composeByteArrayId(
r1.getStart(),
r2.getStart());
final ByteArrayId end = compoundIndexStrategy.composeByteArrayId(
r1.getEnd(),
r2.getEnd());
ranges.add(new ByteArrayRange(
start,
end));
}
}
final Set<ByteArrayRange> compoundIndexRangesWithoutHints = new HashSet<>(
compoundIndexStrategy.getQueryRanges(compoundIndexedRange));
final Set<ByteArrayRange> compoundIndexRangesWithHints = new HashSet<>(
compoundIndexStrategy.getQueryRanges(
compoundIndexedRange,
metaData.toArray(new IndexMetaData[metaData.size()])));
Assert.assertTrue(compoundIndexRangesWithoutHints.containsAll(compoundIndexRangesWithHints));
Assert.assertTrue(compoundIndexRangesWithHints.containsAll(compoundIndexRangesWithoutHints));
List<Persistable> newMetaData = PersistenceUtils.fromBinary(PersistenceUtils.toBinary(metaData));
final Set<ByteArrayRange> compoundIndexRangesWithHints2 = new HashSet<>(
compoundIndexStrategy.getQueryRanges(
compoundIndexedRange,
metaData.toArray(new IndexMetaData[newMetaData.size()])));
Assert.assertTrue(compoundIndexRangesWithoutHints.containsAll(compoundIndexRangesWithHints2));
Assert.assertTrue(compoundIndexRangesWithHints2.containsAll(compoundIndexRangesWithoutHints));
}
}