Example #1
0
  /**
   * Adjust any cursors that are referring to this BIN. This method is called during a split
   * operation. "this" is the BIN being split. newSibling is the new BIN into which the entries from
   * "this" between newSiblingLow and newSiblingHigh have been copied.
   *
   * @param newSibling - the newSibling into which "this" has been split.
   * @param newSiblingLow, newSiblingHigh - the low and high entry of "this" that were moved into
   *     newSibling.
   */
  @Override
  void adjustCursors(IN newSibling, int newSiblingLow, int newSiblingHigh) {
    assert newSibling.isLatchOwnerForWrite();
    assert this.isLatchOwnerForWrite();
    int adjustmentDelta = (newSiblingHigh - newSiblingLow);
    Iterator<CursorImpl> iter = cursorSet.iterator();
    while (iter.hasNext()) {
      CursorImpl cursor = iter.next();
      if (getCursorBINToBeRemoved(cursor) == this) {

        /*
         * This BIN will be removed from the cursor by CursorImpl
         * following advance to next BIN; ignore it.
         */
        continue;
      }
      int cIdx = getCursorIndex(cursor);
      BIN cBin = getCursorBIN(cursor);
      assert cBin == this : "nodeId=" + getNodeId() + " cursor=" + cursor.dumpToString(true);
      assert newSibling instanceof BIN;

      /*
       * There are four cases to consider for cursor adjustments,
       * depending on (1) how the existing node gets split, and (2) where
       * the cursor points to currently.  In cases 1 and 2, the id key of
       * the node being split is to the right of the splitindex so the
       * new sibling gets the node entries to the left of that index.
       * This is indicated by "new sibling" to the left of the vertical
       * split line below.  The right side of the node contains entries
       * that will remain in the existing node (although they've been
       * shifted to the left).  The vertical bar (^) indicates where the
       * cursor currently points.
       *
       * case 1:
       *
       *   We need to set the cursor's "bin" reference to point at the
       *   new sibling, but we don't need to adjust its index since that
       *   continues to be correct post-split.
       *
       *   +=======================================+
       *   |  new sibling        |  existing node  |
       *   +=======================================+
       *         cursor ^
       *
       * case 2:
       *
       *   We only need to adjust the cursor's index since it continues
       *   to point to the current BIN post-split.
       *
       *   +=======================================+
       *   |  new sibling        |  existing node  |
       *   +=======================================+
       *                              cursor ^
       *
       * case 3:
       *
       *   Do nothing.  The cursor continues to point at the correct BIN
       *   and index.
       *
       *   +=======================================+
       *   |  existing Node        |  new sibling  |
       *   +=======================================+
       *         cursor ^
       *
       * case 4:
       *
       *   Adjust the "bin" pointer to point at the new sibling BIN and
       *   also adjust the index.
       *
       *   +=======================================+
       *   |  existing Node        |  new sibling  |
       *   +=======================================+
       *                                 cursor ^
       */
      BIN ns = (BIN) newSibling;
      if (newSiblingLow == 0) {
        if (cIdx < newSiblingHigh) {
          /* case 1 */
          setCursorBIN(cursor, ns);
          iter.remove();
          ns.addCursor(cursor);
        } else {
          /* case 2 */
          setCursorIndex(cursor, cIdx - adjustmentDelta);
        }
      } else {
        if (cIdx >= newSiblingLow) {
          /* case 4 */
          setCursorIndex(cursor, cIdx - newSiblingLow);
          setCursorBIN(cursor, ns);
          iter.remove();
          ns.addCursor(cursor);
        }
      }
    }
  }