Svn bug (??) committed additionnal files, deleting them...
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / src / org / eclipse / linuxtools / lttng / trace / LTTngTrace.java
CommitLineData
5d10d135
ASL
1/*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made 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 * William Bourque (wbourque@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.lttng.trace;
14
28b94d61
FC
15import java.util.HashMap;
16import java.util.Iterator;
17import java.util.Vector;
18
3fbd810a 19import org.eclipse.linuxtools.lttng.LttngException;
5d10d135
ASL
20import org.eclipse.linuxtools.lttng.event.LttngEvent;
21import org.eclipse.linuxtools.lttng.event.LttngEventContent;
22import org.eclipse.linuxtools.lttng.event.LttngEventReference;
28b94d61 23import org.eclipse.linuxtools.lttng.event.LttngEventSource;
5d10d135 24import org.eclipse.linuxtools.lttng.event.LttngEventType;
5d10d135
ASL
25import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
26import org.eclipse.linuxtools.lttng.jni.JniEvent;
28b94d61 27import org.eclipse.linuxtools.lttng.jni.JniMarker;
88144d4a 28import org.eclipse.linuxtools.lttng.jni.JniTime;
5d10d135 29import org.eclipse.linuxtools.lttng.jni.JniTrace;
28b94d61 30import org.eclipse.linuxtools.lttng.jni.JniTracefile;
5d10d135
ASL
31import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
32import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
5d10d135 33import org.eclipse.linuxtools.tmf.trace.TmfTrace;
8d2e2848 34import org.eclipse.linuxtools.tmf.trace.TmfTraceContext;
5d10d135 35
3fbd810a
FC
36
37class LTTngTraceException extends LttngException {
38 static final long serialVersionUID = -1636648737081868146L;
39
40 public LTTngTraceException(String errMsg) {
41 super(errMsg);
42 }
43}
44
5d10d135 45/**
07d9e2ee
FC
46 * <b><u>LTTngTrace</u></b><p>
47 *
5d10d135
ASL
48 * LTTng trace implementation. It accesses the C trace handling library
49 * (seeking, reading and parsing) through the JNI component.
50 */
88144d4a 51public class LTTngTrace extends TmfTrace {
28b94d61
FC
52 private final static boolean SHOW_LTT_DEBUG_DEFAULT = false;
53 private final static boolean IS_PARSING_NEEDED_DEFAULT = false;
54 private final static int CHECKPOINT_PAGE_SIZE = 1;
5d10d135
ASL
55
56 // Reference to our JNI trace
57 private JniTrace currentJniTrace = null;
58
28b94d61
FC
59 // *** HACK ***
60 // To save time, we will declare all component of the LttngEvent during the construction of the trace
61 // Then, while reading the trace, we will just SET the values instead of declaring new object
62 LttngTimestamp eventTimestamp = null;
63 LttngEventSource eventSource = null;
64 LttngEventType eventType = null;
65 LttngEventContent eventContent = null;
66 LttngEventReference eventReference = null;
67 // The actual event
68 LttngEvent currentLttngEvent = null;
69
70 // Hashmap of the possible types of events (Tracefile/CPU/Marker in the JNI)
71 HashMap<String, LttngEventType> traceTypes = null;
72 // This vector will be used to quickly find a marker name from a position
73 Vector<String> traceTypeNames = null;
74
5d10d135 75 /**
07d9e2ee 76 * Default Constructor.<p>
5d10d135 77 *
07d9e2ee
FC
78 * @param path Path to a <b>directory</b> that contain an LTTng trace.
79 *
80 * @exception Exception (most likely LTTngTraceException or FileNotFoundException)
5d10d135
ASL
81 */
82 public LTTngTrace(String path) throws Exception {
07d9e2ee
FC
83 // Call with "wait for completion" true and "skip indexing" false
84 this(path, true, false);
5d10d135
ASL
85 }
86
87 /**
07d9e2ee
FC
88 * Constructor, with control over the indexing.
89 * <p>
90 * @param path Path to a <b>directory</b> that contain an LTTng trace.
91 * @param waitForCompletion Should we wait for indexign to complete before moving on.
92 *
93 * @exception Exception (most likely LTTngTraceException or FileNotFoundException)
07d9e2ee
FC
94 */
95 public LTTngTrace(String path, boolean waitForCompletion) throws Exception {
28b94d61 96 // Call with "skip indexing" false
07d9e2ee
FC
97 this(path, waitForCompletion, false);
98 }
99
100 /**
101 * Default constructor, with control over the indexing and possibility to bypass indexation
5d10d135
ASL
102 * <p>
103 * @param path Path to a <b>directory</b> that contain an LTTng trace.
104 * @param waitForCompletion Should we wait for indexign to complete before moving on.
07d9e2ee 105 * @param bypassIndexing Should we bypass indexing completly? This is should only be useful for unit testing.
5d10d135 106 *
07d9e2ee 107 * @exception Exception (most likely LTTngTraceException or FileNotFoundException)
5d10d135
ASL
108 *
109 */
07d9e2ee
FC
110 public LTTngTrace(String path, boolean waitForCompletion, boolean bypassIndexing) throws Exception {
111 super(path, CHECKPOINT_PAGE_SIZE, true);
5d10d135 112 try {
28b94d61 113 currentJniTrace = new JniTrace(path, SHOW_LTT_DEBUG_DEFAULT);
5d10d135 114 }
3fbd810a
FC
115 catch (Exception e) {
116 throw new LTTngTraceException(e.getMessage());
88144d4a 117 }
28b94d61
FC
118
119 // Set the start time of the trace
a3fe52fc
FC
120 setTimeRange( new TmfTimeRange( new LttngTimestamp(currentJniTrace.getStartTime().getTime()),
121 new LttngTimestamp(currentJniTrace.getEndTime().getTime())
122 )
123 );
07d9e2ee 124
28b94d61
FC
125 // Export all the event types from the JNI side
126 traceTypes = new HashMap<String, LttngEventType>();
127 traceTypeNames = new Vector<String>();
128 initialiseEventTypes(currentJniTrace);
129
130 // *** VERIFY ***
131 // Verify that all those "default constructor" are safe to use
132 eventTimestamp = new LttngTimestamp();
133 eventSource = new LttngEventSource();
134 eventType = new LttngEventType();
135 eventContent = new LttngEventContent(currentLttngEvent);
136 eventReference = new LttngEventReference(this.getName());
137
138 // Create the skeleton event
139 currentLttngEvent = new LttngEvent(eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
140
141 // Set the currentEvent to the eventContent
142 eventContent.setEvent(currentLttngEvent);
143
07d9e2ee
FC
144 // Bypass indexing if asked
145 if ( bypassIndexing == false ) {
146 indexStream();
147 }
5d10d135
ASL
148 }
149
3fbd810a
FC
150 /*
151 * Copy constructor is forbidden for LttngEvenmStream
5d10d135 152 *
3fbd810a
FC
153 * Events are only valid for a very limited period of time and
154 * JNI library does not support multiple access at once (yet?).
07d9e2ee 155 * For this reason, copy constructor should NEVER be used.
5d10d135 156 */
3fbd810a
FC
157 private LTTngTrace(LTTngTrace oldStream) throws Exception {
158 super(null);
159 throw new Exception("Copy constructor should never be use with a LTTngTrace!");
9aae0442
ASL
160 }
161
28b94d61
FC
162 /*
163 * Fill out the HashMap with "Type" (Tracefile/Marker)
164 *
165 * This should be called at construction once the trace is open
166 */
167 private void initialiseEventTypes(JniTrace trace) {
168 // Work variables
169 LttngEventType tmpType = null;
170 String[] markerFieldsLabels = null;
171
172 String newTracefileKey = null;
173 Integer newMarkerKey = null;
174
175 JniTracefile newTracefile = null;
176 JniMarker newMarker = null;
177
178 // First, obtain an iterator on TRACEFILES of owned by the TRACE
179 Iterator<String> tracefileItr = trace.getTracefilesMap().keySet().iterator();
180 while ( tracefileItr.hasNext() ) {
181 newTracefileKey = tracefileItr.next();
182 newTracefile = trace.getTracefilesMap().get(newTracefileKey);
183
184 // From the TRACEFILE read, obtain its MARKER
185 Iterator<Integer> markerItr = newTracefile.getTracefileMarkersMap().keySet().iterator();
186 while ( markerItr.hasNext() ) {
187 newMarkerKey = markerItr.next();
188 newMarker = newTracefile.getTracefileMarkersMap().get(newMarkerKey);
189
190 // From the MARKER we can obtain the MARKERFIELDS keys (i.e. labels)
191 markerFieldsLabels = newMarker.getMarkerFieldsHashMap().keySet().toArray( new String[newMarker.getMarkerFieldsHashMap().size()] );
192 tmpType = new LttngEventType(newTracefile.getTracefileName(), newTracefile.getCpuNumber(), newMarker.getName(), markerFieldsLabels );
193
194 // Add the type to the map/vector
195 addEventTypeToMap(tmpType);
196 }
197 }
198 }
199
200 /*
201 * Add a new type to the HashMap
202 *
203 * As the hashmap use a key format that is a bit dangerous to use, we should always add using this function.
204 */
205 private void addEventTypeToMap(LttngEventType newEventType) {
206 String newTypeKey = EventTypeKey.getEventTypeKey(newEventType);
207
208 this.traceTypes.put(newTypeKey, newEventType);
209 this.traceTypeNames.add(newTypeKey);
210 }
211
3fbd810a 212 /**
28b94d61 213 * Return the next event in the trace.<p>
5d10d135 214 *
07d9e2ee 215 * @param context The actual context of the trace
3fbd810a 216 *
28b94d61 217 * @return The next event, or null if none available
3fbd810a 218 *
28b94d61 219 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
3fbd810a
FC
220 */
221 @Override
28b94d61 222 public LttngEvent parseEvent(TmfTraceContext context) {
35c72307
FC
223 JniEvent jniEvent;
224 LttngTimestamp timestamp = null;
28b94d61 225 LttngEvent returnedEvent = null;
35c72307
FC
226
227 synchronized (currentJniTrace) {
07d9e2ee 228 // Seek to the context's location
35c72307 229 seekLocation(context.getLocation());
07d9e2ee
FC
230
231 // Read an event from the JNI and convert it into a LttngEvent
35c72307 232 jniEvent = currentJniTrace.readNextEvent();
28b94d61
FC
233
234 //currentLttngEvent = (jniEvent != null) ? convertJniEventToTmf(jniEvent, true) : null;
235 if ( jniEvent != null ) {
236 currentLttngEvent = convertJniEventToTmf(jniEvent);
237 returnedEvent = currentLttngEvent;
238 }
07d9e2ee
FC
239
240 // Save timestamp
35c72307
FC
241 timestamp = (LttngTimestamp) getCurrentLocation();
242 }
243 context.setLocation(timestamp);
244 context.setTimestamp(timestamp);
245 context.incrIndex();
28b94d61
FC
246
247 return returnedEvent;
5d10d135
ASL
248 }
249
07d9e2ee
FC
250 /**
251 * Method to convert a JniEvent into a LttngEvent.<p>
252 *
5d10d135
ASL
253 * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean)
254 * with a default value for isParsingNeeded
255 *
07d9e2ee 256 * @param newEvent The JniEvent to convert into LttngEvent
3fbd810a 257 *
28b94d61 258 * @return The converted LttngEvent
3fbd810a 259 *
28b94d61
FC
260 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
261 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
5d10d135 262 */
3fbd810a 263 public LttngEvent convertJniEventToTmf(JniEvent newEvent) {
28b94d61
FC
264 currentLttngEvent = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT);
265
266 return currentLttngEvent;
5d10d135
ASL
267 }
268
07d9e2ee 269 /**
28b94d61 270 * Method to convert a JniEvent into a LttngEvent
5d10d135 271 *
07d9e2ee 272 * @param jniEvent The JniEvent to convert into LttngEvent
5d10d135 273 * @param isParsingNeeded A boolean value telling if the event should be parsed or not.
3fbd810a 274 *
28b94d61 275 * @return The converted LttngEvent
3fbd810a 276 *
28b94d61
FC
277 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
278 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
5d10d135 279 */
3fbd810a 280 public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) {
28b94d61
FC
281 // *** HACK ***
282 // To save time here, we only set value instead of allocating new object
283 // This give an HUGE performance improvement
284 // all allocation done in the LttngTrace constructor
88144d4a 285
28b94d61
FC
286 eventTimestamp.setValue(jniEvent.getEventTime().getTime());
287 eventSource.setSourceId(jniEvent.requestEventSource());
288
289 eventType = traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) );
290
291 eventReference.setValue(jniEvent.getParentTracefile().getTracefilePath());
292 eventReference.setTracepath(this.getName());
293
294// eventContent.setEvent(currentLttngEvent);
295// eventContent.setType(eventType);
296 eventContent.emptyContent();
297
298// currentLttngEvent.setContent(eventContent);
299 currentLttngEvent.setType(eventType);
300 // Save the jni reference
a3fe52fc 301 currentLttngEvent.updateJniEventReference(jniEvent);
28b94d61
FC
302
303 // Parse now if was asked
304 // Warning : THIS IS SLOW
305 if (isParsingNeeded == true ) {
306 eventContent.getFields();
5d10d135 307 }
88144d4a 308
28b94d61 309 return currentLttngEvent;
5d10d135
ASL
310 }
311
5d10d135 312 /**
07d9e2ee
FC
313 * Seek (move) to a certain location in the trace.<p>
314 *
3fbd810a 315 * WARNING : No event is read by this function, it just seek to a certain time.<br>
07d9e2ee 316 * Use "parseEvent()" or "getNextEvent()" to get the event we seeked to.
5d10d135 317 *
3fbd810a
FC
318 * @param location a TmfTimestamp of a position in the trace
319 *
07d9e2ee 320 * @return TmfTraceContext pointing the position in the trace at the seek location
5d10d135 321 */
d2fe33b6 322 public TmfTraceContext seekLocation(Object location) {
6d848cce 323
35c72307
FC
324 LttngTimestamp timestamp = null;
325
326 // If location is null, interpret this as a request to get back to the beginning of the trace
07d9e2ee 327 // in that case, just change the location, the seek will happen below
6d848cce
FC
328 if (location == null) {
329 location = getStartTime();
5d10d135 330 }
35c72307 331
3fbd810a
FC
332 if (location instanceof TmfTimestamp) {
333 long value = ((TmfTimestamp) location).getValue();
6d848cce 334 if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) {
35c72307
FC
335 synchronized (currentJniTrace) {
336 currentJniTrace.seekToTime(new JniTime(value));
337 timestamp = (LttngTimestamp) getCurrentLocation();
338 }
6d848cce 339 }
5d10d135
ASL
340 }
341 else {
6d848cce 342 System.out.println("ERROR : Location not instance of TmfTimestamp");
5d10d135 343 }
98029bc9
FC
344
345 // FIXME: LTTng hack - start
07d9e2ee 346 // return new TmfTraceContext(timestamp, timestamp, 0); // Original
98029bc9
FC
347 return new TmfTraceContext(timestamp, timestamp, -1); // Hacked
348 // FIXME: LTTng hack - end
3fbd810a
FC
349 }
350
351 /**
07d9e2ee 352 * Location (timestamp) of our current position in the trace.<p>
3fbd810a 353 *
07d9e2ee 354 * @return The time (in LttngTimestamp format) of the current event or AFTER endTime if no more event is available.
3fbd810a
FC
355 */
356 @Override
357 public Object getCurrentLocation() {
3fbd810a
FC
358 LttngTimestamp returnedLocation = null;
359 JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
360
361 if ( tmpJniEvent != null ) {
35c72307 362 returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime());
3fbd810a
FC
363 }
364 else {
365 returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 );
366 }
367
368 return returnedLocation;
369 }
370
371 /**
07d9e2ee
FC
372 * Reference to the current LttngTrace we are reading from.<p>
373 *
374 * Note : This bypass the framework and should not be use, except for testing!
375 *
376 * @return Reference to the current LttngTrace
3fbd810a 377 *
28b94d61 378 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
3fbd810a
FC
379 */
380 public JniTrace getCurrentJniTrace() {
381 return currentJniTrace;
382 }
383
384
385 /**
386 * Return a reference to the current LttngEvent we have in memory.
387 *
07d9e2ee
FC
388 * @return The current (last read) LttngEvent
389 *
3fbd810a
FC
390 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
391 */
392 public LttngEvent getCurrentEvent() {
393 return currentLttngEvent;
394 }
395
a3fe52fc
FC
396 /**
397 * Get the major version number for the current trace
398 *
399 * @return Version major or -1 if unknown
400 *
401 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
402 *
403 */
404 public short getVersionMajor() {
405 if ( currentJniTrace!= null ) {
406 return currentJniTrace.getLttMajorVersion();
407 }
408 else {
409 return -1;
410 }
411 }
412
413 /**
414 * Get the minor version number for the current trace
415 *
416 * @return Version minor or -1 if unknown
417 *
418 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
419 *
420 */
421 public short getVersionMinor() {
422 if ( currentJniTrace!= null ) {
423 return currentJniTrace.getLttMinorVersion();
424 }
425 else {
426 return -1;
427 }
428 }
429
430 /**
431 * Get the number of CPU for this trace
432 *
433 * @return Number of CPU or -1 if unknown
434 *
435 * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
436 *
437 */
438 public int getCpuNumber() {
439 if ( currentJniTrace!= null ) {
440 return currentJniTrace.getCpuNumber();
441 }
442 else {
443 return -1;
444 }
445 }
446
3fbd810a
FC
447
448 @Override
cc6eec3e 449 public String toString() {
3fbd810a
FC
450 String returnedData="";
451
452 returnedData += "Path :" + getPath() + " ";
453 returnedData += "Trace:" + currentJniTrace + " ";
454 returnedData += "Event:" + currentLttngEvent;
455
456 return returnedData;
457 }
28b94d61
FC
458}
459
460/*
461 * EventTypeKey inner class
462 *
463 * This class is used to make the process of generating the HashMap key more transparent and so less error prone to use
464 *
465 */
466class EventTypeKey {
467 //*** WARNING ***
468 // These two getEventTypeKey() functions should ALWAYS construct the key the same ways!
469 // Otherwise, every type search will fail!
470
471 static public String getEventTypeKey(LttngEventType newEventType) {
472 String key = newEventType.getTracefileName() + "/" + newEventType.getCpuId().toString() + "/" + newEventType.getMarkerName();
473
474 return key;
475 }
3fbd810a 476
28b94d61
FC
477 static public String getEventTypeKey(JniEvent newEvent) {
478 String key = newEvent.getParentTracefile().getTracefileName() + "/" + newEvent.getParentTracefile().getCpuNumber() + "/" + newEvent.requestEventMarker().getName();
479
480 return key;
481 }
482
483}
This page took 0.051636 seconds and 5 git commands to generate.