@Override
  public short unlink(final long parentId, final String fileName, final AtomicDBUpdate update)
      throws DatabaseException {

    try {

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

      // determine and set the new link count
      short newLinkCount = (short) (file.getLinkCount() - 1);
      file.setLinkCount(newLinkCount);

      // if there will be links remaining after the deletion, update the
      // link count; it must be in the FILE_ID_INDEX, because there have
      // been at least two links
      if (newLinkCount > 0)
        update.addUpdate(
            FILE_ID_INDEX,
            BabuDBStorageHelper.createFileIdIndexKey(file.getId(), FileMetadata.RC_METADATA),
            file.getRCMetadata().getValue());

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

      return newLinkCount;

    } catch (BabuDBException exc) {
      throw new DatabaseException(exc);
    }
  }
  @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);
    }
  }