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