Example #1
0
  /**
   * Reset this walker to run over a set of existing trees.
   *
   * @param ids the trees we need to parse. The walker will execute over this many parallel trees if
   *     the reset is successful.
   * @throws MissingObjectException the given tree object does not exist in this repository.
   * @throws IncorrectObjectTypeException the given object id does not denote a tree, but instead
   *     names some other non-tree type of object. Note that commits are not trees, even if they are
   *     sometimes called a "tree-ish".
   * @throws CorruptObjectException the object claimed to be a tree, but its contents did not appear
   *     to be a tree. The repository may have data corruption.
   * @throws IOException a loose object or pack file could not be read.
   */
  public void reset(final AnyObjectId[] ids)
      throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
          IOException {
    final int oldLen = trees.length;
    final int newLen = ids.length;
    final AbstractTreeIterator[] r = newLen == oldLen ? trees : new AbstractTreeIterator[newLen];
    for (int i = 0; i < newLen; i++) {
      AbstractTreeIterator o;

      if (i < oldLen) {
        o = trees[i];
        while (o.parent != null) o = o.parent;
        if (o instanceof CanonicalTreeParser && o.pathOffset == 0) {
          o.matches = null;
          o.matchShift = 0;
          ((CanonicalTreeParser) o).reset(db, ids[i], curs);
          r[i] = o;
          continue;
        }
      }

      o = parserFor(ids[i]);
      r[i] = o;
    }

    trees = r;
    advance = false;
    depth = 0;
  }
Example #2
0
 void skipEntriesEqual() throws CorruptObjectException {
   final AbstractTreeIterator ch = currentHead;
   for (int i = 0; i < trees.length; i++) {
     final AbstractTreeIterator t = trees[i];
     if (t.matches == ch) {
       t.skip();
       t.matches = null;
     }
   }
 }
Example #3
0
  private void exitSubtree() {
    depth--;
    for (int i = 0; i < trees.length; i++) trees[i] = trees[i].parent;

    AbstractTreeIterator minRef = null;
    for (final AbstractTreeIterator t : trees) {
      if (t.matches != t) continue;
      if (minRef == null || t.pathCompare(minRef) < 0) minRef = t;
    }
    currentHead = minRef;
  }
Example #4
0
  /**
   * Add an already created tree iterator for walking.
   *
   * <p>The position of this tree is returned to the caller, in case the caller has lost track of
   * the order they added the trees into the walker.
   *
   * <p>The tree which the iterator operates on must have the same root as existing trees in the
   * walk.
   *
   * @param p an iterator to walk over. The iterator should be new, with no parent, and should still
   *     be positioned before the first entry. The tree which the iterator operates on must have the
   *     same root as other trees in the walk.
   * @return position of this tree within the walker.
   * @throws CorruptObjectException the iterator was unable to obtain its first entry, due to
   *     possible data corruption within the backing data store.
   */
  public int addTree(final AbstractTreeIterator p) throws CorruptObjectException {
    final int n = trees.length;
    final AbstractTreeIterator[] newTrees = new AbstractTreeIterator[n + 1];

    System.arraycopy(trees, 0, newTrees, 0, n);
    newTrees[n] = p;
    p.matches = null;
    p.matchShift = 0;

    trees = newTrees;
    return n;
  }
Example #5
0
 /**
  * Compare two tree's current ObjectId values for equality.
  *
  * @param nthA first tree to compare the object id from.
  * @param nthB second tree to compare the object id from.
  * @return result of <code>getObjectId(nthA).equals(getObjectId(nthB))</code>.
  * @see #getObjectId(int)
  */
 public boolean idEqual(final int nthA, final int nthB) {
   final AbstractTreeIterator ch = currentHead;
   final AbstractTreeIterator a = trees[nthA];
   final AbstractTreeIterator b = trees[nthB];
   if (a.matches == ch && b.matches == ch) return a.idEqual(b);
   if (a.matches != ch && b.matches != ch) {
     // If neither tree matches the current path node then neither
     // tree has this entry. In such case the ObjectId is zero(),
     // and zero() is always equal to zero().
     //
     return true;
   }
   return false;
 }
Example #6
0
 /**
  * Enter into the current subtree.
  *
  * <p>If the current entry is a subtree this method arranges for its children to be returned
  * before the next sibling following the subtree is returned.
  *
  * @throws MissingObjectException a subtree was found, but the subtree object does not exist in
  *     this repository. The repository may be missing objects.
  * @throws IncorrectObjectTypeException a subtree was found, and the subtree id does not denote a
  *     tree, but instead names some other non-tree type of object. The repository may have data
  *     corruption.
  * @throws CorruptObjectException the contents of a tree did not appear to be a tree. The
  *     repository may have data corruption.
  * @throws IOException a loose object or pack file could not be read.
  */
 public void enterSubtree()
     throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
         IOException {
   final AbstractTreeIterator ch = currentHead;
   final AbstractTreeIterator[] tmp = new AbstractTreeIterator[trees.length];
   for (int i = 0; i < trees.length; i++) {
     final AbstractTreeIterator t = trees[i];
     final AbstractTreeIterator n;
     if (t.matches == ch && !t.eof() && FileMode.TREE.equals(t.mode))
       n = t.createSubtreeIterator(db, idBuffer, curs);
     else n = t.createEmptyTreeIterator();
     tmp[i] = n;
   }
   depth++;
   advance = false;
   System.arraycopy(tmp, 0, trees, 0, trees.length);
 }
