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