@Override public final void customUndo(byte[] message) throws IOException { if (mDatabase.mCustomTxnHandler == null) { throw new IllegalStateException("Custom transaction handler is not installed"); } check(); final CommitLock.Shared shared = mDatabase.commitLock().acquireShared(); try { undoLog().pushCustom(message); } catch (Throwable e) { borked(e, true, true); // rollback = true, rethrow = true } finally { shared.release(); } }
@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i=0; i<pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
/** * Called by _Tree.drop with root node latch held exclusively. * * @param shared commit lock held shared; always released by this method */ Runnable deleteTree(_Tree tree, CommitLock.Shared shared) throws IOException { try { if (!(tree instanceof _TempTree) && !moveToTrash(tree.mId, tree.mIdBytes)) { // Handle concurrent delete attempt. throw new ClosedIndexException(); } } finally { // Always release before calling close, which might require an exclusive lock. shared.release(); } _Node root = tree.close(true, true); if (root == null) { // Handle concurrent close attempt. throw new ClosedIndexException(); } _Tree trashed = newTreeInstance(tree.mId, tree.mIdBytes, tree.mName, root); return new Deletion(trashed, false, null); }
@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i=0; i<pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
/** * Called by Tree.drop with root node latch held exclusively. * * @param shared commit lock held shared; always released by this method */ Runnable deleteTree(Tree tree, CommitLock.Shared shared) throws IOException { try { if (!(tree instanceof TempTree) && !moveToTrash(tree.mId, tree.mIdBytes)) { // Handle concurrent delete attempt. throw new ClosedIndexException(); } } finally { // Always release before calling close, which might require an exclusive lock. shared.release(); } Node root = tree.close(true, true); if (root == null) { // Handle concurrent close attempt. throw new ClosedIndexException(); } Tree trashed = newTreeInstance(tree.mId, tree.mIdBytes, tree.mName, root); return new Deletion(trashed, false, null); }
@Override public void setLength(long length) throws IOException { // FIXME: txn undo/redo try { if (length < 0) { mCursor.store(null); return; } final _CursorFrame leaf = mCursor.leafExclusive(); final CommitLock.Shared shared = mCursor.commitLock(leaf); try { mCursor.notSplitDirty(leaf); action(leaf, OP_SET_LENGTH, length, EMPTY_BYTES, 0, 0); leaf.mNode.releaseExclusive(); } finally { shared.release(); } } catch (IllegalStateException e) { checkOpen(); throw e; } }
@Override public void setLength(long length) throws IOException { // FIXME: txn undo/redo try { if (length < 0) { mCursor.store(null); return; } final _CursorFrame leaf = mCursor.leafExclusive(); final CommitLock.Shared shared = mCursor.commitLock(leaf); try { mCursor.notSplitDirty(leaf); action(leaf, OP_SET_LENGTH, length, EMPTY_BYTES, 0, 0); leaf.mNode.releaseExclusive(); } finally { shared.release(); } } catch (IllegalStateException e) { checkOpen(); throw e; } }
/** * Must be called after all entries in the tree have been deleted and tree is closed. */ void removeFromTrash(Tree tree, Node root) throws IOException { byte[] trashIdKey = newKey(KEY_TYPE_TRASH_ID, tree.mIdBytes); CommitLock.Shared shared = mCommitLock.acquireShared(); try { if (root != null) { root.acquireExclusive(); if (root.mPage == p_closedTreePage()) { // Database has been closed. root.releaseExclusive(); return; } deleteNode(root); } mRegistryKeyMap.delete(Transaction.BOGUS, trashIdKey); mRegistry.delete(Transaction.BOGUS, tree.mIdBytes); } catch (Throwable e) { throw closeOnFailure(this, e); } finally { shared.release(); } }
/** * Called by _Tree.drop with root node latch held exclusively. * * @param shared commit lock held shared; always released by this method */ Runnable deleteTree(_Tree tree, CommitLock.Shared shared) throws IOException { try { if (!(tree instanceof _TempTree) && !moveToTrash(tree.mId, tree.mIdBytes)) { // Handle concurrent delete attempt. throw new ClosedIndexException(); } } finally { // Always release before calling close, which might require an exclusive lock. shared.release(); } _Node root = tree.close(true, true); if (root == null) { // Handle concurrent close attempt. throw new ClosedIndexException(); } _Tree trashed = newTreeInstance(tree.mId, tree.mIdBytes, tree.mName, root); return new Deletion(trashed, false, null); }
/** * Called by Tree.drop with root node latch held exclusively. * * @param shared commit lock held shared; always released by this method */ Runnable deleteTree(Tree tree, CommitLock.Shared shared) throws IOException { try { if (!(tree instanceof TempTree) && !moveToTrash(tree.mId, tree.mIdBytes)) { // Handle concurrent delete attempt. throw new ClosedIndexException(); } } finally { // Always release before calling close, which might require an exclusive lock. shared.release(); } Node root = tree.close(true, true); if (root == null) { // Handle concurrent close attempt. throw new ClosedIndexException(); } Tree trashed = newTreeInstance(tree.mId, tree.mIdBytes, tree.mName, root); return new Deletion(trashed, false, null); }
@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i=0; i<pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i=0; i<pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i=0; i<pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
/** * Called by _Tree.drop with root node latch held exclusively. * * @param shared commit lock held shared; always released by this method */ Runnable deleteTree(_Tree tree, CommitLock.Shared shared) throws IOException { try { if (!(tree instanceof _TempTree) && !moveToTrash(tree.mId, tree.mIdBytes)) { // Handle concurrent delete attempt. throw new ClosedIndexException(); } } finally { // Always release before calling close, which might require an exclusive lock. shared.release(); } _Node root = tree.close(true, true); if (root == null) { // Handle concurrent close attempt. throw new ClosedIndexException(); } _Tree trashed = newTreeInstance(tree.mId, tree.mIdBytes, tree.mName, root); return new Deletion(trashed, false, null); }
@Override public void setLength(long length) throws IOException { // FIXME: txn undo/redo try { if (length < 0) { mCursor.store(null); return; } final CursorFrame leaf = mCursor.leafExclusive(); final CommitLock.Shared shared = mCursor.commitLock(leaf); try { mCursor.notSplitDirty(leaf); action(leaf, OP_SET_LENGTH, length, EMPTY_BYTES, 0, 0); leaf.mNode.releaseExclusive(); } finally { shared.release(); } } catch (IllegalStateException e) { checkOpen(); throw e; } }
/** * Called by Tree.drop with root node latch held exclusively. * * @param shared commit lock held shared; always released by this method */ Runnable deleteTree(Tree tree, CommitLock.Shared shared) throws IOException { try { if (!(tree instanceof TempTree) && !moveToTrash(tree.mId, tree.mIdBytes)) { // Handle concurrent delete attempt. throw new ClosedIndexException(); } } finally { // Always release before calling close, which might require an exclusive lock. shared.release(); } Node root = tree.close(true, true); if (root == null) { // Handle concurrent close attempt. throw new ClosedIndexException(); } Tree trashed = newTreeInstance(tree.mId, tree.mIdBytes, tree.mName, root); return new Deletion(trashed, false, null); }
@Override public long allocatePages(long pageCount) throws IOException { if (pageCount <= 0) { return 0; } Stats stats = new Stats(); mPageManager.addTo(stats); pageCount -= stats.freePages; if (pageCount <= 0) { return 0; } for (int i=0; i<pageCount; i++) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { mPageManager.allocAndRecyclePage(); } catch (Throwable e) { throw closeOnFailure(e); } finally { shared.release(); } } return pageCount; }
@Override public void setLength(long length) throws IOException { // FIXME: txn undo/redo try { if (length < 0) { mCursor.store(null); return; } final CursorFrame leaf = mCursor.leafExclusive(); final CommitLock.Shared shared = mCursor.commitLock(leaf); try { mCursor.notSplitDirty(leaf); action(leaf, OP_SET_LENGTH, length, EMPTY_BYTES, 0, 0); leaf.mNode.releaseExclusive(); } finally { shared.release(); } } catch (IllegalStateException e) { checkOpen(); throw e; } }
/** * @param findTxn optional * @param treeIdBytes optional * @param name required (cannot be null) */ private Tree openTree(Transaction findTxn, byte[] treeIdBytes, byte[] name, boolean create) throws IOException { Tree tree = quickFindIndex(name); if (tree == null) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { tree = doOpenTree(findTxn, treeIdBytes, name, create); } finally { shared.release(); } } return tree; }
/** * @param findTxn optional * @param treeIdBytes optional * @param name required (cannot be null) */ private _Tree openTree(Transaction findTxn, byte[] treeIdBytes, byte[] name, boolean create) throws IOException { _Tree tree = quickFindIndex(name); if (tree == null) { CommitLock.Shared shared = mCommitLock.acquireShared(); try { tree = doOpenTree(findTxn, treeIdBytes, name, create); } finally { shared.release(); } } return tree; }