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