ctf: CtfTmfEvent improvements
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.tmf.ctf.core / src / org / eclipse / tracecompass / tmf / ctf / core / event / CtfTmfEvent.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2015 Ericsson
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 * Alexandre Montplaisir - Initial API and implementation
11 * Bernd Hufmann - Updated for source and model lookup interfaces
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.tmf.ctf.core.event;
15
16 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
17
18 import java.util.ArrayList;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Set;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.eclipse.tracecompass.ctf.core.event.EventDefinition;
26 import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
27 import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
28 import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
29 import org.eclipse.tracecompass.tmf.core.event.ITmfCustomAttributes;
30 import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
31 import org.eclipse.tracecompass.tmf.core.event.ITmfEventType;
32 import org.eclipse.tracecompass.tmf.core.event.TmfEvent;
33 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
34 import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfModelLookup;
35 import org.eclipse.tracecompass.tmf.core.event.lookup.ITmfSourceLookup;
36 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
37 import org.eclipse.tracecompass.tmf.core.trace.ITmfContext;
38 import org.eclipse.tracecompass.tmf.ctf.core.CtfConstants;
39 import org.eclipse.tracecompass.tmf.ctf.core.event.lookup.CtfTmfCallsite;
40 import org.eclipse.tracecompass.tmf.ctf.core.trace.CtfTmfTrace;
41
42 /**
43 * A wrapper class around CTF's Event Definition/Declaration that maps all types
44 * of Declaration to native Java types.
45 *
46 * @author Alexandre Montplaisir
47 */
48 @NonNullByDefault
49 public class CtfTmfEvent extends TmfEvent
50 implements ITmfSourceLookup, ITmfModelLookup, ITmfCustomAttributes {
51
52 // ------------------------------------------------------------------------
53 // Constants
54 // ------------------------------------------------------------------------
55
56 private static final String EMPTY_CTF_EVENT_NAME = "Empty CTF event"; //$NON-NLS-1$
57
58 // ------------------------------------------------------------------------
59 // Support attributes
60 // Not part of this event's "definition", but used to populate lazy-loaded
61 // fields.
62 // ------------------------------------------------------------------------
63
64 private final @Nullable IEventDeclaration fEventDeclaration;
65 private final EventDefinition fEvent;
66
67 // ------------------------------------------------------------------------
68 // Attributes
69 // ------------------------------------------------------------------------
70
71 /* Fields that are introduced by and part of this event's definition. */
72 private final int fSourceCpu;
73 private final String fChannel;
74
75 /** Field to override {@link TmfEvent#getName()}, to bypass the type-getting */
76 private final String fEventName;
77
78 /** Lazy-loaded field containing the event's payload */
79 private transient @Nullable ITmfEventField fContent;
80
81 /** Lazy-loaded field for the type, overriding TmfEvent's field */
82 private transient @Nullable CtfTmfEventType fEventType;
83
84 // ------------------------------------------------------------------------
85 // Constructors
86 // ------------------------------------------------------------------------
87
88 /**
89 * Constructor used by {@link CtfTmfEventFactory#createEvent}
90 */
91 CtfTmfEvent(CtfTmfTrace trace, long rank, TmfNanoTimestamp timestamp,
92 String channel, int cpu, IEventDeclaration declaration, EventDefinition eventDefinition) {
93 super(trace,
94 rank,
95 timestamp,
96 /*
97 * Event type. We don't use TmfEvent's field here, we
98 * re-implement getType().
99 */
100 null,
101 /*
102 * Content handled with a lazy-loaded field re-implemented in
103 * getContent().
104 */
105 null);
106
107 fEventDeclaration = declaration;
108 fSourceCpu = cpu;
109 fEventName = checkNotNull(declaration.getName());
110 fEvent = eventDefinition;
111 fChannel = channel;
112 }
113
114 /**
115 * Inner constructor to create "null" events. Don't use this directly in
116 * normal usage, use {@link CtfTmfEventFactory#getNullEvent(CtfTmfTrace)} to
117 * get an instance of an empty event.
118 *
119 * There is no need to give higher visibility to this method than package
120 * visible.
121 *
122 * @param trace
123 * The trace associated with this event
124 */
125 CtfTmfEvent(CtfTmfTrace trace) {
126 super(trace,
127 ITmfContext.UNKNOWN_RANK,
128 new TmfNanoTimestamp(-1),
129 null,
130 new TmfEventField("", null, new CtfTmfEventField[0])); //$NON-NLS-1$
131 fSourceCpu = -1;
132 fEventName = EMPTY_CTF_EVENT_NAME;
133 fEventDeclaration = null;
134 fEvent = EventDefinition.NULL_EVENT;
135 fChannel = ""; //$NON-NLS-1$
136 }
137
138 /**
139 * Default constructor. Do not use directly, but it needs to be present
140 * because it's used in extension points, and the framework will use this
141 * constructor to get the class type.
142 *
143 * @deprecated Should not be called by normal code
144 */
145 @Deprecated
146 public CtfTmfEvent() {
147 super();
148 fSourceCpu = -1;
149 fEventName = EMPTY_CTF_EVENT_NAME;
150 fEventDeclaration = null;
151 fEvent = EventDefinition.NULL_EVENT;
152 fChannel = ""; //$NON-NLS-1$
153 }
154
155 // ------------------------------------------------------------------------
156 // Getters/Setters/Predicates
157 // ------------------------------------------------------------------------
158
159 /**
160 * Gets the cpu core the event was recorded on.
161 *
162 * @return The cpu id for a given source. In lttng it's from CPUINFO
163 * @since 2.0
164 */
165 public int getCpu() {
166 return fSourceCpu;
167 }
168
169 /**
170 * Return the CTF trace's channel from which this event originates.
171 *
172 * @return The event's channel
173 * @since 2.0
174 */
175 public String getChannel() {
176 return fChannel;
177 }
178
179 // ------------------------------------------------------------------------
180 // TmfEvent
181 // ------------------------------------------------------------------------
182
183 @Override
184 public CtfTmfTrace getTrace() {
185 /*
186 * Should be of the right type, since we take a CtfTmfTrace at the
187 * constructor
188 */
189 return (CtfTmfTrace) super.getTrace();
190 }
191
192 @Override
193 public synchronized ITmfEventType getType() {
194 CtfTmfEventType type = fEventType;
195 if (type == null) {
196 type = new CtfTmfEventType(fEventName, getContent());
197
198 /*
199 * Register the event type in the owning trace, but only if there is
200 * one
201 */
202 getTrace().registerEventType(type);
203 fEventType = type;
204 }
205 return type;
206 }
207
208 @Override
209 public String getName() {
210 return fEventName;
211 }
212
213 @Override
214 public synchronized ITmfEventField getContent() {
215 ITmfEventField content = fContent;
216 if (content == null) {
217 content = new TmfEventField(
218 ITmfEventField.ROOT_FIELD_ID, null, parseFields(fEvent));
219 fContent = content;
220 }
221 return content;
222 }
223
224 /**
225 * Extract the field information from the structDefinition haze-inducing
226 * mess, and put them into something ITmfEventField can cope with.
227 */
228 private static CtfTmfEventField[] parseFields(EventDefinition eventDef) {
229 List<CtfTmfEventField> fields = new ArrayList<>();
230
231 ICompositeDefinition structFields = eventDef.getFields();
232 if (structFields != null) {
233 if (structFields.getFieldNames() != null) {
234 for (String curFieldName : structFields.getFieldNames()) {
235 String fn = checkNotNull(curFieldName);
236 fields.add(CtfTmfEventField.parseField((IDefinition) structFields.getDefinition(fn), fn));
237 }
238 }
239 }
240 /* Add context information as CtfTmfEventField */
241 ICompositeDefinition structContext = eventDef.getContext();
242 if (structContext != null) {
243 for (String contextName : structContext.getFieldNames()) {
244 /* Prefix field name */
245 String curContextName = CtfConstants.CONTEXT_FIELD_PREFIX + contextName;
246 fields.add(CtfTmfEventField.parseField((IDefinition) structContext.getDefinition(contextName), curContextName));
247 }
248 }
249
250 return checkNotNull(fields.toArray(new CtfTmfEventField[fields.size()]));
251 }
252
253 // ------------------------------------------------------------------------
254 // ITmfCustomAttributes
255 // ------------------------------------------------------------------------
256
257 @Override
258 public Set<String> listCustomAttributes() {
259 IEventDeclaration declaration = fEventDeclaration;
260 if (declaration == null) {
261 return new HashSet<>();
262 }
263 return checkNotNull(declaration.getCustomAttributes());
264 }
265
266 @Override
267 public @Nullable String getCustomAttribute(@Nullable String name) {
268 IEventDeclaration declaration = fEventDeclaration;
269 if (declaration == null) {
270 return null;
271 }
272 return declaration.getCustomAttribute(name);
273 }
274
275 // ------------------------------------------------------------------------
276 // ITmfSourceLookup
277 // ------------------------------------------------------------------------
278
279 /**
280 * Get the call site for this event.
281 *
282 * @return the call site information, or null if there is none
283 */
284 @Override
285 public @Nullable CtfTmfCallsite getCallsite() {
286 CtfTmfCallsite callsite = null;
287
288 ITmfEventField ipField = getContent().getField(CtfConstants.CONTEXT_FIELD_PREFIX + CtfConstants.IP_KEY);
289 if (ipField != null && ipField.getValue() instanceof Long) {
290 long ip = (Long) ipField.getValue();
291 callsite = getTrace().getCallsite(fEventName, ip);
292 }
293
294 if (callsite == null) {
295 callsite = getTrace().getCallsite(fEventName);
296 }
297 return callsite;
298 }
299
300 // ------------------------------------------------------------------------
301 // ITmfModelLookup
302 // ------------------------------------------------------------------------
303
304 @Override
305 public @Nullable String getModelUri() {
306 return getCustomAttribute(CtfConstants.MODEL_URI_KEY);
307 }
308
309 // ------------------------------------------------------------------------
310 // Object
311 // ------------------------------------------------------------------------
312
313 @Override
314 public int hashCode() {
315 final int prime = 31;
316 int result = super.hashCode();
317 result = prime * result + getCpu();
318 result = prime * result + getChannel().hashCode();
319 return result;
320 }
321
322 @Override
323 public boolean equals(@Nullable Object obj) {
324 if (!super.equals(obj)) {
325 return false;
326 }
327 /* super.equals() checks that the classes are the same */
328 CtfTmfEvent other = checkNotNull((CtfTmfEvent) obj);
329 if (getCpu() != other.getCpu()) {
330 return false;
331 }
332 if (!getChannel().equals(other.getChannel())) {
333 return false;
334 }
335 return true;
336 }
337
338 }
This page took 0.038258 seconds and 6 git commands to generate.