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