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