Fix for bug 373718: Updates for editor input and bookmarks file
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / experiment / TmfExperiment.java
CommitLineData
8c8bf09f
ASL
1/*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
3 *
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
8 *
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
12
6c13869b 13package org.eclipse.linuxtools.tmf.core.experiment;
8c8bf09f 14
9f584e4c 15import java.util.Collections;
8c8bf09f
ASL
16import java.util.Vector;
17
a1091415 18import org.eclipse.core.resources.IFile;
12c155f5 19import org.eclipse.core.resources.IProject;
828e5592 20import org.eclipse.core.resources.IResource;
05bd3318
FC
21import org.eclipse.core.runtime.IProgressMonitor;
22import org.eclipse.core.runtime.IStatus;
23import org.eclipse.core.runtime.Status;
24import org.eclipse.core.runtime.jobs.Job;
6c13869b 25import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
72f1e62a 26import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
4df4581d 27import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b
FC
28import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
29import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
30import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
31import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
32import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
33import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
1b70b6dc 34import org.eclipse.linuxtools.tmf.core.signal.TmfEndSynchSignal;
6c13869b
FC
35import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal;
36import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
37import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
38import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentUpdatedSignal;
39import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
40import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
41import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
42import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
43import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
44import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
45import org.eclipse.linuxtools.tmf.core.trace.TmfCheckpoint;
46import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
8c8bf09f
ASL
47
48/**
49 * <b><u>TmfExperiment</u></b>
50 * <p>
12c155f5 51 * TmfExperiment presents a time-ordered, unified view of a set of TmfTraces that are part of a tracing experiment.
8c8bf09f
ASL
52 * <p>
53 */
72f1e62a 54public class TmfExperiment<T extends ITmfEvent> extends TmfEventProvider<T> implements ITmfTrace<T> {
8c8bf09f
ASL
55
56 // ------------------------------------------------------------------------
57 // Attributes
58 // ------------------------------------------------------------------------
59
a79913eb 60 // The currently selected experiment
82e04272 61 protected static TmfExperiment<?> fCurrentExperiment = null;
e31e01e8 62
a79913eb 63 // The set of traces that constitute the experiment
12c155f5 64 protected ITmfTrace<T>[] fTraces;
8c8bf09f
ASL
65
66 // The total number of events
82e04272 67 protected long fNbEvents;
8c8bf09f
ASL
68
69 // The experiment time range
82e04272 70 protected TmfTimeRange fTimeRange;
8c8bf09f 71
9b635e61 72 // The experiment reference timestamp (default: Zero)
4df4581d 73 protected ITmfTimestamp fEpoch;
8c8bf09f 74
a79913eb 75 // The experiment index
82e04272 76 protected Vector<TmfCheckpoint> fCheckpoints = new Vector<TmfCheckpoint>();
9f584e4c 77
f6b14ce2
FC
78 // The current experiment context
79 protected TmfExperimentContext fExperimentContext;
a79913eb 80
828e5592
PT
81 // Flag to initialize only once
82 private boolean fInitialized = false;
83
a1091415
PT
84 // The experiment bookmarks file
85 private IFile fBookmarksFile;
86
87 // The properties resource
828e5592
PT
88 private IResource fResource;
89
8c8bf09f
ASL
90 // ------------------------------------------------------------------------
91 // Constructors
92 // ------------------------------------------------------------------------
93
12c155f5
FC
94 @Override
95 public boolean validate(IProject project, String path) {
96 return true;
97 }
98
99 @Override
0710697b 100 public void initTrace(String name, String path, Class<T> eventType) {
12c155f5
FC
101 }
102
103 @Override
0710697b 104 public void initTrace(String name, String path, Class<T> eventType, boolean indexTrace) {
09d11238
PT
105 if (indexTrace) {
106 initializeStreamingMonitor();
107 }
12c155f5
FC
108 }
109
110 @Override
0710697b 111 public void initTrace(String name, String path, Class<T> eventType, int cacheSize) {
12c155f5
FC
112 }
113
114 @Override
0710697b 115 public void initTrace(String name, String path, Class<T> eventType, int cacheSize, boolean indexTrace) {
09d11238
PT
116 if (indexTrace) {
117 initializeStreamingMonitor();
118 }
96c6806f
PT
119 }
120
8c8bf09f
ASL
121 /**
122 * @param type
123 * @param id
124 * @param traces
125 * @param epoch
126 * @param indexPageSize
127 */
4df4581d 128 public TmfExperiment(Class<T> type, String id, ITmfTrace<T>[] traces, ITmfTimestamp epoch, int indexPageSize) {
a4115405 129 this(type, id, traces, TmfTimestamp.ZERO, indexPageSize, false);
a79913eb 130 }
cb866e08 131
4df4581d 132 public TmfExperiment(Class<T> type, String id, ITmfTrace<T>[] traces, ITmfTimestamp epoch, int indexPageSize, boolean preIndexExperiment) {
a79913eb 133 super(id, type);
8c8bf09f 134
a79913eb
FC
135 fTraces = traces;
136 fEpoch = epoch;
137 fIndexPageSize = indexPageSize;
a4115405 138 fTimeRange = TmfTimeRange.NULL_RANGE;
8c8bf09f 139
a79913eb
FC
140 if (preIndexExperiment) {
141 indexExperiment(true);
142 updateTimeRange();
143 }
cb866e08 144
a79913eb 145 }
8c8bf09f 146
82e04272
FC
147 protected TmfExperiment(String id, Class<T> type) {
148 super(id, type);
a79913eb 149 }
82e04272 150
8c8bf09f
ASL
151 /**
152 * @param type
153 * @param id
154 * @param traces
155 */
12c155f5 156 public TmfExperiment(Class<T> type, String id, ITmfTrace<T>[] traces) {
a4115405 157 this(type, id, traces, TmfTimestamp.ZERO, DEFAULT_INDEX_PAGE_SIZE);
8c8bf09f
ASL
158 }
159
160 /**
161 * @param type
162 * @param id
163 * @param traces
164 * @param indexPageSize
165 */
12c155f5 166 public TmfExperiment(Class<T> type, String id, ITmfTrace<T>[] traces, int indexPageSize) {
a4115405 167 this(type, id, traces, TmfTimestamp.ZERO, indexPageSize);
8c8bf09f 168 }
a79913eb 169
f6b14ce2
FC
170 /**
171 * Copy constructor
a79913eb 172 *
f6b14ce2
FC
173 * @param other
174 */
12c155f5 175 @SuppressWarnings("unchecked")
ce785d7d 176 public TmfExperiment(TmfExperiment<T> other) {
a79913eb
FC
177 super(other.getName() + "(clone)", other.fType); //$NON-NLS-1$
178
179 fEpoch = other.fEpoch;
180 fIndexPageSize = other.fIndexPageSize;
181
182 fTraces = new ITmfTrace[other.fTraces.length];
183 for (int trace = 0; trace < other.fTraces.length; trace++) {
12c155f5 184 fTraces[trace] = other.fTraces[trace].copy();
a79913eb
FC
185 }
186
187 fNbEvents = other.fNbEvents;
188 fTimeRange = other.fTimeRange;
189 }
190
191 @Override
12c155f5 192 public TmfExperiment<T> copy() {
a79913eb
FC
193 TmfExperiment<T> experiment = new TmfExperiment<T>(this);
194 TmfSignalManager.deregister(experiment);
195 return experiment;
196 }
197
8c8bf09f 198 /**
ff4ed569 199 * Clears the experiment
8c8bf09f
ASL
200 */
201 @Override
12c155f5 202 @SuppressWarnings("rawtypes")
a79913eb
FC
203 public synchronized void dispose() {
204
205 TmfExperimentDisposedSignal<T> signal = new TmfExperimentDisposedSignal<T>(this, this);
206 broadcast(signal);
09d11238
PT
207 if (fCurrentExperiment == this) {
208 fCurrentExperiment = null;
209 }
a79913eb
FC
210
211 if (fTraces != null) {
212 for (ITmfTrace trace : fTraces) {
213 trace.dispose();
214 }
215 fTraces = null;
216 }
217 if (fCheckpoints != null) {
218 fCheckpoints.clear();
219 }
2fb2eb37 220 super.dispose();
8c8bf09f
ASL
221 }
222
9f584e4c 223 // ------------------------------------------------------------------------
cbd4ad82 224 // ITmfTrace
9f584e4c
FC
225 // ------------------------------------------------------------------------
226
a79913eb
FC
227 @Override
228 public long getNbEvents() {
229 return fNbEvents;
230 }
9f584e4c 231
d4011df2 232 @Override
a79913eb 233 public int getCacheSize() {
54d55ced
FC
234 return fIndexPageSize;
235 }
236
a79913eb
FC
237 @Override
238 public TmfTimeRange getTimeRange() {
239 return fTimeRange;
240 }
9f584e4c 241
a79913eb 242 @Override
4df4581d 243 public ITmfTimestamp getStartTime() {
a79913eb
FC
244 return fTimeRange.getStartTime();
245 }
9f584e4c 246
a79913eb 247 @Override
4df4581d 248 public ITmfTimestamp getEndTime() {
a79913eb
FC
249 return fTimeRange.getEndTime();
250 }
9f584e4c 251
54d55ced 252 public Vector<TmfCheckpoint> getCheckpoints() {
a79913eb 253 return fCheckpoints;
54d55ced
FC
254 }
255
8c8bf09f 256 // ------------------------------------------------------------------------
e31e01e8 257 // Accessors
8c8bf09f
ASL
258 // ------------------------------------------------------------------------
259
c1c69938 260 public static void setCurrentExperiment(TmfExperiment<?> experiment) {
09d11238
PT
261 if (fCurrentExperiment != null && fCurrentExperiment != experiment) {
262 fCurrentExperiment.dispose();
263 }
a79913eb 264 fCurrentExperiment = experiment;
f6b14ce2
FC
265 }
266
e31e01e8 267 public static TmfExperiment<?> getCurrentExperiment() {
a79913eb 268 return fCurrentExperiment;
8c8bf09f
ASL
269 }
270
4df4581d 271 public ITmfTimestamp getEpoch() {
a79913eb 272 return fEpoch;
8c8bf09f
ASL
273 }
274
12c155f5 275 public ITmfTrace<T>[] getTraces() {
a79913eb 276 return fTraces;
8c8bf09f
ASL
277 }
278
279 /**
12c155f5
FC
280 * Returns the rank of the first event with the requested timestamp. If none, returns the index of the next event
281 * (if any).
a79913eb 282 *
85fb0e54 283 * @param timestamp
8c8bf09f
ASL
284 * @return
285 */
d4011df2 286 @Override
4df4581d 287 public long getRank(ITmfTimestamp timestamp) {
a79913eb
FC
288 TmfExperimentContext context = seekEvent(timestamp);
289 return context.getRank();
8c8bf09f
ASL
290 }
291
292 /**
12c155f5 293 * Returns the timestamp of the event at the requested index. If none, returns null.
a79913eb 294 *
8c8bf09f
ASL
295 * @param index
296 * @return
297 */
4df4581d 298 public ITmfTimestamp getTimestamp(int index) {
a79913eb 299 TmfExperimentContext context = seekEvent(index);
72f1e62a 300 ITmfEvent event = getNextEvent(context);
a79913eb 301 return (event != null) ? event.getTimestamp() : null;
8c8bf09f
ASL
302 }
303
304 // ------------------------------------------------------------------------
305 // Operators
306 // ------------------------------------------------------------------------
307
8c8bf09f
ASL
308 /**
309 * Update the global time range
310 */
a79913eb 311 protected void updateTimeRange() {
a4115405
FC
312 ITmfTimestamp startTime = fTimeRange != TmfTimeRange.NULL_RANGE ? fTimeRange.getStartTime() : TmfTimestamp.BIG_CRUNCH;
313 ITmfTimestamp endTime = fTimeRange != TmfTimeRange.NULL_RANGE ? fTimeRange.getEndTime() : TmfTimestamp.BIG_BANG;
a79913eb 314
12c155f5 315 for (ITmfTrace<T> trace : fTraces) {
4df4581d 316 ITmfTimestamp traceStartTime = trace.getStartTime();
a79913eb
FC
317 if (traceStartTime.compareTo(startTime, true) < 0)
318 startTime = traceStartTime;
4df4581d 319 ITmfTimestamp traceEndTime = trace.getEndTime();
a79913eb
FC
320 if (traceEndTime.compareTo(endTime, true) > 0)
321 endTime = traceEndTime;
322 }
323 fTimeRange = new TmfTimeRange(startTime, endTime);
8c8bf09f
ASL
324 }
325
326 // ------------------------------------------------------------------------
327 // TmfProvider
328 // ------------------------------------------------------------------------
a79913eb
FC
329 @Override
330 public ITmfContext armRequest(ITmfDataRequest<T> request) {
9b635e61 331// Tracer.trace("Ctx: Arming request - start");
4df4581d 332 ITmfTimestamp timestamp = (request instanceof ITmfEventRequest<?>) ? ((ITmfEventRequest<T>) request).getRange().getStartTime()
12c155f5 333 : null;
a79913eb 334
a4115405 335 if (TmfTimestamp.BIG_BANG.equals(timestamp) || request.getIndex() > 0) {
a79913eb
FC
336 timestamp = null; // use request index
337 }
338
339 TmfExperimentContext context = null;
340 if (timestamp != null) {
341 // seek by timestamp
342 context = seekEvent(timestamp);
343 ((ITmfEventRequest<T>) request).setStartIndex((int) context.getRank());
344 } else {
345 // Seek by rank
346 if ((fExperimentContext != null) && fExperimentContext.getRank() == request.getIndex()) {
347 // We are already at the right context -> no need to seek
348 context = fExperimentContext;
349 } else {
350 context = seekEvent(request.getIndex());
351 }
352 }
9b635e61 353// Tracer.trace("Ctx: Arming request - done");
a79913eb
FC
354 return context;
355 }
356
357 @SuppressWarnings("unchecked")
358 @Override
359 public T getNext(ITmfContext context) {
360 if (context instanceof TmfExperimentContext) {
361 return (T) getNextEvent((TmfExperimentContext) context);
362 }
363 return null;
364 }
365
366 // ------------------------------------------------------------------------
9f584e4c
FC
367 // ITmfTrace trace positioning
368 // ------------------------------------------------------------------------
369
a79913eb
FC
370 // Returns a brand new context based on the location provided
371 // and initializes the event queues
372 @Override
373 public synchronized TmfExperimentContext seekLocation(ITmfLocation<?> location) {
374 // Validate the location
375 if (location != null && !(location instanceof TmfExperimentLocation)) {
376 return null; // Throw an exception?
377 }
8f50c396 378
a79913eb
FC
379 if (fTraces == null) { // experiment has been disposed
380 return null;
381 }
8f50c396 382
a79913eb 383 // Instantiate the location
12c155f5
FC
384 TmfExperimentLocation expLocation = (location == null) ? new TmfExperimentLocation(new TmfLocationArray(
385 new ITmfLocation<?>[fTraces.length]), new long[fTraces.length]) : (TmfExperimentLocation) location.clone();
8f50c396 386
a79913eb
FC
387 // Create and populate the context's traces contexts
388 TmfExperimentContext context = new TmfExperimentContext(fTraces, new TmfContext[fTraces.length]);
9b635e61
FC
389// Tracer.trace("Ctx: SeekLocation - start");
390
a79913eb
FC
391 long rank = 0;
392 for (int i = 0; i < fTraces.length; i++) {
393 // Get the relevant trace attributes
394 ITmfLocation<?> traceLocation = expLocation.getLocation().locations[i];
395 long traceRank = expLocation.getRanks()[i];
8f50c396 396
a79913eb
FC
397 // Set the corresponding sub-context
398 context.getContexts()[i] = fTraces[i].seekLocation(traceLocation);
399 context.getContexts()[i].setRank(traceRank);
400 rank += traceRank;
8f50c396 401
a79913eb 402 // Set the trace location and read the corresponding event
478e04a4 403 expLocation.getLocation().locations[i] = context.getContexts()[i].getLocation().clone();
a79913eb
FC
404 context.getEvents()[i] = fTraces[i].getNextEvent(context.getContexts()[i]);
405 }
8f50c396 406
9b635e61
FC
407// Tracer.trace("Ctx: SeekLocation - done");
408
a79913eb
FC
409 // Finalize context
410 context.setLocation(expLocation);
411 context.setLastTrace(TmfExperimentContext.NO_TRACE);
412 context.setRank(rank);
9b635e61 413
a79913eb 414 fExperimentContext = context;
9b635e61 415
a79913eb
FC
416 return context;
417 }
9f584e4c 418
a79913eb
FC
419 /*
420 * (non-Javadoc)
421 *
12c155f5 422 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools .tmf.event.TmfTimestamp)
a79913eb
FC
423 */
424 @Override
4df4581d 425 public synchronized TmfExperimentContext seekEvent(ITmfTimestamp timestamp) {
9b635e61
FC
426
427// Tracer.trace("Ctx: seekEvent(TS) - start");
8c8bf09f 428
a79913eb 429 if (timestamp == null) {
a4115405 430 timestamp = TmfTimestamp.BIG_BANG;
a79913eb 431 }
9f584e4c 432
a79913eb
FC
433 // First, find the right checkpoint
434 int index = Collections.binarySearch(fCheckpoints, new TmfCheckpoint(timestamp, null));
9f584e4c
FC
435
436 // In the very likely case that the checkpoint was not found, bsearch
437 // returns its negated would-be location (not an offset...). From that
438 // index, we can then position the stream and get the event.
439 if (index < 0) {
440 index = Math.max(0, -(index + 2));
441 }
442
443 // Position the experiment at the checkpoint
452ad365 444 ITmfLocation<?> location;
9f584e4c 445 synchronized (fCheckpoints) {
a79913eb
FC
446 if (fCheckpoints.size() > 0) {
447 if (index >= fCheckpoints.size()) {
448 index = fCheckpoints.size() - 1;
449 }
450 location = fCheckpoints.elementAt(index).getLocation();
451 } else {
452 location = null;
453 }
9f584e4c
FC
454 }
455
85fb0e54 456 TmfExperimentContext context = seekLocation(location);
cbd4ad82 457 context.setRank((long) index * fIndexPageSize);
9f584e4c 458
a79913eb 459 // And locate the event
72f1e62a 460 ITmfEvent event = parseEvent(context);
9f584e4c 461 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
a79913eb
FC
462 getNextEvent(context);
463 event = parseEvent(context);
9f584e4c
FC
464 }
465
f6b14ce2 466 if (event == null) {
a79913eb
FC
467 context.setLocation(null);
468 context.setRank(ITmfContext.UNKNOWN_RANK);
9b635e61 469 }
f6b14ce2
FC
470
471 return context;
a79913eb 472 }
8c8bf09f 473
a79913eb
FC
474 /*
475 * (non-Javadoc)
476 *
477 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(long)
478 */
479 @Override
480 public synchronized TmfExperimentContext seekEvent(long rank) {
9b635e61
FC
481
482// Tracer.trace("Ctx: seekEvent(rank) - start");
9f584e4c 483
54d55ced
FC
484 // Position the stream at the previous checkpoint
485 int index = (int) rank / fIndexPageSize;
486 ITmfLocation<?> location;
487 synchronized (fCheckpoints) {
a79913eb
FC
488 if (fCheckpoints.size() == 0) {
489 location = null;
490 } else {
491 if (index >= fCheckpoints.size()) {
492 index = fCheckpoints.size() - 1;
493 }
494 location = fCheckpoints.elementAt(index).getLocation();
495 }
54d55ced 496 }
e31e01e8 497
54d55ced 498 TmfExperimentContext context = seekLocation(location);
9b635e61 499 context.setRank((long) index * fIndexPageSize);
54d55ced 500
a79913eb 501 // And locate the event
72f1e62a 502 ITmfEvent event = parseEvent(context);
9b635e61 503 long pos = context.getRank();
fa867360 504 while (event != null && pos++ < rank) {
a79913eb
FC
505 getNextEvent(context);
506 event = parseEvent(context);
54d55ced 507 }
9f584e4c 508
f6b14ce2 509 if (event == null) {
a79913eb
FC
510 context.setLocation(null);
511 context.setRank(ITmfContext.UNKNOWN_RANK);
9b635e61 512 }
f6b14ce2 513
a79913eb
FC
514 return context;
515 }
8c8bf09f 516
c76c54bb
FC
517 @Override
518 public TmfContext seekLocation(double ratio) {
519 TmfContext context = seekEvent((long) (ratio * getNbEvents()));
520 return context;
521 }
522
a79913eb 523 @Override
c76c54bb 524 public double getLocationRatio(ITmfLocation<?> location) {
a79913eb
FC
525 if (location instanceof TmfExperimentLocation) {
526 return (double) seekLocation(location).getRank() / getNbEvents();
527 }
c76c54bb
FC
528 return 0;
529 }
530
a79913eb
FC
531 @Override
532 public ITmfLocation<?> getCurrentLocation() {
533 if (fExperimentContext != null) {
534 return fExperimentContext.getLocation();
535 }
536 return null;
537 }
c76c54bb 538
a79913eb 539 /**
12c155f5 540 * Scan the next events from all traces and return the next one in chronological order.
a79913eb
FC
541 *
542 * @param context
543 * @return
544 */
9b635e61
FC
545
546// private void dumpContext(TmfExperimentContext context, boolean isBefore) {
547
548// TmfContext context0 = context.getContexts()[0];
549// TmfEvent event0 = context.getEvents()[0];
550// TmfExperimentLocation location0 = (TmfExperimentLocation) context.getLocation();
551// long rank0 = context.getRank();
552// int trace = context.getLastTrace();
553//
554// StringBuffer result = new StringBuffer("Ctx: " + (isBefore ? "B " : "A "));
555//
556// result.append("[Ctx: fLoc= " + context0.getLocation().toString() + ", fRnk= " + context0.getRank() + "] ");
557// result.append("[Evt: " + event0.getTimestamp().toString() + "] ");
558// result.append("[Loc: fLoc= " + location0.getLocation()[0].toString() + ", fRnk= " + location0.getRanks()[0] + "] ");
559// result.append("[Rnk: " + rank0 + "], [Trc: " + trace + "]");
560// Tracer.trace(result.toString());
561// }
54d55ced 562
a79913eb 563 @Override
a1440d1f 564 public synchronized ITmfEvent getNextEvent(ITmfContext context) {
a79913eb
FC
565
566 // Validate the context
567 if (!(context instanceof TmfExperimentContext)) {
568 return null; // Throw an exception?
569 }
54d55ced 570
a79913eb 571 if (!context.equals(fExperimentContext)) {
9b635e61 572// Tracer.trace("Ctx: Restoring context");
a79913eb
FC
573 fExperimentContext = seekLocation(context.getLocation());
574 }
575
576 TmfExperimentContext expContext = (TmfExperimentContext) context;
8f50c396 577
9b635e61
FC
578// dumpContext(expContext, true);
579
a79913eb
FC
580 // If an event was consumed previously, get the next one from that trace
581 int lastTrace = expContext.getLastTrace();
582 if (lastTrace != TmfExperimentContext.NO_TRACE) {
583 TmfContext traceContext = expContext.getContexts()[lastTrace];
584 expContext.getEvents()[lastTrace] = expContext.getTraces()[lastTrace].getNextEvent(traceContext);
585 expContext.setLastTrace(TmfExperimentContext.NO_TRACE);
586 }
8f50c396 587
a79913eb 588 // Scan the candidate events and identify the "next" trace to read from
72f1e62a 589 ITmfEvent eventArray[] = expContext.getEvents();
1324801a
FC
590 if (eventArray == null) {
591 return null;
592 }
a79913eb 593 int trace = TmfExperimentContext.NO_TRACE;
a4115405 594 ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH;
1324801a
FC
595 if (eventArray.length == 1) {
596 if (eventArray[0] != null) {
597 timestamp = eventArray[0].getTimestamp();
598 trace = 0;
599 }
600 } else {
601 for (int i = 0; i < eventArray.length; i++) {
72f1e62a 602 ITmfEvent event = eventArray[i];
1324801a 603 if (event != null && event.getTimestamp() != null) {
4df4581d 604 ITmfTimestamp otherTS = event.getTimestamp();
1324801a
FC
605 if (otherTS.compareTo(timestamp, true) < 0) {
606 trace = i;
607 timestamp = otherTS;
608 }
609 }
610 }
a79913eb 611 }
1324801a 612 // Update the experiment context and set the "next" event
72f1e62a 613 ITmfEvent event = null;
a79913eb
FC
614 if (trace != TmfExperimentContext.NO_TRACE) {
615 updateIndex(expContext, timestamp);
82e04272 616
a79913eb
FC
617 TmfContext traceContext = expContext.getContexts()[trace];
618 TmfExperimentLocation expLocation = (TmfExperimentLocation) expContext.getLocation();
64fe8e8a 619// expLocation.getLocation()[trace] = traceContext.getLocation().clone();
478e04a4 620 expLocation.getLocation().locations[trace] = traceContext.getLocation().clone();
82e04272
FC
621
622// updateIndex(expContext, timestamp);
623
a79913eb
FC
624 expLocation.getRanks()[trace] = traceContext.getRank();
625 expContext.setLastTrace(trace);
626 expContext.updateRank(1);
627 event = expContext.getEvents()[trace];
628 fExperimentContext = expContext;
629 }
8f50c396 630
9b635e61
FC
631// if (event != null) {
632// Tracer.trace("Exp: " + (expContext.getRank() - 1) + ": " + event.getTimestamp().toString());
633// dumpContext(expContext, false);
634// Tracer.trace("Ctx: Event returned= " + event.getTimestamp().toString());
635// }
636
a79913eb
FC
637 return event;
638 }
639
4df4581d 640 public synchronized void updateIndex(ITmfContext context, ITmfTimestamp timestamp) {
a79913eb
FC
641 // Build the index as we go along
642 long rank = context.getRank();
643 if (context.isValidRank() && (rank % fIndexPageSize) == 0) {
644 // Determine the table position
645 long position = rank / fIndexPageSize;
646 // Add new entry at proper location (if empty)
647 if (fCheckpoints.size() == position) {
648 ITmfLocation<?> location = context.getLocation().clone();
649 fCheckpoints.add(new TmfCheckpoint(timestamp.clone(), location));
12c155f5
FC
650// System.out.println(this + "[" + (fCheckpoints.size() - 1) + "] " + timestamp + ", "
651// + location.toString());
a79913eb
FC
652 }
653 }
654 }
655
656 /*
657 * (non-Javadoc)
658 *
12c155f5 659 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#parseEvent(org.eclipse.linuxtools .tmf.trace.TmfContext)
a79913eb
FC
660 */
661 @Override
a1440d1f 662 public ITmfEvent parseEvent(ITmfContext context) {
a79913eb
FC
663
664 // Validate the context
665 if (!(context instanceof TmfExperimentContext)) {
666 return null; // Throw an exception?
667 }
668
669 if (!context.equals(fExperimentContext)) {
9b635e61 670// Tracer.trace("Ctx: Restoring context");
a79913eb
FC
671 seekLocation(context.getLocation());
672 }
673
674 TmfExperimentContext expContext = (TmfExperimentContext) context;
675
676 // If an event was consumed previously, get the next one from that trace
677 int lastTrace = expContext.getLastTrace();
678 if (lastTrace != TmfExperimentContext.NO_TRACE) {
679 TmfContext traceContext = expContext.getContexts()[lastTrace];
680 expContext.getEvents()[lastTrace] = expContext.getTraces()[lastTrace].getNextEvent(traceContext);
681 expContext.setLastTrace(TmfExperimentContext.NO_TRACE);
682 fExperimentContext = (TmfExperimentContext) context;
683 }
684
685 // Scan the candidate events and identify the "next" trace to read from
686 int trace = TmfExperimentContext.NO_TRACE;
a4115405 687 ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH;
a79913eb 688 for (int i = 0; i < expContext.getTraces().length; i++) {
72f1e62a 689 ITmfEvent event = expContext.getEvents()[i];
a79913eb 690 if (event != null && event.getTimestamp() != null) {
4df4581d 691 ITmfTimestamp otherTS = event.getTimestamp();
a79913eb
FC
692 if (otherTS.compareTo(timestamp, true) < 0) {
693 trace = i;
694 timestamp = otherTS;
695 }
696 }
697 }
698
72f1e62a 699 ITmfEvent event = null;
a79913eb
FC
700 if (trace != TmfExperimentContext.NO_TRACE) {
701 event = expContext.getEvents()[trace];
702 }
703
704 return event;
705 }
706
707 /*
708 * (non-Javadoc)
709 *
710 * @see java.lang.Object#toString()
711 */
712 @Override
3b38ea61 713 @SuppressWarnings("nls")
a79913eb
FC
714 public String toString() {
715 return "[TmfExperiment (" + getName() + ")]";
716 }
8c8bf09f
ASL
717
718 // ------------------------------------------------------------------------
719 // Indexing
720 // ------------------------------------------------------------------------
721
1b70b6dc 722 private synchronized void initializeStreamingMonitor() {
828e5592
PT
723 if (fInitialized) {
724 return;
725 }
726 fInitialized = true;
727
1b70b6dc
PT
728 if (getStreamingInterval() == 0) {
729 TmfContext context = seekLocation(null);
72f1e62a 730 ITmfEvent event = getNext(context);
1b70b6dc
PT
731 if (event == null) {
732 return;
733 }
a4115405 734 TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp().clone(), TmfTimestamp.BIG_CRUNCH);
828e5592
PT
735 final TmfExperimentRangeUpdatedSignal signal = new TmfExperimentRangeUpdatedSignal(this, this, timeRange);
736
737 // Broadcast in separate thread to prevent deadlock
738 new Thread() {
739 @Override
740 public void run() {
741 broadcast(signal);
742 }
743 }.start();
1b70b6dc
PT
744 return;
745 }
746
747 final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
dfee01ae 748 ITmfTimestamp safeTimestamp = null;
1b70b6dc
PT
749 TmfTimeRange timeRange = null;
750
751 @Override
752 public void run() {
753 while (!fExecutor.isShutdown()) {
754 if (!isIndexingBusy()) {
a4115405
FC
755 ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH;
756 ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG;
1b70b6dc
PT
757 for (ITmfTrace<T> trace : fTraces) {
758 if (trace.getStartTime().compareTo(startTimestamp) < 0) {
759 startTimestamp = trace.getStartTime();
760 }
761 if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) {
762 endTimestamp = trace.getEndTime();
763 }
764 }
765 if (safeTimestamp != null && safeTimestamp.compareTo(getTimeRange().getEndTime(), false) > 0) {
766 timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
767 } else {
768 timeRange = null;
769 }
770 safeTimestamp = endTimestamp;
771 if (timeRange != null) {
772 TmfExperimentRangeUpdatedSignal signal =
773 new TmfExperimentRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange);
774 broadcast(signal);
775 }
776 }
777 try {
778 Thread.sleep(getStreamingInterval());
779 } catch (InterruptedException e) {
780 e.printStackTrace();
781 }
782 }
783 }
784 };
785 thread.start();
786 }
787
788 /* (non-Javadoc)
789 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
790 */
791 @Override
792 public long getStreamingInterval() {
793 long interval = 0;
794 for (ITmfTrace<T> trace : fTraces) {
795 interval = Math.max(interval, trace.getStreamingInterval());
796 }
797 return interval;
798 }
799
a79913eb 800 /*
12c155f5
FC
801 * The experiment holds the globally ordered events of its set of traces. It is expected to provide access to each
802 * individual event by index i.e. it must be possible to request the Nth event of the experiment.
a79913eb 803 *
12c155f5
FC
804 * The purpose of the index is to keep the information needed to rapidly restore the traces contexts at regular
805 * intervals (every INDEX_PAGE_SIZE event).
a79913eb 806 */
8c8bf09f 807
a79913eb
FC
808 // The index page size
809 private static final int DEFAULT_INDEX_PAGE_SIZE = 5000;
810 protected int fIndexPageSize;
811 protected boolean fIndexing = false;
a4115405 812 protected TmfTimeRange fIndexingPendingRange = TmfTimeRange.NULL_RANGE;
e31e01e8 813
1b70b6dc
PT
814 private Integer fEndSynchReference;
815
9b635e61
FC
816// private static BufferedWriter fEventLog = null;
817// private static BufferedWriter openLogFile(String filename) {
818// BufferedWriter outfile = null;
819// try {
820// outfile = new BufferedWriter(new FileWriter(filename));
821// } catch (IOException e) {
822// e.printStackTrace();
823// }
824// return outfile;
825// }
826
a79913eb
FC
827 protected boolean isIndexingBusy() {
828 synchronized (fCheckpoints) {
829 return fIndexing;
830 }
831 }
832
833 protected void indexExperiment(boolean waitForCompletion) {
a4115405 834 indexExperiment(waitForCompletion, 0, TmfTimeRange.ETERNITY);
a79913eb
FC
835 }
836
837 @SuppressWarnings("unchecked")
838 protected void indexExperiment(boolean waitForCompletion, final int index, final TmfTimeRange timeRange) {
839
840 synchronized (fCheckpoints) {
841 if (fIndexing) {
842 return;
843 }
844 fIndexing = true;
845 }
846
8a0edc79
FC
847 final Job job = new Job("Indexing " + getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
848 @Override
849 protected IStatus run(IProgressMonitor monitor) {
850 while (!monitor.isCanceled()) {
851 try {
852 Thread.sleep(100);
853 } catch (InterruptedException e) {
854 return Status.OK_STATUS;
855 }
856 }
857 monitor.done();
858 return Status.OK_STATUS;
859 }
860 };
861 job.schedule();
862
9b635e61 863// fEventLog = openLogFile("TraceEvent.log");
12c155f5 864// System.out.println(System.currentTimeMillis() + ": Experiment indexing started");
550d787e 865
72f1e62a 866 ITmfEventRequest<ITmfEvent> request = new TmfEventRequest<ITmfEvent>(ITmfEvent.class, timeRange, index, TmfDataRequest.ALL_DATA,
12c155f5 867 fIndexPageSize, ITmfDataRequest.ExecutionType.BACKGROUND) { // PATA FOREGROUND
550d787e 868
12c155f5 869// long indexingStart = System.nanoTime();
a79913eb 870
a4115405
FC
871 ITmfTimestamp startTime = (fTimeRange == TmfTimeRange.NULL_RANGE) ? null : fTimeRange.getStartTime();
872 ITmfTimestamp lastTime = (fTimeRange == TmfTimeRange.NULL_RANGE) ? null : fTimeRange.getEndTime();
a79913eb
FC
873 long initialNbEvents = fNbEvents;
874
875 @Override
876 public void handleStarted() {
877 super.handleStarted();
878 }
879
880 @Override
72f1e62a 881 public void handleData(ITmfEvent event) {
a79913eb
FC
882 super.handleData(event);
883 if (event != null) {
4df4581d 884 ITmfTimestamp ts = event.getTimestamp();
a79913eb 885 if (startTime == null)
4df4581d 886 startTime = ts.clone();
887 lastTime = ts.clone();
a79913eb
FC
888 if ((getNbRead() % fIndexPageSize) == 1 && getNbRead() != 1) {
889 updateExperiment();
890 }
891 }
892 }
893
894 @Override
895 public void handleSuccess() {
12c155f5 896// long indexingEnd = System.nanoTime();
9b635e61 897
d61e0854
PT
898 // if the end time is a real value then it is the streaming safe time stamp
899 // set the last time to the safe time stamp to prevent unnecessary indexing requests
314b1e32 900 if (getRange().getEndTime() != TmfTimestamp.BIG_CRUNCH) {
a79913eb
FC
901 lastTime = getRange().getEndTime();
902 }
903 updateExperiment();
12c155f5 904// System.out.println(System.currentTimeMillis() + ": Experiment indexing completed");
f9673903 905
12c155f5
FC
906// long average = (indexingEnd - indexingStart) / fNbEvents;
907// System.out.println(getName() + ": start=" + startTime + ", end=" + lastTime + ", elapsed="
908// + (indexingEnd * 1.0 - indexingStart) / 1000000000);
909// System.out.println(getName() + ": nbEvents=" + fNbEvents + " (" + (average / 1000) + "."
910// + (average % 1000) + " us/evt)");
a79913eb
FC
911 super.handleSuccess();
912 }
e31e01e8 913
05bd3318
FC
914 @Override
915 public void handleCompleted() {
916 job.cancel();
a79913eb
FC
917 super.handleCompleted();
918 synchronized (fCheckpoints) {
919 fIndexing = false;
a4115405 920 if (fIndexingPendingRange != TmfTimeRange.NULL_RANGE) {
a79913eb 921 indexExperiment(false, (int) fNbEvents, fIndexingPendingRange);
a4115405 922 fIndexingPendingRange = TmfTimeRange.NULL_RANGE;
a79913eb
FC
923 }
924 }
05bd3318
FC
925 }
926
a79913eb
FC
927 private void updateExperiment() {
928 int nbRead = getNbRead();
4dc47e28 929 if (startTime != null) {
4df4581d 930 fTimeRange = new TmfTimeRange(startTime, lastTime.clone());
4dc47e28 931 }
a79913eb 932 if (nbRead != 0) {
0c2a2e08
FC
933// updateTimeRange();
934// updateNbEvents();
a79913eb
FC
935 fNbEvents = initialNbEvents + nbRead;
936 notifyListeners();
937 }
938 }
939 };
940
941 sendRequest((ITmfDataRequest<T>) request);
942 if (waitForCompletion)
943 try {
944 request.waitForCompletion();
945 } catch (InterruptedException e) {
946 e.printStackTrace();
947 }
948 }
949
950 protected void notifyListeners() {
951 broadcast(new TmfExperimentUpdatedSignal(this, this)); // , null));
1b70b6dc 952 //broadcast(new TmfExperimentRangeUpdatedSignal(this, this, fTimeRange)); // , null));
a79913eb
FC
953 }
954
8c8bf09f
ASL
955 // ------------------------------------------------------------------------
956 // Signal handlers
957 // ------------------------------------------------------------------------
958
959 @TmfSignalHandler
951d134a 960 public void experimentSelected(TmfExperimentSelectedSignal<T> signal) {
a79913eb
FC
961 TmfExperiment<?> experiment = signal.getExperiment();
962 if (experiment == this) {
963 setCurrentExperiment(experiment);
6e85c58d 964 fEndSynchReference = Integer.valueOf(signal.getReference());
a79913eb 965 }
8c8bf09f
ASL
966 }
967
1b70b6dc
PT
968 @TmfSignalHandler
969 public void endSync(TmfEndSynchSignal signal) {
970 if (fEndSynchReference != null && fEndSynchReference.intValue() == signal.getReference()) {
971 fEndSynchReference = null;
972 initializeStreamingMonitor();
973 }
974
975 }
976
8c8bf09f
ASL
977 @TmfSignalHandler
978 public void experimentUpdated(TmfExperimentUpdatedSignal signal) {
8c8bf09f
ASL
979 }
980
1b70b6dc
PT
981 @TmfSignalHandler
982 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
09d11238
PT
983 if (signal.getExperiment() == this) {
984 indexExperiment(false, (int) fNbEvents, signal.getRange());
985 }
1b70b6dc
PT
986 }
987
8c8bf09f
ASL
988 @TmfSignalHandler
989 public void traceUpdated(TmfTraceUpdatedSignal signal) {
12c155f5 990 for (ITmfTrace<T> trace : fTraces) {
a79913eb
FC
991 if (trace == signal.getTrace()) {
992 synchronized (fCheckpoints) {
993 if (fIndexing) {
a4115405 994 if (fIndexingPendingRange == TmfTimeRange.NULL_RANGE) {
a79913eb
FC
995 fIndexingPendingRange = signal.getRange();
996 } else {
4df4581d 997 ITmfTimestamp startTime = fIndexingPendingRange.getStartTime();
998 ITmfTimestamp endTime = fIndexingPendingRange.getEndTime();
a79913eb
FC
999 if (signal.getRange().getStartTime().compareTo(startTime) < 0) {
1000 startTime = signal.getRange().getStartTime();
1001 }
1002 if (signal.getRange().getEndTime().compareTo(endTime) > 0) {
1003 endTime = signal.getRange().getEndTime();
1004 }
1005 fIndexingPendingRange = new TmfTimeRange(startTime, endTime);
1006 }
1007 return;
1008 }
1009 }
1010 indexExperiment(false, (int) fNbEvents, signal.getRange());
1011 return;
1012 }
1013 }
8c8bf09f
ASL
1014 }
1015
12c155f5
FC
1016 @Override
1017 public String getPath() {
1018 // TODO Auto-generated method stub
1019 return null;
1020 }
1021
828e5592 1022 /**
a1091415
PT
1023 * Set the file to be used for bookmarks on this experiment
1024 * @param file the bookmarks file
828e5592 1025 */
a1091415
PT
1026 public void setBookmarksFile(IFile file) {
1027 fBookmarksFile = file;
1028 }
1029
1030 /**
1031 * Get the file used for bookmarks on this experiment
1032 * @return the bookmarks file or null if none is set
1033 */
1034 public IFile getBookmarksFile() {
1035 return fBookmarksFile;
1036 }
1037
1038 /* (non-Javadoc)
1039 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#setResource(org.eclipse.core.resources.IResource)
1040 */
1041 @Override
828e5592
PT
1042 public void setResource(IResource resource) {
1043 fResource = resource;
1044 }
1045
a1091415
PT
1046 /* (non-Javadoc)
1047 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
828e5592 1048 */
a1091415 1049 @Override
828e5592
PT
1050 public IResource getResource() {
1051 return fResource;
1052 }
4dc47e28 1053}
This page took 0.094721 seconds and 5 git commands to generate.