package com.bigdata.service; import java.util.concurrent.ExecutionException; import com.bigdata.journal.ITx; import com.bigdata.journal.NoSuchIndexException; import com.bigdata.mdi.IMetadataIndex; import com.bigdata.mdi.MetadataIndex.MetadataIndexMetadata; import com.bigdata.util.InnerCause; /** * Concrete implementation for {@link IMetadataIndex} views. * * @author <a href="mailto:thompsonbry@users.sourceforge.net">Bryan Thompson</a> * @version $Id$ * @param <T> */ public class MetadataIndexCache extends AbstractIndexCache<IMetadataIndex>{ /** * Text for an exception thrown when the metadata service has not been * discovered. */ protected static transient final String ERR_NO_METADATA_SERVICE = "Metadata service"; private final AbstractScaleOutFederation<?> fed; public MetadataIndexCache(final AbstractScaleOutFederation<?> fed, final int capacity, final long timeout) { super(capacity, timeout); if (fed == null) throw new IllegalArgumentException(); this.fed = fed; } @Override protected IMetadataIndex newView(final String name, final long timestamp) { final MetadataIndexMetadata mdmd = getMetadataIndexMetadata( name, timestamp); // No such index. if (mdmd == null) return null; switch (fed.metadataIndexCachePolicy) { case NoCache: { return new NoCacheMetadataIndexView(fed, name, timestamp, mdmd); } case CacheAll: { if (timestamp == ITx.UNISOLATED || timestamp == ITx.READ_COMMITTED) { /* * A class that is willing to update its cache if the client * discovers stale locators. */ return new CachingMetadataIndex(fed, name, timestamp, mdmd); } else { /* * A class that caches all the locators. This is used for * historical reads since the locators can not become stale. */ return new CacheOnceMetadataIndex(fed, name, timestamp, mdmd); } } default: throw new AssertionError("Unknown option: " + fed.metadataIndexCachePolicy); } } /** * Return the metadata for the metadata index itself. * <p> * Note: This method always reads through! * * @param name * The name of the scale-out index. * * @param timestamp * * @return The metadata for the metadata index or <code>null</code> * iff no scale-out index is registered by that name at that * timestamp. */ protected MetadataIndexMetadata getMetadataIndexMetadata(final String name, final long timestamp) { final IMetadataService mds = fed.getMetadataService(); if (mds == null) throw new NoSuchService(ERR_NO_METADATA_SERVICE); final MetadataIndexMetadata mdmd; try { // @todo test cache for this object as of that timestamp? mdmd = (MetadataIndexMetadata) mds.getIndexMetadata( MetadataService.getMetadataIndexName(name), timestamp); assert mdmd != null; } catch( NoSuchIndexException ex ) { return null; } catch (ExecutionException ex) { if (InnerCause.isInnerCause(ex, NoSuchIndexException.class)) { // per API. return null; } throw new RuntimeException(ex); } catch (Exception ex) { throw new RuntimeException(ex); } if (mdmd == null) { // No such index. return null; } return mdmd; } }