예제 #1
0
  /**
   * Checks the list of updates for violations. Updates must be ordered strictly from the highest to
   * the lowest PRE value.
   *
   * <p>A single node must not be affected by more than one {@link Rename}, {@link UpdateValue}
   * operation.
   *
   * <p>A single node must not be affected by more than one destructive operation. These operations
   * include {@link Replace}, {@link Delete}.
   */
  public void check() {
    if (ok || updStructural.size() < 2 && updValue.size() < 2) return;

    int i = 0;
    while (i + 1 < updStructural.size()) {
      final BasicUpdate current = updStructural.get(i);
      final BasicUpdate next = updStructural.get(++i);

      // check order of location PRE
      if (current.location < next.location)
        Util.notexpected("Invalid order at location " + current.location);

      if (current.location == next.location) {
        // check multiple {@link Delete}, {@link Replace}
        if (current.destructive() && next.destructive())
          Util.notexpected("Multiple deletes/replaces on node " + current.location);
      }
    }

    i = 0;
    while (i + 1 < updValue.size()) {
      final BasicUpdate current = updValue.get(i++);
      final BasicUpdate next = updValue.get(i);

      // check order of location PRE
      if (current.location < next.location)
        Util.notexpected("Invalid order at location " + current.location);

      if (current.location == next.location) {
        // check multiple {@link Rename}
        if (current instanceof Rename && next instanceof Rename)
          Util.notexpected("Multiple renames on node " + current.location);

        // check multiple {@link UpdateValue}
        if (current instanceof UpdateValue && next instanceof UpdateValue)
          Util.notexpected("Multiple updates on node " + current.location);
      }
    }
    ok = true;
  }
예제 #2
0
  /**
   * Removes superfluous update operations. If a node T is deleted or replaced, all updates on the
   * descendant axis of T can be left out as they won't affect the database after all.
   *
   * <p>Superfluous updates can have a minimum PRE value of pre(T)+1 and a maximum PRE value of
   * pre(T)+size(T).
   *
   * <p>An update with location pre(T)+size(T) can only be removed if the update is an atomic insert
   * and the inserted node is then part of the subtree of T.
   */
  public void optimize() {
    if (opt) return;

    check();
    // traverse from lowest to highest PRE value
    int i = updStructural.size() - 1;
    while (i >= 0) {
      final BasicUpdate u = updStructural.get(i);
      // If this update can lead to superfluous updates ...
      if (u.destructive()) {
        // we determine the lowest and highest PRE values of a superfluous update
        final int pre = u.location;
        final int fol = pre + data.size(pre, data.kind(pre));
        i--;
        // and have a look at the next candidate
        while (i >= 0) {
          final BasicUpdate desc = updStructural.get(i);
          final int descpre = desc.location;
          // if the candidate operates on the subtree of T and inserts a node ...
          if (descpre <= fol
              && (desc instanceof Insert || desc instanceof InsertAttr)
              && desc.parent() >= pre
              && desc.parent() < fol) {
            // it is removed.
            updStructural.remove(i--);

            // Other updates (not inserting a node) that operate on the subtree of T can
            // only have a PRE value that is smaller than the following PRE of T
          } else if (descpre < fol) {
            // these we delete.
            updStructural.remove(i--);

            // Else there's nothing to delete
          } else break;
        }
      } else i--;
    }
    opt = true;
  }