lttng: Update Callstack View documentation
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfTrace.java
CommitLineData
b1baa808 1/*******************************************************************************
e73a4ba5 2 * Copyright (c) 2012, 2013 Ericsson, École Polytechnique de Montréal
b1baa808
MK
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 *
ea271da6
PT
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 * Patrick Tasse - Updated for removal of context clone
e73a4ba5 12 * Geneviève Bastien - Added the createTimestamp function
b1baa808
MK
13 *******************************************************************************/
14
a3fc8213
AM
15package org.eclipse.linuxtools.tmf.core.ctfadaptor;
16
96c0f2af 17import java.nio.BufferOverflowException;
032ecd45 18import java.nio.ByteBuffer;
299e494e
AM
19import java.util.Collections;
20import java.util.Map;
21
a3fc8213
AM
22import org.eclipse.core.resources.IProject;
23import org.eclipse.core.resources.IResource;
a94410d9
MK
24import org.eclipse.core.runtime.IStatus;
25import org.eclipse.core.runtime.Status;
bb52f9bc 26import org.eclipse.linuxtools.ctf.core.event.CTFClock;
032ecd45 27import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
a3fc8213
AM
28import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
29import org.eclipse.linuxtools.ctf.core.trace.CTFTrace;
b5354daa 30import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader;
a94410d9 31import org.eclipse.linuxtools.internal.tmf.core.Activator;
6256d8ad 32import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
b4f71e4a 33import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
3bd46eef
AM
34import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
35import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
a3fc8213 36import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
4b7c469f 37import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
3480bf12 38import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties;
4b7c469f 39import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
032ecd45
MAL
40import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable;
41import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
42import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer;
43import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint;
44import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint;
a3db8436 45import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
a3fc8213 46
9ac2eb62 47/**
d09f973b
FC
48 * The CTf trace handler
49 *
50 * @version 1.0
51 * @author Matthew khouzam
9ac2eb62 52 */
22307af3 53public class CtfTmfTrace extends TmfTrace
032ecd45 54 implements ITmfEventParser, ITmfTraceProperties, ITmfPersistentlyIndexable {
a3fc8213 55
a94410d9
MK
56 // -------------------------------------------
57 // Constants
58 // -------------------------------------------
324a6a4a
BH
59 /**
60 * Default cache size for CTF traces
61 */
62 protected static final int DEFAULT_CACHE_SIZE = 50000;
64c2cb4c 63
bb52f9bc
GB
64 /*
65 * The Ctf clock unique identifier field
66 */
67 private static final String CLOCK_HOST_PROPERTY = "uuid"; //$NON-NLS-1$
68
a94410d9
MK
69 // -------------------------------------------
70 // Fields
71 // -------------------------------------------
a3fc8213 72
4b7c469f
MK
73 /* Reference to the CTF Trace */
74 private CTFTrace fTrace;
a3fc8213 75
a94410d9
MK
76 // -------------------------------------------
77 // TmfTrace Overrides
78 // -------------------------------------------
b1baa808
MK
79 /**
80 * Method initTrace.
063f0d27
AM
81 *
82 * @param resource
83 * The resource associated with this trace
84 * @param path
85 * The path to the trace file
86 * @param eventType
87 * The type of events that will be read from this trace
b1baa808 88 * @throws TmfTraceException
07804639 89 * If something went wrong while reading the trace
b1baa808 90 */
a3fc8213 91 @Override
6256d8ad 92 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType)
b4f71e4a 93 throws TmfTraceException {
4a110860
AM
94 /*
95 * Set the cache size. This has to be done before the call to super()
96 * because the super needs to know the cache size.
97 */
98 setCacheSize();
324a6a4a 99
32c16b50
GB
100 super.initTrace(resource, path, eventType);
101
a3fc8213
AM
102 try {
103 this.fTrace = new CTFTrace(path);
53b235e1 104 CtfIteratorManager.addTrace(this);
81a2d02e 105 CtfTmfContext ctx;
99b483fe 106 /* Set the start and (current) end times for this trace */
81a2d02e 107 ctx = (CtfTmfContext) seekEvent(0L);
132a02b0 108 CtfTmfEvent event = getNext(ctx);
a94410d9 109 if ((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) {
99b483fe
AM
110 /* Handle the case where the trace is empty */
111 this.setStartTime(TmfTimestamp.BIG_BANG);
112 } else {
132a02b0 113 final ITmfTimestamp curTime = event.getTimestamp();
21fb02fa
MK
114 this.setStartTime(curTime);
115 this.setEndTime(curTime);
99b483fe
AM
116 }
117
25e48683 118 } catch (final CTFReaderException e) {
a3fc8213
AM
119 /*
120 * If it failed at the init(), we can assume it's because the file
121 * was not found or was not recognized as a CTF trace. Throw into
122 * the new type of exception expected by the rest of TMF.
123 */
9fa32496 124 throw new TmfTraceException(e.getMessage(), e);
a3fc8213 125 }
a3fc8213
AM
126 }
127
53b235e1
MK
128 @Override
129 public synchronized void dispose() {
130 CtfIteratorManager.removeTrace(this);
5d1c6919
PT
131 if (fTrace != null) {
132 fTrace.dispose();
133 fTrace = null;
134 }
53b235e1
MK
135 super.dispose();
136 }
137
b1baa808
MK
138 /**
139 * Method validate.
a94410d9
MK
140 *
141 * @param project
142 * IProject
143 * @param path
144 * String
145 * @return IStatus IStatus.error or Status.OK_STATUS
b1baa808 146 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
a94410d9 147 * @since 2.0
b1baa808 148 */
a3fc8213 149 @Override
a94410d9
MK
150 public IStatus validate(final IProject project, final String path) {
151 IStatus validTrace = Status.OK_STATUS;
a3fc8213
AM
152 try {
153 final CTFTrace temp = new CTFTrace(path);
07804639 154 if (!temp.majorIsSet()) {
a94410d9 155 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet);
b5354daa
MAL
156 } else {
157 CTFTraceReader ctfTraceReader = new CTFTraceReader(temp);
158 if (!ctfTraceReader.hasMoreEvents()) {
159 // TODO: This will need an additional check when we support live traces
160 // because having no event is valid for a live trace
161 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent);
162 }
163 ctfTraceReader.dispose();
a94410d9 164 }
b5354daa 165 temp.dispose();
25e48683 166 } catch (final CTFReaderException e) {
a94410d9 167 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError +": " + e.toString()); //$NON-NLS-1$
96c0f2af
MK
168 } catch (final BufferOverflowException e){
169 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError +": " + Messages.CtfTmfTrace_BufferOverflowErrorMessage); //$NON-NLS-1$
a3fc8213 170 }
96c0f2af 171
a94410d9 172 return validTrace;
a3fc8213
AM
173 }
174
b1baa808 175 /**
f474d36b 176 * Method getCurrentLocation. This is not applicable in CTF
a94410d9 177 *
f474d36b 178 * @return null, since the trace has no knowledge of the current location
b1baa808 179 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
a3db8436 180 * @since 3.0
b1baa808 181 */
a3fc8213 182 @Override
1e1bef82 183 public ITmfLocation getCurrentLocation() {
f474d36b 184 return null;
a3fc8213
AM
185 }
186
a3db8436
AM
187 /**
188 * @since 3.0
189 */
a3fc8213 190 @Override
1e1bef82 191 public double getLocationRatio(ITmfLocation location) {
4b7c469f 192 final CtfLocation curLocation = (CtfLocation) location;
81a2d02e 193 final CtfTmfContext context = new CtfTmfContext(this);
53b235e1 194 context.setLocation(curLocation);
5976d44a 195 context.seek(curLocation.getLocationInfo());
a94410d9 196 final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo());
53b235e1
MK
197 final long startTime = getIterator(this, context).getStartTime();
198 final long endTime = getIterator(this, context).getEndTime();
132a02b0 199 return ((double) currentTime.getTimestamp() - startTime)
53b235e1 200 / (endTime - startTime);
a3fc8213
AM
201 }
202
b1baa808
MK
203 /**
204 * Method seekEvent.
a94410d9
MK
205 *
206 * @param location
207 * ITmfLocation<?>
b1baa808 208 * @return ITmfContext
a3db8436 209 * @since 3.0
b1baa808 210 */
a3fc8213 211 @Override
76643eb7 212 public synchronized ITmfContext seekEvent(final ITmfLocation location) {
ce2388e0 213 CtfLocation currentLocation = (CtfLocation) location;
81a2d02e 214 CtfTmfContext context = new CtfTmfContext(this);
76643eb7
BH
215 if (fTrace == null) {
216 context.setLocation(null);
217 context.setRank(ITmfContext.UNKNOWN_RANK);
218 return context;
219 }
4a110860
AM
220 /*
221 * The rank is set to 0 if the iterator seeks the beginning. If not, it
222 * will be set to UNKNOWN_RANK, since CTF traces don't support seeking
223 * by rank for now.
224 */
11d6f468 225 if (currentLocation == null) {
f5df94f8 226 currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L));
4a110860 227 context.setRank(0);
11d6f468 228 }
5976d44a 229 if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) {
d62bb185 230 currentLocation = new CtfLocation(getEndTime().getValue() + 1, 0L);
1191a574 231 }
f474d36b 232 context.setLocation(currentLocation);
7f0bab07
PT
233 if (location == null) {
234 CtfTmfEvent event = getIterator(this, context).getCurrentEvent();
235 if (event != null) {
d62bb185 236 currentLocation = new CtfLocation(event.getTimestamp().getValue(), 0);
7f0bab07
PT
237 }
238 }
a94410d9 239 if (context.getRank() != 0) {
3bd44ac8 240 context.setRank(ITmfContext.UNKNOWN_RANK);
64c2cb4c 241 }
f474d36b 242 return context;
a3fc8213
AM
243 }
244
a3fc8213 245 @Override
76643eb7 246 public synchronized ITmfContext seekEvent(double ratio) {
81a2d02e 247 CtfTmfContext context = new CtfTmfContext(this);
76643eb7
BH
248 if (fTrace == null) {
249 context.setLocation(null);
250 context.setRank(ITmfContext.UNKNOWN_RANK);
251 return context;
252 }
b2dc9e02
MK
253 final long end = this.getEndTime().getValue();
254 final long start = this.getStartTime().getValue();
255 final long diff = end - start;
15e89960 256 final long ratioTs = Math.round(diff * ratio) + start;
b2dc9e02 257 context.seek(ratioTs);
f474d36b
PT
258 context.setRank(ITmfContext.UNKNOWN_RANK);
259 return context;
a3fc8213
AM
260 }
261
b1baa808
MK
262 /**
263 * Method readNextEvent.
a94410d9
MK
264 *
265 * @param context
266 * ITmfContext
b1baa808 267 * @return CtfTmfEvent
c32744d6 268 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
b1baa808 269 */
a3fc8213 270 @Override
4b7c469f 271 public synchronized CtfTmfEvent getNext(final ITmfContext context) {
faa38350
PT
272 if (fTrace == null) {
273 return null;
274 }
f474d36b 275 CtfTmfEvent event = null;
81a2d02e 276 if (context instanceof CtfTmfContext) {
575beffc 277 if (context.getLocation() == null || CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationInfo())) {
ae09313d
PT
278 return null;
279 }
81a2d02e 280 CtfTmfContext ctfContext = (CtfTmfContext) context;
788ddcbc 281 event = ctfContext.getCurrentEvent();
4a110860 282
324a6a4a
BH
283 if (event != null) {
284 updateAttributes(context, event.getTimestamp());
788ddcbc
MK
285 ctfContext.advance();
286 ctfContext.increaseRank();
324a6a4a 287 }
f474d36b 288 }
4a110860 289
aa572e22 290 return event;
a3fc8213
AM
291 }
292
4b7c469f
MK
293 /**
294 * gets the CTFtrace that this is wrapping
a94410d9 295 *
4b7c469f
MK
296 * @return the CTF trace
297 */
298 public CTFTrace getCTFTrace() {
a3fc8213
AM
299 return fTrace;
300 }
a1a24d68 301
bb52f9bc
GB
302 /**
303 * Ctf traces have a clock with a unique uuid that will be used to identify
304 * the host. Traces with the same clock uuid will be known to have been made
305 * on the same machine.
306 *
307 * Note: uuid is an optional field, it may not be there for a clock.
308 */
309 @Override
310 public String getHostId() {
311 CTFClock clock = getCTFTrace().getClock();
312 if (clock != null) {
313 String clockHost = (String) clock.getProperty(CLOCK_HOST_PROPERTY);
314 if (clockHost != null) {
315 return clockHost;
316 }
317 }
318 return super.getHostId();
319 }
320
a94410d9 321 // -------------------------------------------
22307af3 322 // ITmfTraceProperties
a94410d9 323 // -------------------------------------------
4b7c469f
MK
324
325 /**
299e494e 326 * @since 2.0
4b7c469f 327 */
22307af3
AM
328 @Override
329 public Map<String, String> getTraceProperties() {
299e494e 330 return Collections.unmodifiableMap(fTrace.getEnvironment());
4b7c469f
MK
331 }
332
a94410d9
MK
333 // -------------------------------------------
334 // Clocks
335 // -------------------------------------------
bfe038ff 336
9ac2eb62
MK
337 /**
338 * gets the clock offset
a94410d9 339 *
9ac2eb62
MK
340 * @return the clock offset in ns
341 */
a94410d9
MK
342 public long getOffset() {
343 if (fTrace != null) {
bfe038ff
MK
344 return fTrace.getOffset();
345 }
346 return 0;
347 }
348
3480bf12
GB
349 /**
350 * Returns whether or not an event is in the metadata of the trace,
351 * therefore if it can possibly be in the trace. It does not verify whether
352 * or not the event is actually in the trace
353 *
354 * @param eventName
355 * The name of the event to check
356 * @return Whether the event is in the metadata or not
4b121c48 357 * @since 2.1
3480bf12
GB
358 */
359 public boolean hasEvent(final String eventName) {
360 Map<Long, IEventDeclaration> events = fTrace.getEvents(0L);
361 if (events != null) {
362 for (IEventDeclaration decl : events.values()) {
363 if (decl.getName().equals(eventName)) {
364 return true;
365 }
366 }
367 }
368 return false;
369 }
370
371 /**
372 * Return whether all requested events are in the metadata
373 *
374 * @param names
375 * The array of events to check for
376 * @return Whether all events are in the metadata
4b121c48 377 * @since 2.1
3480bf12
GB
378 */
379 public boolean hasAllEvents(String[] names) {
380 for (String name : names) {
381 if (!hasEvent(name)) {
382 return false;
383 }
384 }
385 return true;
386 }
387
388 /**
389 * Returns whether the metadata contains at least one of the requested
390 * events
391 *
392 * @param names
393 * The array of event names of check for
394 * @return Whether one of the event is present in trace metadata
4b121c48 395 * @since 2.1
3480bf12
GB
396 */
397 public boolean hasAtLeastOneOfEvents(String[] names) {
398 for (String name : names) {
399 if (hasEvent(name)) {
400 return true;
401 }
402 }
403 return false;
404 }
405
a94410d9
MK
406 // -------------------------------------------
407 // Parser
408 // -------------------------------------------
4b7c469f
MK
409
410 @Override
bfe038ff 411 public CtfTmfEvent parseEvent(ITmfContext context) {
4b7c469f 412 CtfTmfEvent event = null;
ea271da6
PT
413 if (context instanceof CtfTmfContext) {
414 final ITmfContext tmpContext = seekEvent(context.getLocation());
415 event = getNext(tmpContext);
4b7c469f
MK
416 }
417 return event;
11d6f468 418 }
64c2cb4c 419
324a6a4a 420 /**
64c2cb4c 421 * Sets the cache size for a CtfTmfTrace.
324a6a4a
BH
422 */
423 protected void setCacheSize() {
424 setCacheSize(DEFAULT_CACHE_SIZE);
425 }
ce2388e0 426
a94410d9
MK
427 // -------------------------------------------
428 // Helpers
429 // -------------------------------------------
53b235e1 430
a94410d9 431 private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfContext context) {
53b235e1
MK
432 return CtfIteratorManager.getIterator(trace, context);
433 }
36dd544c
MK
434
435 /**
436 * Get an iterator to the trace
437 *
438 * @return an iterator to the trace
ed59ab27 439 * @since 2.0
36dd544c 440 */
a94410d9 441 public CtfIterator createIterator() {
db8e8f7d
AM
442 try {
443 return new CtfIterator(this);
444 } catch (CTFReaderException e) {
445 Activator.logError(e.getMessage(), e);
446 }
447 return null;
36dd544c 448 }
e73a4ba5
GB
449
450 // ------------------------------------------------------------------------
451 // Timestamp transformation functions
452 // ------------------------------------------------------------------------
453
454 /**
455 * @since 3.0
456 */
457 @Override
458 public CtfTmfTimestamp createTimestamp(long ts) {
459 return new CtfTmfTimestamp(getTimestampTransform().transform(ts));
460 }
032ecd45
MAL
461
462 private static int fCheckpointSize = -1;
463
c4767854
AM
464 /**
465 * @since 3.0
466 */
032ecd45
MAL
467 @Override
468 public synchronized int getCheckpointSize() {
469 if (fCheckpointSize == -1) {
470 TmfCheckpoint c = new TmfCheckpoint(new CtfTmfTimestamp(0), new CtfLocation(0, 0), 0);
471 ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE);
472 b.clear();
473 c.serialize(b);
474 fCheckpointSize = b.position();
475 }
476
477 return fCheckpointSize;
478 }
479
480 @Override
481 protected ITmfTraceIndexer createIndexer(int interval) {
482 return new TmfBTreeTraceIndexer(this, interval);
483 }
484
c4767854
AM
485 /**
486 * @since 3.0
487 */
032ecd45
MAL
488 @Override
489 public ITmfLocation restoreLocation(ByteBuffer bufferIn) {
490 return new CtfLocation(bufferIn);
491 }
a3fc8213 492}
This page took 0.070856 seconds and 5 git commands to generate.