View Javadoc
1   /*
2    * Copyright (C) 2011, Google Inc. and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.blame;
12  
13  import java.io.IOException;
14  
15  import org.eclipse.jgit.errors.IncorrectObjectTypeException;
16  import org.eclipse.jgit.errors.MissingObjectException;
17  import org.eclipse.jgit.lib.AnyObjectId;
18  import org.eclipse.jgit.lib.Repository;
19  import org.eclipse.jgit.revwalk.RevCommit;
20  import org.eclipse.jgit.revwalk.RevWalk;
21  
22  final class ReverseWalk extends RevWalk {
23  	ReverseWalk(Repository repo) {
24  		super(repo);
25  	}
26  
27  	/** {@inheritDoc} */
28  	@Override
29  	public ReverseCommit next() throws MissingObjectException,
30  			IncorrectObjectTypeException, IOException {
31  		ReverseCommit c = (ReverseCommit) super.next();
32  		if (c == null)
33  			return null;
34  		for (int pIdx = 0; pIdx < c.getParentCount(); pIdx++)
35  			((ReverseCommit) c.getParent(pIdx)).addChild(c);
36  		return c;
37  	}
38  
39  	/** {@inheritDoc} */
40  	@Override
41  	protected RevCommit createCommit(AnyObjectId id) {
42  		return new ReverseCommit(id);
43  	}
44  
45  	static final class ReverseCommit extends RevCommit {
46  		private static final ReverseCommit[] NO_CHILDREN = {};
47  
48  		private ReverseCommit[] children = NO_CHILDREN;
49  
50  		ReverseCommit(AnyObjectId id) {
51  			super(id);
52  		}
53  
54  		void addChild(ReverseCommit c) {
55  			// Always put the most recent child onto the front of the list.
56  			// This works correctly because our ReverseWalk parent (above)
57  			// runs in COMMIT_TIME_DESC order. Older commits will be popped
58  			// later and should go in front of the children list so they are
59  			// visited first by BlameGenerator when considering candidates.
60  
61  			int cnt = children.length;
62  			switch (cnt) {
63  			case 0:
64  				children = new ReverseCommit[] { c };
65  				break;
66  			case 1:
67  				children = new ReverseCommit[] { c, children[0] };
68  				break;
69  			default:
70  				ReverseCommit[] n = new ReverseCommit[1 + cnt];
71  				n[0] = c;
72  				System.arraycopy(children, 0, n, 1, cnt);
73  				children = n;
74  				break;
75  			}
76  		}
77  
78  		int getChildCount() {
79  			return children.length;
80  		}
81  
82  		ReverseCommit getChild(int nth) {
83  			return children[nth];
84  		}
85  	}
86  }