Commit | Line | Data |
---|---|---|
68761620 FG |
1 | /******************************************************************************* |
2 | * Copyright (c) 2015 École Polytechnique de Montréal | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Francis Giraldeau - Initial implementation and API | |
11 | * Geneviève Bastien - Initial implementation and API | |
12 | *******************************************************************************/ | |
13 | ||
14 | package org.eclipse.tracecompass.analysis.graph.core.base; | |
15 | ||
16 | import java.util.Comparator; | |
17 | ||
18 | import org.eclipse.jdt.annotation.Nullable; | |
19 | ||
20 | /** | |
21 | * Timed vertex for TmfGraph | |
22 | * | |
23 | * @author Francis Giraldeau | |
24 | * @author Geneviève Bastien | |
25 | */ | |
26 | public class TmfVertex implements Comparable<TmfVertex> { | |
27 | ||
28 | private static long count = 0; | |
29 | ||
30 | /** | |
31 | * Describe the four edges coming in and out of a vertex | |
32 | */ | |
33 | public enum EdgeDirection { | |
34 | /** | |
35 | * Constant for the outgoing vertical edge (to other object) | |
36 | */ | |
37 | OUTGOING_VERTICAL_EDGE, | |
38 | /** | |
39 | * Constant for the incoming vertical edge (from other object) | |
40 | */ | |
41 | INCOMING_VERTICAL_EDGE, | |
42 | /** | |
43 | * Constant for the outgoing horizontal edge (to same object) | |
44 | */ | |
45 | OUTGOING_HORIZONTAL_EDGE, | |
46 | /** | |
47 | * Constant for the incoming horizontal edge (from same object) | |
48 | */ | |
49 | INCOMING_HORIZONTAL_EDGE | |
50 | } | |
51 | ||
52 | /** | |
53 | * Compare vertices by ascending timestamps | |
54 | */ | |
55 | public static Comparator<TmfVertex> ascending = new Comparator<TmfVertex>() { | |
56 | @Override | |
57 | public int compare(@Nullable TmfVertex v1, @Nullable TmfVertex v2) { | |
58 | if (v1 == null) { | |
59 | return 1; | |
60 | } | |
61 | if (v2 == null) { | |
62 | return -1; | |
63 | } | |
64 | return v1.getTs() > v2.getTs() ? 1 : (v1.getTs() == v2.getTs() ? 0 : -1); | |
65 | } | |
66 | }; | |
67 | ||
68 | /** | |
69 | * Compare vertices by descending timestamps | |
70 | */ | |
71 | public static Comparator<TmfVertex> descending = new Comparator<TmfVertex>() { | |
72 | @Override | |
73 | public int compare(@Nullable TmfVertex v1, @Nullable TmfVertex v2) { | |
74 | if (v1 == null) { | |
75 | return -1; | |
76 | } | |
77 | if (v2 == null) { | |
78 | return 1; | |
79 | } | |
80 | return v1.getTs() < v2.getTs() ? 1 : (v1.getTs() == v2.getTs() ? 0 : -1); | |
81 | } | |
82 | }; | |
83 | ||
84 | private @Nullable TmfEdge fOutgoingVertical = null; | |
85 | private @Nullable TmfEdge fIncomingVertical = null; | |
86 | private @Nullable TmfEdge fOutgoingHorizontal = null; | |
87 | private @Nullable TmfEdge fIncomingHorizontal = null; | |
88 | private final long fTimestamp; | |
89 | private final long fId; | |
90 | ||
91 | /** | |
92 | * Default Constructor | |
93 | */ | |
94 | public TmfVertex() { | |
95 | this(0); | |
96 | } | |
97 | ||
98 | /** | |
99 | * Constructor with timestamp | |
100 | * | |
101 | * @param ts | |
102 | * The vertex's timestamp | |
103 | */ | |
104 | public TmfVertex(final long ts) { | |
105 | fTimestamp = ts; | |
106 | synchronized (TmfVertex.class) { | |
107 | fId = count++; | |
108 | } | |
109 | } | |
110 | ||
111 | /** | |
112 | * Copy constructor. Keeps same timestamp, but does not keep edges | |
113 | * | |
114 | * @param node | |
115 | * vertex to copy | |
116 | */ | |
117 | public TmfVertex(TmfVertex node) { | |
118 | this(node.fTimestamp); | |
119 | } | |
120 | ||
121 | /** | |
122 | * Copy constructor, but changes the timestamp | |
123 | * | |
124 | * @param node | |
125 | * vertex to copy | |
126 | * @param ts | |
127 | * The timestamp of this new node | |
128 | */ | |
129 | public TmfVertex(TmfVertex node, final long ts) { | |
130 | fTimestamp = ts; | |
131 | synchronized (TmfVertex.class) { | |
132 | fId = count++; | |
133 | } | |
134 | fOutgoingVertical = node.fOutgoingVertical; | |
135 | fIncomingVertical = node.fIncomingVertical; | |
136 | fOutgoingHorizontal = node.fOutgoingHorizontal; | |
137 | fIncomingHorizontal = node.fIncomingHorizontal; | |
138 | } | |
139 | ||
140 | /* | |
141 | * Getters and setters | |
142 | */ | |
143 | ||
144 | /** | |
145 | * Returns the timestamps of this node | |
146 | * | |
147 | * @return the timstamp | |
148 | */ | |
149 | public long getTs() { | |
150 | return fTimestamp; | |
151 | } | |
152 | ||
153 | /** | |
154 | * Returns the unique ID of this node | |
155 | * | |
156 | * @return the vertex's id | |
157 | */ | |
158 | public long getID() { | |
159 | return fId; | |
160 | } | |
161 | ||
162 | /** | |
163 | * Adds an horizontal edge from the current vertex to the 'to' vertex | |
164 | * | |
165 | * @param to | |
166 | * The vertex to link to, belongs to the same object | |
167 | * | |
168 | * @return The new edge | |
169 | */ | |
170 | public TmfEdge linkHorizontal(TmfVertex to) { | |
171 | checkTimestamps(to); | |
732e0744 | 172 | checkNotSelf(to); |
68761620 FG |
173 | return linkHorizontalRaw(to); |
174 | } | |
175 | ||
176 | private TmfEdge linkHorizontalRaw(TmfVertex node) { | |
177 | TmfEdge link = new TmfEdge(this, node); | |
178 | fOutgoingHorizontal = link; | |
179 | node.fIncomingHorizontal = link; | |
180 | return link; | |
181 | } | |
182 | ||
183 | /** | |
184 | * Adds a vertical edge from the current vertex to the 'to' vertex | |
185 | * | |
186 | * @param to | |
187 | * The vertex to link to, belongs to a different object | |
188 | * @return The new edge | |
189 | */ | |
190 | public TmfEdge linkVertical(TmfVertex to) { | |
191 | checkTimestamps(to); | |
732e0744 | 192 | checkNotSelf(to); |
68761620 FG |
193 | return linkVerticalRaw(to); |
194 | } | |
195 | ||
196 | private TmfEdge linkVerticalRaw(TmfVertex to) { | |
197 | TmfEdge link = new TmfEdge(this, to); | |
198 | fOutgoingVertical = link; | |
199 | to.fIncomingVertical = link; | |
200 | return link; | |
201 | } | |
202 | ||
203 | private void checkTimestamps(TmfVertex to) { | |
204 | if (this.fTimestamp > to.fTimestamp) { | |
205 | throw new IllegalArgumentException(Messages.TmfVertex_ArgumentTimestampLower + | |
206 | String.format(": (curr=%d,next=%d,elapsed=%d)", fTimestamp, to.fTimestamp, to.fTimestamp - fTimestamp)); //$NON-NLS-1$ | |
207 | } | |
208 | } | |
209 | ||
732e0744 FG |
210 | private void checkNotSelf(TmfVertex to) { |
211 | if (this == to) { | |
212 | throw new IllegalArgumentException(Messages.TmfVertex_CannotLinkToSelf); | |
213 | } | |
214 | } | |
215 | ||
216 | ||
68761620 FG |
217 | /** |
218 | * Get an edge to or from this vertex in the appropriate direction | |
219 | * | |
220 | * @param dir | |
221 | * The direction of the requested edge | |
222 | * @return The edge from this vertex to the requested direction | |
223 | */ | |
224 | public @Nullable TmfEdge getEdge(EdgeDirection dir) { | |
225 | switch (dir) { | |
226 | case OUTGOING_VERTICAL_EDGE: | |
227 | return fOutgoingVertical; | |
228 | case INCOMING_VERTICAL_EDGE: | |
229 | return fIncomingVertical; | |
230 | case OUTGOING_HORIZONTAL_EDGE: | |
231 | return fOutgoingHorizontal; | |
232 | case INCOMING_HORIZONTAL_EDGE: | |
233 | return fIncomingHorizontal; | |
234 | default: | |
9ee366e2 | 235 | throw new IllegalStateException("Unknown edge direction type : " + dir); //$NON-NLS-1$ |
68761620 FG |
236 | } |
237 | } | |
238 | ||
239 | /** | |
240 | * Removes a directed edge from this vertex. The edge in that direction will | |
241 | * be null. | |
242 | * | |
243 | * @param dir | |
244 | * The direction to remove the edge from | |
245 | */ | |
246 | public void removeEdge(EdgeDirection dir) { | |
247 | switch (dir) { | |
248 | case OUTGOING_VERTICAL_EDGE: | |
249 | fOutgoingVertical = null; | |
250 | break; | |
251 | case INCOMING_VERTICAL_EDGE: | |
252 | fIncomingVertical = null; | |
253 | break; | |
254 | case OUTGOING_HORIZONTAL_EDGE: | |
255 | fOutgoingHorizontal = null; | |
256 | break; | |
257 | case INCOMING_HORIZONTAL_EDGE: | |
258 | fIncomingHorizontal = null; | |
259 | break; | |
260 | default: | |
9ee366e2 | 261 | throw new IllegalStateException("Unknown edge direction type : " + dir); //$NON-NLS-1$ |
68761620 FG |
262 | } |
263 | } | |
264 | ||
265 | /** | |
266 | * Get the neighbor of a vertex from a directed edge. Incoming edges will | |
267 | * return the vertex from the edge and outgoing edges will return the vertex | |
268 | * to. This method is a utility method that can be used in code where the | |
269 | * direction is a variable. If the edge direction is known (using one of the | |
270 | * EdgeDirection constant), it is preferable to use the | |
271 | * {@link TmfEdge#getVertexFrom()} and {@link TmfEdge#getVertexTo()} | |
272 | * directly. | |
273 | * | |
274 | * @param edge | |
275 | * The edge for which to get the right neighbor | |
276 | * @param dir | |
277 | * The direction of this edge | |
278 | * @return The vertex that neighbors another vertex in the requested | |
279 | * direction | |
280 | */ | |
281 | public static TmfVertex getNeighborFromEdge(TmfEdge edge, EdgeDirection dir) { | |
282 | switch (dir) { | |
283 | case OUTGOING_VERTICAL_EDGE: | |
284 | case OUTGOING_HORIZONTAL_EDGE: | |
285 | return edge.getVertexTo(); | |
286 | case INCOMING_VERTICAL_EDGE: | |
287 | case INCOMING_HORIZONTAL_EDGE: | |
288 | return edge.getVertexFrom(); | |
289 | default: | |
9ee366e2 | 290 | throw new IllegalStateException("Unknown edge direction type : " + dir); //$NON-NLS-1$ |
68761620 FG |
291 | } |
292 | } | |
293 | ||
294 | @Override | |
295 | public int compareTo(@Nullable TmfVertex other) { | |
296 | if (other == null) { | |
297 | return 1; | |
298 | } | |
299 | return this.fTimestamp > other.fTimestamp ? 1 : (this.fTimestamp == other.fTimestamp ? 0 : -1); | |
300 | } | |
301 | ||
302 | @Override | |
303 | public String toString() { | |
304 | return "[" + fId + "," + fTimestamp + "]"; //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$ | |
305 | } | |
306 | ||
307 | } |