package mil.nga.giat.geowave.datastore.accumulo.query; import java.io.IOException; import java.util.Collections; import java.util.Iterator; import java.util.List; import org.apache.accumulo.core.client.Scanner; import org.apache.accumulo.core.client.ScannerBase; import org.apache.accumulo.core.client.TableNotFoundException; import org.apache.accumulo.core.data.Range; import org.apache.hadoop.io.Text; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.store.adapter.AdapterStore; import mil.nga.giat.geowave.core.store.filter.DedupeFilter; import mil.nga.giat.geowave.core.store.filter.FilterList; import mil.nga.giat.geowave.core.store.filter.QueryFilter; import mil.nga.giat.geowave.core.store.index.PrimaryIndex; import mil.nga.giat.geowave.core.store.query.QueryOptions; import mil.nga.giat.geowave.datastore.accumulo.AccumuloOperations; import mil.nga.giat.geowave.datastore.accumulo.util.InputFormatIteratorWrapper; /** * * Represents a query operation for a range of Accumulo row IDs. This class is * particularly used by the InputFormat as the iterator that it returns will * contain Entry<GeoWaveInputKey, Object> entries rather than just the object. * This is so the input format has a way of getting the adapter ID and data ID * to define the key. */ public class InputFormatAccumuloRangeQuery extends AccumuloConstraintsQuery { private final static Logger LOGGER = LoggerFactory.getLogger(InputFormatAccumuloRangeQuery.class); private final Range accumuloRange; private final boolean isOutputWritable; private static List<ByteArrayId> getAdapterIds( final PrimaryIndex index, final AdapterStore adapterStore, final QueryOptions queryOptions ) { try { return queryOptions.getAdapterIds(adapterStore); } catch (final IOException e) { LOGGER.error( "Adapter IDs not set and unattainable from the AdapterStore", e); } return Collections.emptyList(); } public InputFormatAccumuloRangeQuery( final AdapterStore adapterStore, final PrimaryIndex index, final Range accumuloRange, final List<QueryFilter> queryFilters, final boolean isOutputWritable, final QueryOptions queryOptions ) { super( getAdapterIds( index, adapterStore, queryOptions), index, null, queryFilters, (DedupeFilter) null, queryOptions.getScanCallback(), null, null, null, null, null, queryOptions.getAuthorizations()); this.accumuloRange = accumuloRange; this.isOutputWritable = isOutputWritable; } @Override protected ScannerBase getScanner( final AccumuloOperations accumuloOperations, final double[] maxResolutionSubsamplingPerDimension, final Integer limit ) { final String tableName = index.getId().getString(); Scanner scanner; try { scanner = accumuloOperations.createScanner( tableName, getAdditionalAuthorizations()); scanner.setRange(accumuloRange); if ((adapterIds != null) && !adapterIds.isEmpty()) { for (final ByteArrayId adapterId : adapterIds) { scanner.fetchColumnFamily(new Text( adapterId.getBytes())); } } return scanner; } catch (final TableNotFoundException e) { LOGGER.warn( "Unable to query table '" + tableName + "'. Table does not exist.", e); return null; } } @Override protected Iterator initIterator( final AdapterStore adapterStore, final ScannerBase scanner ) { return new InputFormatIteratorWrapper( useWholeRowIterator(), adapterStore, index, scanner.iterator(), isOutputWritable, clientFilters.isEmpty() ? null : clientFilters.size() == 1 ? clientFilters.get(0) : new FilterList<QueryFilter>( clientFilters)); } }