Rebalance the tree along the given path. The path is given reversed (as he was calculated
in the insert and delete functions).
Returns the new root of the tree
Of course, the first element of the path must be the root of the tree
345465
function rebalanceAlongPath(node, path) {
		var newRoot = node, 
			rotated, i;
		if (!node.hasOwnProperty('key')) { delete node.height; return node; }   // Empty tree
		// Rebalance the tree and update all heights
		for (i = path.length - 1; i >= 0; i -= 1) {
			path[i].height = 1 + Math.max(path[i].left ? path[i].left.height : 0, path[i].right ? path[i].right.height : 0);
			if (balanceFactor(path[i]) > 1) {
				rotated = rightTooSmall(path[i]);
				if (i === 0) { newRoot = rotated; }
			}
			if (balanceFactor(path[i]) < -1) {
				rotated = leftTooSmall(path[i]);
				if (i === 0) { newRoot = rotated; }
			}
		}
		return newRoot;
	}
344158
function(root, path)
	{
		var parent = root;
		
		if (path != null)
		{
			var tokens = path.split(mxCellPath.PATH_SEPARATOR);
			
			for (var i=0; i<tokens.length; i++)
			{
				parent = parent.getChildAt(parseInt(tokens[i]));
			}
		}
		
		return parent;
	}
69393
public void reInsert(N node, IndexTreePath<E> path, int[] offs) {
    final int depth = path.getPathCount();

    long[] remove = BitsUtil.zero(node.getCapacity());
    List<E> reInsertEntries = new ArrayList<>(offs.length);
    for(int i = 0; i < offs.length; i++) {
      reInsertEntries.add(node.getEntry(offs[i]));
      BitsUtil.setI(remove, offs[i]);
    }
    // Remove the entries we reinsert
    node.removeMask(remove);
    writeNode(node);

    // and adapt the mbrs
    IndexTreePath<E> childPath = path;
    N child = node;
    while(childPath.getParentPath() != null) {
      N parent = getNode(childPath.getParentPath().getEntry());
      int indexOfChild = childPath.getIndex();
      if(child.adjustEntry(parent.getEntry(indexOfChild))) {
        writeNode(parent);
        childPath = childPath.getParentPath();
        child = parent;
      }
      else {
        break;
        // TODO: stop writing when MBR didn't change!
      }
    }

    // reinsert the first entries
    final Logging log = getLogger();
    for(E entry : reInsertEntries) {
      if(node.isLeaf()) {
        if(log.isDebugging()) {
          log.debug("reinsert " + entry);
        }
        insertLeafEntry(entry);
      }
      else {
        if(log.isDebugging()) {
          log.debug("reinsert " + entry + " at " + depth);
        }
        insertDirectoryEntry(entry, depth);
      }
    }
  }
5543
def re_balance(self):
        
        self.update_heights(recursive=False)
        self.update_balances(False)

        while self.balance < -1 or self.balance > 1:
            if self.balance > 1:
                if self.node.left.balance < 0:
                    self.node.left.rotate_left()
                    self.update_heights()
                    self.update_balances()
                self.rotate_right()
                self.update_heights()
                self.update_balances()

            if self.balance < -1:
                if self.node.right.balance > 0:
                    self.node.right.rotate_right()
                    self.update_heights()
                    self.update_balances()
                self.rotate_left()
                self.update_heights()
                self.update_balances()
1150587
private void rollingRemove() throws TTException {
        final ITreeData startNode = mDelegate.getCurrentNode();
        long hashToRemove = startNode.getHash();
        long hashToAdd = 0;
        long newHash = 0;
        // go the path to the root
        do {
            synchronized (mDelegate.getCurrentNode()) {
                getPtx().getData(mDelegate.getCurrentNode().getDataKey());
                if (mDelegate.getCurrentNode().getDataKey() == startNode.getDataKey()) {
                    // the begin node is always null
                    newHash = 0;
                } else if (mDelegate.getCurrentNode().getDataKey() == startNode.getParentKey()) {
                    // the parent node is just removed
                    newHash = mDelegate.getCurrentNode().getHash() - (hashToRemove * PRIME);
                    hashToRemove = mDelegate.getCurrentNode().getHash();
                } else {
                    // the ancestors are all touched regarding the modification
                    newHash = mDelegate.getCurrentNode().getHash() - (hashToRemove * PRIME);
                    newHash = newHash + hashToAdd * PRIME;
                    hashToRemove = mDelegate.getCurrentNode().getHash();
                }
                mDelegate.getCurrentNode().setHash(newHash);
                hashToAdd = newHash;
                getPtx().setData(mDelegate.getCurrentNode());
            }
        } while (moveTo(mDelegate.getCurrentNode().getParentKey()));

        mDelegate.setCurrentNode(startNode);
    }
