package mil.nga.giat.geowave.core.index.simple;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import com.google.common.primitives.UnsignedBytes;
import mil.nga.giat.geowave.core.index.ByteArrayId;
import mil.nga.giat.geowave.core.index.ByteArrayRange;
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.data.NumericValue;
@RunWith(Parameterized.class)
public class SimpleNumericIndexStrategyTest
{
private final SimpleNumericIndexStrategy<? extends Number> strategy;
public SimpleNumericIndexStrategyTest(
final SimpleNumericIndexStrategy<?> strategy ) {
this.strategy = strategy;
}
@Parameters
public static Collection<Object[]> instancesToTest() {
return Arrays.asList(
new Object[] {
new SimpleShortIndexStrategy()
},
new Object[] {
new SimpleIntegerIndexStrategy()
},
new Object[] {
new SimpleLongIndexStrategy()
});
}
private static long castToLong(
final Number n ) {
if (n instanceof Short) {
return ((short) n.shortValue());
}
else if (n instanceof Integer) {
return ((int) n.intValue());
}
else if (n instanceof Long) {
return (long) n.longValue();
}
else {
throw new UnsupportedOperationException(
"only supports casting Short, Integer, and Long");
}
}
private static MultiDimensionalNumericData getIndexedRange(
final long value ) {
return getIndexedRange(
value,
value);
}
private static MultiDimensionalNumericData getIndexedRange(
final long min,
final long max ) {
NumericData[] dataPerDimension;
if (min == max) {
dataPerDimension = new NumericData[] {
new NumericValue(
min)
};
}
else {
dataPerDimension = new NumericData[] {
new NumericRange(
min,
max)
};
}
return new BasicNumericDataset(
dataPerDimension);
}
private byte[] getByteArray(
final long value ) {
final MultiDimensionalNumericData indexedRange = getIndexedRange(value);
final List<ByteArrayId> insertionIds = strategy.getInsertionIds(indexedRange);
final ByteArrayId insertionId = insertionIds.get(0);
return insertionId.getBytes();
}
@Test
public void testGetQueryRangesPoint() {
final MultiDimensionalNumericData indexedRange = getIndexedRange(10l);
final List<ByteArrayRange> ranges = strategy.getQueryRanges(indexedRange);
Assert.assertEquals(
ranges.size(),
1);
final ByteArrayRange range = ranges.get(0);
final ByteArrayId start = range.getStart();
final ByteArrayId end = range.getEnd();
Assert.assertTrue(Arrays.equals(
start.getBytes(),
end.getBytes()));
Assert.assertEquals(
10L,
castToLong(strategy.getLexicoder().fromByteArray(
start.getBytes())));
}
@Test
public void testGetQueryRangesRange() {
final long startValue = 10;
final long endValue = 15;
final MultiDimensionalNumericData indexedRange = getIndexedRange(
startValue,
endValue);
final List<ByteArrayRange> ranges = strategy.getQueryRanges(indexedRange);
Assert.assertEquals(
ranges.size(),
1);
final ByteArrayRange range = ranges.get(0);
final ByteArrayId start = range.getStart();
final ByteArrayId end = range.getEnd();
Assert.assertEquals(
castToLong(strategy.getLexicoder().fromByteArray(
start.getBytes())),
startValue);
Assert.assertEquals(
castToLong(strategy.getLexicoder().fromByteArray(
end.getBytes())),
endValue);
}
/**
* Check that lexicographical sorting of the byte arrays yields the same
* sort order as sorting the values
*/
@Test
public void testRangeSortOrder() {
final List<Long> values = Arrays.asList(
10l,
0l,
15l,
-275l,
982l,
430l,
-1l,
1l,
82l);
final List<byte[]> byteArrays = new ArrayList<>(
values.size());
for (final long value : values) {
final byte[] bytes = getByteArray(value);
byteArrays.add(bytes);
}
Collections.sort(values);
Collections.sort(
byteArrays,
UnsignedBytes.lexicographicalComparator());
final List<Long> convertedValues = new ArrayList<>(
values.size());
for (final byte[] bytes : byteArrays) {
final long value = castToLong(strategy.getLexicoder().fromByteArray(
bytes));
convertedValues.add(value);
}
Assert.assertTrue(values.equals(convertedValues));
}
@Test
public void testGetInsertionIdsPoint() {
final long pointValue = 5926;
final MultiDimensionalNumericData indexedData = getIndexedRange(pointValue);
final List<ByteArrayId> insertionIds = strategy.getInsertionIds(indexedData);
Assert.assertEquals(
insertionIds.size(),
1);
final ByteArrayId insertionId = insertionIds.get(0);
Assert.assertEquals(
castToLong(strategy.getLexicoder().fromByteArray(
insertionId.getBytes())),
pointValue);
}
@Test
public void testGetInsertionIdsRange() {
final long startValue = 9876;
final long endValue = startValue + 15;
final MultiDimensionalNumericData indexedData = getIndexedRange(
startValue,
endValue);
final List<ByteArrayId> insertionIds = strategy.getInsertionIds(indexedData);
Assert.assertEquals(
insertionIds.size(),
(int) ((endValue - startValue) + 1));
int i = 0;
for (final ByteArrayId insertionId : insertionIds) {
Assert.assertEquals(
castToLong(strategy.getLexicoder().fromByteArray(
insertionId.getBytes())),
startValue + i++);
}
}
}