package mil.nga.giat.geowave.mapreduce; import java.util.HashMap; import java.util.Map; import org.apache.commons.collections.IteratorUtils; import org.apache.commons.collections.Transformer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.JobContext; import mil.nga.giat.geowave.core.index.ByteArrayId; import mil.nga.giat.geowave.core.store.CloseableIterator; import mil.nga.giat.geowave.core.store.CloseableIteratorWrapper; import mil.nga.giat.geowave.core.store.index.Index; import mil.nga.giat.geowave.core.store.index.IndexStore; import mil.nga.giat.geowave.core.store.index.PrimaryIndex; /** * This class implements an index store by first checking the job context for an * index and keeping a local cache of indices that have been discovered. It will * check the metadata store if it cannot find an index in the job context. */ public class JobContextIndexStore implements IndexStore { private static final Class<?> CLASS = JobContextIndexStore.class; private final JobContext context; private final IndexStore persistentIndexStore; private final Map<ByteArrayId, Index<?, ?>> indexCache = new HashMap<ByteArrayId, Index<?, ?>>(); public JobContextIndexStore( final JobContext context, final IndexStore persistentIndexStore ) { this.context = context; this.persistentIndexStore = persistentIndexStore; } @Override public void addIndex( final Index<?, ?> index ) { indexCache.put( index.getId(), index); } @Override public Index<?, ?> getIndex( final ByteArrayId indexId ) { Index<?, ?> index = indexCache.get(indexId); if (index == null) { index = getIndexInternal(indexId); } return index; } @Override public boolean indexExists( final ByteArrayId indexId ) { if (indexCache.containsKey(indexId)) { return true; } final Index<?, ?> index = getIndexInternal(indexId); return index != null; } private Index<?, ?> getIndexInternal( final ByteArrayId indexId ) { // first try to get it from the job context Index<?, ?> index = getIndex( context, indexId); if (index == null) { // then try to get it from the accumulo persistent store index = persistentIndexStore.getIndex(indexId); } if (index != null) { indexCache.put( indexId, index); } return index; } @Override public void removeAll() { indexCache.clear(); } @Override public CloseableIterator<Index<?, ?>> getIndices() { final CloseableIterator<Index<?, ?>> it = persistentIndexStore.getIndices(); // cache any results return new CloseableIteratorWrapper<Index<?, ?>>( it, IteratorUtils.transformedIterator( it, new Transformer() { @Override public Object transform( final Object obj ) { if (obj instanceof Index<?, ?>) { indexCache.put( ((Index<?, ?>) obj).getId(), (Index<?, ?>) obj); } return obj; } })); } public static void addIndex( final Configuration config, final PrimaryIndex index ) { GeoWaveConfiguratorBase.addIndex( CLASS, config, index); } protected static PrimaryIndex getIndex( final JobContext context, final ByteArrayId indexId ) { return GeoWaveConfiguratorBase.getIndex( CLASS, context, indexId); } public static PrimaryIndex[] getIndices( final JobContext context ) { return GeoWaveConfiguratorBase.getIndices( CLASS, context); } }