274925
def refresh_balance(self):
        
        left_depth = self.left_node.depth if self.left_node else 0
        right_depth = self.right_node.depth if self.right_node else 0
        self.depth = 1 + max(left_depth, right_depth)
        self.balance = right_depth - left_depth
355768
private void postTraversalProcessing() {
		int nc1 = treeSize;
		info[KR] = new int[leafCount];
		info[RKR] = new int[leafCount];

		int lc = leafCount;
		int i = 0;

		// compute left-most leaf descendants
		// go along the left-most path, remember each node and assign to it the path's
		// leaf
		// compute right-most leaf descendants (in reversed postorder)
		for (i = 0; i < treeSize; i++) {
			if (paths[LEFT][i] == -1) {
				info[POST2_LLD][i] = i;
			} else {
				info[POST2_LLD][i] = info[POST2_LLD][paths[LEFT][i]];
			}
			if (paths[RIGHT][i] == -1) {
				info[RPOST2_RLD][treeSize - 1 - info[POST2_PRE][i]] =
						(treeSize - 1 - info[POST2_PRE][i]);
			} else {
				info[RPOST2_RLD][treeSize - 1 - info[POST2_PRE][i]] =
						info[RPOST2_RLD][treeSize - 1
								- info[POST2_PRE][paths[RIGHT][i]]];
			}
		}

		// compute key root nodes
		// compute reversed key root nodes (in revrsed postorder)
		boolean[] visited = new boolean[nc1];
		boolean[] visitedR = new boolean[nc1];
		Arrays.fill(visited, false);
		int k = lc - 1;
		int kR = lc - 1;
		for (i = nc1 - 1; i >= 0; i--) {
			if (!visited[info[POST2_LLD][i]]) {
				info[KR][k] = i;
				visited[info[POST2_LLD][i]] = true;
				k--;
			}
			if (!visitedR[info[RPOST2_RLD][i]]) {
				info[RKR][kR] = i;
				visitedR[info[RPOST2_RLD][i]] = true;
				kR--;
			}
		}

		// compute minimal key roots for every subtree
		// compute minimal reversed key roots for every subtree (in reversed postorder)
		int parent = -1;
		int parentR = -1;
		for (i = 0; i < leafCount; i++) {
			parent = info[KR][i];
			while (parent > -1 && info[POST2_MIN_KR][parent] == -1) {
				info[POST2_MIN_KR][parent] = i;
				parent = info[POST2_PARENT][parent];
			}
			parentR = info[RKR][i];
			while (parentR > -1 && info[RPOST2_MIN_RKR][parentR] == -1) {
				info[RPOST2_MIN_RKR][parentR] = i;
				parentR =
						info[POST2_PARENT][info[RPOST2_POST][parentR]]; // get parent's postorder
				if (parentR > -1) {
					parentR = treeSize - 1 - info[POST2_PRE][parentR]; // if parent exists get its
					// rev. postorder
				}
			}
		}
	}
1180201
private void rotateLeft(int n) {
        final int r = right(n);
        final int lr = left(r);
        right(n, lr);
        if (lr != NIL) {
            parent(lr, n);
        }
        final int p = parent(n);
        parent(r, p);
        if (p == NIL) {
            root = r;
        } else if (left(p) == n) {
            left(p, r);
        } else {
            assert right(p) == n;
            right(p, r);
        }
        left(r, n);
        parent(n, r);
        fixAggregates(n);
        fixAggregates(parent(n));
    }
390719
public static Path getRootPath(Path path) {
    if (path.isRoot()) {
      return path;
    }
    return getRootPath(path.getParent());
  }
779693
def _root(self):
        
        _n = self
        while _n.parent:
            _n = _n.parent
        return _n
