@Override public void deletePersistentSnapshot(String dbName, String snapshotName) throws BabuDBException { BabuDBRequestResultImpl<Object> result = new BabuDBRequestResultImpl<Object>(dbs.getResponseManager()); dbs.getTransactionManager() .makePersistent( dbs.getDatabaseManager().createTransaction().deleteSnapshot(dbName, snapshotName), result); result.get(); }
/* (non-Javadoc) * @see org.xtreemfs.babudb.api.SnapshotManager#createPersistentSnapshot(java.lang.String, org.xtreemfs.babudb.snapshots.SnapshotConfig) */ @Override public void createPersistentSnapshot(String dbName, SnapshotConfig snap) throws BabuDBException { // synchronously executing the request BabuDBRequestResultImpl<Object> result = new BabuDBRequestResultImpl<Object>(dbs.getResponseManager()); dbs.getTransactionManager() .makePersistent( dbs.getDatabaseManager().createTransaction().createSnapshot(dbName, snap), result); result.get(); }
/** Feed the transactionManager with the knowledge on how to handle snapshot related requests. */ private void initializeTransactionManager() { dbs.getTransactionManager() .registerInMemoryProcessing( Operation.TYPE_CREATE_SNAP, new InMemoryProcessing() { @Override public Object[] deserializeRequest(ReusableBuffer serialized) throws BabuDBException { ObjectInputStream oin = null; try { oin = new ObjectInputStream(new ByteArrayInputStream(serialized.array())); int dbId = oin.readInt(); SnapshotConfig snap = (SnapshotConfig) oin.readObject(); return new Object[] {dbId, snap}; } catch (Exception e) { throw new BabuDBException( ErrorCode.IO_ERROR, "Could not deserialize operation of type " + Operation.TYPE_CREATE_SNAP + ", because: " + e.getMessage(), e); } finally { try { serialized.flip(); if (oin != null) oin.close(); } catch (IOException ioe) { /* who cares? */ } } } @Override public OperationInternal convertToOperation(Object[] args) { return new BabuDBTransaction.BabuDBOperation( Operation.TYPE_CREATE_SNAP, (String) null, new Object[] {args[0], args[1]}); } @Override public Object process(OperationInternal operation) throws BabuDBException { Object[] args = operation.getParams(); // parse args int dbId = (Integer) args[0]; SnapshotConfig snap = (SnapshotConfig) args[1]; // complete arguments if (dbId == InsertRecordGroup.DB_ID_UNKNOWN && operation.getDatabaseName() != null) { dbId = dbs.getDatabaseManager() .getDatabase(operation.getDatabaseName()) .getLSMDB() .getDatabaseId(); operation.updateParams(new Object[] {dbId, snap}); } else if (operation.getDatabaseName() == null) { operation.updateDatabaseName( dbs.getDatabaseManager().getDatabase(dbId).getName()); } Map<String, Snapshot> snapMap = snapshotDBs.get(operation.getDatabaseName()); if (snapMap == null) { snapMap = new HashMap<String, Snapshot>(); snapshotDBs.put(operation.getDatabaseName(), snapMap); } // if the snapshot already exists ... if (snapMap.containsKey(snap.getName())) { throw new BabuDBException( ErrorCode.SNAP_EXISTS, "snapshot '" + snap.getName() + "' already exists"); } snapMap.put(snap.getName(), new Snapshot(null, dbs)); // first, create new in-memory snapshots of all indices int[] snapIds = null; try { dbs.getTransactionManager().lockService(); // create the snapshot snapIds = dbs.getDatabaseManager() .getDatabase(dbId) .getLSMDB() .createSnapshot(snap.getIndices()); } catch (InterruptedException e) { throw new BabuDBException(ErrorCode.INTERRUPTED, e.getMessage()); } finally { dbs.getTransactionManager().unlockService(); } // then, enqueue a snapshot materialization request in the // checkpointer's queue dbs.getCheckpointer() .addSnapshotMaterializationRequest(operation.getDatabaseName(), snapIds, snap); // as long as the snapshot has not been persisted yet, add a view on // the current snapshot in the original database to the snapshot DB map synchronized (snapshotDBs) { Snapshot s = snapMap.get(snap.getName()); if (s.getView() == null) { s.setView(new InMemoryView(dbs, operation.getDatabaseName(), snap, snapIds)); } } return null; } }); dbs.getTransactionManager() .registerInMemoryProcessing( Operation.TYPE_DELETE_SNAP, new InMemoryProcessing() { @Override public Object[] deserializeRequest(ReusableBuffer serialized) throws BabuDBException { byte[] payload = serialized.array(); int offs = payload[0]; String dbName = new String(payload, 1, offs); String snapName = new String(payload, offs + 1, payload.length - offs - 1); serialized.flip(); return new Object[] {dbName, snapName}; } @Override public OperationInternal convertToOperation(Object[] args) { return new BabuDBTransaction.BabuDBOperation( Operation.TYPE_DELETE_SNAP, (String) args[0], new Object[] {args[1]}); } @Override public Object process(OperationInternal operation) throws BabuDBException { // parse args String snapshotName = (String) operation.getParams()[0]; final Map<String, Snapshot> snapMap = snapshotDBs.get(operation.getDatabaseName()); if (snapMap == null) { throw new BabuDBException( ErrorCode.NO_SUCH_SNAPSHOT, "snapshot '" + snapshotName + "' does not exist"); } final Snapshot snap = snapMap.get(snapshotName); // if the snapshot does not exist ... if (snap == null) { throw new BabuDBException( ErrorCode.NO_SUCH_SNAPSHOT, "snapshot '" + snapshotName + "' does not exist"); } // shut down and remove the view snap.getView().shutdown(); snapMap.remove(snapshotName); // if a snapshot materialization request is currently in the // checkpointer queue, remove it dbs.getCheckpointer() .removeSnapshotMaterializationRequest( operation.getDatabaseName(), snapshotName); // delete the snapshot subdirectory on disk if available FSUtils.delTree( new File(getSnapshotDir(operation.getDatabaseName(), snapshotName))); return null; } }); }