1 /*******************************************************************************
2 * Copyright (c) 2011 Ericsson
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
9 * Contributors: Alexandre Montplaisir - Initial API and implementation
10 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
14 import java
.util
.ArrayList
;
15 import java
.util
.HashMap
;
16 import java
.util
.Iterator
;
17 import java
.util
.List
;
18 import java
.util
.Map
.Entry
;
20 import org
.eclipse
.linuxtools
.ctf
.core
.event
.CTFCallsite
;
21 import org
.eclipse
.linuxtools
.ctf
.core
.event
.EventDefinition
;
22 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.Definition
;
23 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.IntegerDefinition
;
24 import org
.eclipse
.linuxtools
.ctf
.core
.event
.types
.StructDefinition
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventType
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
31 * A wrapper class around CTF's Event Definition/Declaration that maps all
32 * types of Declaration to native Java types.
35 * @author Alexandre Montplaisir
37 public final class CtfTmfEvent
implements ITmfEvent
, Cloneable
{
39 // ------------------------------------------------------------------------
41 // ------------------------------------------------------------------------
43 private static final String NO_STREAM
= "No stream"; //$NON-NLS-1$
44 private static final String EMPTY_CTF_EVENT_NAME
= "Empty CTF event"; //$NON-NLS-1$
46 /** Prefix for Context information stored as CtfTmfEventfield */
47 private static final String CONTEXT_FIELD_PREFIX
= "context."; //$NON-NLS-1$
49 // ------------------------------------------------------------------------
51 // ------------------------------------------------------------------------
53 private final CtfTmfTrace fTrace
;
54 private final long timestamp
;
55 private final int sourceCPU
;
56 private final long typeId
;
57 private final String eventName
;
58 private final String fileName
;
60 private final CtfTmfContent fContent
;
62 // ------------------------------------------------------------------------
64 // ------------------------------------------------------------------------
67 * Usual CTFEvent constructor, where we read an event from the trace (via
68 * the StreamInputReader).
71 * CTF EventDefinition object corresponding to this trace event
73 * The path to the trace file
75 * The trace from which this event originates
77 public CtfTmfEvent(EventDefinition eventDef
, String fileName
,
78 CtfTmfTrace originTrace
) {
79 this.fTrace
= originTrace
;
81 if (eventDef
== null) {
85 this.fileName
= NO_STREAM
;
86 this.eventName
= EMPTY_CTF_EVENT_NAME
;
91 /* Read the base event info */
92 Long offset
= originTrace
.getCTFTrace().getOffset();
93 this.timestamp
= eventDef
.getTimestamp() + offset
;
94 this.sourceCPU
= eventDef
.getCPU();
95 this.typeId
= eventDef
.getDeclaration().getId();
96 this.eventName
= eventDef
.getDeclaration().getName();
97 this.fileName
= fileName
;
100 this.fContent
= new CtfTmfContent(ITmfEventField
.ROOT_FIELD_ID
,
101 parseFields(eventDef
));
105 * Extract the field information from the structDefinition haze-inducing
106 * mess, and put them into something ITmfEventField can cope with.
109 * CTF EventDefinition to read
110 * @return CtfTmfEventField[] The array of fields that were read
112 private CtfTmfEventField
[] parseFields(EventDefinition eventDef
) {
113 List
<CtfTmfEventField
> fields
= new ArrayList
<CtfTmfEventField
>();
115 StructDefinition structFields
= eventDef
.getFields();
116 HashMap
<String
, Definition
> definitions
= structFields
.getDefinitions();
117 String curFieldName
= null;
118 Definition curFieldDef
;
119 CtfTmfEventField curField
;
120 Iterator
<Entry
<String
, Definition
>> it
= definitions
.entrySet().iterator();
121 while(it
.hasNext()) {
122 Entry
<String
, Definition
> entry
= it
.next();
123 curFieldName
= entry
.getKey();
124 curFieldDef
= entry
.getValue();
125 curField
= CtfTmfEventField
.parseField(curFieldDef
, curFieldName
);
126 fields
.add(curField
);
129 /* Add context information as CtfTmfEventField */
131 StructDefinition structContext
= eventDef
.getContext();
132 if (structContext
!= null) {
133 definitions
= structContext
.getDefinitions();
134 String curContextName
;
135 Definition curContextDef
;
136 CtfTmfEventField curContext
;
137 it
= definitions
.entrySet().iterator();
138 while(it
.hasNext()) {
139 Entry
<String
, Definition
> entry
= it
.next();
140 /* This is to get the instruction pointer if available */
141 if (entry
.getKey().equals("_ip") && //$NON-NLS-1$
142 (entry
.getValue() instanceof IntegerDefinition
)) {
143 ip
= ((IntegerDefinition
) entry
.getValue()).getValue();
145 /* Prefix field name to */
146 curContextName
= CONTEXT_FIELD_PREFIX
+ entry
.getKey();
147 curContextDef
= entry
.getValue();
148 curContext
= CtfTmfEventField
.parseField(curContextDef
, curContextName
);
149 fields
.add(curContext
);
153 final String name
= eventDef
.getDeclaration().getName();
154 List
<CTFCallsite
> eventList
= fTrace
.getCTFTrace().getCallsiteCandidates(name
);
155 if (!eventList
.isEmpty()) {
156 final String callsite
= "callsite"; //$NON-NLS-1$
157 if (eventList
.size() == 1 || ip
== -1) {
158 CTFCallsite cs
= eventList
.get(0);
159 fields
.add(new CTFStringField(cs
.toString(), callsite
));
161 fields
.add(new CTFStringField(
162 fTrace
.getCTFTrace().getCallsite(name
, ip
).toString(),
167 return fields
.toArray(new CtfTmfEventField
[fields
.size()]);
174 * CtfTmfEvent to copy
176 public CtfTmfEvent(CtfTmfEvent other
) {
177 this.fTrace
= other
.getTrace();
178 /* Primitives, those will be copied by value */
179 this.timestamp
= other
.timestamp
;
180 this.sourceCPU
= other
.sourceCPU
;
181 this.typeId
= other
.typeId
;
183 /* Strings are immutable, it's safe to shallow-copy them */
184 this.eventName
= other
.eventName
;
185 this.fileName
= other
.fileName
;
187 /* Copy the fields over */
188 this.fContent
= (CtfTmfContent
) other
.fContent
.clone();
192 * Inner constructor to create "null" events. Don't use this directly in
193 * normal usage, use CtfTmfEvent.getNullEvent() to get an instance of an
196 * This needs to be public however because it's used in extension points,
197 * and the framework will use this constructor to get the class type.
199 public CtfTmfEvent() {
204 this.fileName
= NO_STREAM
;
205 this.eventName
= EMPTY_CTF_EVENT_NAME
;
206 this.fContent
= new CtfTmfContent("", new CtfTmfEventField
[0]); //$NON-NLS-1$
209 // ------------------------------------------------------------------------
210 // Getters/Setters/Predicates
211 // ------------------------------------------------------------------------
213 private static CtfTmfEvent nullEvent
= null;
218 * @return an empty event. */
219 public static CtfTmfEvent
getNullEvent() {
220 if (nullEvent
== null) {
221 nullEvent
= new CtfTmfEvent();
227 * Gets the current timestamp of the event
229 * @return the current timestamp (long) */
230 public long getTimestampValue() {
231 return this.timestamp
;
235 * Gets the cpu core the event was recorded on.
237 * @return the cpu id for a given source. In lttng it's from CPUINFO */
238 public int getCPU() {
239 return this.sourceCPU
;
243 * Return this event's ID, according to the trace's metadata. Watch out,
244 * this ID is not constant from one trace to another for the same event
245 * types! Use "getEventName()" for a constant reference.
248 * @return the event ID */
249 public long getID() {
254 * Gets the name of a current event.
256 * @return the event name */
257 public String
getEventName() {
262 * Gets the channel name of a field.
264 * @return the channel name. */
265 public String
getChannelName() {
266 return this.fileName
;
271 * @return CtfTmfTrace
272 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getTrace()
275 public CtfTmfTrace
getTrace() {
282 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getRank()
285 public long getRank() {
286 // TODO Auto-generated method stub
290 private ITmfTimestamp fTimestamp
= null;
292 // TODO Benchmark if the singleton approach is faster than just
293 // instantiating a final fTimestramp right away at creation time
295 * Method getTimestamp.
296 * @return ITmfTimestamp
297 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getTimestamp()
300 public ITmfTimestamp
getTimestamp() {
301 if (fTimestamp
== null) {
302 fTimestamp
= new CtfTmfTimestamp(timestamp
);
307 String fSource
= null;
311 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getSource()
314 public String
getSource() {
315 // TODO Returns CPU for now
316 if(fSource
== null) {
317 fSource
= Integer
.toString(getCPU());
324 * @return ITmfEventType
325 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getType()
328 public ITmfEventType
getType() {
329 CtfTmfEventType ctfTmfEventType
= CtfTmfEventType
.get(eventName
);
330 if( ctfTmfEventType
== null ){
331 ctfTmfEventType
= new CtfTmfEventType( this.getEventName(), this.getContent());
333 return ctfTmfEventType
;
338 * @return ITmfEventField
339 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getContent()
342 public ITmfEventField
getContent() {
346 String fReference
= null;
348 * Method getReference.
350 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#getReference()
353 public String
getReference() {
354 if( fReference
== null){
355 fReference
= getChannelName();
362 * @return CtfTmfEvent
363 * @see org.eclipse.linuxtools.tmf.core.event.ITmfEvent#clone()
366 public CtfTmfEvent
clone() {
367 return new CtfTmfEvent(this);