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