tmf: Move TmfEventRequest.ALL_DATA to the interface
[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
GB
20import java.io.FileInputStream;
21import java.io.FileNotFoundException;
22import java.io.FileOutputStream;
23import java.io.IOException;
24import java.io.ObjectInputStream;
25import java.io.ObjectOutputStream;
35c160d9 26import java.util.Collections;
8a6ff07f 27import java.util.HashMap;
35c160d9 28import java.util.LinkedHashMap;
a51b2b9f 29import java.util.Map;
c068a752 30import java.util.Map.Entry;
8c8bf09f 31
e73a4ba5 32import org.eclipse.core.resources.IFolder;
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 =
35c160d9 135 new LinkedHashMap<String, ITmfStateSystem>();
a51b2b9f 136
e73a4ba5
GB
137 private ITmfTimestampTransform fTsTransform;
138
c068a752
GB
139 private final Map<String, IAnalysisModule> fAnalysisModules =
140 new LinkedHashMap<String, IAnalysisModule>();
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
347 @Override
348 public final IAnalysisModule getAnalysisModule(String analysisId) {
349 return fAnalysisModules.get(analysisId);
350 }
351
352 @Override
8a6ff07f
GB
353 public <T> Map<String, T> getAnalysisModules(Class<T> moduleclass) {
354 Map<String, T> modules = new HashMap<String, T>();
c068a752
GB
355 for (Entry<String, IAnalysisModule> entry : fAnalysisModules.entrySet()) {
356 if (moduleclass.isAssignableFrom(entry.getValue().getClass())) {
8a6ff07f 357 modules.put(entry.getKey(), moduleclass.cast(entry.getValue()));
c068a752
GB
358 }
359 }
360 return modules;
361 }
362
363 @Override
364 public Map<String, IAnalysisModule> getAnalysisModules() {
365 return Collections.unmodifiableMap(fAnalysisModules);
366 }
367
b5ee6881
FC
368 /**
369 * Clears the trace
370 */
371 @Override
372 public synchronized void dispose() {
1a4205d9 373 /* Clean up the index if applicable */
77551cc2
FC
374 if (getIndexer() != null) {
375 getIndexer().dispose();
376 }
1a4205d9
AM
377
378 /* Clean up the statistics */
379 if (fStatistics != null) {
380 fStatistics.dispose();
381 }
a51b2b9f
AM
382
383 /* Clean up the state systems */
384 for (ITmfStateSystem ss : fStateSystems.values()) {
385 ss.dispose();
386 }
387
b5ee6881
FC
388 super.dispose();
389 }
390
3791b5df 391 // ------------------------------------------------------------------------
09e86496 392 // ITmfTrace - Basic getters
e31e01e8 393 // ------------------------------------------------------------------------
8c8bf09f 394
25e48683 395 @Override
6256d8ad
AM
396 public Class<ITmfEvent> getEventType() {
397 return (Class<ITmfEvent>) super.getType();
25e48683
FC
398 }
399
d4011df2 400 @Override
09e86496
FC
401 public IResource getResource() {
402 return fResource;
8c8bf09f
ASL
403 }
404
d4011df2 405 @Override
09e86496
FC
406 public String getPath() {
407 return fPath;
8c8bf09f
ASL
408 }
409
20658947
FC
410 @Override
411 public int getCacheSize() {
412 return fCacheSize;
413 }
414
20658947
FC
415 @Override
416 public long getStreamingInterval() {
417 return fStreamingInterval;
418 }
419
0316808c
FC
420 /**
421 * @return the trace indexer
a3db8436 422 * @since 3.0
0316808c 423 */
6256d8ad 424 protected ITmfTraceIndexer getIndexer() {
0316808c
FC
425 return fIndexer;
426 }
427
428 /**
429 * @return the trace parser
430 */
6256d8ad 431 protected ITmfEventParser getParser() {
0316808c
FC
432 return fParser;
433 }
434
200789b3
AM
435 /**
436 * @since 2.0
437 */
438 @Override
439 public ITmfStatistics getStatistics() {
440 return fStatistics;
441 }
442
7898bb21
AM
443 /**
444 * @since 2.0
8a6ff07f 445 * @deprecated See {@link ITmfTrace}
7898bb21 446 */
8a6ff07f
GB
447 @SuppressWarnings("deprecation")
448 @Deprecated
7898bb21 449 @Override
35c160d9
AM
450 public final Map<String, ITmfStateSystem> getStateSystems() {
451 return Collections.unmodifiableMap(fStateSystems);
7898bb21
AM
452 }
453
6c5e0863
AM
454 /**
455 * @since 2.0
8a6ff07f 456 * @deprecated See {@link ITmfTrace}
6c5e0863 457 */
8a6ff07f
GB
458 @SuppressWarnings("deprecation")
459 @Deprecated
6c5e0863
AM
460 @Override
461 public final void registerStateSystem(String id, ITmfStateSystem ss) {
462 fStateSystems.put(id, ss);
463 }
464
09e86496
FC
465 // ------------------------------------------------------------------------
466 // ITmfTrace - Trace characteristics getters
467 // ------------------------------------------------------------------------
468
d4011df2 469 @Override
5419a136 470 public synchronized long getNbEvents() {
3791b5df 471 return fNbEvents;
b0a282fb
FC
472 }
473
3bd46eef
AM
474 /**
475 * @since 2.0
62d1696a 476 */
d4011df2 477 @Override
12c155f5 478 public TmfTimeRange getTimeRange() {
cb866e08 479 return new TmfTimeRange(fStartTime, fEndTime);
8c8bf09f
ASL
480 }
481
3bd46eef
AM
482 /**
483 * @since 2.0
e31e01e8 484 */
d4011df2 485 @Override
4df4581d 486 public ITmfTimestamp getStartTime() {
4593bd5b 487 return fStartTime;
146a887c
FC
488 }
489
3bd46eef
AM
490 /**
491 * @since 2.0
e31e01e8 492 */
d4011df2 493 @Override
4df4581d 494 public ITmfTimestamp getEndTime() {
4593bd5b 495 return fEndTime;
20658947
FC
496 }
497
d7ee91bb 498 /**
d7ee91bb
PT
499 * @since 2.0
500 */
66262ad8
BH
501 @Override
502 public ITmfTimestamp getInitialRangeOffset() {
d7ee91bb
PT
503 final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec
504 return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE);
505 }
506
bb52f9bc
GB
507 /**
508 * @since 3.0
509 */
510 @Override
511 public String getHostId() {
512 return this.getName();
513 }
514
20658947 515 // ------------------------------------------------------------------------
d7ee91bb 516 // Convenience setters
20658947
FC
517 // ------------------------------------------------------------------------
518
0316808c
FC
519 /**
520 * Set the trace cache size. Must be done at initialization time.
0bfb7d06 521 *
0316808c
FC
522 * @param cacheSize The trace cache size
523 */
524 protected void setCacheSize(final int cacheSize) {
525 fCacheSize = cacheSize;
526 }
527
528 /**
529 * Set the trace known number of events. This can be quite dynamic
530 * during indexing or for live traces.
0bfb7d06 531 *
0316808c
FC
532 * @param nbEvents The number of events
533 */
534 protected synchronized void setNbEvents(final long nbEvents) {
535 fNbEvents = (nbEvents > 0) ? nbEvents : 0;
536 }
537
20658947
FC
538 /**
539 * Update the trace events time range
0bfb7d06 540 *
20658947 541 * @param range the new time range
3bd46eef 542 * @since 2.0
20658947
FC
543 */
544 protected void setTimeRange(final TmfTimeRange range) {
4593bd5b
AM
545 fStartTime = range.getStartTime();
546 fEndTime = range.getEndTime();
20658947
FC
547 }
548
549 /**
550 * Update the trace chronologically first event timestamp
0bfb7d06 551 *
20658947 552 * @param startTime the new first event timestamp
3bd46eef 553 * @since 2.0
20658947
FC
554 */
555 protected void setStartTime(final ITmfTimestamp startTime) {
4593bd5b 556 fStartTime = startTime;
20658947
FC
557 }
558
559 /**
560 * Update the trace chronologically last event timestamp
0bfb7d06 561 *
20658947 562 * @param endTime the new last event timestamp
3bd46eef 563 * @since 2.0
20658947
FC
564 */
565 protected void setEndTime(final ITmfTimestamp endTime) {
4593bd5b 566 fEndTime = endTime;
20658947
FC
567 }
568
569 /**
0316808c 570 * Set the polling interval for live traces (default = 0 = no streaming).
0bfb7d06 571 *
20658947
FC
572 * @param interval the new trace streaming interval
573 */
574 protected void setStreamingInterval(final long interval) {
1703b536 575 fStreamingInterval = (interval > 0) ? interval : 0;
146a887c
FC
576 }
577
0316808c
FC
578 /**
579 * Set the trace parser. Must be done at initialization time.
0bfb7d06 580 *
0316808c
FC
581 * @param parser the new trace parser
582 */
6256d8ad 583 protected void setParser(final ITmfEventParser parser) {
0316808c
FC
584 fParser = parser;
585 }
586
09e86496 587 // ------------------------------------------------------------------------
7e6347b0 588 // ITmfTrace - SeekEvent operations (returning a trace context)
09e86496
FC
589 // ------------------------------------------------------------------------
590
1b70b6dc 591 @Override
7e6347b0 592 public synchronized ITmfContext seekEvent(final long rank) {
09e86496 593
7e6347b0 594 // A rank <= 0 indicates to seek the first event
2352aed9 595 if (rank <= 0) {
1e1bef82 596 ITmfContext context = seekEvent((ITmfLocation) null);
2352aed9
FC
597 context.setRank(0);
598 return context;
599 }
09e86496 600
09e86496 601 // Position the trace at the checkpoint
7e6347b0 602 final ITmfContext context = fIndexer.seekIndex(rank);
09e86496
FC
603
604 // And locate the requested event context
7e6347b0
FC
605 long pos = context.getRank();
606 if (pos < rank) {
c32744d6 607 ITmfEvent event = getNext(context);
0bfb7d06 608 while ((event != null) && (++pos < rank)) {
c32744d6 609 event = getNext(context);
7e6347b0 610 }
09e86496
FC
611 }
612 return context;
1b70b6dc
PT
613 }
614
3bd46eef
AM
615 /**
616 * @since 2.0
09e86496
FC
617 */
618 @Override
7e6347b0 619 public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) {
09e86496 620
7e6347b0 621 // A null timestamp indicates to seek the first event
2352aed9 622 if (timestamp == null) {
1e1bef82 623 ITmfContext context = seekEvent((ITmfLocation) null);
2352aed9
FC
624 context.setRank(0);
625 return context;
626 }
09e86496 627
1703b536 628 // Position the trace at the checkpoint
408e65d2 629 ITmfContext context = fIndexer.seekIndex(timestamp);
09e86496
FC
630
631 // And locate the requested event context
ea271da6
PT
632 ITmfLocation previousLocation = context.getLocation();
633 long previousRank = context.getRank();
634 ITmfEvent event = getNext(context);
7e6347b0 635 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
ea271da6
PT
636 previousLocation = context.getLocation();
637 previousRank = context.getRank();
638 event = getNext(context);
09e86496 639 }
0316808c
FC
640 if (event == null) {
641 context.setLocation(null);
642 context.setRank(ITmfContext.UNKNOWN_RANK);
ea271da6
PT
643 } else {
644 context.dispose();
645 context = seekEvent(previousLocation);
646 context.setRank(previousRank);
0316808c 647 }
09e86496
FC
648 return context;
649 }
0283f7ff 650
09e86496
FC
651 // ------------------------------------------------------------------------
652 // ITmfTrace - Read operations (returning an actual event)
653 // ------------------------------------------------------------------------
654
d4011df2 655 @Override
6256d8ad 656 public synchronized ITmfEvent getNext(final ITmfContext context) {
09e86496 657 // parseEvent() does not update the context
6256d8ad 658 final ITmfEvent event = fParser.parseEvent(context);
09e86496 659 if (event != null) {
d337369a 660 updateAttributes(context, event.getTimestamp());
09e86496
FC
661 context.setLocation(getCurrentLocation());
662 context.increaseRank();
663 processEvent(event);
664 }
665 return event;
666 }
667
668 /**
d337369a 669 * Hook for special event processing by the concrete class
7e6347b0 670 * (called by TmfTrace.getEvent())
0bfb7d06 671 *
d337369a 672 * @param event the event
09e86496
FC
673 */
674 protected void processEvent(final ITmfEvent event) {
d337369a 675 // Do nothing
09e86496
FC
676 }
677
d337369a
FC
678 /**
679 * Update the trace attributes
0bfb7d06 680 *
d337369a 681 * @param context the current trace context
2848c377 682 * @param timestamp the corresponding timestamp
3bd46eef 683 * @since 2.0
d337369a
FC
684 */
685 protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) {
0bfb7d06 686 if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) {
4593bd5b 687 fStartTime = timestamp;
09e86496 688 }
0bfb7d06 689 if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) {
4593bd5b 690 fEndTime = timestamp;
09e86496
FC
691 }
692 if (context.hasValidRank()) {
d337369a 693 long rank = context.getRank();
09e86496
FC
694 if (fNbEvents <= rank) {
695 fNbEvents = rank + 1;
696 }
200789b3
AM
697 if (fIndexer != null) {
698 fIndexer.updateIndex(context, timestamp);
699 }
09e86496 700 }
abfad0aa
FC
701 }
702
3791b5df 703 // ------------------------------------------------------------------------
d337369a 704 // TmfDataProvider
3791b5df
FC
705 // ------------------------------------------------------------------------
706
77c4a6df
AM
707 /**
708 * @since 2.0
d337369a 709 */
3791b5df 710 @Override
fd3f1eff 711 public synchronized ITmfContext armRequest(final ITmfEventRequest request) {
faa38350
PT
712 if (executorIsShutdown()) {
713 return null;
714 }
fd3f1eff
AM
715 if (!TmfTimestamp.BIG_BANG.equals(request.getRange().getStartTime())
716 && (request.getIndex() == 0)) {
717 final ITmfContext context = seekEvent(request.getRange().getStartTime());
718 request.setStartIndex((int) context.getRank());
8584dc20 719 return context;
8584dc20 720
5419a136
AM
721 }
722 return seekEvent(request.getIndex());
3791b5df
FC
723 }
724
faa38350
PT
725 // ------------------------------------------------------------------------
726 // Signal handlers
727 // ------------------------------------------------------------------------
728
729 /**
730 * Handler for the Trace Opened signal
731 *
732 * @param signal
733 * The incoming signal
734 * @since 2.0
735 */
736 @TmfSignalHandler
737 public void traceOpened(TmfTraceOpenedSignal signal) {
b9a5bf8f
AM
738 boolean signalIsForUs = false;
739 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
740 if (trace == this) {
741 signalIsForUs = true;
fe0c44c4 742 break;
faa38350
PT
743 }
744 }
faa38350 745
b9a5bf8f 746 if (!signalIsForUs) {
fe0c44c4
AM
747 return;
748 }
749
750 /*
b9a5bf8f 751 * The signal is either for this trace, or for an experiment containing
fe0c44c4
AM
752 * this trace.
753 */
b22a582a
AM
754 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, null, null);
755 status.add(buildStatistics());
756 status.add(buildStateSystem());
c068a752 757 status.add(executeAnalysis());
b22a582a
AM
758 if (!status.isOK()) {
759 Activator.log(status);
fe0c44c4
AM
760 }
761
762 /* Refresh the project, so it can pick up new files that got created. */
763 try {
764 if (fResource != null) {
765 fResource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
faa38350 766 }
fe0c44c4
AM
767 } catch (CoreException e) {
768 e.printStackTrace();
faa38350 769 }
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
798 /**
799 * Signal handler for the TmfTraceRangeUpdatedSignal signal
800 *
801 * @param signal The incoming signal
802 * @since 2.0
803 */
804 @TmfSignalHandler
805 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
806 if (signal.getTrace() == this) {
807 getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
808 }
809 }
810
032ecd45
MAL
811 /**
812 * Signal handler for the TmfTraceUpdatedSignal signal
813 *
814 * @param signal The incoming signal
815 * @since 2.0
816 */
817 @TmfSignalHandler
818 public void traceUpdated(final TmfTraceUpdatedSignal signal) {
819 if (signal.getSource() == getIndexer()) {
820 fNbEvents = signal.getNbEvents();
821 fStartTime = signal.getRange().getStartTime();
822 fEndTime = signal.getRange().getEndTime();
823 }
824 }
825
e73a4ba5
GB
826 /**
827 * Returns the file resource used to store synchronization formula. The file
828 * may not exist.
829 *
830 * @return the synchronization file
831 */
832 private File getSyncFormulaFile() {
833 File file = null;
834 if (fResource instanceof IFolder) {
835 try {
836 String supplDirectory;
837
838 supplDirectory = fResource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
839
840 file = new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE);
841
842 } catch (CoreException e) {
843
844 }
845 }
846 return file;
847 }
848
849 // ------------------------------------------------------------------------
850 // Timestamp transformation functions
851 // ------------------------------------------------------------------------
852
853 /**
854 * @since 3.0
855 */
856 @Override
857 public ITmfTimestampTransform getTimestampTransform() {
858 if (fTsTransform == null) {
859 /* Check if a formula is stored somewhere in the resources */
860 File sync_file = getSyncFormulaFile();
861 if (sync_file != null && sync_file.exists()) {
862
863 try {
864 FileInputStream fis = new FileInputStream(sync_file);
865 ObjectInputStream ois = new ObjectInputStream(fis);
866 fTsTransform = (ITmfTimestampTransform) ois.readObject();
867
868 ois.close();
869 fis.close();
870 } catch (ClassNotFoundException e1) {
871 fTsTransform = TmfTimestampTransform.IDENTITY;
872 } catch (FileNotFoundException e1) {
873 fTsTransform = TmfTimestampTransform.IDENTITY;
874 } catch (IOException e1) {
875 fTsTransform = TmfTimestampTransform.IDENTITY;
876 }
877 } else {
878 fTsTransform = TmfTimestampTransform.IDENTITY;
879 }
880 }
881 return fTsTransform;
882 }
883
884 /**
885 * @since 3.0
886 */
887 @Override
888 public void setTimestampTransform(final ITmfTimestampTransform tt) {
889 fTsTransform = tt;
890
891 /* Save the timestamp transform to a file */
892 File sync_file = getSyncFormulaFile();
893 if (sync_file != null) {
894 if (sync_file.exists()) {
895 sync_file.delete();
896 }
897 FileOutputStream fos;
898 ObjectOutputStream oos;
899
900 /* Save the header of the file */
901 try {
902 fos = new FileOutputStream(sync_file, false);
903 oos = new ObjectOutputStream(fos);
904
905 oos.writeObject(fTsTransform);
906 oos.close();
907 fos.close();
908 } catch (IOException e1) {
909 Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$
910 }
911 }
912 }
913
914 /**
915 * @since 3.0
916 */
917 @Override
918 public ITmfTimestamp createTimestamp(long ts) {
919 return new TmfTimestamp(getTimestampTransform().transform(ts));
920 }
921
3791b5df 922 // ------------------------------------------------------------------------
09e86496 923 // toString
3791b5df
FC
924 // ------------------------------------------------------------------------
925
12c155f5 926 @Override
09e86496 927 @SuppressWarnings("nls")
5419a136 928 public synchronized String toString() {
20658947
FC
929 return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize
930 + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime
931 + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
12c155f5
FC
932 }
933
8c8bf09f 934}
This page took 0.110896 seconds and 5 git commands to generate.