@Override
 public void deleteDatabase() throws DatabaseException {
   try {
     dbMan.deleteDatabase(database.getName());
     notifyVolumeDelete(volume.getId());
   } catch (BabuDBException exc) {
     throw new DatabaseException(exc);
   }
 }
  /**
   * Instantiates a storage manager by loading an existing volume database.
   *
   * @param dbs the database system
   * @param db the database
   */
  public BabuDBStorageManager(BabuDB dbs, Database db) throws DatabaseException {

    this.dbMan = dbs.getDatabaseManager();
    this.snapMan = dbs.getSnapshotManager();
    this.database = db;
    this.vcListeners = new LinkedList<VolumeChangeListener>();

    volume = new BabuDBVolumeInfo();
    volume.init(this);
  }
  public void setXAttr(
      long fileId, String uid, String key, byte[] value, boolean init, AtomicDBUpdate update)
      throws DatabaseException {

    try {
      short collNumber =
          init ? -1 : BabuDBStorageHelper.findXAttrCollisionNumber(database, fileId, uid, key);

      BufferBackedXAttr xattr = new BufferBackedXAttr(fileId, uid, key, value, collNumber);
      update.addUpdate(XATTRS_INDEX, xattr.getKeyBuf(), value == null ? null : xattr.getValBuf());

      if (key.startsWith(SYS_ATTR_KEY_PREFIX + MRCHelper.POLICY_ATTR_PREFIX))
        notifyAttributeSet(volume.getId(), key, value == null ? null : new String(value));

    } catch (BabuDBException exc) {
      throw new DatabaseException(exc);
    }
  }
  @Override
  public FileMetadata createFile(
      long fileId,
      long parentId,
      String fileName,
      int atime,
      int ctime,
      int mtime,
      String userId,
      String groupId,
      int perms,
      long w32Attrs,
      long size,
      boolean readOnly,
      int epoch,
      int issEpoch,
      AtomicDBUpdate update)
      throws DatabaseException {

    // create metadata
    BufferBackedFileMetadata fileMetadata =
        new BufferBackedFileMetadata(
            parentId, fileName, userId, groupId, fileId, atime, ctime, mtime, size, perms, w32Attrs,
            (short) 1, epoch, issEpoch, readOnly);

    // update main metadata in the file index
    update.addUpdate(
        FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue());
    update.addUpdate(
        FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue());

    // add an entry to the file ID index
    update.addUpdate(
        FILE_ID_INDEX,
        BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3),
        BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName));

    volume.updateVolumeSize(size, update);
    updateCount(NUM_FILES_KEY, true, update);

    return fileMetadata;
  }
  @Override
  public short delete(final long parentId, final String fileName, final AtomicDBUpdate update)
      throws DatabaseException {

    try {

      // retrieve the file metadata
      BufferBackedFileMetadata file = BabuDBStorageHelper.getMetadata(database, parentId, fileName);

      // check whether there is only one link remaining
      short newLinkCount = (short) (file.getLinkCount() - 1);
      assert (newLinkCount >= 0);

      // decrement the link count
      file.setLinkCount(newLinkCount);

      // if there will be links remaining after the deletion, update the
      // link count
      if (newLinkCount > 0)
        update.addUpdate(
            FILE_ID_INDEX,
            BabuDBStorageHelper.createFileIdIndexKey(file.getId(), FileMetadata.RC_METADATA),
            file.getRCMetadata().getValue());

      // delete all keys ...

      // remove all content from the file index
      update.addUpdate(
          BabuDBStorageManager.FILE_INDEX,
          BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.FC_METADATA),
          null);
      update.addUpdate(
          BabuDBStorageManager.FILE_INDEX,
          BabuDBStorageHelper.createFileKey(parentId, fileName, FileMetadata.RC_METADATA),
          null);

      // if the last link to the file is supposed to be deleted, remove
      // the remaining metadata, including ACLs and XAttrs
      if (newLinkCount == 0) {

        // remove the back link from the file ID index
        update.addUpdate(
            BabuDBStorageManager.FILE_ID_INDEX,
            BabuDBStorageHelper.createFileIdIndexKey(file.getId(), (byte) 3),
            null);

        // remove potentially existing metadata from the file ID index
        update.addUpdate(
            BabuDBStorageManager.FILE_ID_INDEX,
            BabuDBStorageHelper.createFileIdIndexKey(file.getId(), FileMetadata.FC_METADATA),
            null);
        update.addUpdate(
            BabuDBStorageManager.FILE_ID_INDEX,
            BabuDBStorageHelper.createFileIdIndexKey(file.getId(), FileMetadata.RC_METADATA),
            null);

        byte[] idBytes = new byte[8];
        ByteBuffer.wrap(idBytes).putLong(file.getId());

        // remove all ACLs
        ResultSet<byte[], byte[]> it =
            database.prefixLookup(BabuDBStorageManager.ACL_INDEX, idBytes, null).get();
        while (it.hasNext())
          update.addUpdate(BabuDBStorageManager.ACL_INDEX, it.next().getKey(), null);
        it.free();

        // remove all extended attributes
        it = database.prefixLookup(BabuDBStorageManager.XATTRS_INDEX, idBytes, null).get();
        while (it.hasNext())
          update.addUpdate(BabuDBStorageManager.XATTRS_INDEX, it.next().getKey(), null);
        it.free();

        // if a file is deleted, update file count and volume size
        if (file.isDirectory()) {
          updateCount(NUM_DIRS_KEY, false, update);
        } else if (file.getXLocList() != null) {
          volume.updateVolumeSize(-file.getSize(), update);
          updateCount(NUM_FILES_KEY, false, update);
        }
      }

      return file.getLinkCount();

    } catch (BabuDBException exc) {
      throw new DatabaseException(exc);
    }
  }
  /**
   * Instantiates a storage manager by creating a new database.
   *
   * @param dbs the database system
   * @param volumeId the volume ID
   */
  public BabuDBStorageManager(
      BabuDB dbs,
      String volumeId,
      String volumeName,
      short fileAccessPolicyId,
      short[] osdPolicy,
      short[] replPolicy,
      String ownerId,
      String owningGroupId,
      int perms,
      ACLEntry[] acl,
      org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.StripingPolicy rootDirDefSp,
      boolean allowSnaps,
      long volumeQuota,
      Map<String, String> attrs)
      throws DatabaseException {

    this.dbMan = dbs.getDatabaseManager();
    this.snapMan = dbs.getSnapshotManager();
    this.vcListeners = new LinkedList<VolumeChangeListener>();
    this.volume = new BabuDBVolumeInfo();

    TransactionalBabuDBUpdate update = new TransactionalBabuDBUpdate(dbMan);
    update.createDatabase(volumeId, 5);

    // atime, ctime, mtime
    int time = (int) (TimeSync.getGlobalTime() / 1000);

    // create the root directory; the name is the database name
    createDir(1, 0, volumeName, time, time, time, ownerId, owningGroupId, perms, 0, true, update);
    setLastFileId(1, update);

    volume.init(
        this,
        update.getDatabaseName(),
        volumeName,
        osdPolicy,
        replPolicy,
        fileAccessPolicyId,
        allowSnaps,
        volumeQuota,
        update);

    // set the default striping policy
    if (rootDirDefSp != null) setDefaultStripingPolicy(1, rootDirDefSp, true, update);

    if (acl != null)
      for (ACLEntry entry : acl) setACLEntry(1L, entry.getEntity(), entry.getRights(), update);

    if (attrs != null)
      for (Entry<String, String> attr : attrs.entrySet())
        setXAttr(
            1L,
            SYSTEM_UID,
            "xtreemfs.volattr." + attr.getKey(),
            attr.getValue().getBytes(),
            true,
            update);

    update.execute();

    try {
      database = dbMan.getDatabase(update.getDatabaseName());
    } catch (Exception exc) {
      throw new DatabaseException(exc);
    }

    notifyVolumeChange(volume);
  }
 @Override
 public String[] getAllSnapshots() {
   return snapMan.getAllSnapshots(volume.getId());
 }