801181
private void adjustTree(IndexTreePath<E> subtree) {
    final Logging log = getLogger();
    if(log.isDebugging()) {
      log.debugFine("Adjust tree " + subtree + "\n");
    }

    // get the root of the subtree
    int nodeIndex = subtree.getIndex();
    N node = getNode(subtree.getEntry());

    // overflow in node; split the node
    if(hasOverflow(node)) {
      // do the split
      Assignments<E> assignments = settings.splitStrategy.split(this, node);
      final N newNode = node.isLeaf() ? createNewLeafNode() : createNewDirectoryNode();

      List<E> entries1 = new ArrayList<>(assignments.getFirstAssignments().size());
      List<E> entries2 = new ArrayList<>(assignments.getSecondAssignments().size());
      // Store final parent distances:
      for(DistanceEntry<E> ent : assignments.getFirstAssignments()) {
        final E e = ent.getEntry();
        e.setParentDistance(ent.getDistance());
        entries1.add(e);
      }
      for(DistanceEntry<E> ent : assignments.getSecondAssignments()) {
        final E e = ent.getEntry();
        e.setParentDistance(ent.getDistance());
        entries2.add(e);
      }
      node.splitTo(newNode, entries1, entries2);

      // write changes to file
      writeNode(node);
      writeNode(newNode);

      if(log.isDebuggingFine()) {
        log.debugFine(new StringBuilder(1000)//
            .append("Split Node ").append(node.getPageID()).append(" (").append(this.getClass()).append(')').append(FormatUtil.NEWLINE)//
            .append("      newNode ").append(newNode.getPageID()).append(FormatUtil.NEWLINE)//
            .append("      firstPromoted ").append(assignments.getFirstRoutingObject()).append(FormatUtil.NEWLINE)//
            .append("      firstAssignments(").append(node.getPageID()).append(") ").append(assignments.getFirstAssignments()).append(FormatUtil.NEWLINE)//
            .append("      firstCR ").append(assignments.computeFirstCover(node.isLeaf())).append(FormatUtil.NEWLINE)//
            .append("      secondPromoted ").append(assignments.getSecondRoutingObject()).append(FormatUtil.NEWLINE)//
            .append("      secondAssignments(").append(newNode.getPageID()).append(") ").append(assignments.getSecondAssignments()).append(FormatUtil.NEWLINE)//
            .append("      secondCR ").append(assignments.computeSecondCover(node.isLeaf())).append(FormatUtil.NEWLINE));
      }

      // if root was split: create a new root that points the two split nodes
      if(isRoot(node)) {
        // FIXME: stimmen die parentDistance der Kinder in node & splitNode?
        IndexTreePath<E> newRootPath = createNewRoot(node, newNode, assignments.getFirstRoutingObject(), assignments.getSecondRoutingObject());
        adjustTree(newRootPath);
      }
      // node is not root
      else {
        // get the parent and add the new split node
        E parentEntry = subtree.getParentPath().getEntry();
        N parent = getNode(parentEntry);
        if(log.isDebugging()) {
          log.debugFine("parent " + parent);
        }
        double parentDistance2 = distance(parentEntry.getRoutingObjectID(), assignments.getSecondRoutingObject());
        // logger.warning("parent: "+parent.toString()+" split: " +
        // splitNode.toString()+ " dist:"+parentDistance2);
        parent.addDirectoryEntry(createNewDirectoryEntry(newNode, assignments.getSecondRoutingObject(), parentDistance2));

        // adjust the entry representing the (old) node, that has been split
        double parentDistance1 = distance(parentEntry.getRoutingObjectID(), assignments.getFirstRoutingObject());
        // logger.warning("parent: "+parent.toString()+" node: " +
        // node.toString()+ " dist:"+parentDistance1);
        node.adjustEntry(parent.getEntry(nodeIndex), assignments.getFirstRoutingObject(), parentDistance1, this);

        // write changes in parent to file
        writeNode(parent);
        adjustTree(subtree.getParentPath());
      }
    }
    // no overflow, only adjust parameters of the entry representing the node
    else {
      if(!isRoot(node)) {
        E parentEntry = subtree.getParentPath().getEntry();
        N parent = getNode(parentEntry);
        E entry = parent.getEntry(subtree.getIndex());
        boolean changed = node.adjustEntry(entry, entry.getRoutingObjectID(), entry.getParentDistance(), this);
        // write changes in parent to file
        if(changed) {
          writeNode(parent);
          adjustTree(subtree.getParentPath());
        }
      }
      // root level is reached
      else {
        E rootEntry = getRootEntry();
        node.adjustEntry(rootEntry, rootEntry.getRoutingObjectID(), rootEntry.getParentDistance(), this);
      }
    }
  }
760325
def walk_tree(start, attr):
    
    path = [start]
    for child in path:
        yield child
        idx = path.index(child)
        for grandchild in reversed(getattr(child, attr)):
            path.insert(idx + 1, grandchild)
478332
def _split_path(xj_path):
    

    res = xj_path.rsplit('.', 1)
    root_key = res[0]
    if len(res) > 1:
        return root_key, res[1]
    else:
        if root_key and root_key != '.':
            return None, root_key
        else:
            raise XJPathError('Path cannot be empty', (xj_path,))
70886
def reverse_segment(path, n1, n2):
    
    q = path.copy()
    if n2 > n1:
        q[n1:(n2+1)] = path[n1:(n2+1)][::-1]
        return q
    else:
        seg = np.hstack((path[n1:], path[:(n2+1)]))[::-1]
        brk = len(q) - n1
        q[n1:] = seg[:brk]
        q[:(n2+1)] = seg[brk:]
        return q
