private CanonicalTreeParser ParserFor(AnyObjectId id) { var p = new CanonicalTreeParser(); p.reset(_db, id, _cursor); return(p); }
/** * Back door to quickly Create a subtree iterator for any subtree. * <para /> * Don't use this unless you are ObjectWalk. The method is meant to be * called only once the current entry has been identified as a tree and its * identity has been converted into an ObjectId. * * @param repo * repository to load the tree data from. * @param id * ObjectId of the tree to open. * @param curs * window cursor to use during repository access. * @return a new parser that walks over the current subtree. * @throws IOException * a loose object or pack file could not be Read. */ public CanonicalTreeParser createSubtreeIterator0(Repository repo, AnyObjectId id, WindowCursor curs) // [henon] createSubtreeIterator0 <--- not a typo! { var p = new CanonicalTreeParser(this); p.reset(repo, id, curs); return(p); }
/** * 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(AnyObjectId id) { if (_trees.Length == 1) { AbstractTreeIterator iterator = _trees[0]; while (iterator.Parent != null) { iterator = iterator.Parent; } CanonicalTreeParser oParse = (iterator as CanonicalTreeParser); if (oParse != null) { iterator.Matches = null; iterator.MatchShift = 0; oParse.reset(_db, id, _cursor); _trees[0] = iterator; } else { _trees[0] = ParserFor(id); } } else { _trees = new AbstractTreeIterator[] { ParserFor(id) }; } _advance = false; _depth = 0; }
/** * Reset this parser to walk through the given tree. * * @param repo * repository to load the tree data from. * @param id * identity of the tree being parsed; used only in exception * messages if data corruption is found. * @param curs * window cursor to use during repository access. * @return the root level parser. * @throws MissingObjectException * the object supplied is not available from the repository. * @throws IncorrectObjectTypeException * the object supplied as an argument is not actually a tree and * cannot be parsed as though it were a tree. * @throws IOException * a loose object or pack file could not be Read. */ public CanonicalTreeParser resetRoot(Repository repo, AnyObjectId id, WindowCursor curs) { CanonicalTreeParser p = this; while (p.Parent != null) { p = (CanonicalTreeParser)p.Parent; } p.reset(repo, id, curs); return(p); }
/// <summary> /// Return this iterator, or its parent, if the tree is at eof. /// </summary> /// <returns></returns> public CanonicalTreeParser next() { CanonicalTreeParser iterator = this; while (true) { iterator.next(1); if (iterator.eof() && iterator.Parent != null) { // Parent was left pointing at the entry for us; advance // the parent to the next entry, possibly unwinding many // levels up the tree. // iterator = (CanonicalTreeParser)iterator.Parent; continue; } return(iterator); } }
/** * 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(AnyObjectId[] ids) { if (ids == null) { throw new ArgumentNullException("ids"); } int oldLen = _trees.Length; int newLen = ids.Length; AbstractTreeIterator[] r = newLen == oldLen ? _trees : new AbstractTreeIterator[newLen]; for (int i = 0; i < newLen; i++) { AbstractTreeIterator iterator; if (i < oldLen) { iterator = _trees[i]; while (iterator.Parent != null) { iterator = iterator.Parent; } CanonicalTreeParser oParse = (iterator as CanonicalTreeParser); if (oParse != null && iterator.PathOffset == 0) { iterator.Matches = null; iterator.MatchShift = 0; oParse.reset(_db, ids[i], _cursor); r[i] = iterator; continue; } } iterator = ParserFor(ids[i]); r[i] = iterator; } _trees = r; _advance = false; _depth = 0; }
/// <summary> /// Return this iterator, or its parent, if the tree is at eof. /// </summary> /// <returns></returns> public CanonicalTreeParser next() { CanonicalTreeParser iterator = this; while (true) { if (iterator._nextPtr == iterator._raw.Length) { // This parser has reached EOF, return to the parent. if (iterator._parent == null) { iterator._currPtr = iterator._nextPtr; return(iterator); } iterator = (CanonicalTreeParser)iterator.Parent; continue; } iterator._prevPtr = iterator._currPtr; iterator._currPtr = iterator._nextPtr; iterator.ParseEntry(); return(iterator); } }
/// <summary> /// Create a new revision and object walker for a given repository. /// </summary> /// <param name="repo"> /// The repository the walker will obtain data from. /// </param> public ObjectWalk(Repository repo) : base(repo) { _pendingObjects = new BlockObjQueue(); _treeWalk = new CanonicalTreeParser(); }
private void MarkTreeUninteresting(RevObject tree) { if ((tree.Flags & UNINTERESTING) != 0) return; tree.Flags |= UNINTERESTING; _treeWalk = _treeWalk.resetRoot(Repository, tree, WindowCursor); while (!_treeWalk.eof()) { FileMode mode = _treeWalk.EntryFileMode; var sType = (int)mode.ObjectType; switch (sType) { case Constants.OBJ_BLOB: _treeWalk.getEntryObjectId(IdBuffer); lookupBlob(IdBuffer).Flags |= UNINTERESTING; break; case Constants.OBJ_TREE: _treeWalk.getEntryObjectId(IdBuffer); RevTree t = lookupTree(IdBuffer); if ((t.Flags & UNINTERESTING) == 0) { t.Flags |= UNINTERESTING; _treeWalk = _treeWalk.createSubtreeIterator0(Repository, t, WindowCursor); continue; } break; default: if (FileMode.GitLink == FileMode.FromBits(mode.Bits)) break; _treeWalk.getEntryObjectId(IdBuffer); throw new CorruptObjectException("Invalid mode " + mode + " for " + IdBuffer + " " + _treeWalk.EntryPathString + " in " + tree + "."); } _treeWalk = _treeWalk.next(); } }
internal override void reset(int retainFlags) { base.reset(retainFlags); _pendingObjects = new BlockObjQueue(); _treeWalk = new CanonicalTreeParser(); _currentTree = null; last = null; }
/// <summary> /// Pop the next most recent object. /// </summary> /// <returns>next most recent object; null if traversal is over.</returns> /// <exception cref="MissingObjectException"> /// One or or more of the next objects are not available from the /// object database, but were thought to be candidates for /// traversal. This usually indicates a broken link. /// </exception> /// <exception cref="IncorrectObjectTypeException"> /// One or or more of the objects in a tree do not match the type indicated. /// </exception> /// <exception cref="Exception"> /// A pack file or loose object could not be Read. /// </exception> public RevObject nextObject() { if (last != null) { _treeWalk = last is RevTree ? enter(last) : _treeWalk.next(); } while (!_treeWalk.eof()) { FileMode mode = _treeWalk.EntryFileMode; switch ((int)mode.ObjectType) { case Constants.OBJ_BLOB: _treeWalk.getEntryObjectId(IdBuffer); RevBlob blob = lookupBlob(IdBuffer); if ((blob.Flags & SEEN) != 0) break; blob.Flags |= SEEN; if (ShouldSkipObject(blob)) break; last = blob; return blob; case Constants.OBJ_TREE: _treeWalk.getEntryObjectId(IdBuffer); RevTree tree = lookupTree(IdBuffer); if ((tree.Flags & SEEN) != 0) break; tree.Flags |= SEEN; if (ShouldSkipObject(tree)) break; last = tree; return tree; default: if (FileMode.GitLink.Equals(mode.Bits)) break; _treeWalk.getEntryObjectId(IdBuffer); throw new CorruptObjectException("Invalid mode " + mode + " for " + IdBuffer.Name + " '" + _treeWalk.EntryPathString + "' in " + _currentTree.Name + "."); } _treeWalk = _treeWalk.next(); } last = null; while (true) { RevObject obj = _pendingObjects.next(); if (obj == null) return null; if ((obj.Flags & SEEN) != 0) continue; obj.Flags |= SEEN; if (ShouldSkipObject(obj)) continue; RevTree oTree = (obj as RevTree); if (oTree != null) { _currentTree = oTree; _treeWalk = _treeWalk.resetRoot(Repository, _currentTree, WindowCursor); } return obj; } }
public override void Dispose() { base.Dispose(); _pendingObjects = new BlockObjQueue(); _treeWalk = new CanonicalTreeParser(); _currentTree = null; last = null; }
// [henon] createSubtreeIterator0 <--- not a typo! /** * Back door to quickly Create a subtree iterator for any subtree. * <para /> * Don't use this unless you are ObjectWalk. The method is meant to be * called only once the current entry has been identified as a tree and its * identity has been converted into an ObjectId. * * @param repo * repository to load the tree data from. * @param id * ObjectId of the tree to open. * @param curs * window cursor to use during repository access. * @return a new parser that walks over the current subtree. * @throws IOException * a loose object or pack file could not be Read. */ public CanonicalTreeParser createSubtreeIterator0(Repository repo, AnyObjectId id, WindowCursor curs) { var p = new CanonicalTreeParser(this); p.reset(repo, id, curs); return p; }
/// <summary> /// Pop the next most recent object. /// </summary> /// <returns>next most recent object; null if traversal is over.</returns> /// <exception cref="MissingObjectException"> /// One or or more of the next objects are not available from the /// object database, but were thought to be candidates for /// traversal. This usually indicates a broken link. /// </exception> /// <exception cref="IncorrectObjectTypeException"> /// One or or more of the objects in a tree do not match the type indicated. /// </exception> /// <exception cref="Exception"> /// A pack file or loose object could not be Read. /// </exception> public RevObject nextObject() { _fromTreeWalk = false; if (_nextSubtree != null) { _treeWalk = _treeWalk.createSubtreeIterator0(Repository, _nextSubtree, WindowCursor); _nextSubtree = null; } while (!_treeWalk.eof()) { FileMode mode = _treeWalk.EntryFileMode; var sType = (int)mode.ObjectType; switch (sType) { case Constants.OBJ_BLOB: _treeWalk.getEntryObjectId(IdBuffer); RevBlob blob = lookupBlob(IdBuffer); if ((blob.Flags & SEEN) != 0) break; blob.Flags |= SEEN; if (ShouldSkipObject(blob)) break; _fromTreeWalk = true; return blob; case Constants.OBJ_TREE: _treeWalk.getEntryObjectId(IdBuffer); RevTree tree = lookupTree(IdBuffer); if ((tree.Flags & SEEN) != 0) break; tree.Flags |= SEEN; if (ShouldSkipObject(tree)) break; _nextSubtree = tree; _fromTreeWalk = true; return tree; default: if (FileMode.GitLink.Equals(mode.Bits)) break; _treeWalk.getEntryObjectId(IdBuffer); throw new CorruptObjectException("Invalid mode " + mode + " for " + IdBuffer + " " + _treeWalk.EntryPathString + " in " + _currentTree + "."); } _treeWalk = _treeWalk.next(); } while (true) { RevObject obj = _pendingObjects.next(); if (obj == null) return null; if ((obj.Flags & SEEN) != 0) continue; obj.Flags |= SEEN; if (ShouldSkipObject(obj)) continue; if (obj is RevTree) { _currentTree = (RevTree)obj; _treeWalk = _treeWalk.resetRoot(Repository, _currentTree, WindowCursor); } return obj; } }