ctf: Introduce ICTFStream
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / event / EventDeclaration.java
CommitLineData
866e5b51 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2011, 2014 Ericsson, Ecole Polytechnique de Montreal and others
866e5b51
FC
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: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
12
f357bcd4 13package org.eclipse.tracecompass.internal.ctf.core.event;
866e5b51 14
8e964be1
MK
15import java.util.HashMap;
16import java.util.Map;
17import java.util.Set;
18
a4fa4e36 19import org.eclipse.jdt.annotation.NonNull;
5b341dc8 20import org.eclipse.jdt.annotation.Nullable;
4e929a07 21import org.eclipse.tracecompass.common.core.NonNullUtils;
680f9173 22import org.eclipse.tracecompass.ctf.core.CTFException;
5b341dc8 23import org.eclipse.tracecompass.ctf.core.CTFStrings;
f357bcd4
AM
24import org.eclipse.tracecompass.ctf.core.event.EventDefinition;
25import org.eclipse.tracecompass.ctf.core.event.IEventDeclaration;
26import org.eclipse.tracecompass.ctf.core.event.io.BitBuffer;
fbe6fa6f 27import org.eclipse.tracecompass.ctf.core.event.scope.ILexicalScope;
5b341dc8 28import org.eclipse.tracecompass.ctf.core.event.types.Definition;
778bce67 29import org.eclipse.tracecompass.ctf.core.event.types.ICompositeDefinition;
5b341dc8 30import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
f357bcd4
AM
31import org.eclipse.tracecompass.ctf.core.event.types.StructDeclaration;
32import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
5b341dc8 33import org.eclipse.tracecompass.ctf.core.trace.CTFIOException;
f357bcd4 34import org.eclipse.tracecompass.ctf.core.trace.CTFStreamInputReader;
4a143d93 35import org.eclipse.tracecompass.ctf.core.trace.CTFTrace;
42f8feff 36import org.eclipse.tracecompass.ctf.core.trace.ICTFPacketDescriptor;
5b341dc8 37import org.eclipse.tracecompass.internal.ctf.core.event.types.composite.EventHeaderDefinition;
8aa463e0 38import org.eclipse.tracecompass.internal.ctf.core.trace.CTFStream;
866e5b51
FC
39
40/**
be6df2d8
AM
41 * Representation of one type of event. A bit like "int" or "long" but for trace
42 * events.
866e5b51 43 */
8e964be1 44public class EventDeclaration implements IEventDeclaration {
866e5b51
FC
45
46 // ------------------------------------------------------------------------
47 // Attributes
48 // ------------------------------------------------------------------------
49
50 /**
51 * Name of the event
52 */
75259c16 53 private String fName;
866e5b51
FC
54
55 /**
56 * Event context structure declaration
57 */
75259c16 58 private StructDeclaration fContext = null;
866e5b51
FC
59
60 /**
61 * Event fields structure declaration
62 */
75259c16 63 private StructDeclaration fFields = null;
866e5b51 64
866e5b51
FC
65 /**
66 * Stream to which belongs this event.
67 */
4a143d93 68 private @Nullable CTFStream fStream = null;
866e5b51 69
53047a66
MK
70 /**
71 * Loglevel of an event
72 */
75259c16 73 private long fLogLevel;
53047a66 74
8e964be1 75 /** Map of this event type's custom CTF attributes */
75259c16 76 private final Map<String, String> fCustomAttributes = new HashMap<>();
8e964be1 77
5f715709
MK
78 private int fId = (int) UNSET_EVENT_ID;
79
866e5b51
FC
80 // ------------------------------------------------------------------------
81 // Constructors
82 // ------------------------------------------------------------------------
83
be6df2d8
AM
84 /**
85 * Default constructor. Use the setters afterwards to set the fields
86 * accordingly.
87 */
8e964be1
MK
88 public EventDeclaration() {
89 }
be6df2d8 90
94c255ef
MK
91 /**
92 * Creates an instance of EventDefinition corresponding to this declaration.
93 *
42f8feff
MK
94 * @param streamEventContextDecl
95 * event context
96 * @param packetDescriptor
97 * current packet
98 * @param packetContext
99 * packet context
94c255ef
MK
100 * @param eventHeaderDef
101 * The event header definition
102 * @param input
103 * the bitbuffer input source
5b341dc8 104 * @param prevTimestamp
94c255ef
MK
105 * The timestamp when the event was taken
106 * @return A new EventDefinition.
107 * @throws CTFException
108 * As a bitbuffer is used to read, it could have wrapped
109 * IOExceptions.
110 */
42f8feff
MK
111 public EventDefinition createDefinition(StructDeclaration streamEventContextDecl, ICTFPacketDescriptor packetDescriptor, ICompositeDefinition packetContext, ICompositeDefinition eventHeaderDef, @NonNull BitBuffer input, long prevTimestamp)
112 throws CTFException {
4a143d93
MK
113 final CTFStream stream = fStream;
114 final CTFTrace trace = stream == null ? null : stream.getTrace();
115 StructDefinition streamEventContext = streamEventContextDecl != null ? streamEventContextDecl.createDefinition(trace, ILexicalScope.STREAM_EVENT_CONTEXT, input) : null;
116 StructDefinition eventContext = fContext != null ? fContext.createFieldDefinition(eventHeaderDef, trace, ILexicalScope.CONTEXT, input) : null;
117 StructDefinition eventPayload = fFields != null ? fFields.createFieldDefinition(eventHeaderDef, trace, ILexicalScope.FIELDS, input) : null;
86e85a45 118 long timestamp = calculateTimestamp(eventHeaderDef, prevTimestamp, eventPayload, eventContext);
94c255ef 119
42f8feff 120 int cpu = (int) packetDescriptor.getTargetId();
94c255ef
MK
121 return new EventDefinition(
122 this,
42f8feff 123 cpu,
94c255ef
MK
124 timestamp,
125 eventHeaderDef,
126 streamEventContext,
127 eventContext,
128 packetContext,
129 eventPayload);
130 }
131
86e85a45 132 private static long calculateTimestamp(@Nullable ICompositeDefinition eventHeaderDef, long prevTimestamp, StructDefinition eventPayload, StructDefinition eventContext) throws CTFIOException {
5b341dc8
MK
133 long timestamp = 0;
134 Definition def = null;
135 if (eventHeaderDef instanceof EventHeaderDefinition) {
136 EventHeaderDefinition eventHeaderDefinition = (EventHeaderDefinition) eventHeaderDef;
137 timestamp = calculateTimestamp(eventHeaderDefinition.getTimestamp(), eventHeaderDefinition.getTimestampLength(), prevTimestamp);
06807afe 138 def = eventHeaderDefinition;
5b341dc8
MK
139 } else if (eventHeaderDef instanceof StructDefinition) {
140 StructDefinition structDefinition = (StructDefinition) eventHeaderDef;
141 def = structDefinition.lookupDefinition(CTFStrings.TIMESTAMP);
142 } else if (eventHeaderDef != null) {
143 throw new CTFIOException("Event header def is not a Struct or an Event Header"); //$NON-NLS-1$
144 }
145 if (def == null && eventPayload != null) {
146 def = eventPayload.lookupDefinition(CTFStrings.TIMESTAMP);
147 }
86e85a45
MK
148 if (def == null && eventContext != null) {
149 def = eventContext.lookupDefinition(CTFStrings.TIMESTAMP);
150 }
5b341dc8
MK
151 if (def instanceof IntegerDefinition) {
152 IntegerDefinition timestampDef = (IntegerDefinition) def;
153 timestamp = calculateTimestamp(timestampDef, prevTimestamp);
154 }
155 return timestamp;
156 }
157
8e964be1 158 @Override
680f9173 159 public EventDefinition createDefinition(CTFStreamInputReader streamInputReader, @NonNull BitBuffer input, long timestamp) throws CTFException {
a4fa4e36 160 StructDeclaration streamEventContextDecl = streamInputReader.getStreamEventContextDecl();
4a143d93
MK
161 final @Nullable CTFStream stream = fStream;
162 final CTFTrace trace = stream == null ? null : stream.getTrace();
163 StructDefinition streamEventContext = streamEventContextDecl != null ? streamEventContextDecl.createDefinition(trace, ILexicalScope.STREAM_EVENT_CONTEXT, input) : null;
42f8feff 164 ICompositeDefinition packetContext = streamInputReader.getCurrentPacketReader().getCurrentPacketEventHeader();
4a143d93
MK
165 StructDefinition eventContext = fContext != null ? fContext.createDefinition(trace, ILexicalScope.CONTEXT, input) : null;
166 StructDefinition eventPayload = fFields != null ? fFields.createDefinition(trace, ILexicalScope.FIELDS, input) : null;
a4fa4e36
MK
167
168 // a bit lttng specific
169 // CTF doesn't require a timestamp,
170 // but it's passed to us
171 return new EventDefinition(
172 this,
408f954e 173 streamInputReader.getCPU(),
a4fa4e36 174 timestamp,
408f954e 175 null,
a4fa4e36
MK
176 streamEventContext,
177 eventContext,
178 packetContext,
179 eventPayload);
866e5b51
FC
180 }
181
182 // ------------------------------------------------------------------------
183 // Getters/Setters/Predicates
184 // ------------------------------------------------------------------------
185
9ac2eb62
MK
186 /**
187 * Sets a name for an event Declaration
8e964be1
MK
188 *
189 * @param name
190 * the name
9ac2eb62 191 */
866e5b51 192 public void setName(String name) {
75259c16 193 fName = name;
866e5b51
FC
194 }
195
8e964be1 196 @Override
866e5b51 197 public String getName() {
75259c16 198 return fName;
866e5b51
FC
199 }
200
9ac2eb62
MK
201 /**
202 * Sets the context for an event declaration (see CTF specification)
8e964be1
MK
203 *
204 * @param context
205 * the context in structdeclaration format
9ac2eb62 206 */
866e5b51 207 public void setContext(StructDeclaration context) {
75259c16 208 fContext = context;
866e5b51
FC
209 }
210
9ac2eb62
MK
211 /**
212 * Sets the fields of an event declaration
8e964be1
MK
213 *
214 * @param fields
215 * the fields in structdeclaration format
9ac2eb62 216 */
866e5b51 217 public void setFields(StructDeclaration fields) {
75259c16 218 fFields = fields;
866e5b51
FC
219 }
220
8e964be1 221 @Override
866e5b51 222 public StructDeclaration getFields() {
75259c16 223 return fFields;
866e5b51
FC
224 }
225
8e964be1 226 @Override
866e5b51 227 public StructDeclaration getContext() {
75259c16 228 return fContext;
866e5b51
FC
229 }
230
9ac2eb62 231 /**
ecb12461 232 * Sets the id of an event declaration
8e964be1
MK
233 *
234 * @param id
235 * the id
9ac2eb62 236 */
866e5b51 237 public void setId(long id) {
5f715709
MK
238 if (id < 0 || id > Integer.MAX_VALUE) {
239 throw new IllegalArgumentException("id out of range"); //$NON-NLS-1$
240 }
241 fId = (int) id;
866e5b51
FC
242 }
243
8e964be1 244 @Override
866e5b51 245 public Long getId() {
5f715709
MK
246 return Long.valueOf(fId);
247 }
248
249 /**
250 * Faster get id assuming you have less than a billion event types
251 *
252 * @return the event id
253 */
254 public int id() {
75259c16 255 return fId;
866e5b51
FC
256 }
257
9ac2eb62 258 /**
ecb12461 259 * Sets the stream of an event declaration
8e964be1
MK
260 *
261 * @param stream
262 * the stream
9ac2eb62 263 */
d84419e1 264 public void setStream(CTFStream stream) {
75259c16 265 fStream = stream;
866e5b51
FC
266 }
267
8e964be1 268 @Override
d84419e1 269 public CTFStream getStream() {
75259c16 270 return fStream;
866e5b51
FC
271 }
272
9ac2eb62
MK
273 /**
274 * Is the name of the event declaration set
8e964be1 275 *
9ac2eb62
MK
276 * @return is the name set?
277 */
866e5b51 278 public boolean nameIsSet() {
75259c16 279 return fName != null;
866e5b51
FC
280 }
281
9ac2eb62
MK
282 /**
283 * Is the context set
8e964be1 284 *
9ac2eb62
MK
285 * @return is the context set
286 */
866e5b51 287 public boolean contextIsSet() {
75259c16 288 return fContext != null;
866e5b51
FC
289 }
290
9ac2eb62
MK
291 /**
292 * Is a field set?
8e964be1 293 *
9ac2eb62
MK
294 * @return Is the field set?
295 */
866e5b51 296 public boolean fieldsIsSet() {
75259c16 297 return fFields != null;
866e5b51
FC
298 }
299
9ac2eb62
MK
300 /**
301 * Is the id set?
8e964be1 302 *
9ac2eb62
MK
303 * @return is the id set?
304 */
866e5b51 305 public boolean idIsSet() {
8e0c9d81 306 return (fId != UNSET_EVENT_ID);
866e5b51
FC
307 }
308
9ac2eb62
MK
309 /**
310 * Is the stream set?
8e964be1 311 *
9ac2eb62
MK
312 * @return is the stream set?
313 */
866e5b51 314 public boolean streamIsSet() {
75259c16 315 return fStream != null;
866e5b51
FC
316 }
317
8e964be1 318 @Override
53047a66 319 public long getLogLevel() {
75259c16 320 return fLogLevel;
53047a66
MK
321 }
322
9ac2eb62
MK
323 /**
324 * Sets the log level
8e964be1
MK
325 *
326 * @param level
327 * the log level
9ac2eb62 328 */
8e964be1 329 public void setLogLevel(long level) {
75259c16 330 fLogLevel = level;
53047a66
MK
331 }
332
8e964be1
MK
333 @Override
334 public Set<String> getCustomAttributes() {
75259c16 335 return fCustomAttributes.keySet();
8e964be1
MK
336 }
337
338 @Override
339 public String getCustomAttribute(String key) {
75259c16 340 return fCustomAttributes.get(key);
8e964be1
MK
341 }
342
343 /**
344 * Sets a custom attribute value.
345 *
346 * @param key
347 * the key of the attribute
348 * @param value
349 * the value of the attribute
8e964be1
MK
350 */
351 public void setCustomAttribute(String key, String value) {
75259c16 352 fCustomAttributes.put(key, value);
8e964be1
MK
353 }
354
5b341dc8
MK
355 /**
356 * Calculates the timestamp value of the event, possibly using the timestamp
357 * from the last event.
358 *
359 * @param timestampDef
360 * Integer definition of the timestamp.
361 * @return The calculated timestamp value.
362 */
363 private static long calculateTimestamp(IntegerDefinition timestampDef, long lastTimestamp) {
364 int len = timestampDef.getDeclaration().getLength();
365 final long value = timestampDef.getValue();
366
367 return calculateTimestamp(value, len, lastTimestamp);
368 }
369
370 private static long calculateTimestamp(final long value, int len, long prevTimestamp) {
371 long newval;
372 long majorasbitmask;
373 long lastTimestamp = prevTimestamp;
374 /*
375 * If the timestamp length is 64 bits, it is a full timestamp.
376 */
377 if (len == Long.SIZE) {
378 lastTimestamp = value;
379 return lastTimestamp;
380 }
381
382 /*
383 * Bit mask to keep / remove all old / new bits.
384 */
385 majorasbitmask = (1L << len) - 1;
386
387 /*
388 * If the new value is smaller than the corresponding bits of the last
389 * timestamp, we assume an overflow of the compact representation.
390 */
391 newval = value;
392 if (newval < (lastTimestamp & majorasbitmask)) {
393 newval = newval + (1L << len);
394 }
395
396 /* Keep only the high bits of the old value */
397 lastTimestamp = lastTimestamp & ~majorasbitmask;
398
399 /* Then add the low bits of the new value */
400 lastTimestamp = lastTimestamp + newval;
401
402 return lastTimestamp;
403 }
404
866e5b51
FC
405 // ------------------------------------------------------------------------
406 // Operations
407 // ------------------------------------------------------------------------
408
409 @Override
410 public boolean equals(Object obj) {
411 if (this == obj) {
412 return true;
413 }
414 if (obj == null) {
415 return false;
416 }
417 if (!(obj instanceof EventDeclaration)) {
418 return false;
419 }
420 EventDeclaration other = (EventDeclaration) obj;
4e929a07 421 if (fId != (other.fId)) {
866e5b51
FC
422 return false;
423 }
4e929a07 424 if (!NonNullUtils.equalsNullable(fContext, other.fContext)) {
866e5b51
FC
425 return false;
426 }
4e929a07 427 if (!NonNullUtils.equalsNullable(fFields, other.fFields)) {
866e5b51
FC
428 return false;
429 }
4e929a07 430 if (!NonNullUtils.equalsNullable(fName, other.fName)) {
866e5b51
FC
431 return false;
432 }
4e929a07 433 if (!NonNullUtils.equalsNullable(fStream, other.fStream)) {
866e5b51
FC
434 return false;
435 }
75259c16 436 if (!fCustomAttributes.equals(other.fCustomAttributes)) {
8e964be1
MK
437 return false;
438 }
866e5b51
FC
439 return true;
440 }
441
442 @Override
443 public int hashCode() {
444 final int prime = 31;
445 int result = 1;
446 result = (prime * result)
75259c16
MK
447 + ((fContext == null) ? 0 : fContext.hashCode());
448 result = (prime * result) + ((fFields == null) ? 0 : fFields.hashCode());
5f715709 449 result = (prime * result) + fId;
75259c16 450 result = (prime * result) + ((fName == null) ? 0 : fName.hashCode());
4a143d93
MK
451 final CTFStream stream = fStream;
452 result = (prime * result) + ((stream == null) ? 0 : stream.hashCode());
75259c16 453 result = (prime * result) + fCustomAttributes.hashCode();
866e5b51
FC
454 return result;
455 }
456
457}
This page took 0.111783 seconds and 5 git commands to generate.