View Javadoc
1   /*
2    * Copyright (C) 2008, 2014 Shawn O. Pearce <spearce@spearce.org> 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.revplot;
12  
13  import org.eclipse.jgit.lib.AnyObjectId;
14  import org.eclipse.jgit.lib.Ref;
15  import org.eclipse.jgit.revwalk.RevCommit;
16  
17  /**
18   * A commit reference to a commit in the DAG.
19   *
20   * @param <L>
21   *            type of lane being used by the plotter.
22   * @see PlotCommitList
23   */
24  public class PlotCommit<L extends PlotLane> extends RevCommit {
25  	static final PlotCommit[] NO_CHILDREN = {};
26  
27  	static final PlotLane[] NO_LANES = {};
28  
29  	static final Ref[] NO_REFS = {};
30  
31  	PlotLane[] forkingOffLanes;
32  
33  	PlotLane[] passingLanes;
34  
35  	PlotLane[] mergingLanes;
36  
37  	PlotLane lane;
38  
39  	PlotCommit[] children;
40  
41  	Ref[] refs;
42  
43  	/**
44  	 * Create a new commit.
45  	 *
46  	 * @param id
47  	 *            the identity of this commit.
48  	 */
49  	protected PlotCommit(AnyObjectId id) {
50  		super(id);
51  		forkingOffLanes = NO_LANES;
52  		passingLanes = NO_LANES;
53  		mergingLanes = NO_LANES;
54  		children = NO_CHILDREN;
55  		refs = NO_REFS;
56  	}
57  
58  	void addForkingOffLane(PlotLane f) {
59  		forkingOffLanes = addLane(f, forkingOffLanes);
60  	}
61  
62  	void addPassingLane(PlotLane c) {
63  		passingLanes = addLane(c, passingLanes);
64  	}
65  
66  	void addMergingLane(PlotLane m) {
67  		mergingLanes = addLane(m, mergingLanes);
68  	}
69  
70  	private static PlotLane[] addLane(PlotLane l, PlotLane[] lanes) {
71  		final int cnt = lanes.length;
72  		switch (cnt) {
73  		case 0:
74  			lanes = new PlotLane[] { l };
75  			break;
76  		case 1:
77  			lanes = new PlotLane[] { lanes[0], l };
78  			break;
79  		default:
80  			final PlotLane[] n = new PlotLane[cnt + 1];
81  			System.arraycopy(lanes, 0, n, 0, cnt);
82  			n[cnt] = l;
83  			lanes = n;
84  			break;
85  		}
86  		return lanes;
87  	}
88  
89  	void addChild(PlotCommit c) {
90  		final int cnt = children.length;
91  		switch (cnt) {
92  		case 0:
93  			children = new PlotCommit[] { c };
94  			break;
95  		case 1:
96  			if (!c.getId().equals(children[0].getId()))
97  				children = new PlotCommit[] { children[0], c };
98  			break;
99  		default:
100 			for (PlotCommit pc : children)
101 				if (c.getId().equals(pc.getId()))
102 					return;
103 			final PlotCommit[] n = new PlotCommit[cnt + 1];
104 			System.arraycopy(children, 0, n, 0, cnt);
105 			n[cnt] = c;
106 			children = n;
107 			break;
108 		}
109 	}
110 
111 	/**
112 	 * Get the number of child commits listed in this commit.
113 	 *
114 	 * @return number of children; always a positive value but can be 0.
115 	 */
116 	public final int getChildCount() {
117 		return children.length;
118 	}
119 
120 	/**
121 	 * Get the nth child from this commit's child list.
122 	 *
123 	 * @param nth
124 	 *            child index to obtain. Must be in the range 0 through
125 	 *            {@link #getChildCount()}-1.
126 	 * @return the specified child.
127 	 * @throws java.lang.ArrayIndexOutOfBoundsException
128 	 *             an invalid child index was specified.
129 	 */
130 	public final PlotCommit getChild(int nth) {
131 		return children[nth];
132 	}
133 
134 	/**
135 	 * Determine if the given commit is a child (descendant) of this commit.
136 	 *
137 	 * @param c
138 	 *            the commit to test.
139 	 * @return true if the given commit built on top of this commit.
140 	 */
141 	@SuppressWarnings("ReferenceEquality")
142 	public final boolean isChild(PlotCommit c) {
143 		for (PlotCommit a : children)
144 			if (a == c)
145 				return true;
146 		return false;
147 	}
148 
149 	/**
150 	 * Get the number of refs for this commit.
151 	 *
152 	 * @return number of refs; always a positive value but can be 0.
153 	 */
154 	public final int getRefCount() {
155 		return refs.length;
156 	}
157 
158 	/**
159 	 * Get the nth Ref from this commit's ref list.
160 	 *
161 	 * @param nth
162 	 *            ref index to obtain. Must be in the range 0 through
163 	 *            {@link #getRefCount()}-1.
164 	 * @return the specified ref.
165 	 * @throws java.lang.ArrayIndexOutOfBoundsException
166 	 *             an invalid ref index was specified.
167 	 */
168 	public final Ref getRef(int nth) {
169 		return refs[nth];
170 	}
171 
172 	/**
173 	 * Obtain the lane this commit has been plotted into.
174 	 *
175 	 * @return the assigned lane for this commit.
176 	 */
177 	@SuppressWarnings("unchecked")
178 	public final L getLane() {
179 		return (L) lane;
180 	}
181 
182 	/** {@inheritDoc} */
183 	@Override
184 	public void reset() {
185 		forkingOffLanes = NO_LANES;
186 		passingLanes = NO_LANES;
187 		mergingLanes = NO_LANES;
188 		children = NO_CHILDREN;
189 		lane = null;
190 		super.reset();
191 	}
192 }