package mil.nga.giat.geowave.datastore.accumulo.query; import java.io.IOException; import java.util.Iterator; import java.util.List; import org.apache.accumulo.core.client.ScannerBase; import org.apache.commons.lang3.tuple.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.Iterators; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.index.StringUtils; import mil.nga.giat.geowave.core.store.CloseableIterator; import mil.nga.giat.geowave.core.store.CloseableIteratorWrapper; import mil.nga.giat.geowave.core.store.adapter.AdapterStore; import mil.nga.giat.geowave.core.store.adapter.DataAdapter; import mil.nga.giat.geowave.core.store.callback.ScanCallback; import mil.nga.giat.geowave.core.store.data.visibility.DifferingFieldVisibilityEntryCount; 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.FilteredIndexQuery; import mil.nga.giat.geowave.datastore.accumulo.AccumuloOperations; import mil.nga.giat.geowave.datastore.accumulo.util.AccumuloEntryIteratorWrapper; import mil.nga.giat.geowave.datastore.accumulo.util.ScannerClosableWrapper; public abstract class AccumuloFilteredIndexQuery extends AccumuloQuery implements FilteredIndexQuery { protected List<QueryFilter> clientFilters; private final static Logger LOGGER = LoggerFactory.getLogger(AccumuloFilteredIndexQuery.class); protected final ScanCallback<?> scanCallback; public AccumuloFilteredIndexQuery( final List<ByteArrayId> adapterIds, final PrimaryIndex index, final ScanCallback<?> scanCallback, final Pair<List<String>, DataAdapter<?>> fieldIdsAdapterPair, final DifferingFieldVisibilityEntryCount visibilityCounts, final String... authorizations ) { super( adapterIds, index, fieldIdsAdapterPair, visibilityCounts, authorizations); this.scanCallback = scanCallback; } protected List<QueryFilter> getClientFilters() { return clientFilters; } @Override public void setClientFilters( final List<QueryFilter> clientFilters ) { this.clientFilters = clientFilters; } protected abstract void addScanIteratorSettings( final ScannerBase scanner ); @SuppressWarnings("rawtypes") public CloseableIterator<Object> query( final AccumuloOperations accumuloOperations, final AdapterStore adapterStore, final double[] maxResolutionSubsamplingPerDimension, final Integer limit ) { boolean exists = false; try { exists = accumuloOperations.tableExists(StringUtils.stringFromBinary(index.getId().getBytes())); } catch (final IOException e) { LOGGER.error( "Table does not exist", e); } if (!exists) { LOGGER.warn("Table does not exist " + StringUtils.stringFromBinary(index.getId().getBytes())); return new CloseableIterator.Empty(); } final ScannerBase scanner = getScanner( accumuloOperations, maxResolutionSubsamplingPerDimension, limit); if (scanner == null) { LOGGER.error("Could not get scanner instance, getScanner returned null"); return new CloseableIterator.Empty(); } addScanIteratorSettings(scanner); Iterator it = initIterator( adapterStore, scanner); if ((limit != null) && (limit > 0)) { it = Iterators.limit( it, limit); } return initCloseableIterator( scanner, it); } protected CloseableIterator<Object> initCloseableIterator( ScannerBase scanner, Iterator it ) { return new CloseableIteratorWrapper( new ScannerClosableWrapper( scanner), it); } protected Iterator initIterator( final AdapterStore adapterStore, final ScannerBase scanner ) { return new AccumuloEntryIteratorWrapper( useWholeRowIterator(), adapterStore, index, scanner.iterator(), clientFilters.isEmpty() ? null : clientFilters.size() == 1 ? clientFilters.get(0) : new FilterList<QueryFilter>( clientFilters), scanCallback); } }