Commit | Line | Data |
---|---|---|
e73a4ba5 | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2013, 2015 École Polytechnique de Montréal |
e73a4ba5 GB |
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 | * Geneviève Bastien - Initial implementation and API | |
11 | *******************************************************************************/ | |
12 | ||
2bdf0193 | 13 | package org.eclipse.tracecompass.tmf.core.event.matching; |
e73a4ba5 | 14 | |
27213c57 | 15 | import java.util.Collection; |
4d2a4a2c GB |
16 | import java.util.HashSet; |
17 | import java.util.Set; | |
e73a4ba5 | 18 | |
2bdf0193 AM |
19 | import org.eclipse.tracecompass.internal.tmf.core.Activator; |
20 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; | |
21 | import org.eclipse.tracecompass.tmf.core.request.ITmfEventRequest; | |
22 | import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest; | |
23 | import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange; | |
24 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | |
4d2a4a2c GB |
25 | import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; |
26 | import org.eclipse.tracecompass.tmf.core.trace.experiment.TmfExperiment; | |
e73a4ba5 | 27 | |
2939944e GB |
28 | import com.google.common.collect.HashMultimap; |
29 | import com.google.common.collect.ImmutableList; | |
30 | import com.google.common.collect.Multimap; | |
31 | ||
e73a4ba5 GB |
32 | /** |
33 | * Abstract class to extend to match certain type of events in a trace | |
34 | * | |
35 | * @author Geneviève Bastien | |
36 | * @since 3.0 | |
37 | */ | |
38 | public abstract class TmfEventMatching implements ITmfEventMatching { | |
39 | ||
40 | /** | |
41 | * The matching type | |
42 | * | |
43 | * FIXME Not the best place to put this. Have an array of match types as a | |
44 | * parameter of each trace? | |
45 | */ | |
46 | public enum MatchingType { | |
47 | /** | |
48 | * NETWORK, match network events | |
49 | */ | |
50 | NETWORK | |
51 | } | |
52 | ||
4d2a4a2c GB |
53 | private static final Multimap<MatchingType, ITmfMatchEventDefinition> MATCH_DEFINITIONS = HashMultimap.create(); |
54 | ||
e73a4ba5 GB |
55 | /** |
56 | * The array of traces to match | |
57 | */ | |
27213c57 | 58 | private final Collection<ITmfTrace> fTraces; |
e73a4ba5 GB |
59 | |
60 | /** | |
61 | * The class to call once a match is found | |
62 | */ | |
63 | private final IMatchProcessingUnit fMatches; | |
64 | ||
2939944e | 65 | private final Multimap<ITmfTrace, ITmfMatchEventDefinition> fMatchMap = HashMultimap.create(); |
e73a4ba5 GB |
66 | |
67 | /** | |
68 | * Constructor with multiple traces and a match processing object | |
69 | * | |
70 | * @param traces | |
71 | * The set of traces for which to match events | |
72 | * @param tmfEventMatches | |
73 | * The match processing class | |
74 | */ | |
27213c57 | 75 | public TmfEventMatching(Collection<ITmfTrace> traces, IMatchProcessingUnit tmfEventMatches) { |
e73a4ba5 GB |
76 | if (tmfEventMatches == null) { |
77 | throw new IllegalArgumentException(); | |
78 | } | |
4d2a4a2c | 79 | fTraces = new HashSet<>(traces); |
e73a4ba5 GB |
80 | fMatches = tmfEventMatches; |
81 | } | |
82 | ||
83 | /** | |
4d2a4a2c GB |
84 | * Returns the traces to synchronize. These are the traces that were |
85 | * specified in the constructor, they may contain either traces or | |
86 | * experiment. | |
e73a4ba5 | 87 | * |
4d2a4a2c | 88 | * @return The traces to synchronize |
e73a4ba5 | 89 | */ |
4d2a4a2c GB |
90 | protected Collection<ITmfTrace> getTraces() { |
91 | return new HashSet<>(fTraces); | |
92 | } | |
93 | ||
94 | /** | |
95 | * Returns the individual traces to process. If some of the traces specified | |
96 | * to synchronize in the constructor were experiments, only the traces | |
97 | * contained in this experiment will be returned. No {@link TmfExperiment} | |
98 | * are returned by this method. | |
99 | * | |
100 | * @return The individual traces to synchronize, no experiments | |
101 | */ | |
102 | protected Collection<ITmfTrace> getIndividualTraces() { | |
103 | Set<ITmfTrace> traces = new HashSet<>(); | |
104 | for (ITmfTrace trace : fTraces) { | |
c14c0757 | 105 | traces.addAll(TmfTraceManager.getTraceSet(trace)); |
4d2a4a2c GB |
106 | } |
107 | return traces; | |
e73a4ba5 GB |
108 | } |
109 | ||
110 | /** | |
111 | * Returns the match processing unit | |
112 | * | |
113 | * @return The match processing unit | |
114 | */ | |
115 | protected IMatchProcessingUnit getProcessingUnit() { | |
116 | return fMatches; | |
117 | } | |
118 | ||
119 | /** | |
2939944e | 120 | * Returns the match event definitions corresponding to the trace |
e73a4ba5 GB |
121 | * |
122 | * @param trace | |
123 | * The trace | |
124 | * @return The match event definition object | |
125 | */ | |
2939944e GB |
126 | protected Collection<ITmfMatchEventDefinition> getEventDefinitions(ITmfTrace trace) { |
127 | return ImmutableList.copyOf(fMatchMap.get(trace)); | |
e73a4ba5 GB |
128 | } |
129 | ||
130 | /** | |
131 | * Method that initializes any data structure for the event matching. It | |
132 | * also assigns to each trace an event matching definition instance that | |
133 | * applies to the trace | |
134 | */ | |
135 | protected void initMatching() { | |
136 | fMatches.init(fTraces); | |
4d2a4a2c | 137 | Collection<ITmfMatchEventDefinition> deflist = MATCH_DEFINITIONS.get(getMatchingType()); |
e73a4ba5 GB |
138 | if (deflist == null) { |
139 | return; | |
140 | } | |
4d2a4a2c | 141 | for (ITmfTrace trace : getIndividualTraces()) { |
e73a4ba5 GB |
142 | for (ITmfMatchEventDefinition def : deflist) { |
143 | if (def.canMatchTrace(trace)) { | |
144 | fMatchMap.put(trace, def); | |
e73a4ba5 GB |
145 | } |
146 | } | |
147 | } | |
148 | } | |
149 | ||
150 | /** | |
151 | * Calls any post matching methods of the processing class | |
152 | */ | |
153 | protected void finalizeMatching() { | |
154 | fMatches.matchingEnded(); | |
155 | } | |
156 | ||
157 | /** | |
158 | * Prints stats from the matching | |
159 | * | |
160 | * @return string of statistics | |
161 | */ | |
162 | @SuppressWarnings("nls") | |
163 | @Override | |
164 | public String toString() { | |
165 | return getClass().getSimpleName() + " [ " + fMatches + " ]"; | |
166 | } | |
167 | ||
168 | /** | |
169 | * Matches one event | |
170 | * | |
171 | * @param event | |
172 | * The event to match | |
27213c57 AM |
173 | * @param trace |
174 | * The trace to which this event belongs | |
e73a4ba5 | 175 | */ |
27213c57 | 176 | protected abstract void matchEvent(ITmfEvent event, ITmfTrace trace); |
e73a4ba5 GB |
177 | |
178 | /** | |
179 | * Returns the matching type this class implements | |
180 | * | |
181 | * @return A matching type | |
182 | */ | |
183 | protected abstract MatchingType getMatchingType(); | |
184 | ||
185 | /** | |
186 | * Method that start the process of matching events | |
187 | * | |
188 | * @return Whether the match was completed correctly or not | |
189 | */ | |
190 | @Override | |
191 | public boolean matchEvents() { | |
192 | ||
193 | /* Are there traces to match? If no, return false */ | |
27213c57 | 194 | if (!(fTraces.size() > 0)) { |
e73a4ba5 GB |
195 | return false; |
196 | } | |
197 | ||
198 | // TODO Start a new thread here? | |
199 | initMatching(); | |
200 | ||
201 | /** | |
202 | * For each trace, get the events and for each event, call the | |
203 | * MatchEvent method | |
204 | * | |
205 | * FIXME This would use a lot of memory if the traces are big, because | |
206 | * all involved events from first trace will have to be kept before a | |
207 | * first match is possible with second trace. | |
208 | * | |
209 | * <pre> | |
210 | * Other possible matching strategy: | |
211 | * Incremental: | |
212 | * Sliding window: | |
213 | * Other strategy: start with the shortest trace, take a few events | |
214 | * at the beginning and at the end | |
215 | * Experiment strategy: have the experiment do the request, then events will | |
216 | * come from both traces chronologically, but then instead of ITmfTrace[], it | |
217 | * would be preferable to have experiment | |
218 | * </pre> | |
219 | */ | |
27213c57 AM |
220 | for (ITmfTrace trace : fTraces) { |
221 | EventMatchingBuildRequest request = new EventMatchingBuildRequest(this, trace); | |
e73a4ba5 GB |
222 | |
223 | /* | |
224 | * Send the request to the trace here, since there is probably no | |
225 | * experiment. | |
226 | */ | |
27213c57 | 227 | trace.sendRequest(request); |
e73a4ba5 GB |
228 | try { |
229 | request.waitForCompletion(); | |
230 | } catch (InterruptedException e) { | |
231 | Activator.logInfo(e.getMessage()); | |
232 | } | |
233 | } | |
234 | ||
235 | finalizeMatching(); | |
236 | ||
237 | return true; | |
238 | } | |
239 | ||
240 | /** | |
241 | * Registers an event match definition to be used for a certain match type | |
242 | * | |
243 | * @param match | |
244 | * The event matching definition | |
245 | */ | |
246 | public static void registerMatchObject(ITmfMatchEventDefinition match) { | |
247 | for (MatchingType type : match.getApplicableMatchingTypes()) { | |
4d2a4a2c | 248 | MATCH_DEFINITIONS.put(type, match); |
e73a4ba5 GB |
249 | } |
250 | } | |
251 | ||
252 | } | |
253 | ||
254 | class EventMatchingBuildRequest extends TmfEventRequest { | |
255 | ||
256 | private final TmfEventMatching matching; | |
27213c57 | 257 | private final ITmfTrace trace; |
e73a4ba5 | 258 | |
27213c57 | 259 | EventMatchingBuildRequest(TmfEventMatching matching, ITmfTrace trace) { |
91e7f946 | 260 | super(ITmfEvent.class, |
e73a4ba5 GB |
261 | TmfTimeRange.ETERNITY, |
262 | 0, | |
2740e05c | 263 | ITmfEventRequest.ALL_DATA, |
fd3f1eff | 264 | ITmfEventRequest.ExecutionType.FOREGROUND); |
e73a4ba5 | 265 | this.matching = matching; |
27213c57 | 266 | this.trace = trace; |
e73a4ba5 GB |
267 | } |
268 | ||
269 | @Override | |
270 | public void handleData(final ITmfEvent event) { | |
271 | super.handleData(event); | |
41f3b36b | 272 | matching.matchEvent(event, trace); |
e73a4ba5 GB |
273 | } |
274 | ||
275 | @Override | |
276 | public void handleSuccess() { | |
277 | super.handleSuccess(); | |
278 | } | |
279 | ||
280 | @Override | |
281 | public void handleCancel() { | |
282 | super.handleCancel(); | |
283 | } | |
284 | ||
285 | @Override | |
286 | public void handleFailure() { | |
287 | super.handleFailure(); | |
288 | } | |
289 | } |