package org.deephacks.confit.internal.berkeley;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.Environment;
import org.deephacks.confit.admin.query.BeanQuery;
import org.deephacks.confit.internal.berkeley.BerkeleyDb.ForEachBean;
import org.deephacks.confit.model.AbortRuntimeException;
import org.deephacks.confit.model.Bean;
import org.deephacks.confit.model.BeanId;
import org.deephacks.confit.model.Events;
import org.deephacks.confit.model.Schema;
import org.deephacks.confit.serialization.BytesUtils;
import org.deephacks.confit.spi.BeanManager;
import org.deephacks.confit.spi.Lookup;
import org.deephacks.confit.spi.SchemaManager;
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
public class BerkeleyBeanManager extends BeanManager {
public static final String BERKELEY_DB_NAME = "confit.berkeley";
public static final String BERKELEY_DB_REFERENCES = "confit.berkeleyRefs";
private static final SchemaManager schemaManager = SchemaManager.lookup();
private final BerkeleyDb db;
public BerkeleyBeanManager() {
Environment env = Lookup.get().lookup(Environment.class);
Preconditions.checkNotNull(env);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setTransactional(true);
dbConfig.setAllowCreate(true);
dbConfig.setSortedDuplicates(false);
dbConfig.setBtreeComparator(new FastKeyComparator());
// all keys have schema name prefix
dbConfig.setKeyPrefixing(true);
Database database = env.openDatabase(null, BERKELEY_DB_NAME, dbConfig);
db = new BerkeleyDb(new TxDatabase(database));
}
@Override
public void create(Bean bean) throws AbortRuntimeException {
try {
byte[] key = bean.getId().write();
byte[] value = bean.write();
if (!db.put(key, value)) {
throw Events.CFG303_BEAN_ALREADY_EXIST(bean.getId());
}
db.commit();
} catch (AbortRuntimeException e) {
db.abort();
throw e;
} catch (Exception e) {
db.abort();
throw new RuntimeException(e);
}
}
@Override
public void create(Collection <Bean> beans) throws AbortRuntimeException {
for (Bean bean : beans) {
byte[] key = bean.getId().write();
byte[] value = bean.write();
if (!db.put(key, value)) {
throw Events.CFG303_BEAN_ALREADY_EXIST(bean.getId());
}
}
db.commit();
}
@Override
public void createSingleton(BeanId singleton) {
try {
byte[] key = singleton.write();
db.put(key, new byte[0]);
db.commit();
} catch (AbortRuntimeException e) {
db.abort();
throw e;
} catch (Exception e) {
db.abort();
throw new RuntimeException(e);
}
}
@Override
public void set(Bean bean) {
}
@Override
public void set(Collection<Bean> bean) throws AbortRuntimeException {
}
@Override
public void merge(Bean bean) throws AbortRuntimeException {
}
@Override
public void merge(Collection<Bean> bean) throws AbortRuntimeException {
}
@Override
public Optional<Bean> getEager(BeanId id) throws AbortRuntimeException {
byte[] key = id.write();
Optional<byte[]> optionalValue = db.get(key);
if (!optionalValue.isPresent()) {
return Optional.absent();
}
Bean bean = Bean.read(id, optionalValue.get());
return Optional.fromNullable(bean);
}
@Override
public Optional<Bean> getLazy(BeanId id) throws AbortRuntimeException {
return null;
}
@Override
public Optional<Bean> getSingleton(String schemaName) throws IllegalArgumentException {
return null;
}
@Override
public Map<BeanId, Bean> list(final String schemaName) throws AbortRuntimeException {
final Map<BeanId, Bean> beans = new LinkedHashMap<>();
db.list(schemaName, new ForEachBean() {
@Override
public boolean match(BeanId id, byte[] data) {
Bean bean = Bean.read(id, data);
beans.put(id, bean);
return true;
}
});
return beans;
}
@Override
public Map<BeanId, Bean> list(final String schemaName, final Collection<String> ids) throws AbortRuntimeException {
final Map<BeanId, Bean> beans = new LinkedHashMap<>();
db.list(schemaName, new ForEachBean() {
@Override
public boolean match(BeanId id, byte[] data) {
if (ids.contains(id.getInstanceId())) {
Bean bean = Bean.read(id, data);
beans.put(id, bean);
}
return true;
}
});
return beans;
}
@Override
public Bean delete(BeanId id) throws AbortRuntimeException {
return null;
}
@Override
public Collection<Bean> delete(String schemaName, Collection<String> instanceIds) throws AbortRuntimeException {
return null;
}
@Override
public BeanQuery newQuery(Schema schema) {
return null;
}
static class FastKeyComparator implements Comparator<byte[]>, Serializable {
@Override
public int compare(byte[] o1, byte[] o2) {
return BytesUtils.compareTo(o1, 0, o1.length, o2, 0, o2.length);
}
}
}