package org.deephacks.confit.internal.berkeley; import com.google.common.base.Optional; import com.sleepycat.je.DatabaseConfig; import com.sleepycat.je.Environment; import org.deephacks.confit.serialization.Bytes; import org.deephacks.confit.serialization.UniqueIds; import org.deephacks.confit.spi.Lookup; import static java.nio.charset.StandardCharsets.UTF_8; public class BerkeleyUniqueIds extends UniqueIds { private static final String SCHEMAS = "schemas"; private static final String INSTANCES = "instances"; private final TxDatabase instances; private final TxDatabase schemas; private final byte NAME_PREFIX = 0; private final byte ID_PREFIX = 1; public BerkeleyUniqueIds() { super(true); Environment env = Lookup.get().lookup(Environment.class); DatabaseConfig dbConfig = new DatabaseConfig(); dbConfig.setTransactional(true); dbConfig.setAllowCreate(true); dbConfig.setSortedDuplicates(false); this.schemas = new TxDatabase(env.openDatabase(null, SCHEMAS, dbConfig)); this.instances = new TxDatabase(env.openDatabase(null, INSTANCES, dbConfig)); } @Override protected String getSchemaNameFromStorage(int id) { Optional<byte[]> optionalName = schemas.get(getIdKey(id)); if (optionalName.isPresent()) { return new String(optionalName.get(), UTF_8); } throw new IllegalArgumentException("Id does not exist in storage " + id); } @Override protected int getSchemaIdFromStorage(String name) { byte[] nameBytes = name.getBytes(UTF_8); Optional <byte[]> optionalId = schemas.get(getNameKey(nameBytes)); if (optionalId.isPresent()) { return Bytes.getInt(optionalId.get()); } byte[] key = SCHEMAS.getBytes(UTF_8); long id = schemas.increment(key); byte[] nameKey = getNameKey(nameBytes); byte[] idKey = getIdKey(id); schemas.put(nameKey, Bytes.fromLong(id)); schemas.put(idKey, nameBytes); return (int) id; } @Override protected String getInstanceNameFromStorage(long id) { Optional<byte[]> optionalName = instances.get(getIdKey(id)); if (optionalName.isPresent()) { return new String(optionalName.get(), UTF_8); } throw new IllegalArgumentException("Id does not exist in storage " + id); } @Override protected long getInstanceIdFromStorage(String name) { byte[] nameBytes = name.getBytes(UTF_8); Optional <byte[]> optionalId = instances.get(getNameKey(nameBytes)); if (optionalId.isPresent()) { return Bytes.getLong(optionalId.get()); } byte[] key = INSTANCES.getBytes(UTF_8); long id = instances.increment(key); byte[] nameKey = getNameKey(nameBytes); byte[] idKey = getIdKey(id); instances.put(nameKey, Bytes.fromLong(id)); instances.put(idKey, nameBytes); return id; } private byte[] getIdKey(long id) { byte[] k = Bytes.fromLong(id); return new byte[] { ID_PREFIX, k[0], k[1], k[2], k[3], k[4], k[5], k[6], k[7]}; } private byte[] getNameKey(byte[] name) { byte[] key = new byte[name.length + 1]; key[0] = NAME_PREFIX; System.arraycopy(name, 0, key, 1, name.length); return key; } }