* Feed the transactionManager with the knowledge to handle database-modifying related requests.
*/
private void initializeTransactionManager() {
dbs.getTransactionManager().registerInMemoryProcessing(Operation.TYPE_CREATE_DB,
new InMemoryProcessing() {
@Override
public Object[] deserializeRequest(ReusableBuffer serialized) throws BabuDBException {
serialized.getInt(); // do not use, deprecated
String dbName = serialized.getString();
int indices = serialized.getInt();
serialized.flip();
return new Object[] { dbName, indices, null };
}
@Override
public OperationInternal convertToOperation(Object[] args) {
return new BabuDBTransaction.BabuDBOperation(Operation.TYPE_CREATE_DB,
(String) args[0], new Object[] { args[1], args[2] });
}
@Override
public DatabaseInternal process(OperationInternal operation) throws BabuDBException {
// parse args
Object[] args = operation.getParams();
int numIndices = (Integer) args[0];
ByteRangeComparator[] com = null;
if (args.length > 2) {
com = (ByteRangeComparator[]) args[1];
}
if (com == null) {
ByteRangeComparator[] comps = new ByteRangeComparator[numIndices];
final ByteRangeComparator defaultComparator = compInstances
.get(DefaultByteRangeComparator.class.getName());
for (int i = 0; i < numIndices; i++) {
comps[i] = defaultComparator;
}
com = comps;
}
DatabaseImpl db = null;
synchronized (getDBModificationLock()) {
synchronized (dbs.getCheckpointer()) {
if (dbsByName.containsKey(operation.getDatabaseName())) {
throw new BabuDBException(ErrorCode.DB_EXISTS, "database '" +
operation.getDatabaseName() + "' already exists");
}
final int dbId = nextDbId++;
db = new DatabaseImpl(dbs, new LSMDatabase(operation.getDatabaseName(),
dbId, dbs.getConfig().getBaseDir() + operation.getDatabaseName() +
File.separatorChar, numIndices, false, com, dbs.getConfig()
.getCompression(), dbs.getConfig().getMaxNumRecordsPerBlock(), dbs
.getConfig().getMaxBlockFileSize(),
dbs.getConfig().getDisableMMap(), dbs.getConfig().getMMapLimit()));
dbsById.put(dbId, db);
dbsByName.put(operation.getDatabaseName(), db);
dbs.getDBConfigFile().save();
}
}
return db;
}
});
dbs.getTransactionManager().registerInMemoryProcessing(Operation.TYPE_DELETE_DB,
new InMemoryProcessing() {
@Override
public Object[] deserializeRequest(ReusableBuffer serialized) throws BabuDBException {
serialized.getInt(); // do not use, deprecated
String dbName = serialized.getString();
serialized.flip();
return new Object[] { dbName };
}
@Override
public OperationInternal convertToOperation(Object[] args) {
return new BabuDBTransaction.BabuDBOperation(Operation.TYPE_DELETE_DB, (String) args[0],
null);
}
@Override
public Object process(OperationInternal operation) throws BabuDBException {
int dbId = InsertRecordGroup.DB_ID_UNKNOWN;
synchronized (getDBModificationLock()) {
synchronized (dbs.getCheckpointer()) {
if (!dbsByName.containsKey(operation.getDatabaseName())) {
throw new BabuDBException(ErrorCode.NO_SUCH_DB, "database '" +
operation.getDatabaseName() + "' does not exists");
}
final LSMDatabase db = getDatabase(operation.getDatabaseName()).getLSMDB();
dbId = db.getDatabaseId();
dbsByName.remove(operation.getDatabaseName());
dbsById.remove(dbId);
dbs.getSnapshotManager().deleteAllSnapshots(operation.getDatabaseName());
dbs.getDBConfigFile().save();
File dbDir = new File(dbs.getConfig().getBaseDir(),
operation.getDatabaseName());
if (dbDir.exists()) {
FSUtils.delTree(dbDir);
}
}
}
return null;
}
});
dbs.getTransactionManager().registerInMemoryProcessing(Operation.TYPE_COPY_DB,
new InMemoryProcessing() {
@Override
public Object[] deserializeRequest(ReusableBuffer serialized) throws BabuDBException {
serialized.getInt(); // do not use, deprecated
serialized.getInt(); // do not use, deprecated
String sourceDB = serialized.getString();
String destDB = serialized.getString();
serialized.flip();
return new Object[] { sourceDB, destDB };
}
@Override
public OperationInternal convertToOperation(Object[] args) {
return new BabuDBTransaction.BabuDBOperation(Operation.TYPE_COPY_DB, (String) args[0],
new Object[] { args[1] });
}
@Override
public Object process(OperationInternal operation) throws BabuDBException {
// parse args
String destDB = (String) operation.getParams()[0];
DatabaseInternal sDB = getDatabase(operation.getDatabaseName());
int dbId;
synchronized (getDBModificationLock()) {
synchronized (dbs.getCheckpointer()) {
if (dbsByName.containsKey(destDB)) {
throw new BabuDBException(ErrorCode.DB_EXISTS, "database '" + destDB
+ "' already exists");
}
dbId = nextDbId++;
// just "reserve" the name
dbsByName.put(destDB, null);
dbs.getDBConfigFile().save();
}
}
// materializing the snapshot takes some time, we should not
// hold the
// lock meanwhile!
try {
sDB.proceedSnapshot(destDB);
} catch (InterruptedException i) {
throw new BabuDBException(ErrorCode.INTERNAL_ERROR,
"Snapshot creation was interrupted.", i);
}
// create new DB and load from snapshot
DatabaseInternal newDB = new DatabaseImpl(dbs, new LSMDatabase(destDB, dbId,
dbs.getConfig().getBaseDir() + destDB + File.separatorChar,
sDB.getLSMDB().getIndexCount(), true, sDB.getComparators(),
dbs.getConfig().getCompression(),
dbs.getConfig().getMaxNumRecordsPerBlock(),
dbs.getConfig().getMaxBlockFileSize(), dbs.getConfig().getDisableMMap(),
dbs.getConfig().getMMapLimit()));
// insert real database
synchronized (dbModificationLock) {
dbsById.put(dbId, newDB);
dbsByName.put(destDB, newDB);
dbs.getDBConfigFile().save();
}
return null;
}
});
dbs.getTransactionManager().registerInMemoryProcessing(Operation.TYPE_GROUP_INSERT,
new InMemoryProcessing() {
@Override
public Object[] deserializeRequest(ReusableBuffer serialized) throws BabuDBException {
InsertRecordGroup irg = InsertRecordGroup.deserialize(serialized);