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