package com.jivesoftware.os.amza.berkeleydb; import com.google.common.collect.Sets; import com.jivesoftware.os.amza.api.AmzaVersionConstants; import com.jivesoftware.os.amza.api.partition.VersionedPartitionName; import com.jivesoftware.os.amza.api.wal.WALIndexProvider; import com.jivesoftware.os.mlogger.core.MetricLogger; import com.jivesoftware.os.mlogger.core.MetricLoggerFactory; import com.sleepycat.je.DatabaseNotFoundException; import com.sleepycat.je.Environment; import com.sleepycat.je.EnvironmentConfig; import java.io.File; import java.util.Set; /** * */ public class BerkeleyDBWALIndexProvider implements WALIndexProvider<BerkeleyDBWALIndex> { private static final MetricLogger LOG = MetricLoggerFactory.getLogger(); public static final String INDEX_CLASS_NAME = "berkeleydb"; private final String name; private final Environment[] environments; public BerkeleyDBWALIndexProvider(String name, int numberOfStripes, File[] baseDirs) { this.name = name; this.environments = new Environment[numberOfStripes]; for (int i = 0; i < environments.length; i++) { File active = new File(new File(new File(baseDirs[i % baseDirs.length], AmzaVersionConstants.LATEST_VERSION), INDEX_CLASS_NAME), String.valueOf(i)); if (!active.exists() && !active.mkdirs()) { throw new RuntimeException("Failed while trying to mkdirs for " + active); } // Open the environment, creating one if it does not exist EnvironmentConfig envConfig = new EnvironmentConfig() //.setConfigParam(EnvironmentConfig.ENV_RUN_CHECKPOINTER, "false") .setAllowCreate(true) .setSharedCache(true); envConfig.setCachePercentVoid(30); this.environments[i] = new Environment(active, envConfig); } } @Override public String getName() { return name; } @Override public BerkeleyDBWALIndex createIndex(VersionedPartitionName versionedPartitionName, int maxValueSizeInIndex, int stripe) throws Exception { BerkeleyDBWALIndexName indexName = new BerkeleyDBWALIndexName(BerkeleyDBWALIndexName.Type.active, versionedPartitionName.toBase64()); return new BerkeleyDBWALIndex(name, versionedPartitionName, environments, indexName, stripe); } @Override public void deleteIndex(VersionedPartitionName versionedPartitionName, int stripe) throws Exception { BerkeleyDBWALIndexName name = new BerkeleyDBWALIndexName(BerkeleyDBWALIndexName.Type.active, versionedPartitionName.toBase64()); Environment env = environments[stripe]; for (BerkeleyDBWALIndexName n : name.all()) { try { env.removeDatabase(null, n.getPrimaryName()); LOG.info("Removed database: {}", n.getPrimaryName()); } catch (DatabaseNotFoundException x) { // ignore } try { env.removeDatabase(null, n.getPrefixName()); LOG.info("Removed database: {}", n.getPrefixName()); } catch (DatabaseNotFoundException x) { // ignore } } } @Override public void flush(Iterable<BerkeleyDBWALIndex> indexes, boolean fsync) throws Exception { Set<Integer> stripes = Sets.newHashSet(); for (BerkeleyDBWALIndex index : indexes) { stripes.add(index.getStripe()); } for (int stripe : stripes) { environments[stripe].flushLog(fsync); } } @Override public void start() { } @Override public void stop() { } }