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