1304311
def delete(self, value, key):
        

        # Base case: The empty tree cannot possibly have the desired value.
        if self is NULL:
            raise KeyError(value)

        direction = cmp(key(value), key(self.value))

        # Because we lean to the left, the left case stands alone.
        if direction < 0:
            if (not self.left.red and
                self.left is not NULL and
                not self.left.left.red):
                self = self.move_red_left()
            # Delete towards the left.
            left = self.left.delete(value, key)
            self = self._replace(left=left)
        else:
            # If we currently lean to the left, lean to the right for now.
            if self.left.red:
                self = self.rotate_right()

            # Best case: The node on our right (which we just rotated there) is a
            # red link and also we were just holding the node to delete. In that
            # case, we just rotated NULL into our current node, and the node to
            # the right is the lone matching node to delete.
            if direction == 0 and self.right is NULL:
                return NULL

            # No? Okay. Move more reds to the right so that we can continue to
            # traverse in that direction. At *this* spot, we do have to confirm
            # that node.right is not NULL...
            if (not self.right.red and
                self.right is not NULL and
                not self.right.left.red):
                self = self.move_red_right()

            if direction > 0:
                # Delete towards the right.
                right = self.right.delete(value, key)
                self = self._replace(right=right)
            else:
                # Annoying case: The current node was the node to delete all
                # along! Use a right-handed minimum deletion. First find the
                # replacement value to rebuild the current node with, then delete
                # the replacement value from the right-side tree. Finally, create
                # the new node with the old value replaced and the replaced value
                # deleted.
                rnode = self.right
                while rnode is not NULL:
                    rnode = rnode.left

                right, replacement = self.right.delete_min()
                self = self._replace(value=replacement, right=right)

        return self.balance()
887263
function (node, root) {
    var bc; // Best Current node
    // Initial insertion is special because we resize the Tree and we don't
    // care about any overflow (seriously, how can the first object overflow?)
    if (root.nodes.length === 0) {
      root.x = node.x;
      root.y = node.y;
      root.w = node.w;
      root.h = node.h;
      root.nodes.push(node);
      return;
    }

    // Find the best fitting leaf node
    // chooseLeaf returns an array of all tree levels (including root)
    // that were traversed while trying to find the leaf
    var treeStack = chooseLeafSubtree(node, root);
    var retObj = node;//{x:rect.x,y:rect.y,w:rect.w,h:rect.h, leaf:obj};
    var pbc;
    // Walk back up the tree resizing and inserting as needed
    while (treeStack.length > 0) {
      //handle the case of an empty node (from a split)
      if (bc && 'nodes' in bc && bc.nodes.length === 0) {
        pbc = bc; // Past bc
        bc = treeStack.pop();
        for (var t = 0;t < bc.nodes.length;t++) {
          if (bc.nodes[t] === pbc || bc.nodes[t].nodes.length === 0) {
            bc.nodes.splice(t, 1);
            break;
          }
        }
      } else {
        bc = treeStack.pop();
      }

      // If there is data attached to this retObj
      if ('leaf' in retObj || 'nodes' in retObj || Array.isArray(retObj)) {
        // Do Insert
        if (Array.isArray(retObj)) {
          for (var ai = 0; ai < retObj.length; ai++) {
            rectangle.expandRectangle(bc, retObj[ai]);
          }
          bc.nodes = bc.nodes.concat(retObj);
        } else {
          rectangle.expandRectangle(bc, retObj);
          bc.nodes.push(retObj); // Do Insert
        }

        if (bc.nodes.length <= maxWidth)  { // Start Resizeing Up the Tree
          retObj = {x: bc.x, y: bc.y, w: bc.w, h: bc.h};
        }  else { // Otherwise Split this Node
          // linearSplit() returns an array containing two new nodes
          // formed from the split of the previous node's overflow
          var a = linearSplit(bc.nodes);
          retObj = a;//[1];

          if (treeStack.length < 1)  { // If are splitting the root..
            bc.nodes.push(a[0]);
            treeStack.push(bc);  // Reconsider the root element
            retObj = a[1];
          } /*else {
            delete bc;
          }*/
        }
      } else { // Otherwise Do Resize
        //Just keep applying the new bounding rectangle to the parents..
        rectangle.expandRectangle(bc, retObj);
        retObj = {x: bc.x, y: bc.y, w: bc.w, h: bc.h};
      }
    }
  }
1058045
private static void reverse(int[] path, int i, int j) {
        while (i < j) {
            int tmp = path[i];
            path[i] = path[j];
            path[j] = tmp;
            i++;
            j--;
        }
    }