예제 #1
0
 /** Bind this frame to a tree node. Called with exclusive latch held. */
 void bind(Node node, int nodePos) {
   mNode = node;
   mNodePos = nodePos;
   TreeCursorFrame last = node.mLastCursorFrame;
   if (last != null) {
     mPrevCousin = last;
     last.mNextCousin = this;
   }
   node.mLastCursorFrame = this;
 }
예제 #2
0
 /** Unbind this frame from a tree node. Called with exclusive latch held. */
 void unbind() {
   TreeCursorFrame prev = mPrevCousin;
   TreeCursorFrame next = mNextCousin;
   if (prev != null) {
     prev.mNextCousin = next;
     mPrevCousin = null;
   }
   if (next != null) {
     next.mPrevCousin = prev;
     mNextCousin = null;
   } else {
     mNode.mLastCursorFrame = prev;
   }
 }
예제 #3
0
  /**
   * Copy this frame and all parent frames.
   *
   * @param dest new frame instance to receive copy
   */
  void copyInto(TreeCursorFrame dest) {
    Node node = acquireExclusive();
    TreeCursorFrame parent = mParentFrame;

    if (parent != null) {
      node.releaseExclusive();
      TreeCursorFrame parentCopy = new TreeCursorFrame();

      while (true) {
        // Need to check if parent is null, when looping back.
        if (parent != null) {
          parent.copyInto(parentCopy);
        }

        // Parent can change when tree height is concurrently changing.
        node = acquireExclusive();
        final TreeCursorFrame actualParent = mParentFrame;

        if (actualParent == parent) {
          // Parent frame hasn't changed, so use the copy.
          if (parent != null) {
            dest.mParentFrame = parentCopy;
          }
          break;
        }

        // Get rid of the stale copy and do over, which should be rare.
        node.releaseExclusive();
        popAll(parentCopy);
        parent = actualParent;
      }
    }

    dest.mNotFoundKey = mNotFoundKey;
    dest.bind(node, mNodePos);
    node.releaseExclusive();
  }
예제 #4
0
 /** Pop given non-null frame and all parent frames. */
 static void popAll(TreeCursorFrame frame) {
   outer:
   do {
     Node node = frame.mNode;
     while (true) {
       if (node == null) {
         // Frame was not bound properly, suggesting that cursor is
         // being cleaned up in response to an exception. Frame
         // cannot be latched, so just go to the parent.
         frame = frame.mParentFrame;
         continue outer;
       }
       node.acquireExclusive();
       Node actualNode = frame.mNode;
       if (actualNode == node) {
         frame = frame.pop();
         node.releaseExclusive();
         continue outer;
       }
       node.releaseExclusive();
       node = actualNode;
     }
   } while (frame != null);
 }