/** * Adjust cursors referring to this BIN following an insert. * * @param insertIndex - The index of the new entry. */ @Override void adjustCursorsForInsert(int insertIndex) { assert this.isLatchOwnerForWrite(); /* cursorSet may be null if this is being created through createFromLog() */ if (cursorSet != null) { Iterator<CursorImpl> iter = cursorSet.iterator(); while (iter.hasNext()) { CursorImpl cursor = iter.next(); if (getCursorBINToBeRemoved(cursor) != this) { int cIdx = getCursorIndex(cursor); if (insertIndex <= cIdx) { setCursorIndex(cursor, cIdx + 1); } } } } }
/** * 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); } } } }