lttng: Support live updating of Control Flow view and Resources view
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfTrace.java
CommitLineData
8c8bf09f 1/*******************************************************************************
089a4872 2 * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal
0bfb7d06 3 *
8c8bf09f
ASL
4 * All rights reserved. This program and the accompanying materials are
5 * made 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
0bfb7d06 8 *
8c8bf09f 9 * Contributors:
20658947
FC
10 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Updated as per TMF Trace Model 1.0
ea271da6 12 * Patrick Tasse - Updated for removal of context clone
e73a4ba5
GB
13 * Geneviève Bastien - Added timestamp transforms, its saving to file and
14 * timestamp creation functions
8c8bf09f
ASL
15 *******************************************************************************/
16
6c13869b 17package org.eclipse.linuxtools.tmf.core.trace;
8c8bf09f 18
6f4a1d2b 19import java.io.File;
e73a4ba5 20import java.io.FileInputStream;
e73a4ba5
GB
21import java.io.FileOutputStream;
22import java.io.IOException;
23import java.io.ObjectInputStream;
24import java.io.ObjectOutputStream;
35c160d9 25import java.util.Collections;
8a6ff07f 26import java.util.HashMap;
35c160d9 27import java.util.LinkedHashMap;
a51b2b9f 28import java.util.Map;
c068a752 29import java.util.Map.Entry;
8c8bf09f 30
e73a4ba5 31import org.eclipse.core.resources.IFolder;
9de979b2 32import org.eclipse.core.resources.IProject;
828e5592 33import org.eclipse.core.resources.IResource;
faa38350 34import org.eclipse.core.runtime.CoreException;
42459d24 35import org.eclipse.core.runtime.IStatus;
b22a582a 36import org.eclipse.core.runtime.MultiStatus;
032ecd45 37import org.eclipse.core.runtime.Path;
42459d24 38import org.eclipse.core.runtime.Status;
b22a582a 39import org.eclipse.linuxtools.internal.tmf.core.Activator;
e73a4ba5 40import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
c068a752
GB
41import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModule;
42import org.eclipse.linuxtools.tmf.core.analysis.IAnalysisModuleHelper;
43import org.eclipse.linuxtools.tmf.core.analysis.TmfAnalysisManager;
6c13869b 44import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
72f1e62a 45import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
c068a752 46import org.eclipse.linuxtools.tmf.core.exceptions.TmfAnalysisException;
b4f71e4a 47import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
5419a136 48import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
faa38350 49import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
fec1ac0b 50import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
faa38350
PT
51import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
52import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
032ecd45 53import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
7898bb21 54import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
200789b3 55import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
1c0de632 56import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics;
e73a4ba5
GB
57import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
58import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
3bd46eef
AM
59import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
60import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
61import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
a3db8436
AM
62import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
63import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpointIndexer;
64import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
8c8bf09f
ASL
65
66/**
09e86496
FC
67 * Abstract implementation of ITmfTrace.
68 * <p>
13cb5f43
FC
69 * Since the concept of 'location' is trace specific, the concrete classes have
70 * to provide the related methods, namely:
71 * <ul>
72 * <li> public ITmfLocation<?> getCurrentLocation()
73 * <li> public double getLocationRatio(ITmfLocation<?> location)
74 * <li> public ITmfContext seekEvent(ITmfLocation<?> location)
75 * <li> public ITmfContext seekEvent(double ratio)
da1a4b39 76 * <li> public IStatus validate(IProject project, String path)
13cb5f43
FC
77 * </ul>
78 * A concrete trace must provide its corresponding parser. A common way to
79 * accomplish this is by making the concrete class extend TmfTrace and
80 * implement ITmfEventParser.
81 * <p>
82 * The concrete class can either specify its own indexer or use the provided
83 * TmfCheckpointIndexer (default). In this case, the trace cache size will be
84 * used as checkpoint interval.
0bfb7d06 85 *
f7703ed6
FC
86 * @version 1.0
87 * @author Francois Chouinard
88 *
f7703ed6
FC
89 * @see ITmfEvent
90 * @see ITmfTraceIndexer
91 * @see ITmfEventParser
8c8bf09f 92 */
6256d8ad 93public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
62d1696a 94
e31e01e8 95 // ------------------------------------------------------------------------
8c8bf09f 96 // Attributes
e31e01e8 97 // ------------------------------------------------------------------------
8c8bf09f 98
09e86496
FC
99 // The resource used for persistent properties for this trace
100 private IResource fResource;
101
b0a282fb 102 // The trace path
12c155f5 103 private String fPath;
b0a282fb 104
0316808c
FC
105 // The trace cache page size
106 private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
62d1696a 107
0316808c
FC
108 // The number of events collected (so far)
109 private long fNbEvents = 0;
62d1696a
FC
110
111 // The time span of the event stream
9cbe7899 112 private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG;
a4115405 113 private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
62d1696a 114
0316808c
FC
115 // The trace streaming interval (0 = no streaming)
116 private long fStreamingInterval = 0;
085d898f 117
0316808c 118 // The trace indexer
6256d8ad 119 private ITmfTraceIndexer fIndexer;
20658947 120
0316808c 121 // The trace parser
6256d8ad 122 private ITmfEventParser fParser;
7e6347b0 123
200789b3
AM
124 // The trace's statistics
125 private ITmfStatistics fStatistics;
126
a51b2b9f
AM
127 /**
128 * The collection of state systems that are registered with this trace. Each
129 * sub-class can decide to add its (one or many) state system to this map
130 * during their {@link #buildStateSystem()}.
131 *
132 * @since 2.0
133 */
a1529f38
AM
134 @Deprecated
135 protected final Map<String, ITmfStateSystem> fStateSystems = new LinkedHashMap<>();
a51b2b9f 136
e73a4ba5
GB
137 private ITmfTimestampTransform fTsTransform;
138
a1529f38 139 private final Map<String, IAnalysisModule> fAnalysisModules = new LinkedHashMap<>();
c068a752 140
e73a4ba5
GB
141 private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$
142
e31e01e8 143 // ------------------------------------------------------------------------
3791b5df 144 // Construction
e31e01e8 145 // ------------------------------------------------------------------------
8c8bf09f 146
62d1696a 147 /**
3791b5df 148 * The default, parameterless, constructor
62d1696a 149 */
3791b5df
FC
150 public TmfTrace() {
151 super();
ab186fbb 152 fIndexer = createIndexer(DEFAULT_BLOCK_SIZE);
05bd3318
FC
153 }
154
155 /**
8cf330ae 156 * Full constructor.
0bfb7d06 157 *
8cf330ae
AM
158 * @param resource
159 * The resource associated to the trace
160 * @param type
161 * The type of events that will be read from this trace
162 * @param path
163 * The path to the trace on the filesystem
164 * @param cacheSize
165 * The trace cache size. Pass '-1' to use the default specified
166 * in {@link ITmfTrace#DEFAULT_TRACE_CACHE_SIZE}
167 * @param interval
168 * The trace streaming interval. You can use '0' for post-mortem
169 * traces.
8cf330ae
AM
170 * @param parser
171 * The trace event parser. Use 'null' if (and only if) the trace
172 * object itself is also the ITmfEventParser to be used.
173 * @throws TmfTraceException
174 * If something failed during the opening
20658947 175 */
8cf330ae
AM
176 protected TmfTrace(final IResource resource,
177 final Class<? extends ITmfEvent> type,
178 final String path,
179 final int cacheSize,
180 final long interval,
8cf330ae
AM
181 final ITmfEventParser parser)
182 throws TmfTraceException {
00641a97 183 super();
0316808c 184 fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
3791b5df 185 fStreamingInterval = interval;
13cb5f43 186 fParser = parser;
09e86496 187 initialize(resource, path, type);
8c8bf09f
ASL
188 }
189
3791b5df
FC
190 /**
191 * Copy constructor
0bfb7d06 192 *
3791b5df 193 * @param trace the original trace
063f0d27 194 * @throws TmfTraceException Should not happen usually
3791b5df 195 */
6256d8ad 196 public TmfTrace(final TmfTrace trace) throws TmfTraceException {
3791b5df 197 super();
0316808c 198 if (trace == null) {
3791b5df 199 throw new IllegalArgumentException();
0316808c 200 }
20658947
FC
201 fCacheSize = trace.getCacheSize();
202 fStreamingInterval = trace.getStreamingInterval();
13cb5f43
FC
203 fParser = trace.fParser;
204 initialize(trace.getResource(), trace.getPath(), trace.getEventType());
3791b5df
FC
205 }
206
032ecd45
MAL
207 /**
208 * Creates the indexer instance. Classes extending this class can override
209 * this to provide a different indexer implementation.
210 *
211 * @param interval the checkpoints interval
212 *
213 * @return the indexer
214 * @since 3.0
215 */
216 protected ITmfTraceIndexer createIndexer(int interval) {
217 return new TmfCheckpointIndexer(this, interval);
218 }
219
7e6347b0
FC
220 // ------------------------------------------------------------------------
221 // ITmfTrace - Initializers
222 // ------------------------------------------------------------------------
223
7e6347b0 224 @Override
6256d8ad 225 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
7e6347b0 226 initialize(resource, path, type);
7e6347b0
FC
227 }
228
09e86496 229 /**
1703b536 230 * Initialize the trace common attributes and the base component.
0bfb7d06
MK
231 *
232 * @param resource the Eclipse resource (trace)
1703b536
FC
233 * @param path the trace path
234 * @param type the trace event type
0bfb7d06 235 *
6f4e8ec0 236 * @throws TmfTraceException If something failed during the initialization
3791b5df 237 */
248af329
AM
238 protected void initialize(final IResource resource,
239 final String path,
240 final Class<? extends ITmfEvent> type)
241 throws TmfTraceException {
0316808c 242 if (path == null) {
b4f71e4a 243 throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$
0316808c 244 }
3791b5df 245 fPath = path;
1703b536 246 fResource = resource;
25e48683 247 String traceName = (resource != null) ? resource.getName() : null;
1703b536
FC
248 // If no resource was provided, extract the display name the trace path
249 if (traceName == null) {
032ecd45 250 traceName = new Path(path).lastSegment();
1703b536 251 }
2352aed9
FC
252 if (fParser == null) {
253 if (this instanceof ITmfEventParser) {
6256d8ad 254 fParser = (ITmfEventParser) this;
2352aed9
FC
255 } else {
256 throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$
257 }
258 }
3791b5df 259 super.init(traceName, type);
fec1ac0b
BH
260 // register as VIP after super.init() because TmfComponent registers to signal manager there
261 TmfSignalManager.registerVIP(this);
ab186fbb 262 fIndexer = createIndexer(fCacheSize);
3791b5df
FC
263 }
264
2352aed9
FC
265 /**
266 * Indicates if the path points to an existing file/directory
0bfb7d06 267 *
2352aed9
FC
268 * @param path the path to test
269 * @return true if the file/directory exists
3791b5df 270 */
2352aed9 271 protected boolean fileExists(final String path) {
085d898f 272 final File file = new File(path);
3791b5df
FC
273 return file.exists();
274 }
275
c7e1020d 276 /**
51e75066 277 * @since 2.0
c7e1020d 278 */
51e75066
AM
279 @Override
280 public void indexTrace(boolean waitForCompletion) {
9e0640dc 281 getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion);
c7e1020d
FC
282 }
283
200789b3 284 /**
6f4e8ec0 285 * The default implementation of TmfTrace uses a TmfStatistics back-end.
200789b3
AM
286 * Override this if you want to specify another type (or none at all).
287 *
b22a582a
AM
288 * @return An IStatus indicating if the statistics could be built
289 * successfully or not.
290 * @since 3.0
200789b3 291 */
b22a582a 292 protected IStatus buildStatistics() {
200789b3
AM
293 /*
294 * Initialize the statistics provider, but only if a Resource has been
295 * set (so we don't build it for experiments, for unit tests, etc.)
296 */
b22a582a
AM
297 try {
298 fStatistics = (fResource == null ? null : new TmfStateStatistics(this) );
299 } catch (TmfTraceException e) {
300 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e);
301 }
302 return Status.OK_STATUS;
200789b3
AM
303 }
304
faa38350
PT
305 /**
306 * Build the state system(s) associated with this trace type.
307 *
42459d24
AM
308 * @return An IStatus indicating if the state system could be build
309 * successfully or not.
310 * @since 3.0
faa38350 311 */
8a6ff07f 312 @Deprecated
42459d24 313 protected IStatus buildStateSystem() {
faa38350
PT
314 /*
315 * Nothing is done in the base implementation, please specify
a51b2b9f 316 * how/if to register a new state system in derived classes.
faa38350 317 */
42459d24 318 return Status.OK_STATUS;
faa38350
PT
319 }
320
c068a752
GB
321 /**
322 * Instantiate the applicable analysis modules and executes the analysis
323 * modules that are meant to be automatically executed
324 *
325 * @return An IStatus indicating whether the analysis could be run
326 * successfully or not
327 * @since 3.0
328 */
329 protected IStatus executeAnalysis() {
330 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
331 Map<String, IAnalysisModuleHelper> modules = TmfAnalysisManager.getAnalysisModules(this.getClass());
332 for (IAnalysisModuleHelper helper : modules.values()) {
333 try {
334 IAnalysisModule module = helper.newModule(this);
335 fAnalysisModules.put(module.getId(), module);
336 if (module.isAutomatic()) {
337 status.add(module.schedule());
338 }
339 } catch (TmfAnalysisException e) {
340 status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(), e));
341 }
342 }
343 return status;
344 }
345
c4767854
AM
346 /**
347 * @since 3.0
348 */
c068a752
GB
349 @Override
350 public final IAnalysisModule getAnalysisModule(String analysisId) {
351 return fAnalysisModules.get(analysisId);
352 }
353
c4767854
AM
354 /**
355 * @since 3.0
356 */
c068a752 357 @Override
8a6ff07f 358 public <T> Map<String, T> getAnalysisModules(Class<T> moduleclass) {
a4524c1b 359 Map<String, T> modules = new HashMap<>();
c068a752
GB
360 for (Entry<String, IAnalysisModule> entry : fAnalysisModules.entrySet()) {
361 if (moduleclass.isAssignableFrom(entry.getValue().getClass())) {
8a6ff07f 362 modules.put(entry.getKey(), moduleclass.cast(entry.getValue()));
c068a752
GB
363 }
364 }
365 return modules;
366 }
367
c4767854
AM
368 /**
369 * @since 3.0
370 */
c068a752
GB
371 @Override
372 public Map<String, IAnalysisModule> getAnalysisModules() {
373 return Collections.unmodifiableMap(fAnalysisModules);
374 }
375
b5ee6881
FC
376 /**
377 * Clears the trace
378 */
379 @Override
380 public synchronized void dispose() {
1a4205d9 381 /* Clean up the index if applicable */
77551cc2
FC
382 if (getIndexer() != null) {
383 getIndexer().dispose();
384 }
1a4205d9
AM
385
386 /* Clean up the statistics */
387 if (fStatistics != null) {
388 fStatistics.dispose();
389 }
a51b2b9f
AM
390
391 /* Clean up the state systems */
392 for (ITmfStateSystem ss : fStateSystems.values()) {
393 ss.dispose();
394 }
395
a1529f38
AM
396 /* Clean up the analysis modules */
397 for (IAnalysisModule module : fAnalysisModules.values()) {
398 module.dispose();
399 }
400
b5ee6881
FC
401 super.dispose();
402 }
403
3791b5df 404 // ------------------------------------------------------------------------
09e86496 405 // ITmfTrace - Basic getters
e31e01e8 406 // ------------------------------------------------------------------------
8c8bf09f 407
25e48683 408 @Override
0f89d4ba
AM
409 public Class<? extends ITmfEvent> getEventType() {
410 return super.getType();
25e48683
FC
411 }
412
d4011df2 413 @Override
09e86496
FC
414 public IResource getResource() {
415 return fResource;
8c8bf09f
ASL
416 }
417
d4011df2 418 @Override
09e86496
FC
419 public String getPath() {
420 return fPath;
8c8bf09f
ASL
421 }
422
20658947
FC
423 @Override
424 public int getCacheSize() {
425 return fCacheSize;
426 }
427
20658947
FC
428 @Override
429 public long getStreamingInterval() {
430 return fStreamingInterval;
431 }
432
0316808c
FC
433 /**
434 * @return the trace indexer
a3db8436 435 * @since 3.0
0316808c 436 */
6256d8ad 437 protected ITmfTraceIndexer getIndexer() {
0316808c
FC
438 return fIndexer;
439 }
440
441 /**
442 * @return the trace parser
443 */
6256d8ad 444 protected ITmfEventParser getParser() {
0316808c
FC
445 return fParser;
446 }
447
200789b3
AM
448 /**
449 * @since 2.0
450 */
451 @Override
452 public ITmfStatistics getStatistics() {
453 return fStatistics;
454 }
455
7898bb21
AM
456 /**
457 * @since 2.0
8a6ff07f 458 * @deprecated See {@link ITmfTrace}
7898bb21 459 */
8a6ff07f 460 @Deprecated
7898bb21 461 @Override
35c160d9
AM
462 public final Map<String, ITmfStateSystem> getStateSystems() {
463 return Collections.unmodifiableMap(fStateSystems);
7898bb21
AM
464 }
465
6c5e0863
AM
466 /**
467 * @since 2.0
8a6ff07f 468 * @deprecated See {@link ITmfTrace}
6c5e0863 469 */
8a6ff07f 470 @Deprecated
6c5e0863
AM
471 @Override
472 public final void registerStateSystem(String id, ITmfStateSystem ss) {
473 fStateSystems.put(id, ss);
474 }
475
09e86496
FC
476 // ------------------------------------------------------------------------
477 // ITmfTrace - Trace characteristics getters
478 // ------------------------------------------------------------------------
479
d4011df2 480 @Override
5419a136 481 public synchronized long getNbEvents() {
3791b5df 482 return fNbEvents;
b0a282fb
FC
483 }
484
3bd46eef
AM
485 /**
486 * @since 2.0
62d1696a 487 */
d4011df2 488 @Override
12c155f5 489 public TmfTimeRange getTimeRange() {
cb866e08 490 return new TmfTimeRange(fStartTime, fEndTime);
8c8bf09f
ASL
491 }
492
3bd46eef
AM
493 /**
494 * @since 2.0
e31e01e8 495 */
d4011df2 496 @Override
4df4581d 497 public ITmfTimestamp getStartTime() {
4593bd5b 498 return fStartTime;
146a887c
FC
499 }
500
3bd46eef
AM
501 /**
502 * @since 2.0
e31e01e8 503 */
d4011df2 504 @Override
4df4581d 505 public ITmfTimestamp getEndTime() {
4593bd5b 506 return fEndTime;
20658947
FC
507 }
508
d7ee91bb 509 /**
d7ee91bb
PT
510 * @since 2.0
511 */
66262ad8
BH
512 @Override
513 public ITmfTimestamp getInitialRangeOffset() {
d7ee91bb
PT
514 final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec
515 return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE);
516 }
517
bb52f9bc
GB
518 /**
519 * @since 3.0
520 */
521 @Override
522 public String getHostId() {
523 return this.getName();
524 }
525
20658947 526 // ------------------------------------------------------------------------
d7ee91bb 527 // Convenience setters
20658947
FC
528 // ------------------------------------------------------------------------
529
0316808c
FC
530 /**
531 * Set the trace cache size. Must be done at initialization time.
0bfb7d06 532 *
0316808c
FC
533 * @param cacheSize The trace cache size
534 */
535 protected void setCacheSize(final int cacheSize) {
536 fCacheSize = cacheSize;
537 }
538
539 /**
540 * Set the trace known number of events. This can be quite dynamic
541 * during indexing or for live traces.
0bfb7d06 542 *
0316808c
FC
543 * @param nbEvents The number of events
544 */
545 protected synchronized void setNbEvents(final long nbEvents) {
546 fNbEvents = (nbEvents > 0) ? nbEvents : 0;
547 }
548
20658947
FC
549 /**
550 * Update the trace events time range
0bfb7d06 551 *
20658947 552 * @param range the new time range
3bd46eef 553 * @since 2.0
20658947
FC
554 */
555 protected void setTimeRange(final TmfTimeRange range) {
4593bd5b
AM
556 fStartTime = range.getStartTime();
557 fEndTime = range.getEndTime();
20658947
FC
558 }
559
560 /**
561 * Update the trace chronologically first event timestamp
0bfb7d06 562 *
20658947 563 * @param startTime the new first event timestamp
3bd46eef 564 * @since 2.0
20658947
FC
565 */
566 protected void setStartTime(final ITmfTimestamp startTime) {
4593bd5b 567 fStartTime = startTime;
20658947
FC
568 }
569
570 /**
571 * Update the trace chronologically last event timestamp
0bfb7d06 572 *
20658947 573 * @param endTime the new last event timestamp
3bd46eef 574 * @since 2.0
20658947
FC
575 */
576 protected void setEndTime(final ITmfTimestamp endTime) {
4593bd5b 577 fEndTime = endTime;
20658947
FC
578 }
579
580 /**
0316808c 581 * Set the polling interval for live traces (default = 0 = no streaming).
0bfb7d06 582 *
20658947
FC
583 * @param interval the new trace streaming interval
584 */
585 protected void setStreamingInterval(final long interval) {
1703b536 586 fStreamingInterval = (interval > 0) ? interval : 0;
146a887c
FC
587 }
588
0316808c
FC
589 /**
590 * Set the trace parser. Must be done at initialization time.
0bfb7d06 591 *
0316808c
FC
592 * @param parser the new trace parser
593 */
6256d8ad 594 protected void setParser(final ITmfEventParser parser) {
0316808c
FC
595 fParser = parser;
596 }
597
09e86496 598 // ------------------------------------------------------------------------
7e6347b0 599 // ITmfTrace - SeekEvent operations (returning a trace context)
09e86496
FC
600 // ------------------------------------------------------------------------
601
1b70b6dc 602 @Override
7e6347b0 603 public synchronized ITmfContext seekEvent(final long rank) {
09e86496 604
7e6347b0 605 // A rank <= 0 indicates to seek the first event
2352aed9 606 if (rank <= 0) {
1e1bef82 607 ITmfContext context = seekEvent((ITmfLocation) null);
2352aed9
FC
608 context.setRank(0);
609 return context;
610 }
09e86496 611
09e86496 612 // Position the trace at the checkpoint
7e6347b0 613 final ITmfContext context = fIndexer.seekIndex(rank);
09e86496
FC
614
615 // And locate the requested event context
7e6347b0
FC
616 long pos = context.getRank();
617 if (pos < rank) {
c32744d6 618 ITmfEvent event = getNext(context);
0bfb7d06 619 while ((event != null) && (++pos < rank)) {
c32744d6 620 event = getNext(context);
7e6347b0 621 }
09e86496
FC
622 }
623 return context;
1b70b6dc
PT
624 }
625
3bd46eef
AM
626 /**
627 * @since 2.0
09e86496
FC
628 */
629 @Override
7e6347b0 630 public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) {
09e86496 631
7e6347b0 632 // A null timestamp indicates to seek the first event
2352aed9 633 if (timestamp == null) {
1e1bef82 634 ITmfContext context = seekEvent((ITmfLocation) null);
2352aed9
FC
635 context.setRank(0);
636 return context;
637 }
09e86496 638
1703b536 639 // Position the trace at the checkpoint
408e65d2 640 ITmfContext context = fIndexer.seekIndex(timestamp);
09e86496
FC
641
642 // And locate the requested event context
ea271da6
PT
643 ITmfLocation previousLocation = context.getLocation();
644 long previousRank = context.getRank();
645 ITmfEvent event = getNext(context);
7e6347b0 646 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
ea271da6
PT
647 previousLocation = context.getLocation();
648 previousRank = context.getRank();
649 event = getNext(context);
09e86496 650 }
0316808c
FC
651 if (event == null) {
652 context.setLocation(null);
653 context.setRank(ITmfContext.UNKNOWN_RANK);
ea271da6
PT
654 } else {
655 context.dispose();
656 context = seekEvent(previousLocation);
657 context.setRank(previousRank);
0316808c 658 }
09e86496
FC
659 return context;
660 }
0283f7ff 661
09e86496
FC
662 // ------------------------------------------------------------------------
663 // ITmfTrace - Read operations (returning an actual event)
664 // ------------------------------------------------------------------------
665
d4011df2 666 @Override
6256d8ad 667 public synchronized ITmfEvent getNext(final ITmfContext context) {
09e86496 668 // parseEvent() does not update the context
6256d8ad 669 final ITmfEvent event = fParser.parseEvent(context);
09e86496 670 if (event != null) {
d337369a 671 updateAttributes(context, event.getTimestamp());
09e86496
FC
672 context.setLocation(getCurrentLocation());
673 context.increaseRank();
674 processEvent(event);
675 }
676 return event;
677 }
678
679 /**
d337369a 680 * Hook for special event processing by the concrete class
7e6347b0 681 * (called by TmfTrace.getEvent())
0bfb7d06 682 *
d337369a 683 * @param event the event
09e86496
FC
684 */
685 protected void processEvent(final ITmfEvent event) {
d337369a 686 // Do nothing
09e86496
FC
687 }
688
d337369a
FC
689 /**
690 * Update the trace attributes
0bfb7d06 691 *
d337369a 692 * @param context the current trace context
2848c377 693 * @param timestamp the corresponding timestamp
3bd46eef 694 * @since 2.0
d337369a
FC
695 */
696 protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) {
0bfb7d06 697 if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) {
4593bd5b 698 fStartTime = timestamp;
09e86496 699 }
0bfb7d06 700 if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) {
4593bd5b 701 fEndTime = timestamp;
09e86496
FC
702 }
703 if (context.hasValidRank()) {
d337369a 704 long rank = context.getRank();
09e86496
FC
705 if (fNbEvents <= rank) {
706 fNbEvents = rank + 1;
707 }
200789b3
AM
708 if (fIndexer != null) {
709 fIndexer.updateIndex(context, timestamp);
710 }
09e86496 711 }
abfad0aa
FC
712 }
713
3791b5df 714 // ------------------------------------------------------------------------
d337369a 715 // TmfDataProvider
3791b5df
FC
716 // ------------------------------------------------------------------------
717
77c4a6df
AM
718 /**
719 * @since 2.0
d337369a 720 */
3791b5df 721 @Override
fd3f1eff 722 public synchronized ITmfContext armRequest(final ITmfEventRequest request) {
faa38350
PT
723 if (executorIsShutdown()) {
724 return null;
725 }
fd3f1eff
AM
726 if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime())
727 && (request.getIndex() == 0)) {
728 final ITmfContext context = seekEvent(request.getRange().getStartTime());
729 request.setStartIndex((int) context.getRank());
8584dc20 730 return context;
8584dc20 731
5419a136
AM
732 }
733 return seekEvent(request.getIndex());
3791b5df
FC
734 }
735
faa38350
PT
736 // ------------------------------------------------------------------------
737 // Signal handlers
738 // ------------------------------------------------------------------------
739
740 /**
741 * Handler for the Trace Opened signal
742 *
743 * @param signal
744 * The incoming signal
745 * @since 2.0
746 */
747 @TmfSignalHandler
748 public void traceOpened(TmfTraceOpenedSignal signal) {
b9a5bf8f
AM
749 boolean signalIsForUs = false;
750 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
751 if (trace == this) {
752 signalIsForUs = true;
fe0c44c4 753 break;
faa38350
PT
754 }
755 }
faa38350 756
b9a5bf8f 757 if (!signalIsForUs) {
fe0c44c4
AM
758 return;
759 }
760
761 /*
b9a5bf8f 762 * The signal is either for this trace, or for an experiment containing
fe0c44c4
AM
763 * this trace.
764 */
b22a582a
AM
765 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
766 status.add(buildStatistics());
767 status.add(buildStateSystem());
c068a752 768 status.add(executeAnalysis());
b22a582a
AM
769 if (!status.isOK()) {
770 Activator.log(status);
fe0c44c4
AM
771 }
772
9de979b2 773 refreshSupplementaryFiles();
fe0c44c4 774
faa38350 775 if (signal.getTrace() == this) {
f8fc4a3a 776 /* Additionally, the signal is directly for this trace. */
faa38350
PT
777 if (getNbEvents() == 0) {
778 return;
779 }
780
f8fc4a3a
PT
781 /* For a streaming trace, the range updated signal should be sent
782 * by the subclass when a new safe time is determined.
783 */
784 if (getStreamingInterval() > 0) {
785 return;
786 }
787
faa38350
PT
788 final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
789 final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
790
791 // Broadcast in separate thread to prevent deadlock
089a4872 792 broadcastAsync(rangeUpdatedsignal);
faa38350
PT
793 return;
794 }
795 }
796
9de979b2
GB
797 /**
798 * Refresh the supplementary files resources, so it can pick up new files
799 * that got created.
c4767854 800 * @since 3.0
9de979b2
GB
801 */
802 public void refreshSupplementaryFiles() {
803 if (fResource != null) {
804 IProject project = fResource.getProject();
805 IFolder supplFolder = project.getFolder(TmfCommonConstants.TRACE_SUPPLEMENATARY_FOLDER_NAME);
806 if (supplFolder.exists()) {
807 try {
808 supplFolder.refreshLocal(IResource.DEPTH_INFINITE, null);
809 } catch (CoreException e) {
810 Activator.logError("Error refreshing resources", e); //$NON-NLS-1$
811 }
812 }
813 }
814 }
815
faa38350
PT
816 /**
817 * Signal handler for the TmfTraceRangeUpdatedSignal signal
818 *
819 * @param signal The incoming signal
820 * @since 2.0
821 */
822 @TmfSignalHandler
823 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
824 if (signal.getTrace() == this) {
825 getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
826 }
827 }
828
032ecd45
MAL
829 /**
830 * Signal handler for the TmfTraceUpdatedSignal signal
831 *
832 * @param signal The incoming signal
c4767854 833 * @since 3.0
032ecd45
MAL
834 */
835 @TmfSignalHandler
836 public void traceUpdated(final TmfTraceUpdatedSignal signal) {
837 if (signal.getSource() == getIndexer()) {
838 fNbEvents = signal.getNbEvents();
839 fStartTime = signal.getRange().getStartTime();
840 fEndTime = signal.getRange().getEndTime();
841 }
842 }
843
e73a4ba5
GB
844 /**
845 * Returns the file resource used to store synchronization formula. The file
846 * may not exist.
847 *
848 * @return the synchronization file
849 */
850 private File getSyncFormulaFile() {
851 File file = null;
852 if (fResource instanceof IFolder) {
853 try {
854 String supplDirectory;
855
856 supplDirectory = fResource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
857
858 file = new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE);
859
860 } catch (CoreException e) {
861
862 }
863 }
864 return file;
865 }
866
867 // ------------------------------------------------------------------------
868 // Timestamp transformation functions
869 // ------------------------------------------------------------------------
870
871 /**
872 * @since 3.0
873 */
874 @Override
875 public ITmfTimestampTransform getTimestampTransform() {
876 if (fTsTransform == null) {
877 /* Check if a formula is stored somewhere in the resources */
878 File sync_file = getSyncFormulaFile();
879 if (sync_file != null && sync_file.exists()) {
880
a4524c1b
AM
881 try (FileInputStream fis = new FileInputStream(sync_file);
882 ObjectInputStream ois = new ObjectInputStream(fis);) {
883
e73a4ba5
GB
884 fTsTransform = (ITmfTimestampTransform) ois.readObject();
885
a4524c1b 886 } catch (ClassNotFoundException | IOException e) {
e73a4ba5
GB
887 fTsTransform = TmfTimestampTransform.IDENTITY;
888 }
889 } else {
890 fTsTransform = TmfTimestampTransform.IDENTITY;
891 }
892 }
893 return fTsTransform;
894 }
895
896 /**
897 * @since 3.0
898 */
899 @Override
900 public void setTimestampTransform(final ITmfTimestampTransform tt) {
901 fTsTransform = tt;
902
903 /* Save the timestamp transform to a file */
904 File sync_file = getSyncFormulaFile();
905 if (sync_file != null) {
906 if (sync_file.exists()) {
907 sync_file.delete();
908 }
909 FileOutputStream fos;
910 ObjectOutputStream oos;
911
912 /* Save the header of the file */
913 try {
914 fos = new FileOutputStream(sync_file, false);
915 oos = new ObjectOutputStream(fos);
916
917 oos.writeObject(fTsTransform);
918 oos.close();
919 fos.close();
920 } catch (IOException e1) {
921 Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$
922 }
923 }
924 }
925
926 /**
927 * @since 3.0
928 */
929 @Override
930 public ITmfTimestamp createTimestamp(long ts) {
931 return new TmfTimestamp(getTimestampTransform().transform(ts));
932 }
933
3791b5df 934 // ------------------------------------------------------------------------
09e86496 935 // toString
3791b5df
FC
936 // ------------------------------------------------------------------------
937
12c155f5 938 @Override
09e86496 939 @SuppressWarnings("nls")
5419a136 940 public synchronized String toString() {
20658947
FC
941 return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize
942 + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime
943 + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
12c155f5
FC
944 }
945
8c8bf09f 946}
This page took 0.145736 seconds and 5 git commands to generate.