TMF: Change event matching key from a list to a plain old java object
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / event / matching / TmfNetworkEventMatching.java
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.tracecompass.tmf.core.event.matching;
14
15 import java.util.Collection;
16
17 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
18 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
19
20 import com.google.common.collect.HashBasedTable;
21 import com.google.common.collect.Table;
22
23 /**
24 * This class matches events typically network-style, ie. where some events are
25 * 'send' events and the other 'receive' events or out/in events
26 *
27 * @author Geneviève Bastien
28 * @since 3.0
29 */
30 public class TmfNetworkEventMatching extends TmfEventMatching {
31
32 /**
33 * Hashtables for unmatches incoming events
34 */
35 private final Table<ITmfTrace, IEventMatchingKey, ITmfEvent> fUnmatchedIn = HashBasedTable.create();
36
37 /**
38 * Hashtables for unmatches outgoing events
39 */
40 private final Table<ITmfTrace, IEventMatchingKey, ITmfEvent> fUnmatchedOut = HashBasedTable.create();
41
42 /**
43 * Enum for in and out types
44 */
45 public enum Direction {
46 /**
47 * The event is a 'receive' type of event
48 */
49 IN,
50 /**
51 * The event is a 'send' type of event
52 */
53 OUT,
54 }
55
56 /**
57 * Constructor with multiple traces and match processing object
58 *
59 * @param traces
60 * The set of traces for which to match events
61 */
62 public TmfNetworkEventMatching(Collection<ITmfTrace> traces) {
63 this(traces, new TmfEventMatches());
64 }
65
66 /**
67 * Constructor with multiple traces and match processing object
68 *
69 * @param traces
70 * The set of traces for which to match events
71 * @param tmfEventMatches
72 * The match processing class
73 */
74 public TmfNetworkEventMatching(Collection<ITmfTrace> traces, IMatchProcessingUnit tmfEventMatches) {
75 super(traces, tmfEventMatches);
76 }
77
78 /**
79 * Method that initializes any data structure for the event matching
80 */
81 @Override
82 public void initMatching() {
83 // Initialize the matching infrastructure (unmatched event lists)
84 fUnmatchedIn.clear();
85 fUnmatchedOut.clear();
86 super.initMatching();
87 }
88
89 @Override
90 protected MatchingType getMatchingType() {
91 return MatchingType.NETWORK;
92 }
93
94 @Override
95 public synchronized void matchEvent(ITmfEvent event, ITmfTrace trace) {
96 ITmfNetworkMatchDefinition def = null;
97 Direction evType = null;
98 for (ITmfMatchEventDefinition oneDef : getEventDefinitions(event.getTrace())) {
99 if (oneDef instanceof ITmfNetworkMatchDefinition) {
100 def = (ITmfNetworkMatchDefinition) oneDef;
101 evType = def.getDirection(event);
102 if (evType != null) {
103 break;
104 }
105 }
106 }
107
108 if (def == null || evType == null) {
109 return;
110 }
111
112 /* Get the event's unique fields */
113 IEventMatchingKey eventKey = def.getEventKey(event);
114
115 if (eventKey == null) {
116 return;
117 }
118 Table<ITmfTrace, IEventMatchingKey, ITmfEvent> unmatchedTbl, companionTbl;
119
120 /* Point to the appropriate table */
121 switch (evType) {
122 case IN:
123 unmatchedTbl = fUnmatchedIn;
124 companionTbl = fUnmatchedOut;
125 break;
126 case OUT:
127 unmatchedTbl = fUnmatchedOut;
128 companionTbl = fUnmatchedIn;
129 break;
130 default:
131 return;
132 }
133
134 boolean found = false;
135 TmfEventDependency dep = null;
136 /* Search for the event in the companion table */
137 for (ITmfTrace mTrace : getIndividualTraces()) {
138 if (companionTbl.contains(mTrace, eventKey)) {
139 found = true;
140 ITmfEvent companionEvent = companionTbl.get(mTrace, eventKey);
141
142 /* Remove the element from the companion table */
143 companionTbl.remove(mTrace, eventKey);
144
145 /* Create the dependency object */
146 switch (evType) {
147 case IN:
148 dep = new TmfEventDependency(companionEvent, event);
149 break;
150 case OUT:
151 dep = new TmfEventDependency(event, companionEvent);
152 break;
153 default:
154 break;
155
156 }
157 }
158 }
159
160 /*
161 * If no companion was found, add the event to the appropriate unMatched
162 * lists
163 */
164 if (found) {
165 getProcessingUnit().addMatch(dep);
166 } else {
167 /*
168 * If an event is already associated with this key, do not add it
169 * again, we keep the first event chronologically, so if its match
170 * is eventually found, it is associated with the first send or
171 * receive event. At best, it is a good guess, at worst, the match
172 * will be too far off to be accurate. Too bad!
173 *
174 * TODO: maybe instead of just one event, we could have a list of
175 * events as value for the unmatched table. Not necessary right now
176 * though
177 */
178 if (!unmatchedTbl.contains(event.getTrace(), eventKey)) {
179 unmatchedTbl.put(event.getTrace(), eventKey, event);
180 }
181 }
182
183 }
184
185 /**
186 * Prints stats from the matching
187 *
188 * @return string of statistics
189 */
190 @SuppressWarnings("nls")
191 @Override
192 public String toString() {
193 final String cr = System.getProperty("line.separator");
194 StringBuilder b = new StringBuilder();
195 b.append(getProcessingUnit());
196 int i = 0;
197 for (ITmfTrace trace : getIndividualTraces()) {
198 b.append("Trace " + i++ + ":" + cr +
199 " " + fUnmatchedIn.row(trace).size() + " unmatched incoming events" + cr +
200 " " + fUnmatchedOut.row(trace).size() + " unmatched outgoing events" + cr);
201 }
202
203 return b.toString();
204 }
205
206 }
This page took 0.035356 seconds and 5 git commands to generate.