/**
  * 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;
 }
Exemple #2
0
 /**
  * This method updates the distance values of the specified pre value and the following siblings
  * of all ancestor-or-self nodes.
  *
  * @param pre root node
  * @param size size to be added/removed
  */
 private void updateDist(final int pre, final int size) {
   int p = pre;
   while (p < meta.size) {
     final int k = kind(p);
     if (k == DOC) break;
     dist(p, k, dist(p, k) + size);
     p += size(p, k);
   }
 }
  /**
   * 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));
      }
    }
  }