package mil.nga.giat.geowave.datastore.hbase.query; import java.io.IOException; import java.nio.ByteBuffer; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.exceptions.DeserializationException; import org.apache.hadoop.hbase.filter.FilterBase; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.index.MultiDimensionalCoordinateRangesArray; import mil.nga.giat.geowave.core.index.MultiDimensionalCoordinateRangesArray.ArrayOfArrays; import mil.nga.giat.geowave.core.index.MultiDimensionalCoordinates; import mil.nga.giat.geowave.core.index.NumericIndexStrategy; import mil.nga.giat.geowave.core.index.PersistenceUtils; import mil.nga.giat.geowave.core.store.entities.GeowaveRowId; import mil.nga.giat.geowave.core.store.query.CoordinateRangeUtils.RangeCache; import mil.nga.giat.geowave.core.store.query.CoordinateRangeUtils.RangeLookupFactory; public class HBaseNumericIndexStrategyFilter extends FilterBase { private NumericIndexStrategy indexStrategy; private MultiDimensionalCoordinateRangesArray[] coordinateRanges; private RangeCache rangeCache; public HBaseNumericIndexStrategyFilter() {} public HBaseNumericIndexStrategyFilter( final NumericIndexStrategy indexStrategy, final MultiDimensionalCoordinateRangesArray[] coordinateRanges ) { super(); this.indexStrategy = indexStrategy; this.coordinateRanges = coordinateRanges; rangeCache = RangeLookupFactory.createMultiRangeLookup(coordinateRanges); } public static HBaseNumericIndexStrategyFilter parseFrom( final byte[] pbBytes ) throws DeserializationException { final ByteBuffer buf = ByteBuffer.wrap(pbBytes); NumericIndexStrategy indexStrategy; MultiDimensionalCoordinateRangesArray[] coordinateRanges; try { final int indexStrategyLength = buf.getInt(); final byte[] indexStrategyBytes = new byte[indexStrategyLength]; buf.get(indexStrategyBytes); indexStrategy = PersistenceUtils.fromBinary( indexStrategyBytes, NumericIndexStrategy.class); final byte[] coordRangeBytes = new byte[pbBytes.length - indexStrategyLength - 4]; buf.get(coordRangeBytes); final ArrayOfArrays arrays = new ArrayOfArrays(); arrays.fromBinary(coordRangeBytes); coordinateRanges = arrays.getCoordinateArrays(); } catch (final Exception e) { throw new DeserializationException( "Unable to read parameters", e); } return new HBaseNumericIndexStrategyFilter( indexStrategy, coordinateRanges); } @Override public byte[] toByteArray() throws IOException { final byte[] indexStrategyBytes = PersistenceUtils.toBinary(indexStrategy); final byte[] coordinateRangesBinary = new ArrayOfArrays( coordinateRanges).toBinary(); final ByteBuffer buf = ByteBuffer.allocate(coordinateRangesBinary.length + indexStrategyBytes.length + 4); buf.putInt(indexStrategyBytes.length); buf.put(indexStrategyBytes); buf.put(coordinateRangesBinary); return buf.array(); } @Override public ReturnCode filterKeyValue( final Cell cell ) throws IOException { if (inBounds(cell)) { return ReturnCode.INCLUDE; } return ReturnCode.SKIP; } private boolean inBounds( final Cell cell ) { final MultiDimensionalCoordinates coordinates = indexStrategy.getCoordinatesPerDimension(new ByteArrayId( new GeowaveRowId( cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()).getInsertionId())); return rangeCache.inBounds(coordinates); } }