package voldemort.store.routed;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import voldemort.VoldemortException;
import voldemort.cluster.Cluster;
import voldemort.cluster.failuredetector.FailureDetector;
import voldemort.store.Store;
import voldemort.store.StoreDefinition;
import voldemort.store.nonblockingstore.NonblockingStore;
import voldemort.store.nonblockingstore.ThreadPoolBasedNonblockingStoreImpl;
import voldemort.store.slop.Slop;
import voldemort.utils.ByteArray;
import com.google.common.collect.Maps;
public class RoutedStoreFactory {
private ExecutorService threadPool;
private final Logger logger = Logger.getLogger(getClass());
public RoutedStoreFactory() {
this.threadPool = null;
}
// TODO using threadPool to simulate nonblocking store isn't a good way and
// should be deprecated
// There are a few tests stilling using this path and should be cleaned up
// They can be identified by examining the call Hierarchy of this method
@Deprecated
public RoutedStoreFactory(ExecutorService threadPool) {
this.threadPool = threadPool;
}
public NonblockingStore toNonblockingStore(Store<ByteArray, byte[], byte[]> store) {
if(store instanceof NonblockingStore) {
return (NonblockingStore) store;
} else if(threadPool == null) {
throw new VoldemortException("ThreadPool is not initialized. ThreadPool is required in RoutedStoreFactory constructor if using blocking stores");
} else {
if(logger.isEnabledFor(Level.WARN)) {
logger.warn("Using pseudo NonblockingStore implementation for " + store.getClass());
}
return new ThreadPoolBasedNonblockingStoreImpl(threadPool, store);
}
}
@Deprecated
public void setThreadPool(ExecutorService threadPool) {
this.threadPool = threadPool;
}
public RoutedStore create(Cluster cluster,
StoreDefinition storeDefinition,
Map<Integer, Store<ByteArray, byte[], byte[]>> nodeStores,
FailureDetector failureDetector,
RoutedStoreConfig routedStoreConfig) {
Map<Integer, NonblockingStore> nonblockingStores = Maps.newHashMap();
for(Map.Entry<Integer, Store<ByteArray, byte[], byte[]>> entry: nodeStores.entrySet())
nonblockingStores.put(entry.getKey(), toNonblockingStore(entry.getValue()));
return create(cluster,
storeDefinition,
nodeStores,
nonblockingStores,
null,
null,
failureDetector,
routedStoreConfig);
}
private Map<String, PipelineRoutedStats> storeStatsMap = new HashMap<String, PipelineRoutedStats>();
private synchronized PipelineRoutedStats getPipelineRoutedStats(String storeName,
String identifierString) {
String key = storeName + identifierString;
if(storeStatsMap.containsKey(key)) {
return storeStatsMap.get(key);
}
PipelineRoutedStats stats = new PipelineRoutedStats(key);
storeStatsMap.put(key, stats);
return stats;
}
public RoutedStore create(Cluster cluster,
StoreDefinition storeDefinition,
Map<Integer, Store<ByteArray, byte[], byte[]>> nodeStores,
Map<Integer, NonblockingStore> nonblockingStores,
Map<Integer, Store<ByteArray, Slop, byte[]>> slopStores,
Map<Integer, NonblockingStore> nonblockingSlopStores,
FailureDetector failureDetector,
RoutedStoreConfig routedStoreConfig) {
PipelineRoutedStats stats = getPipelineRoutedStats(storeDefinition.getName(),
routedStoreConfig.getIdentifierString());
return new PipelineRoutedStore(nodeStores,
nonblockingStores,
slopStores,
nonblockingSlopStores,
cluster,
storeDefinition,
failureDetector,
routedStoreConfig.getRepairReads(),
routedStoreConfig.getTimeoutConfig(),
routedStoreConfig.getClientZoneId(),
routedStoreConfig.isJmxEnabled(),
stats,
routedStoreConfig.getZoneAffinity());
}
}