1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2012 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Updated as per TMF Trace Model 1.0
12 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.core
.experiment
;
16 import java
.util
.Vector
;
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
;
49 * TmfExperiment presents a time-ordered, unified view of a set of TmfTraces
50 * that are part of a tracing experiment.
52 public class TmfExperiment
<T
extends ITmfEvent
> extends TmfTrace
<T
> implements ITmfEventParser
<T
> {
54 // ------------------------------------------------------------------------
56 // ------------------------------------------------------------------------
58 // The currently selected experiment
59 private static TmfExperiment
<?
> fCurrentExperiment
= null;
61 // The set of traces that constitute the experiment
62 private ITmfTrace
<T
>[] fTraces
;
64 // The experiment time range
65 private TmfTimeRange fTimeRange
;
67 // The total number of events
68 private long fNbEvents
;
70 // The experiment index
71 private Vector
<TmfCheckpoint
> fCheckpoints
= new Vector
<TmfCheckpoint
>();
73 // The current experiment context
74 private TmfExperimentContext fExperimentContext
;
76 // Flag to initialize only once
77 private boolean fInitialized
= false;
79 // The experiment bookmarks file
80 private IFile fBookmarksFile
;
82 // The properties resource
83 private IResource fResource
;
85 // ------------------------------------------------------------------------
87 // ------------------------------------------------------------------------
90 public boolean validate(final IProject project
, final String path
) {
95 public void initTrace(final IResource resource
, final String path
, final Class
<T
> eventType
) {
104 * @param indexPageSize
105 * @throws TmfTraceException
107 public TmfExperiment(final Class
<T
> type
, final String id
, final ITmfTrace
<T
>[] traces
, final ITmfTimestamp epoch
,
108 final int indexPageSize
)
110 this(type
, id
, traces
, TmfTimestamp
.ZERO
, indexPageSize
, false);
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
)
117 setCacheSize(indexPageSize
);
118 setStreamingInterval(0);
119 setIndexer(new TmfCheckpointIndexer(this));
122 super.initialize(null, path
, type
);
123 } catch (TmfTraceException e
) {
128 fTimeRange
= TmfTimeRange
.NULL_RANGE
;
130 // if (preIndexExperiment) {
131 // indexExperiment(true, 0, TmfTimeRange.ETERNITY);
132 // updateTimeRange();
137 // * Initialize the trace common attributes and the base component.
139 // * @param resource the Eclipse resource (trace)
140 // * @param path the trace path
141 // * @param type the trace event type
143 // * @throws TmfTraceException
146 // @SuppressWarnings("unchecked")
147 // protected void initialize(final IResource resource, final String path, final Class<T> type) {
149 // super.initialize(resource, path, type);
152 // protected TmfExperiment(final String id, final Class<T> type) {
160 * @throws TmfTraceException
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
);
170 * @param indexPageSize
171 * @throws TmfTraceException
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
);
178 * Clears the experiment
181 @SuppressWarnings("rawtypes")
182 public synchronized void dispose() {
184 final TmfExperimentDisposedSignal
<T
> signal
= new TmfExperimentDisposedSignal
<T
>(this, this);
186 if (fCurrentExperiment
== this)
187 fCurrentExperiment
= null;
189 if (fTraces
!= null) {
190 for (final ITmfTrace trace
: fTraces
)
194 if (fCheckpoints
!= null)
195 fCheckpoints
.clear();
199 // ------------------------------------------------------------------------
201 // ------------------------------------------------------------------------
204 public Class
<T
> getEventType() {
209 public long getNbEvents() {
214 public int getCacheSize() {
215 return fIndexPageSize
;
219 public TmfTimeRange
getTimeRange() {
224 public ITmfTimestamp
getStartTime() {
225 return fTimeRange
.getStartTime();
229 public ITmfTimestamp
getEndTime() {
230 return fTimeRange
.getEndTime();
233 public Vector
<TmfCheckpoint
> getCheckpoints() {
237 // ------------------------------------------------------------------------
239 // ------------------------------------------------------------------------
241 public static void setCurrentExperiment(final TmfExperiment
<?
> experiment
) {
242 if (fCurrentExperiment
!= null && fCurrentExperiment
!= experiment
)
243 fCurrentExperiment
.dispose();
244 fCurrentExperiment
= experiment
;
247 public static TmfExperiment
<?
> getCurrentExperiment() {
248 return fCurrentExperiment
;
251 public ITmfTrace
<T
>[] getTraces() {
256 * Returns the timestamp of the event at the requested index. If none,
259 * @param index the event index (rank)
260 * @return the corresponding event timestamp
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;
269 // ------------------------------------------------------------------------
271 // ------------------------------------------------------------------------
274 * Update the global time range
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
;
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
;
288 fTimeRange
= new TmfTimeRange(startTime
, endTime
);
291 // ------------------------------------------------------------------------
293 // ------------------------------------------------------------------------
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) {
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
;
312 context
= seekEvent(request
.getIndex());
313 // Tracer.trace("Ctx: Arming request - done");
318 // @SuppressWarnings("unchecked")
319 // public T getNext(final ITmfContext context) {
320 // if (context instanceof TmfExperimentContext)
321 // return (T) readNextEvent(context);
325 // ------------------------------------------------------------------------
326 // ITmfTrace trace positioning
327 // ------------------------------------------------------------------------
329 // Returns a brand new context based on the location provided
330 // and initializes the event queues
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?
340 // Instantiate the location
341 final TmfExperimentLocation expLocation
= (location
== null) ?
new TmfExperimentLocation(new TmfLocationArray(
342 new ITmfLocation
<?
>[fTraces
.length
])) : (TmfExperimentLocation
) location
.clone();
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");
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];
354 // Set the corresponding sub-context
355 context
.getContexts()[i
] = fTraces
[i
].seekEvent(traceLocation
);
356 // context.getContexts()[i].setRank(traceRank);
357 // rank += traceRank;
359 // Set the trace location and read the corresponding event
361 * The (TmfContext) cast should be safe since we created 'context'
362 * ourselves higher up.
364 expLocation
.getLocation().getLocations()[i
] = context
.getContexts()[i
].getLocation().clone();
365 context
.getEvents()[i
] = fTraces
[i
].readNextEvent(context
.getContexts()[i
]);
368 // Tracer.trace("Ctx: SeekLocation - done");
371 context
.setLocation(expLocation
);
372 context
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
373 // context.setRank(rank);
374 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
376 fExperimentContext
= context
;
382 // * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools .tmf.event.TmfTimestamp)
385 // public synchronized TmfExperimentContext seekEvent(ITmfTimestamp timestamp) {
387 // // Tracer.trace("Ctx: seekEvent(TS) - start");
389 // if (timestamp == null)
390 // timestamp = TmfTimestamp.BIG_BANG;
392 // // First, find the right checkpoint
393 // int index = Collections.binarySearch(fCheckpoints, new TmfCheckpoint(timestamp, null));
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.
399 // index = Math.max(0, -(index + 2));
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();
412 // final TmfExperimentContext context = seekEvent(location);
413 // context.setRank((long) index * fIndexPageSize);
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);
423 // if (event == null) {
424 // context.setLocation(null);
425 // context.setRank(ITmfContext.UNKNOWN_RANK);
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);
436 //// if (event == null) {
437 //// context.setLocation(null);
438 //// context.setRank(ITmfContext.UNKNOWN_RANK);
445 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(long)
448 // public synchronized TmfExperimentContext seekEvent(final long rank) {
450 // // Tracer.trace("Ctx: seekEvent(rank) - start");
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)
459 // if (index >= fCheckpoints.size())
460 // index = fCheckpoints.size() - 1;
461 // location = fCheckpoints.elementAt(index).getLocation();
465 // final TmfExperimentContext context = seekEvent(location);
466 // context.setRank((long) index * fIndexPageSize);
468 //// // Position the trace at the checkpoint
469 //// final ITmfContext context = fIndexer.seekIndex(rank);
471 // // And locate the requested event context
472 // long pos = context.getRank();
474 // ITmfEvent event = readNextEvent(context);
475 // while (event != null && ++pos < rank) {
476 // event = readNextEvent(context);
478 // if (event == null) {
479 // context.setLocation(null);
480 // context.setRank(ITmfContext.UNKNOWN_RANK);
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);
493 //// if (event == null) {
494 //// context.setLocation(null);
495 //// context.setRank(ITmfContext.UNKNOWN_RANK);
502 public ITmfContext
seekEvent(final double ratio
) {
503 final ITmfContext context
= seekEvent((long) (ratio
* getNbEvents()));
508 public double getLocationRatio(final ITmfLocation
<?
> location
) {
509 if (location
instanceof TmfExperimentLocation
)
510 return (double) seekEvent(location
).getRank() / getNbEvents();
515 public ITmfLocation
<?
> getCurrentLocation() {
516 if (fExperimentContext
!= null)
517 return fExperimentContext
.getLocation();
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();
528 // StringBuffer result = new StringBuffer("Ctx: " + (isBefore ? "B " : "A "));
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());
538 // * Scan the next events from all traces and return the next one in
539 // * chronological order.
541 // * @param context the trace context
542 // * @return the next event
545 // public synchronized ITmfEvent readNextEvent(final ITmfContext context) {
547 // // Validate the context
548 // if (!(context instanceof TmfExperimentContext))
549 // return null; // Throw an exception?
551 // if (!context.equals(fExperimentContext))
552 // // Tracer.trace("Ctx: Restoring context");
553 // fExperimentContext = seekEvent(context.getLocation());
555 // final TmfExperimentContext expContext = (TmfExperimentContext) context;
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);
566 // // Scan the candidate events and identify the "next" trace to read from
567 // final ITmfEvent eventArray[] = expContext.getEvents();
568 // if (eventArray == 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();
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) {
584 // timestamp = otherTS;
589 // // Update the experiment context and set the "next" event
590 // ITmfEvent event = null;
591 // if (trace != TmfExperimentContext.NO_TRACE) {
592 // updateIndex(expContext, timestamp);
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();
599 // // updateIndex(expContext, timestamp);
601 //// expLocation.getRanks()[trace] = traceContext.getRank();
602 // expContext.setLastTrace(trace);
603 // expContext.increaseRank();
604 // event = expContext.getEvents()[trace];
605 // fExperimentContext = expContext;
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());
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());
633 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#parseEvent(org.eclipse.linuxtools .tmf.trace.TmfContext)
635 @SuppressWarnings("unchecked")
637 public T
parseEvent(final ITmfContext context
) {
639 // Validate the context
640 if (!(context
instanceof TmfExperimentContext
))
641 return null; // Throw an exception?
643 if (!context
.equals(fExperimentContext
))
644 // Tracer.trace("Ctx: Restoring context");
645 fExperimentContext
= seekEvent(context
.getLocation());
647 final TmfExperimentContext expContext
= (TmfExperimentContext
) context
;
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;
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) {
671 fExperimentContext
.setLastTrace(trace
);
673 // // Scan the candidate events and identify the "next" trace to read from
674 // final ITmfEvent eventArray[] = expContext.getEvents();
675 // if (eventArray == 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();
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) {
691 // timestamp = otherTS;
696 // // Update the experiment context and set the "next" event
697 // ITmfEvent event = null;
698 // if (trace != TmfExperimentContext.NO_TRACE) {
699 // updateIndex(expContext, timestamp);
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();
706 // // updateIndex(expContext, timestamp);
708 //// expLocation.getRanks()[trace] = traceContext.getRank();
709 // expContext.setLastTrace(trace);
710 // expContext.increaseRank();
711 // event = expContext.getEvents()[trace];
712 // fExperimentContext = expContext;
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());
724 if (trace
!= TmfExperimentContext
.NO_TRACE
)
725 event
= (T
) expContext
.getEvents()[trace
];
731 * @see java.lang.Object#toString()
734 @SuppressWarnings("nls")
735 public String
toString() {
736 return "[TmfExperiment (" + getName() + ")]";
739 // ------------------------------------------------------------------------
741 // ------------------------------------------------------------------------
743 private synchronized void initializeStreamingMonitor() {
748 if (getStreamingInterval() == 0) {
749 final ITmfContext context
= seekEvent(0);
750 final ITmfEvent event
= getNext(context
);
753 final TmfTimeRange timeRange
= new TmfTimeRange(event
.getTimestamp().clone(), TmfTimestamp
.BIG_CRUNCH
);
754 final TmfExperimentRangeUpdatedSignal signal
= new TmfExperimentRangeUpdatedSignal(this, this, timeRange
);
756 // Broadcast in separate thread to prevent deadlock
766 final Thread thread
= new Thread("Streaming Monitor for experiment " + getName()) { ////$NON-NLS-1$
767 private ITmfTimestamp safeTimestamp
= null;
768 private TmfTimeRange timeRange
= null;
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();
782 if (safeTimestamp
!= null && safeTimestamp
.compareTo(getTimeRange().getEndTime(), false) > 0)
783 timeRange
= new TmfTimeRange(startTimestamp
, safeTimestamp
);
786 safeTimestamp
= endTimestamp
;
787 if (timeRange
!= null) {
788 final TmfExperimentRangeUpdatedSignal signal
=
789 new TmfExperimentRangeUpdatedSignal(TmfExperiment
.this, TmfExperiment
.this, timeRange
);
794 Thread
.sleep(getStreamingInterval());
795 } catch (final InterruptedException e
) {
807 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
810 public long getStreamingInterval() {
812 for (final ITmfTrace
<T
> trace
: fTraces
)
813 interval
= Math
.max(interval
, trace
.getStreamingInterval());
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.
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
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
;
833 private Integer fEndSynchReference
;
835 // private static BufferedWriter fEventLog = null;
836 // private static BufferedWriter openLogFile(String filename) {
837 // BufferedWriter outfile = null;
839 // outfile = new BufferedWriter(new FileWriter(filename));
840 // } catch (IOException e) {
841 // e.printStackTrace();
846 protected boolean isIndexingBusy() {
847 synchronized (fCheckpoints
) {
852 // @SuppressWarnings("unchecked")
853 // private void indexExperiment(final boolean waitForCompletion, final int index, final TmfTimeRange timeRange) {
855 // synchronized (fCheckpoints) {
861 // final Job job = new Job("Indexing " + getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
864 // protected IStatus run(final IProgressMonitor monitor) {
865 // while (!monitor.isCanceled())
867 // Thread.sleep(100);
868 // } catch (final InterruptedException e) {
869 // return Status.OK_STATUS;
872 // return Status.OK_STATUS;
877 // // fEventLog = openLogFile("TraceEvent.log");
878 // // System.out.println(System.currentTimeMillis() + ": Experiment indexing started");
880 // final ITmfEventRequest<ITmfEvent> request = new TmfEventRequest<ITmfEvent>(ITmfEvent.class, timeRange, index,
881 // TmfDataRequest.ALL_DATA,
882 // fIndexPageSize, ITmfDataRequest.ExecutionType.BACKGROUND) { // PATA
885 //// long indexingStart = System.nanoTime();
887 // ITmfTimestamp startTime = (fTimeRange == TmfTimeRange.NULL_RANGE) ? null : fTimeRange.getStartTime();
888 // ITmfTimestamp lastTime = (fTimeRange == TmfTimeRange.NULL_RANGE) ? null : fTimeRange.getEndTime();
889 // long initialNbEvents = fNbEvents;
892 // public void handleStarted() {
893 // super.handleStarted();
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();
905 // if ((getNbRead() % fIndexPageSize) == 1 && getNbRead() != 1) {
906 // updateExperiment();
911 // public void handleSuccess() {
912 //// long indexingEnd = System.nanoTime();
914 // // if the end time is a real value then it is the streaming safe
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();
933 // public void handleCompleted() {
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;
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();
958 // sendRequest((ITmfDataRequest<T>) request);
959 // if (waitForCompletion)
961 // request.waitForCompletion();
962 // } catch (final InterruptedException e) {
963 // e.printStackTrace();
967 protected void notifyListeners() {
968 broadcast(new TmfExperimentUpdatedSignal(this, this)); // , null));
969 // broadcast(new TmfExperimentRangeUpdatedSignal(this, this,
970 // fTimeRange)); // , null));
973 // ------------------------------------------------------------------------
975 // ------------------------------------------------------------------------
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();
989 public void endSync(final TmfEndSynchSignal signal
) {
990 if (fEndSynchReference
!= null && fEndSynchReference
.intValue() == signal
.getReference()) {
991 fEndSynchReference
= null;
992 initializeStreamingMonitor();
997 public void experimentUpdated(final TmfExperimentUpdatedSignal signal
) {
1001 public void experimentRangeUpdated(final TmfExperimentRangeUpdatedSignal signal
) {
1002 if (signal
.getExperiment() == this) {
1003 // indexExperiment(false, (int) fNbEvents, signal.getRange());
1004 getIndexer().buildIndex(false);
1008 // @TmfSignalHandler
1009 // public void traceUpdated(final TmfTraceUpdatedSignal signal) {
1010 // for (final ITmfTrace<T> trace : fTraces)
1011 // if (trace == signal.getTrace()) {
1012 // synchronized (fCheckpoints) {
1014 // if (fIndexingPendingRange == TmfTimeRange.NULL_RANGE)
1015 // fIndexingPendingRange = signal.getRange();
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);
1028 // indexExperiment(false, (int) fNbEvents, signal.getRange());
1034 public String
getPath() {
1035 // TODO Auto-generated method stub
1040 * Set the file to be used for bookmarks on this experiment
1042 * @param file the bookmarks file
1044 public void setBookmarksFile(final IFile file
) {
1045 fBookmarksFile
= file
;
1049 * Get the file used for bookmarks on this experiment
1051 * @return the bookmarks file or null if none is set
1053 public IFile
getBookmarksFile() {
1054 return fBookmarksFile
;
1060 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
1063 public IResource
getResource() {