1 /*******************************************************************************
2 * Copyright (c) 2009, 2010 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 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.experiment
;
15 import java
.util
.Collections
;
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
.component
.TmfEventProvider
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimeRange
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
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
.signal
.TmfTraceUpdatedSignal
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
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
.TmfContext
;
48 * <b><u>TmfExperiment</u></b>
50 * TmfExperiment presents a time-ordered, unified view of a set of TmfTraces that are part of a tracing experiment.
53 public class TmfExperiment
<T
extends ITmfEvent
> extends TmfEventProvider
<T
> implements ITmfTrace
<T
> {
55 // ------------------------------------------------------------------------
57 // ------------------------------------------------------------------------
59 // The currently selected experiment
60 protected static TmfExperiment
<?
> fCurrentExperiment
= null;
62 // The set of traces that constitute the experiment
63 protected ITmfTrace
<T
>[] fTraces
;
65 // The total number of events
66 protected long fNbEvents
;
68 // The experiment time range
69 protected TmfTimeRange fTimeRange
;
71 // The experiment reference timestamp (default: Zero)
72 protected ITmfTimestamp fEpoch
;
74 // The experiment index
75 protected Vector
<TmfCheckpoint
> fCheckpoints
= new Vector
<TmfCheckpoint
>();
77 // The current experiment context
78 protected TmfExperimentContext fExperimentContext
;
80 // Flag to initialize only once
81 private boolean fInitialized
= false;
83 // The experiment bookmarks file
84 private IFile fBookmarksFile
;
86 // The properties resource
87 private IResource fResource
;
89 // ------------------------------------------------------------------------
91 // ------------------------------------------------------------------------
94 public boolean validate(IProject project
, String path
) {
99 public void initTrace(String name
, String path
, Class
<T
> eventType
) {
107 * @param indexPageSize
109 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
, ITmfTimestamp epoch
, int indexPageSize
) {
110 this(type
, id
, traces
, TmfTimestamp
.ZERO
, indexPageSize
, false);
113 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
, ITmfTimestamp epoch
, int indexPageSize
, boolean preIndexExperiment
) {
118 fIndexPageSize
= indexPageSize
;
119 fTimeRange
= TmfTimeRange
.NULL_RANGE
;
121 if (preIndexExperiment
) {
122 indexExperiment(true, 0, TmfTimeRange
.ETERNITY
);
127 protected TmfExperiment(String id
, Class
<T
> type
) {
136 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
) {
137 this(type
, id
, traces
, TmfTimestamp
.ZERO
, DEFAULT_INDEX_PAGE_SIZE
);
144 * @param indexPageSize
146 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
, int indexPageSize
) {
147 this(type
, id
, traces
, TmfTimestamp
.ZERO
, indexPageSize
);
151 * Clears the experiment
154 @SuppressWarnings("rawtypes")
155 public synchronized void dispose() {
157 TmfExperimentDisposedSignal
<T
> signal
= new TmfExperimentDisposedSignal
<T
>(this, this);
159 if (fCurrentExperiment
== this) {
160 fCurrentExperiment
= null;
163 if (fTraces
!= null) {
164 for (ITmfTrace trace
: fTraces
) {
169 if (fCheckpoints
!= null) {
170 fCheckpoints
.clear();
175 // ------------------------------------------------------------------------
177 // ------------------------------------------------------------------------
180 public long getNbEvents() {
185 public int getIndexPageSize() {
186 return fIndexPageSize
;
190 public TmfTimeRange
getTimeRange() {
195 public ITmfTimestamp
getStartTime() {
196 return fTimeRange
.getStartTime();
200 public ITmfTimestamp
getEndTime() {
201 return fTimeRange
.getEndTime();
204 public Vector
<TmfCheckpoint
> getCheckpoints() {
208 // ------------------------------------------------------------------------
210 // ------------------------------------------------------------------------
212 public static void setCurrentExperiment(TmfExperiment
<?
> experiment
) {
213 if (fCurrentExperiment
!= null && fCurrentExperiment
!= experiment
) {
214 fCurrentExperiment
.dispose();
216 fCurrentExperiment
= experiment
;
219 public static TmfExperiment
<?
> getCurrentExperiment() {
220 return fCurrentExperiment
;
223 public ITmfTimestamp
getEpoch() {
227 public ITmfTrace
<T
>[] getTraces() {
232 * Returns the rank of the first event with the requested timestamp. If none, returns the index of the next event
235 * @param timestamp the event timestamp
236 * @return the corresponding event rank
239 public long getRank(ITmfTimestamp timestamp
) {
240 TmfExperimentContext context
= seekEvent(timestamp
);
241 return context
.getRank();
245 * Returns the timestamp of the event at the requested index. If none, returns null.
247 * @param index the event index (rank)
248 * @return the corresponding event timestamp
250 public ITmfTimestamp
getTimestamp(int index
) {
251 TmfExperimentContext context
= seekEvent(index
);
252 ITmfEvent event
= getNextEvent(context
);
253 return (event
!= null) ? event
.getTimestamp() : null;
256 // ------------------------------------------------------------------------
258 // ------------------------------------------------------------------------
261 * Update the global time range
263 protected void updateTimeRange() {
264 ITmfTimestamp startTime
= fTimeRange
!= TmfTimeRange
.NULL_RANGE ? fTimeRange
.getStartTime() : TmfTimestamp
.BIG_CRUNCH
;
265 ITmfTimestamp endTime
= fTimeRange
!= TmfTimeRange
.NULL_RANGE ? fTimeRange
.getEndTime() : TmfTimestamp
.BIG_BANG
;
267 for (ITmfTrace
<T
> trace
: fTraces
) {
268 ITmfTimestamp traceStartTime
= trace
.getStartTime();
269 if (traceStartTime
.compareTo(startTime
, true) < 0)
270 startTime
= traceStartTime
;
271 ITmfTimestamp traceEndTime
= trace
.getEndTime();
272 if (traceEndTime
.compareTo(endTime
, true) > 0)
273 endTime
= traceEndTime
;
275 fTimeRange
= new TmfTimeRange(startTime
, endTime
);
278 // ------------------------------------------------------------------------
280 // ------------------------------------------------------------------------
282 public ITmfContext
armRequest(ITmfDataRequest
<T
> request
) {
283 // Tracer.trace("Ctx: Arming request - start");
284 ITmfTimestamp timestamp
= (request
instanceof ITmfEventRequest
<?
>) ?
((ITmfEventRequest
<T
>) request
).getRange().getStartTime()
287 if (TmfTimestamp
.BIG_BANG
.equals(timestamp
) || request
.getIndex() > 0) {
288 timestamp
= null; // use request index
291 TmfExperimentContext context
= null;
292 if (timestamp
!= null) {
294 context
= seekEvent(timestamp
);
295 ((ITmfEventRequest
<T
>) request
).setStartIndex((int) context
.getRank());
298 if ((fExperimentContext
!= null) && fExperimentContext
.getRank() == request
.getIndex()) {
299 // We are already at the right context -> no need to seek
300 context
= fExperimentContext
;
302 context
= seekEvent(request
.getIndex());
305 // Tracer.trace("Ctx: Arming request - done");
309 @SuppressWarnings("unchecked")
311 public T
getNext(ITmfContext context
) {
312 if (context
instanceof TmfExperimentContext
) {
313 return (T
) getNextEvent((TmfExperimentContext
) context
);
318 // ------------------------------------------------------------------------
319 // ITmfTrace trace positioning
320 // ------------------------------------------------------------------------
322 // Returns a brand new context based on the location provided
323 // and initializes the event queues
325 public synchronized TmfExperimentContext
seekLocation(ITmfLocation
<?
> location
) {
326 // Validate the location
327 if (location
!= null && !(location
instanceof TmfExperimentLocation
)) {
328 return null; // Throw an exception?
331 if (fTraces
== null) { // experiment has been disposed
335 // Instantiate the location
336 TmfExperimentLocation expLocation
= (location
== null) ?
new TmfExperimentLocation(new TmfLocationArray(
337 new ITmfLocation
<?
>[fTraces
.length
]), new long[fTraces
.length
]) : (TmfExperimentLocation
) location
.clone();
339 // Create and populate the context's traces contexts
340 TmfExperimentContext context
= new TmfExperimentContext(fTraces
, new TmfContext
[fTraces
.length
]);
341 // Tracer.trace("Ctx: SeekLocation - start");
344 for (int i
= 0; i
< fTraces
.length
; i
++) {
345 // Get the relevant trace attributes
346 ITmfLocation
<?
> traceLocation
= expLocation
.getLocation().locations
[i
];
347 long traceRank
= expLocation
.getRanks()[i
];
349 // Set the corresponding sub-context
350 context
.getContexts()[i
] = fTraces
[i
].seekLocation(traceLocation
);
351 context
.getContexts()[i
].setRank(traceRank
);
354 // Set the trace location and read the corresponding event
355 /* The (TmfContext) cast should be safe since we created 'context'
356 * ourselves higher up. */
357 expLocation
.getLocation().locations
[i
] = ((TmfContext
) context
.getContexts()[i
]).getLocation().clone();
358 context
.getEvents()[i
] = fTraces
[i
].getNextEvent(context
.getContexts()[i
]);
361 // Tracer.trace("Ctx: SeekLocation - done");
364 context
.setLocation(expLocation
);
365 context
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
366 context
.setRank(rank
);
368 fExperimentContext
= context
;
376 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools .tmf.event.TmfTimestamp)
379 public synchronized TmfExperimentContext
seekEvent(ITmfTimestamp timestamp
) {
381 // Tracer.trace("Ctx: seekEvent(TS) - start");
383 if (timestamp
== null) {
384 timestamp
= TmfTimestamp
.BIG_BANG
;
387 // First, find the right checkpoint
388 int index
= Collections
.binarySearch(fCheckpoints
, new TmfCheckpoint(timestamp
, null));
390 // In the very likely case that the checkpoint was not found, bsearch
391 // returns its negated would-be location (not an offset...). From that
392 // index, we can then position the stream and get the event.
394 index
= Math
.max(0, -(index
+ 2));
397 // Position the experiment at the checkpoint
398 ITmfLocation
<?
> location
;
399 synchronized (fCheckpoints
) {
400 if (fCheckpoints
.size() > 0) {
401 if (index
>= fCheckpoints
.size()) {
402 index
= fCheckpoints
.size() - 1;
404 location
= fCheckpoints
.elementAt(index
).getLocation();
410 TmfExperimentContext context
= seekLocation(location
);
411 context
.setRank((long) index
* fIndexPageSize
);
413 // And locate the event
414 ITmfEvent event
= parseEvent(context
);
415 while (event
!= null && event
.getTimestamp().compareTo(timestamp
, false) < 0) {
416 getNextEvent(context
);
417 event
= parseEvent(context
);
421 context
.setLocation(null);
422 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
431 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(long)
434 public synchronized TmfExperimentContext
seekEvent(long rank
) {
436 // Tracer.trace("Ctx: seekEvent(rank) - start");
438 // Position the stream at the previous checkpoint
439 int index
= (int) rank
/ fIndexPageSize
;
440 ITmfLocation
<?
> location
;
441 synchronized (fCheckpoints
) {
442 if (fCheckpoints
.size() == 0) {
445 if (index
>= fCheckpoints
.size()) {
446 index
= fCheckpoints
.size() - 1;
448 location
= fCheckpoints
.elementAt(index
).getLocation();
452 TmfExperimentContext context
= seekLocation(location
);
453 context
.setRank((long) index
* fIndexPageSize
);
455 // And locate the event
456 ITmfEvent event
= parseEvent(context
);
457 long pos
= context
.getRank();
458 while (event
!= null && pos
++ < rank
) {
459 getNextEvent(context
);
460 event
= parseEvent(context
);
464 context
.setLocation(null);
465 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
472 public TmfContext
seekLocation(double ratio
) {
473 TmfContext context
= seekEvent((long) (ratio
* getNbEvents()));
478 public double getLocationRatio(ITmfLocation
<?
> location
) {
479 if (location
instanceof TmfExperimentLocation
) {
480 return (double) seekLocation(location
).getRank() / getNbEvents();
486 public ITmfLocation
<?
> getCurrentLocation() {
487 if (fExperimentContext
!= null) {
488 return fExperimentContext
.getLocation();
493 // private void dumpContext(TmfExperimentContext context, boolean isBefore) {
495 // TmfContext context0 = context.getContexts()[0];
496 // TmfEvent event0 = context.getEvents()[0];
497 // TmfExperimentLocation location0 = (TmfExperimentLocation) context.getLocation();
498 // long rank0 = context.getRank();
499 // int trace = context.getLastTrace();
501 // StringBuffer result = new StringBuffer("Ctx: " + (isBefore ? "B " : "A "));
503 // result.append("[Ctx: fLoc= " + context0.getLocation().toString() + ", fRnk= " + context0.getRank() + "] ");
504 // result.append("[Evt: " + event0.getTimestamp().toString() + "] ");
505 // result.append("[Loc: fLoc= " + location0.getLocation()[0].toString() + ", fRnk= " + location0.getRanks()[0] + "] ");
506 // result.append("[Rnk: " + rank0 + "], [Trc: " + trace + "]");
507 // Tracer.trace(result.toString());
511 * Scan the next events from all traces and return the next one in chronological order.
513 * @param context the trace context
514 * @return the next event
516 @SuppressWarnings("unchecked")
518 public synchronized ITmfEvent
getNextEvent(ITmfContext context
) {
520 // Validate the context
521 if (!(context
instanceof TmfExperimentContext
)) {
522 return null; // Throw an exception?
525 if (!context
.equals(fExperimentContext
)) {
526 // Tracer.trace("Ctx: Restoring context");
527 fExperimentContext
= seekLocation(context
.getLocation());
530 TmfExperimentContext expContext
= (TmfExperimentContext
) context
;
532 // dumpContext(expContext, true);
534 // If an event was consumed previously, get the next one from that trace
535 int lastTrace
= expContext
.getLastTrace();
536 if (lastTrace
!= TmfExperimentContext
.NO_TRACE
) {
537 ITmfContext traceContext
= expContext
.getContexts()[lastTrace
];
538 expContext
.getEvents()[lastTrace
] = expContext
.getTraces()[lastTrace
].getNextEvent(traceContext
);
539 expContext
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
542 // Scan the candidate events and identify the "next" trace to read from
543 ITmfEvent eventArray
[] = expContext
.getEvents();
544 if (eventArray
== null) {
547 int trace
= TmfExperimentContext
.NO_TRACE
;
548 ITmfTimestamp timestamp
= TmfTimestamp
.BIG_CRUNCH
;
549 if (eventArray
.length
== 1) {
550 if (eventArray
[0] != null) {
551 timestamp
= eventArray
[0].getTimestamp();
555 for (int i
= 0; i
< eventArray
.length
; i
++) {
556 ITmfEvent event
= eventArray
[i
];
557 if (event
!= null && event
.getTimestamp() != null) {
558 ITmfTimestamp otherTS
= event
.getTimestamp();
559 if (otherTS
.compareTo(timestamp
, true) < 0) {
566 // Update the experiment context and set the "next" event
567 ITmfEvent event
= null;
568 if (trace
!= TmfExperimentContext
.NO_TRACE
) {
569 updateIndex(expContext
, timestamp
);
571 ITmfContext traceContext
= expContext
.getContexts()[trace
];
572 TmfExperimentLocation expLocation
= (TmfExperimentLocation
) expContext
.getLocation();
573 // expLocation.getLocation()[trace] = traceContext.getLocation().clone();
574 expLocation
.getLocation().locations
[trace
] = (ITmfLocation
<?
extends Comparable
<?
>>) traceContext
.getLocation().clone();
576 // updateIndex(expContext, timestamp);
578 expLocation
.getRanks()[trace
] = traceContext
.getRank();
579 expContext
.setLastTrace(trace
);
580 expContext
.updateRank(1);
581 event
= expContext
.getEvents()[trace
];
582 fExperimentContext
= expContext
;
585 // if (event != null) {
586 // Tracer.trace("Exp: " + (expContext.getRank() - 1) + ": " + event.getTimestamp().toString());
587 // dumpContext(expContext, false);
588 // Tracer.trace("Ctx: Event returned= " + event.getTimestamp().toString());
594 public synchronized void updateIndex(ITmfContext context
, ITmfTimestamp timestamp
) {
595 // Build the index as we go along
596 long rank
= context
.getRank();
597 if (context
.isValidRank() && (rank
% fIndexPageSize
) == 0) {
598 // Determine the table position
599 long position
= rank
/ fIndexPageSize
;
600 // Add new entry at proper location (if empty)
601 if (fCheckpoints
.size() == position
) {
602 ITmfLocation
<?
> location
= context
.getLocation().clone();
603 fCheckpoints
.add(new TmfCheckpoint(timestamp
.clone(), location
));
604 // System.out.println(this + "[" + (fCheckpoints.size() - 1) + "] " + timestamp + ", "
605 // + location.toString());
613 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#parseEvent(org.eclipse.linuxtools .tmf.trace.TmfContext)
616 public ITmfEvent
parseEvent(ITmfContext context
) {
618 // Validate the context
619 if (!(context
instanceof TmfExperimentContext
)) {
620 return null; // Throw an exception?
623 if (!context
.equals(fExperimentContext
)) {
624 // Tracer.trace("Ctx: Restoring context");
625 seekLocation(context
.getLocation());
628 TmfExperimentContext expContext
= (TmfExperimentContext
) context
;
630 // If an event was consumed previously, get the next one from that trace
631 int lastTrace
= expContext
.getLastTrace();
632 if (lastTrace
!= TmfExperimentContext
.NO_TRACE
) {
633 ITmfContext traceContext
= expContext
.getContexts()[lastTrace
];
634 expContext
.getEvents()[lastTrace
] = expContext
.getTraces()[lastTrace
].getNextEvent(traceContext
);
635 expContext
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
636 fExperimentContext
= (TmfExperimentContext
) context
;
639 // Scan the candidate events and identify the "next" trace to read from
640 int trace
= TmfExperimentContext
.NO_TRACE
;
641 ITmfTimestamp timestamp
= TmfTimestamp
.BIG_CRUNCH
;
642 for (int i
= 0; i
< expContext
.getTraces().length
; i
++) {
643 ITmfEvent event
= expContext
.getEvents()[i
];
644 if (event
!= null && event
.getTimestamp() != null) {
645 ITmfTimestamp otherTS
= event
.getTimestamp();
646 if (otherTS
.compareTo(timestamp
, true) < 0) {
653 ITmfEvent event
= null;
654 if (trace
!= TmfExperimentContext
.NO_TRACE
) {
655 event
= expContext
.getEvents()[trace
];
664 * @see java.lang.Object#toString()
667 @SuppressWarnings("nls")
668 public String
toString() {
669 return "[TmfExperiment (" + getName() + ")]";
672 // ------------------------------------------------------------------------
674 // ------------------------------------------------------------------------
676 private synchronized void initializeStreamingMonitor() {
682 if (getStreamingInterval() == 0) {
683 TmfContext context
= seekLocation(null);
684 ITmfEvent event
= getNext(context
);
688 TmfTimeRange timeRange
= new TmfTimeRange(event
.getTimestamp().clone(), TmfTimestamp
.BIG_CRUNCH
);
689 final TmfExperimentRangeUpdatedSignal signal
= new TmfExperimentRangeUpdatedSignal(this, this, timeRange
);
691 // Broadcast in separate thread to prevent deadlock
701 final Thread thread
= new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
702 ITmfTimestamp safeTimestamp
= null;
703 TmfTimeRange timeRange
= null;
707 while (!fExecutor
.isShutdown()) {
708 if (!isIndexingBusy()) {
709 ITmfTimestamp startTimestamp
= TmfTimestamp
.BIG_CRUNCH
;
710 ITmfTimestamp endTimestamp
= TmfTimestamp
.BIG_BANG
;
711 for (ITmfTrace
<T
> trace
: fTraces
) {
712 if (trace
.getStartTime().compareTo(startTimestamp
) < 0) {
713 startTimestamp
= trace
.getStartTime();
715 if (trace
.getStreamingInterval() != 0 && trace
.getEndTime().compareTo(endTimestamp
) > 0) {
716 endTimestamp
= trace
.getEndTime();
719 if (safeTimestamp
!= null && safeTimestamp
.compareTo(getTimeRange().getEndTime(), false) > 0) {
720 timeRange
= new TmfTimeRange(startTimestamp
, safeTimestamp
);
724 safeTimestamp
= endTimestamp
;
725 if (timeRange
!= null) {
726 TmfExperimentRangeUpdatedSignal signal
=
727 new TmfExperimentRangeUpdatedSignal(TmfExperiment
.this, TmfExperiment
.this, timeRange
);
732 Thread
.sleep(getStreamingInterval());
733 } catch (InterruptedException e
) {
743 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
746 public long getStreamingInterval() {
748 for (ITmfTrace
<T
> trace
: fTraces
) {
749 interval
= Math
.max(interval
, trace
.getStreamingInterval());
755 * The experiment holds the globally ordered events of its set of traces. It is expected to provide access to each
756 * individual event by index i.e. it must be possible to request the Nth event of the experiment.
758 * The purpose of the index is to keep the information needed to rapidly restore the traces contexts at regular
759 * intervals (every INDEX_PAGE_SIZE event).
762 // The index page size
763 private static final int DEFAULT_INDEX_PAGE_SIZE
= 5000;
764 protected int fIndexPageSize
;
765 protected boolean fIndexing
= false;
766 protected TmfTimeRange fIndexingPendingRange
= TmfTimeRange
.NULL_RANGE
;
768 private Integer fEndSynchReference
;
770 // private static BufferedWriter fEventLog = null;
771 // private static BufferedWriter openLogFile(String filename) {
772 // BufferedWriter outfile = null;
774 // outfile = new BufferedWriter(new FileWriter(filename));
775 // } catch (IOException e) {
776 // e.printStackTrace();
781 protected boolean isIndexingBusy() {
782 synchronized (fCheckpoints
) {
788 public void indexTrace(boolean waitForCompletion
) {
789 if (waitForCompletion
) {
790 initializeStreamingMonitor();
794 @SuppressWarnings("unchecked")
795 protected void indexExperiment(boolean waitForCompletion
, final int index
, final TmfTimeRange timeRange
) {
797 synchronized (fCheckpoints
) {
804 final Job job
= new Job("Indexing " + getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
806 protected IStatus
run(IProgressMonitor monitor
) {
807 while (!monitor
.isCanceled()) {
810 } catch (InterruptedException e
) {
811 return Status
.OK_STATUS
;
815 return Status
.OK_STATUS
;
820 // fEventLog = openLogFile("TraceEvent.log");
821 // System.out.println(System.currentTimeMillis() + ": Experiment indexing started");
823 ITmfEventRequest
<ITmfEvent
> request
= new TmfEventRequest
<ITmfEvent
>(ITmfEvent
.class, timeRange
, index
, TmfDataRequest
.ALL_DATA
,
824 fIndexPageSize
, ITmfDataRequest
.ExecutionType
.BACKGROUND
) { // PATA FOREGROUND
826 // long indexingStart = System.nanoTime();
828 ITmfTimestamp startTime
= (fTimeRange
== TmfTimeRange
.NULL_RANGE
) ?
null : fTimeRange
.getStartTime();
829 ITmfTimestamp lastTime
= (fTimeRange
== TmfTimeRange
.NULL_RANGE
) ?
null : fTimeRange
.getEndTime();
830 long initialNbEvents
= fNbEvents
;
833 public void handleStarted() {
834 super.handleStarted();
838 public void handleData(ITmfEvent event
) {
839 super.handleData(event
);
841 ITmfTimestamp ts
= event
.getTimestamp();
842 if (startTime
== null)
843 startTime
= ts
.clone();
844 lastTime
= ts
.clone();
845 if ((getNbRead() % fIndexPageSize
) == 1 && getNbRead() != 1) {
852 public void handleSuccess() {
853 // long indexingEnd = System.nanoTime();
855 // if the end time is a real value then it is the streaming safe time stamp
856 // set the last time to the safe time stamp to prevent unnecessary indexing requests
857 if (getRange().getEndTime() != TmfTimestamp
.BIG_CRUNCH
) {
858 lastTime
= getRange().getEndTime();
861 // System.out.println(System.currentTimeMillis() + ": Experiment indexing completed");
863 // long average = (indexingEnd - indexingStart) / fNbEvents;
864 // System.out.println(getName() + ": start=" + startTime + ", end=" + lastTime + ", elapsed="
865 // + (indexingEnd * 1.0 - indexingStart) / 1000000000);
866 // System.out.println(getName() + ": nbEvents=" + fNbEvents + " (" + (average / 1000) + "."
867 // + (average % 1000) + " us/evt)");
868 super.handleSuccess();
872 public void handleCompleted() {
874 super.handleCompleted();
875 synchronized (fCheckpoints
) {
877 if (fIndexingPendingRange
!= TmfTimeRange
.NULL_RANGE
) {
878 indexExperiment(false, (int) fNbEvents
, fIndexingPendingRange
);
879 fIndexingPendingRange
= TmfTimeRange
.NULL_RANGE
;
884 private void updateExperiment() {
885 int nbRead
= getNbRead();
886 if (startTime
!= null) {
887 fTimeRange
= new TmfTimeRange(startTime
, lastTime
.clone());
890 // updateTimeRange();
892 fNbEvents
= initialNbEvents
+ nbRead
;
898 sendRequest((ITmfDataRequest
<T
>) request
);
899 if (waitForCompletion
)
901 request
.waitForCompletion();
902 } catch (InterruptedException e
) {
907 protected void notifyListeners() {
908 broadcast(new TmfExperimentUpdatedSignal(this, this)); // , null));
909 //broadcast(new TmfExperimentRangeUpdatedSignal(this, this, fTimeRange)); // , null));
912 // ------------------------------------------------------------------------
914 // ------------------------------------------------------------------------
917 public void experimentSelected(TmfExperimentSelectedSignal
<T
> signal
) {
918 TmfExperiment
<?
> experiment
= signal
.getExperiment();
919 if (experiment
== this) {
920 setCurrentExperiment(experiment
);
921 fEndSynchReference
= Integer
.valueOf(signal
.getReference());
926 public void endSync(TmfEndSynchSignal signal
) {
927 if (fEndSynchReference
!= null && fEndSynchReference
.intValue() == signal
.getReference()) {
928 fEndSynchReference
= null;
929 initializeStreamingMonitor();
935 public void experimentUpdated(TmfExperimentUpdatedSignal signal
) {
939 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal
) {
940 if (signal
.getExperiment() == this) {
941 indexExperiment(false, (int) fNbEvents
, signal
.getRange());
946 public void traceUpdated(TmfTraceUpdatedSignal signal
) {
947 for (ITmfTrace
<T
> trace
: fTraces
) {
948 if (trace
== signal
.getTrace()) {
949 synchronized (fCheckpoints
) {
951 if (fIndexingPendingRange
== TmfTimeRange
.NULL_RANGE
) {
952 fIndexingPendingRange
= signal
.getRange();
954 ITmfTimestamp startTime
= fIndexingPendingRange
.getStartTime();
955 ITmfTimestamp endTime
= fIndexingPendingRange
.getEndTime();
956 if (signal
.getRange().getStartTime().compareTo(startTime
) < 0) {
957 startTime
= signal
.getRange().getStartTime();
959 if (signal
.getRange().getEndTime().compareTo(endTime
) > 0) {
960 endTime
= signal
.getRange().getEndTime();
962 fIndexingPendingRange
= new TmfTimeRange(startTime
, endTime
);
967 indexExperiment(false, (int) fNbEvents
, signal
.getRange());
974 public String
getPath() {
975 // TODO Auto-generated method stub
980 * Set the file to be used for bookmarks on this experiment
981 * @param file the bookmarks file
983 public void setBookmarksFile(IFile file
) {
984 fBookmarksFile
= file
;
988 * Get the file used for bookmarks on this experiment
989 * @return the bookmarks file or null if none is set
991 public IFile
getBookmarksFile() {
992 return fBookmarksFile
;
996 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#setResource(org.eclipse.core.resources.IResource)
999 public void setResource(IResource resource
) {
1000 fResource
= resource
;
1004 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
1007 public IResource
getResource() {