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