@Override public void setMetadata(FileMetadata metadata, byte type, AtomicDBUpdate update) throws DatabaseException { assert (metadata instanceof BufferBackedFileMetadata); BufferBackedFileMetadata md = (BufferBackedFileMetadata) metadata; int index = md.getIndexId(); if (type == -1) for (byte i = 0; i < BufferBackedFileMetadata.NUM_BUFFERS; i++) { byte[] valBuf = md.getValueBuffer(i); assert (valBuf != null); update.addUpdate( index, index == FILE_ID_INDEX ? BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), i) : md.getKeyBuffer(i), valBuf); } else { byte[] valBuf = md.getValueBuffer(type); assert (valBuf != null); update.addUpdate( index, index == FILE_ID_INDEX ? BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), type) : md.getKeyBuffer(type), valBuf); } }
@Override public void link( final FileMetadata metadata, final long newParentId, final String newFileName, final AtomicDBUpdate update) { // get the link source BufferBackedFileMetadata md = (BufferBackedFileMetadata) metadata; // increment the link count short links = metadata.getLinkCount(); md.setLinkCount((short) (links + 1)); // insert the whole metadata of the original file in the file ID // index update.addUpdate( FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), FileMetadata.FC_METADATA), md.getFCMetadataValue()); update.addUpdate( FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), FileMetadata.RC_METADATA), md.getRCMetadata().getValue()); // remove the back link update.addUpdate( FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), (byte) 3), null); // if the metadata was retrieved from the FILE_INDEX and hasn't // been deleted before (i.e. links == 0), ensure that the original // file in the file index now points to the file ID index, and // remove the FC and XLoc metadata entries if (links != 0 && md.getIndexId() == FILE_INDEX) { update.addUpdate( FILE_INDEX, md.getRCMetadata().getKey(), BabuDBStorageHelper.createLinkTarget(metadata.getId())); update.addUpdate(FILE_INDEX, md.getFCMetadataKey(), null); } // create an entry for the new link to the metadata in the file // index update.addUpdate( FILE_INDEX, BabuDBStorageHelper.createFileKey(newParentId, newFileName, FileMetadata.RC_METADATA), BabuDBStorageHelper.createLinkTarget(metadata.getId())); }
@Override public FileMetadata createSymLink( long fileId, long parentId, String fileName, int atime, int ctime, int mtime, String userId, String groupId, String ref, AtomicDBUpdate update) { // create metadata BufferBackedFileMetadata fileMetadata = new BufferBackedFileMetadata( parentId, fileName, userId, groupId, fileId, atime, ctime, mtime, ref.length(), 0777, 0, (short) 1, 0, 0, false); // create link target (XAttr) BufferBackedXAttr lt = new BufferBackedXAttr(fileId, SYSTEM_UID, LINK_TARGET_ATTR_NAME, ref.getBytes(), (short) 0); update.addUpdate(XATTRS_INDEX, lt.getKeyBuf(), lt.getValBuf()); // 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)); return fileMetadata; }
@Override public FileMetadata getMetadata(long fileId) throws DatabaseException { try { // create the key for the file ID index lookup byte[] key = BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) -1); ByteBuffer.wrap(key).putLong(fileId); byte[][] valBufs = new byte[BufferBackedFileMetadata.NUM_BUFFERS][]; // retrieve the metadata from the link index ResultSet<byte[], byte[]> it = database.prefixLookup(BabuDBStorageManager.FILE_ID_INDEX, key, null).get(); while (it.hasNext()) { Entry<byte[], byte[]> curr = it.next(); int type = BabuDBStorageHelper.getType(curr.getKey(), BabuDBStorageManager.FILE_ID_INDEX); // if the value is a back link, resolve it if (type == 3) { long parentId = ByteBuffer.wrap(curr.getValue()).getLong(); String fileName = new String(curr.getValue(), 8, curr.getValue().length - 8); return getMetadata(parentId, fileName); } valBufs[type] = curr.getValue(); } it.free(); // if not metadata was found for the file ID, return null if (valBufs[FileMetadata.RC_METADATA] == null) return null; byte[][] keyBufs = new byte[][] {null, BabuDBStorageHelper.createFileKey(0, "", FileMetadata.RC_METADATA)}; // otherwise, a hard link target is contained in the index; create a // new metadata object in this case return new BufferBackedFileMetadata(keyBufs, valBufs, BabuDBStorageManager.FILE_ID_INDEX); } 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 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); } }
public FileMetadata createDir( long fileId, long parentId, String fileName, int atime, int ctime, int mtime, String userId, String groupId, int perms, long w32Attrs, boolean initCount, AtomicDBUpdate update) throws DatabaseException { // create metadata BufferBackedFileMetadata fileMetadata = new BufferBackedFileMetadata( parentId, fileName, userId, groupId, fileId, atime, ctime, mtime, perms, w32Attrs, (short) 1); // 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)); if (initCount) initCount(NUM_DIRS_KEY, update); else updateCount(NUM_DIRS_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); } }