/** * Calculates the new distance value for the given node. * * @param preAfter the current PRE value of the node (after structural updates have been applied) * @return new distance for the given node */ private int calculateNewDistance(final int preAfter) { final int kind = data.kind(preAfter); final int distanceBefore = data.dist(preAfter, kind); final int preBefore = calculatePreValue(preAfter, true); final int parentBefore = preBefore - distanceBefore; final int parentAfter = calculatePreValue(parentBefore, false); return preAfter - parentAfter; }
/** * Updates distances to restore parent-child relationships that have been invalidated by * structural updates. * * <p>Each structural update (insert/delete) leads to a shift of higher PRE values. This * invalidates parent-child relationships. Distances are only updated after all structural updates * have been carried out to make sure each node (that has to be updated) is only touched once. */ public void updateDistances() { accumulatePreValueShifts(); final IntSet alreadyUpdatedNodes = new IntSet(); for (final BasicUpdate update : updStructural) { int newPreOfAffectedNode = update.preOfAffectedNode + update.accumulatedShifts; /* Update distance for the affected node and all following siblings of nodes * on the ancestor-or-self axis. */ while (newPreOfAffectedNode < data.meta.size) { if (alreadyUpdatedNodes.contains(newPreOfAffectedNode)) break; data.dist( newPreOfAffectedNode, data.kind(newPreOfAffectedNode), calculateNewDistance(newPreOfAffectedNode)); alreadyUpdatedNodes.add(newPreOfAffectedNode); newPreOfAffectedNode += data.size(newPreOfAffectedNode, data.kind(newPreOfAffectedNode)); } } }