Example #7
0
  /**
   * Advance this walker to the next relevant entry.
   *
   * @return true if there is an entry available; false if all entries have been walked and the walk
   *     of this set of tree iterators is over.
   * @throws MissingObjectException {@link #isRecursive()} was enabled, a subtree was found, but the
   *     subtree object does not exist in this repository. The repository may be missing objects.
   * @throws IncorrectObjectTypeException {@link #isRecursive()} was enabled, a subtree was found,
   *     and the subtree id does not denote a tree, but instead names some other non-tree type of
   *     object. The repository may have data corruption.
   * @throws CorruptObjectException the contents of a tree did not appear to be a tree. The
   *     repository may have data corruption.
   * @throws IOException a loose object or pack file could not be read.
   */
  public boolean next()
      throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
          IOException {
    try {
      if (advance) {
        advance = false;
        postChildren = false;
        popEntriesEqual();
      }

      for (; ; ) {
        final AbstractTreeIterator t = min();
        if (t.eof()) {
          if (depth > 0) {
            exitSubtree();
            if (postOrderTraversal) {
              advance = true;
              postChildren = true;
              return true;
            }
            popEntriesEqual();
            continue;
          }
          return false;
        }

        currentHead = t;
        if (!filter.include(this)) {
          skipEntriesEqual();
          continue;
        }

        if (recursive && FileMode.TREE.equals(t.mode)) {
          enterSubtree();
          continue;
        }

        advance = true;
        return true;
      }
    } catch (StopWalkException stop) {
      for (final AbstractTreeIterator t : trees) t.stopWalk();
      return false;
    }
  }
Example #8
0
  /**
   * Reset this walker to run over a single existing tree.
   *
   * @param id the tree we need to parse. The walker will execute over this single tree if the reset
   *     is successful.
   * @throws MissingObjectException the given tree object does not exist in this repository.
   * @throws IncorrectObjectTypeException the given object id does not denote a tree, but instead
   *     names some other non-tree type of object. Note that commits are not trees, even if they are
   *     sometimes called a "tree-ish".
   * @throws CorruptObjectException the object claimed to be a tree, but its contents did not appear
   *     to be a tree. The repository may have data corruption.
   * @throws IOException a loose object or pack file could not be read.
   */
  public void reset(final AnyObjectId id)
      throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException,
          IOException {
    if (trees.length == 1) {
      AbstractTreeIterator o = trees[0];
      while (o.parent != null) o = o.parent;
      if (o instanceof CanonicalTreeParser) {
        o.matches = null;
        o.matchShift = 0;
        ((CanonicalTreeParser) o).reset(db, id, curs);
        trees[0] = o;
      } else {
        trees[0] = parserFor(id);
      }
    } else {
      trees = new AbstractTreeIterator[] {parserFor(id)};
    }

    advance = false;
    depth = 0;
  }
Example #9
0
  AbstractTreeIterator min() throws CorruptObjectException {
    int i = 0;
    AbstractTreeIterator minRef = trees[i];
    while (minRef.eof() && ++i < trees.length) minRef = trees[i];
    if (minRef.eof()) return minRef;

    minRef.matches = minRef;
    while (++i < trees.length) {
      final AbstractTreeIterator t = trees[i];
      if (t.eof()) continue;
      final int cmp = t.pathCompare(minRef);
      if (cmp < 0) {
        t.matches = t;
        minRef = t;
      } else if (cmp == 0) {
        t.matches = minRef;
      }
    }

    return minRef;
  }
Example #10
0
 /**
  * Obtain the ObjectId for the current entry.
  *
  * <p>Every tree supplies an object id, even if the tree does not contain the current entry. In
  * the latter case {@link ObjectId#zeroId()} is supplied.
  *
  * <p>Applications should try to use {@link #idEqual(int, int)} when possible as it avoids
  * conversion overheads.
  *
  * @param out buffer to copy the object id into.
  * @param nth tree to obtain the object identifier from.
  * @see #idEqual(int, int)
  */
 public void getObjectId(final MutableObjectId out, final int nth) {
   final AbstractTreeIterator t = trees[nth];
   if (t.matches == currentHead) t.getEntryObjectId(out);
   else out.clear();
 }
Example #11
0
 /**
  * Obtain the ObjectId for the current entry.
  *
  * <p>Using this method to compare ObjectId values between trees of this walker is very
  * inefficient. Applications should try to use {@link #idEqual(int, int)} or {@link
  * #getObjectId(MutableObjectId, int)} whenever possible.
  *
  * <p>Every tree supplies an object id, even if the tree does not contain the current entry. In
  * the latter case {@link ObjectId#zeroId()} is returned.
  *
  * @param nth tree to obtain the object identifier from.
  * @return object identifier for the current tree entry.
  * @see #getObjectId(MutableObjectId, int)
  * @see #idEqual(int, int)
  */
 public ObjectId getObjectId(final int nth) {
   final AbstractTreeIterator t = trees[nth];
   return t.matches == currentHead ? t.getEntryObjectId() : ObjectId.zeroId();
 }