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; | |
27213c57 | 16 | import java.util.Collection; |
e73a4ba5 GB |
17 | import java.util.HashMap; |
18 | import java.util.List; | |
19 | import java.util.Map; | |
20 | ||
21 | import org.eclipse.linuxtools.internal.tmf.core.Activator; | |
e73a4ba5 | 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 | */ | |
27213c57 | 52 | private final Collection<ITmfTrace> fTraces; |
e73a4ba5 GB |
53 | |
54 | /** | |
55 | * The class to call once a match is found | |
56 | */ | |
57 | private final IMatchProcessingUnit fMatches; | |
58 | ||
a4524c1b | 59 | private static final Map<MatchingType, List<ITmfMatchEventDefinition>> fMatchDefinitions = new HashMap<>(); |
e73a4ba5 | 60 | |
a4524c1b | 61 | private final Map<ITmfTrace, ITmfMatchEventDefinition> fMatchMap = new HashMap<>(); |
e73a4ba5 GB |
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 | */ | |
27213c57 | 71 | public TmfEventMatching(Collection<ITmfTrace> traces, IMatchProcessingUnit tmfEventMatches) { |
e73a4ba5 GB |
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 | */ | |
27213c57 | 84 | protected Collection<? extends ITmfTrace> getTraces() { |
e73a4ba5 GB |
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 | |
27213c57 AM |
152 | * @param trace |
153 | * The trace to which this event belongs | |
e73a4ba5 | 154 | */ |
27213c57 | 155 | protected abstract void matchEvent(ITmfEvent event, ITmfTrace trace); |
e73a4ba5 GB |
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 */ | |
27213c57 | 173 | if (!(fTraces.size() > 0)) { |
e73a4ba5 GB |
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 | */ | |
27213c57 AM |
199 | for (ITmfTrace trace : fTraces) { |
200 | EventMatchingBuildRequest request = new EventMatchingBuildRequest(this, trace); | |
e73a4ba5 GB |
201 | |
202 | /* | |
203 | * Send the request to the trace here, since there is probably no | |
204 | * experiment. | |
205 | */ | |
27213c57 | 206 | trace.sendRequest(request); |
e73a4ba5 GB |
207 | try { |
208 | request.waitForCompletion(); | |
209 | } catch (InterruptedException e) { | |
210 | Activator.logInfo(e.getMessage()); | |
211 | } | |
212 | } | |
213 | ||
214 | finalizeMatching(); | |
215 | ||
216 | return true; | |
217 | } | |
218 | ||
219 | /** | |
220 | * Registers an event match definition to be used for a certain match type | |
221 | * | |
222 | * @param match | |
223 | * The event matching definition | |
224 | */ | |
225 | public static void registerMatchObject(ITmfMatchEventDefinition match) { | |
226 | for (MatchingType type : match.getApplicableMatchingTypes()) { | |
227 | if (!fMatchDefinitions.containsKey(type)) { | |
228 | fMatchDefinitions.put(type, new ArrayList<ITmfMatchEventDefinition>()); | |
229 | } | |
230 | fMatchDefinitions.get(type).add(match); | |
231 | } | |
232 | } | |
233 | ||
234 | } | |
235 | ||
236 | class EventMatchingBuildRequest extends TmfEventRequest { | |
237 | ||
238 | private final TmfEventMatching matching; | |
27213c57 | 239 | private final ITmfTrace trace; |
e73a4ba5 | 240 | |
27213c57 | 241 | EventMatchingBuildRequest(TmfEventMatching matching, ITmfTrace trace) { |
91e7f946 | 242 | super(ITmfEvent.class, |
e73a4ba5 GB |
243 | TmfTimeRange.ETERNITY, |
244 | 0, | |
2740e05c | 245 | ITmfEventRequest.ALL_DATA, |
fd3f1eff | 246 | ITmfEventRequest.ExecutionType.FOREGROUND); |
e73a4ba5 | 247 | this.matching = matching; |
27213c57 | 248 | this.trace = trace; |
e73a4ba5 GB |
249 | } |
250 | ||
251 | @Override | |
252 | public void handleData(final ITmfEvent event) { | |
253 | super.handleData(event); | |
254 | if (event != null) { | |
27213c57 | 255 | matching.matchEvent(event, trace); |
e73a4ba5 GB |
256 | } |
257 | } | |
258 | ||
259 | @Override | |
260 | public void handleSuccess() { | |
261 | super.handleSuccess(); | |
262 | } | |
263 | ||
264 | @Override | |
265 | public void handleCancel() { | |
266 | super.handleCancel(); | |
267 | } | |
268 | ||
269 | @Override | |
270 | public void handleFailure() { | |
271 | super.handleFailure(); | |
272 | } | |
273 | } |