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
.io
.FileNotFoundException
;
16 import java
.util
.Collections
;
17 import java
.util
.Vector
;
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
.ITmfTimestamp
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfEvent
;
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
.TmfSignalManager
;
41 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfTraceUpdatedSignal
;
42 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
43 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfLocation
;
44 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
45 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfCheckpoint
;
46 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfContext
;
49 * <b><u>TmfExperiment</u></b>
51 * TmfExperiment presents a time-ordered, unified view of a set of TmfTraces that are part of a tracing experiment.
54 public class TmfExperiment
<T
extends TmfEvent
> extends TmfEventProvider
<T
> implements ITmfTrace
<T
> {
56 // ------------------------------------------------------------------------
58 // ------------------------------------------------------------------------
60 // The currently selected experiment
61 protected static TmfExperiment
<?
> fCurrentExperiment
= null;
63 // The set of traces that constitute the experiment
64 protected ITmfTrace
<T
>[] fTraces
;
66 // The total number of events
67 protected long fNbEvents
;
69 // The experiment time range
70 protected TmfTimeRange fTimeRange
;
72 // The experiment reference timestamp (default: Zero)
73 protected ITmfTimestamp fEpoch
;
75 // The experiment index
76 protected Vector
<TmfCheckpoint
> fCheckpoints
= new Vector
<TmfCheckpoint
>();
78 // The current experiment context
79 protected TmfExperimentContext fExperimentContext
;
81 // Flag to initialize only once
82 private boolean fInitialized
= false;
84 // The experiment resource
85 private IResource fResource
;
87 // ------------------------------------------------------------------------
89 // ------------------------------------------------------------------------
92 public boolean validate(IProject project
, String path
) {
97 public void initTrace(String name
, String path
, Class
<T
> eventType
) {
101 public void initTrace(String name
, String path
, Class
<T
> eventType
, boolean indexTrace
) {
103 initializeStreamingMonitor();
108 public void initTrace(String name
, String path
, Class
<T
> eventType
, int cacheSize
) {
112 public void initTrace(String name
, String path
, Class
<T
> eventType
, int cacheSize
, boolean indexTrace
) {
114 initializeStreamingMonitor();
123 * @param indexPageSize
125 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
, ITmfTimestamp epoch
, int indexPageSize
) {
126 this(type
, id
, traces
, TmfTimestamp
.Zero
, indexPageSize
, false);
129 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
, ITmfTimestamp epoch
, int indexPageSize
, boolean preIndexExperiment
) {
134 fIndexPageSize
= indexPageSize
;
135 fTimeRange
= TmfTimeRange
.Null
;
137 if (preIndexExperiment
) {
138 indexExperiment(true);
144 protected TmfExperiment(String id
, Class
<T
> type
) {
153 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
) {
154 this(type
, id
, traces
, TmfTimestamp
.Zero
, DEFAULT_INDEX_PAGE_SIZE
);
161 * @param indexPageSize
163 public TmfExperiment(Class
<T
> type
, String id
, ITmfTrace
<T
>[] traces
, int indexPageSize
) {
164 this(type
, id
, traces
, TmfTimestamp
.Zero
, indexPageSize
);
172 @SuppressWarnings("unchecked")
173 public TmfExperiment(TmfExperiment
<T
> other
) {
174 super(other
.getName() + "(clone)", other
.fType
); //$NON-NLS-1$
176 fEpoch
= other
.fEpoch
;
177 fIndexPageSize
= other
.fIndexPageSize
;
179 fTraces
= new ITmfTrace
[other
.fTraces
.length
];
180 for (int trace
= 0; trace
< other
.fTraces
.length
; trace
++) {
181 fTraces
[trace
] = other
.fTraces
[trace
].copy();
184 fNbEvents
= other
.fNbEvents
;
185 fTimeRange
= other
.fTimeRange
;
189 public TmfExperiment
<T
> copy() {
190 TmfExperiment
<T
> experiment
= new TmfExperiment
<T
>(this);
191 TmfSignalManager
.deregister(experiment
);
196 * Clears the experiment
199 @SuppressWarnings("rawtypes")
200 public synchronized void dispose() {
202 TmfExperimentDisposedSignal
<T
> signal
= new TmfExperimentDisposedSignal
<T
>(this, this);
204 if (fCurrentExperiment
== this) {
205 fCurrentExperiment
= null;
208 if (fTraces
!= null) {
209 for (ITmfTrace trace
: fTraces
) {
214 if (fCheckpoints
!= null) {
215 fCheckpoints
.clear();
220 // ------------------------------------------------------------------------
222 // ------------------------------------------------------------------------
225 public long getNbEvents() {
230 public int getCacheSize() {
231 return fIndexPageSize
;
235 public TmfTimeRange
getTimeRange() {
240 public ITmfTimestamp
getStartTime() {
241 return fTimeRange
.getStartTime();
245 public ITmfTimestamp
getEndTime() {
246 return fTimeRange
.getEndTime();
249 public Vector
<TmfCheckpoint
> getCheckpoints() {
253 // ------------------------------------------------------------------------
255 // ------------------------------------------------------------------------
257 public static void setCurrentExperiment(TmfExperiment
<?
> experiment
) {
258 if (fCurrentExperiment
!= null && fCurrentExperiment
!= experiment
) {
259 fCurrentExperiment
.dispose();
261 fCurrentExperiment
= experiment
;
264 public static TmfExperiment
<?
> getCurrentExperiment() {
265 return fCurrentExperiment
;
268 public ITmfTimestamp
getEpoch() {
272 public ITmfTrace
<T
>[] getTraces() {
277 * Returns the rank of the first event with the requested timestamp. If none, returns the index of the next event
284 public long getRank(ITmfTimestamp timestamp
) {
285 TmfExperimentContext context
= seekEvent(timestamp
);
286 return context
.getRank();
290 * Returns the timestamp of the event at the requested index. If none, returns null.
295 public ITmfTimestamp
getTimestamp(int index
) {
296 TmfExperimentContext context
= seekEvent(index
);
297 TmfEvent event
= getNextEvent(context
);
298 return (event
!= null) ? event
.getTimestamp() : null;
301 // ------------------------------------------------------------------------
303 // ------------------------------------------------------------------------
306 * Update the global time range
308 protected void updateTimeRange() {
309 ITmfTimestamp startTime
= fTimeRange
!= TmfTimeRange
.Null ? fTimeRange
.getStartTime() : TmfTimestamp
.BigCrunch
;
310 ITmfTimestamp endTime
= fTimeRange
!= TmfTimeRange
.Null ? fTimeRange
.getEndTime() : TmfTimestamp
.BigBang
;
312 for (ITmfTrace
<T
> trace
: fTraces
) {
313 ITmfTimestamp traceStartTime
= trace
.getStartTime();
314 if (traceStartTime
.compareTo(startTime
, true) < 0)
315 startTime
= traceStartTime
;
316 ITmfTimestamp traceEndTime
= trace
.getEndTime();
317 if (traceEndTime
.compareTo(endTime
, true) > 0)
318 endTime
= traceEndTime
;
320 fTimeRange
= new TmfTimeRange(startTime
, endTime
);
323 // ------------------------------------------------------------------------
325 // ------------------------------------------------------------------------
327 public ITmfContext
armRequest(ITmfDataRequest
<T
> request
) {
328 // Tracer.trace("Ctx: Arming request - start");
329 ITmfTimestamp timestamp
= (request
instanceof ITmfEventRequest
<?
>) ?
((ITmfEventRequest
<T
>) request
).getRange().getStartTime()
332 if (TmfTimestamp
.BigBang
.equals(timestamp
) || request
.getIndex() > 0) {
333 timestamp
= null; // use request index
336 TmfExperimentContext context
= null;
337 if (timestamp
!= null) {
339 context
= seekEvent(timestamp
);
340 ((ITmfEventRequest
<T
>) request
).setStartIndex((int) context
.getRank());
343 if ((fExperimentContext
!= null) && fExperimentContext
.getRank() == request
.getIndex()) {
344 // We are already at the right context -> no need to seek
345 context
= fExperimentContext
;
347 context
= seekEvent(request
.getIndex());
350 // Tracer.trace("Ctx: Arming request - done");
354 @SuppressWarnings("unchecked")
356 public T
getNext(ITmfContext context
) {
357 if (context
instanceof TmfExperimentContext
) {
358 return (T
) getNextEvent((TmfExperimentContext
) context
);
363 // ------------------------------------------------------------------------
364 // ITmfTrace trace positioning
365 // ------------------------------------------------------------------------
367 // Returns a brand new context based on the location provided
368 // and initializes the event queues
370 public synchronized TmfExperimentContext
seekLocation(ITmfLocation
<?
> location
) {
371 // Validate the location
372 if (location
!= null && !(location
instanceof TmfExperimentLocation
)) {
373 return null; // Throw an exception?
376 if (fTraces
== null) { // experiment has been disposed
380 // Instantiate the location
381 TmfExperimentLocation expLocation
= (location
== null) ?
new TmfExperimentLocation(new TmfLocationArray(
382 new ITmfLocation
<?
>[fTraces
.length
]), new long[fTraces
.length
]) : (TmfExperimentLocation
) location
.clone();
384 // Create and populate the context's traces contexts
385 TmfExperimentContext context
= new TmfExperimentContext(fTraces
, new TmfContext
[fTraces
.length
]);
386 // Tracer.trace("Ctx: SeekLocation - start");
389 for (int i
= 0; i
< fTraces
.length
; i
++) {
390 // Get the relevant trace attributes
391 ITmfLocation
<?
> traceLocation
= expLocation
.getLocation().locations
[i
];
392 long traceRank
= expLocation
.getRanks()[i
];
394 // Set the corresponding sub-context
395 context
.getContexts()[i
] = fTraces
[i
].seekLocation(traceLocation
);
396 context
.getContexts()[i
].setRank(traceRank
);
399 // Set the trace location and read the corresponding event
400 expLocation
.getLocation().locations
[i
] = context
.getContexts()[i
].getLocation().clone();
401 context
.getEvents()[i
] = fTraces
[i
].getNextEvent(context
.getContexts()[i
]);
404 // Tracer.trace("Ctx: SeekLocation - done");
407 context
.setLocation(expLocation
);
408 context
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
409 context
.setRank(rank
);
411 fExperimentContext
= context
;
419 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools .tmf.event.TmfTimestamp)
422 public synchronized TmfExperimentContext
seekEvent(ITmfTimestamp timestamp
) {
424 // Tracer.trace("Ctx: seekEvent(TS) - start");
426 if (timestamp
== null) {
427 timestamp
= TmfTimestamp
.BigBang
;
430 // First, find the right checkpoint
431 int index
= Collections
.binarySearch(fCheckpoints
, new TmfCheckpoint(timestamp
, null));
433 // In the very likely case that the checkpoint was not found, bsearch
434 // returns its negated would-be location (not an offset...). From that
435 // index, we can then position the stream and get the event.
437 index
= Math
.max(0, -(index
+ 2));
440 // Position the experiment at the checkpoint
441 ITmfLocation
<?
> location
;
442 synchronized (fCheckpoints
) {
443 if (fCheckpoints
.size() > 0) {
444 if (index
>= fCheckpoints
.size()) {
445 index
= fCheckpoints
.size() - 1;
447 location
= fCheckpoints
.elementAt(index
).getLocation();
453 TmfExperimentContext context
= seekLocation(location
);
454 context
.setRank((long) index
* fIndexPageSize
);
456 // And locate the event
457 TmfEvent event
= parseEvent(context
);
458 while (event
!= null && event
.getTimestamp().compareTo(timestamp
, false) < 0) {
459 getNextEvent(context
);
460 event
= parseEvent(context
);
464 context
.setLocation(null);
465 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
474 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(long)
477 public synchronized TmfExperimentContext
seekEvent(long rank
) {
479 // Tracer.trace("Ctx: seekEvent(rank) - start");
481 // Position the stream at the previous checkpoint
482 int index
= (int) rank
/ fIndexPageSize
;
483 ITmfLocation
<?
> location
;
484 synchronized (fCheckpoints
) {
485 if (fCheckpoints
.size() == 0) {
488 if (index
>= fCheckpoints
.size()) {
489 index
= fCheckpoints
.size() - 1;
491 location
= fCheckpoints
.elementAt(index
).getLocation();
495 TmfExperimentContext context
= seekLocation(location
);
496 context
.setRank((long) index
* fIndexPageSize
);
498 // And locate the event
499 TmfEvent event
= parseEvent(context
);
500 long pos
= context
.getRank();
501 while (event
!= null && pos
++ < rank
) {
502 getNextEvent(context
);
503 event
= parseEvent(context
);
507 context
.setLocation(null);
508 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
515 public TmfContext
seekLocation(double ratio
) {
516 TmfContext context
= seekEvent((long) (ratio
* getNbEvents()));
521 public double getLocationRatio(ITmfLocation
<?
> location
) {
522 if (location
instanceof TmfExperimentLocation
) {
523 return (double) seekLocation(location
).getRank() / getNbEvents();
529 public ITmfLocation
<?
> getCurrentLocation() {
530 if (fExperimentContext
!= null) {
531 return fExperimentContext
.getLocation();
537 * Scan the next events from all traces and return the next one in chronological order.
543 // private void dumpContext(TmfExperimentContext context, boolean isBefore) {
545 // TmfContext context0 = context.getContexts()[0];
546 // TmfEvent event0 = context.getEvents()[0];
547 // TmfExperimentLocation location0 = (TmfExperimentLocation) context.getLocation();
548 // long rank0 = context.getRank();
549 // int trace = context.getLastTrace();
551 // StringBuffer result = new StringBuffer("Ctx: " + (isBefore ? "B " : "A "));
553 // result.append("[Ctx: fLoc= " + context0.getLocation().toString() + ", fRnk= " + context0.getRank() + "] ");
554 // result.append("[Evt: " + event0.getTimestamp().toString() + "] ");
555 // result.append("[Loc: fLoc= " + location0.getLocation()[0].toString() + ", fRnk= " + location0.getRanks()[0] + "] ");
556 // result.append("[Rnk: " + rank0 + "], [Trc: " + trace + "]");
557 // Tracer.trace(result.toString());
561 public synchronized TmfEvent
getNextEvent(TmfContext context
) {
563 // Validate the context
564 if (!(context
instanceof TmfExperimentContext
)) {
565 return null; // Throw an exception?
568 if (!context
.equals(fExperimentContext
)) {
569 // Tracer.trace("Ctx: Restoring context");
570 fExperimentContext
= seekLocation(context
.getLocation());
573 TmfExperimentContext expContext
= (TmfExperimentContext
) context
;
575 // dumpContext(expContext, true);
577 // If an event was consumed previously, get the next one from that trace
578 int lastTrace
= expContext
.getLastTrace();
579 if (lastTrace
!= TmfExperimentContext
.NO_TRACE
) {
580 TmfContext traceContext
= expContext
.getContexts()[lastTrace
];
581 expContext
.getEvents()[lastTrace
] = expContext
.getTraces()[lastTrace
].getNextEvent(traceContext
);
582 expContext
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
585 // Scan the candidate events and identify the "next" trace to read from
586 TmfEvent eventArray
[] = expContext
.getEvents();
587 if (eventArray
== null) {
590 int trace
= TmfExperimentContext
.NO_TRACE
;
591 ITmfTimestamp timestamp
= TmfTimestamp
.BigCrunch
;
592 if (eventArray
.length
== 1) {
593 if (eventArray
[0] != null) {
594 timestamp
= eventArray
[0].getTimestamp();
598 for (int i
= 0; i
< eventArray
.length
; i
++) {
599 TmfEvent event
= eventArray
[i
];
600 if (event
!= null && event
.getTimestamp() != null) {
601 ITmfTimestamp otherTS
= event
.getTimestamp();
602 if (otherTS
.compareTo(timestamp
, true) < 0) {
609 // Update the experiment context and set the "next" event
610 TmfEvent event
= null;
611 if (trace
!= TmfExperimentContext
.NO_TRACE
) {
612 updateIndex(expContext
, timestamp
);
614 TmfContext traceContext
= expContext
.getContexts()[trace
];
615 TmfExperimentLocation expLocation
= (TmfExperimentLocation
) expContext
.getLocation();
616 // expLocation.getLocation()[trace] = traceContext.getLocation().clone();
617 expLocation
.getLocation().locations
[trace
] = traceContext
.getLocation().clone();
619 // updateIndex(expContext, timestamp);
621 expLocation
.getRanks()[trace
] = traceContext
.getRank();
622 expContext
.setLastTrace(trace
);
623 expContext
.updateRank(1);
624 event
= expContext
.getEvents()[trace
];
625 fExperimentContext
= expContext
;
628 // if (event != null) {
629 // Tracer.trace("Exp: " + (expContext.getRank() - 1) + ": " + event.getTimestamp().toString());
630 // dumpContext(expContext, false);
631 // Tracer.trace("Ctx: Event returned= " + event.getTimestamp().toString());
637 public synchronized void updateIndex(ITmfContext context
, ITmfTimestamp timestamp
) {
638 // Build the index as we go along
639 long rank
= context
.getRank();
640 if (context
.isValidRank() && (rank
% fIndexPageSize
) == 0) {
641 // Determine the table position
642 long position
= rank
/ fIndexPageSize
;
643 // Add new entry at proper location (if empty)
644 if (fCheckpoints
.size() == position
) {
645 ITmfLocation
<?
> location
= context
.getLocation().clone();
646 fCheckpoints
.add(new TmfCheckpoint(timestamp
.clone(), location
));
647 // System.out.println(this + "[" + (fCheckpoints.size() - 1) + "] " + timestamp + ", "
648 // + location.toString());
656 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#parseEvent(org.eclipse.linuxtools .tmf.trace.TmfContext)
659 public TmfEvent
parseEvent(TmfContext context
) {
661 // Validate the context
662 if (!(context
instanceof TmfExperimentContext
)) {
663 return null; // Throw an exception?
666 if (!context
.equals(fExperimentContext
)) {
667 // Tracer.trace("Ctx: Restoring context");
668 seekLocation(context
.getLocation());
671 TmfExperimentContext expContext
= (TmfExperimentContext
) context
;
673 // If an event was consumed previously, get the next one from that trace
674 int lastTrace
= expContext
.getLastTrace();
675 if (lastTrace
!= TmfExperimentContext
.NO_TRACE
) {
676 TmfContext traceContext
= expContext
.getContexts()[lastTrace
];
677 expContext
.getEvents()[lastTrace
] = expContext
.getTraces()[lastTrace
].getNextEvent(traceContext
);
678 expContext
.setLastTrace(TmfExperimentContext
.NO_TRACE
);
679 fExperimentContext
= (TmfExperimentContext
) context
;
682 // Scan the candidate events and identify the "next" trace to read from
683 int trace
= TmfExperimentContext
.NO_TRACE
;
684 ITmfTimestamp timestamp
= TmfTimestamp
.BigCrunch
;
685 for (int i
= 0; i
< expContext
.getTraces().length
; i
++) {
686 TmfEvent event
= expContext
.getEvents()[i
];
687 if (event
!= null && event
.getTimestamp() != null) {
688 ITmfTimestamp otherTS
= event
.getTimestamp();
689 if (otherTS
.compareTo(timestamp
, true) < 0) {
696 TmfEvent event
= null;
697 if (trace
!= TmfExperimentContext
.NO_TRACE
) {
698 event
= expContext
.getEvents()[trace
];
707 * @see java.lang.Object#toString()
710 @SuppressWarnings("nls")
711 public String
toString() {
712 return "[TmfExperiment (" + getName() + ")]";
715 // ------------------------------------------------------------------------
717 // ------------------------------------------------------------------------
719 private synchronized void initializeStreamingMonitor() {
725 if (getStreamingInterval() == 0) {
726 TmfContext context
= seekLocation(null);
727 TmfEvent event
= getNext(context
);
731 TmfTimeRange timeRange
= new TmfTimeRange(event
.getTimestamp(), TmfTimestamp
.BigCrunch
);
732 final TmfExperimentRangeUpdatedSignal signal
= new TmfExperimentRangeUpdatedSignal(this, this, timeRange
);
734 // Broadcast in separate thread to prevent deadlock
744 final Thread thread
= new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
745 ITmfTimestamp safeTimestamp
= null;
746 TmfTimeRange timeRange
= null;
750 while (!fExecutor
.isShutdown()) {
751 if (!isIndexingBusy()) {
752 ITmfTimestamp startTimestamp
= TmfTimestamp
.BigCrunch
;
753 ITmfTimestamp endTimestamp
= TmfTimestamp
.BigBang
;
754 for (ITmfTrace
<T
> trace
: fTraces
) {
755 if (trace
.getStartTime().compareTo(startTimestamp
) < 0) {
756 startTimestamp
= trace
.getStartTime();
758 if (trace
.getStreamingInterval() != 0 && trace
.getEndTime().compareTo(endTimestamp
) > 0) {
759 endTimestamp
= trace
.getEndTime();
762 if (safeTimestamp
!= null && safeTimestamp
.compareTo(getTimeRange().getEndTime(), false) > 0) {
763 timeRange
= new TmfTimeRange(startTimestamp
, safeTimestamp
);
767 safeTimestamp
= endTimestamp
;
768 if (timeRange
!= null) {
769 TmfExperimentRangeUpdatedSignal signal
=
770 new TmfExperimentRangeUpdatedSignal(TmfExperiment
.this, TmfExperiment
.this, timeRange
);
775 Thread
.sleep(getStreamingInterval());
776 } catch (InterruptedException e
) {
786 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
789 public long getStreamingInterval() {
791 for (ITmfTrace
<T
> trace
: fTraces
) {
792 interval
= Math
.max(interval
, trace
.getStreamingInterval());
798 * The experiment holds the globally ordered events of its set of traces. It is expected to provide access to each
799 * individual event by index i.e. it must be possible to request the Nth event of the experiment.
801 * The purpose of the index is to keep the information needed to rapidly restore the traces contexts at regular
802 * intervals (every INDEX_PAGE_SIZE event).
805 // The index page size
806 private static final int DEFAULT_INDEX_PAGE_SIZE
= 5000;
807 protected int fIndexPageSize
;
808 protected boolean fIndexing
= false;
809 protected TmfTimeRange fIndexingPendingRange
= TmfTimeRange
.Null
;
811 private Integer fEndSynchReference
;
813 // private static BufferedWriter fEventLog = null;
814 // private static BufferedWriter openLogFile(String filename) {
815 // BufferedWriter outfile = null;
817 // outfile = new BufferedWriter(new FileWriter(filename));
818 // } catch (IOException e) {
819 // e.printStackTrace();
824 protected boolean isIndexingBusy() {
825 synchronized (fCheckpoints
) {
830 protected void indexExperiment(boolean waitForCompletion
) {
831 indexExperiment(waitForCompletion
, 0, TmfTimeRange
.Eternity
);
834 @SuppressWarnings("unchecked")
835 protected void indexExperiment(boolean waitForCompletion
, final int index
, final TmfTimeRange timeRange
) {
837 synchronized (fCheckpoints
) {
844 final Job job
= new Job("Indexing " + getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
846 protected IStatus
run(IProgressMonitor monitor
) {
847 while (!monitor
.isCanceled()) {
850 } catch (InterruptedException e
) {
851 return Status
.OK_STATUS
;
855 return Status
.OK_STATUS
;
860 // fEventLog = openLogFile("TraceEvent.log");
861 // System.out.println(System.currentTimeMillis() + ": Experiment indexing started");
863 ITmfEventRequest
<TmfEvent
> request
= new TmfEventRequest
<TmfEvent
>(TmfEvent
.class, timeRange
, index
, TmfDataRequest
.ALL_DATA
,
864 fIndexPageSize
, ITmfDataRequest
.ExecutionType
.BACKGROUND
) { // PATA FOREGROUND
866 // long indexingStart = System.nanoTime();
868 ITmfTimestamp startTime
= (fTimeRange
== TmfTimeRange
.Null
) ?
null : fTimeRange
.getStartTime();
869 ITmfTimestamp lastTime
= (fTimeRange
== TmfTimeRange
.Null
) ?
null : fTimeRange
.getEndTime();
870 long initialNbEvents
= fNbEvents
;
873 public void handleStarted() {
874 super.handleStarted();
878 public void handleData(TmfEvent event
) {
879 super.handleData(event
);
881 ITmfTimestamp ts
= event
.getTimestamp();
882 if (startTime
== null)
883 startTime
= ts
.clone();
884 lastTime
= ts
.clone();
885 if ((getNbRead() % fIndexPageSize
) == 1 && getNbRead() != 1) {
892 public void handleSuccess() {
893 // long indexingEnd = System.nanoTime();
895 if (getRange() != TmfTimeRange
.Eternity
) {
896 lastTime
= getRange().getEndTime();
899 // System.out.println(System.currentTimeMillis() + ": Experiment indexing completed");
901 // long average = (indexingEnd - indexingStart) / fNbEvents;
902 // System.out.println(getName() + ": start=" + startTime + ", end=" + lastTime + ", elapsed="
903 // + (indexingEnd * 1.0 - indexingStart) / 1000000000);
904 // System.out.println(getName() + ": nbEvents=" + fNbEvents + " (" + (average / 1000) + "."
905 // + (average % 1000) + " us/evt)");
906 super.handleSuccess();
910 public void handleCompleted() {
912 super.handleCompleted();
913 synchronized (fCheckpoints
) {
915 if (fIndexingPendingRange
!= TmfTimeRange
.Null
) {
916 indexExperiment(false, (int) fNbEvents
, fIndexingPendingRange
);
917 fIndexingPendingRange
= TmfTimeRange
.Null
;
922 private void updateExperiment() {
923 int nbRead
= getNbRead();
924 if (startTime
!= null) {
925 fTimeRange
= new TmfTimeRange(startTime
, lastTime
.clone());
928 // updateTimeRange();
930 fNbEvents
= initialNbEvents
+ nbRead
;
936 sendRequest((ITmfDataRequest
<T
>) request
);
937 if (waitForCompletion
)
939 request
.waitForCompletion();
940 } catch (InterruptedException e
) {
945 protected void notifyListeners() {
946 broadcast(new TmfExperimentUpdatedSignal(this, this)); // , null));
947 //broadcast(new TmfExperimentRangeUpdatedSignal(this, this, fTimeRange)); // , null));
950 // ------------------------------------------------------------------------
952 // ------------------------------------------------------------------------
955 public void experimentSelected(TmfExperimentSelectedSignal
<T
> signal
) {
956 TmfExperiment
<?
> experiment
= signal
.getExperiment();
957 if (experiment
== this) {
958 setCurrentExperiment(experiment
);
959 fEndSynchReference
= new Integer(signal
.getReference());
964 public void endSync(TmfEndSynchSignal signal
) {
965 if (fEndSynchReference
!= null && fEndSynchReference
.intValue() == signal
.getReference()) {
966 fEndSynchReference
= null;
967 initializeStreamingMonitor();
973 public void experimentUpdated(TmfExperimentUpdatedSignal signal
) {
977 public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal
) {
978 if (signal
.getExperiment() == this) {
979 indexExperiment(false, (int) fNbEvents
, signal
.getRange());
984 public void traceUpdated(TmfTraceUpdatedSignal signal
) {
985 for (ITmfTrace
<T
> trace
: fTraces
) {
986 if (trace
== signal
.getTrace()) {
987 synchronized (fCheckpoints
) {
989 if (fIndexingPendingRange
== TmfTimeRange
.Null
) {
990 fIndexingPendingRange
= signal
.getRange();
992 ITmfTimestamp startTime
= fIndexingPendingRange
.getStartTime();
993 ITmfTimestamp endTime
= fIndexingPendingRange
.getEndTime();
994 if (signal
.getRange().getStartTime().compareTo(startTime
) < 0) {
995 startTime
= signal
.getRange().getStartTime();
997 if (signal
.getRange().getEndTime().compareTo(endTime
) > 0) {
998 endTime
= signal
.getRange().getEndTime();
1000 fIndexingPendingRange
= new TmfTimeRange(startTime
, endTime
);
1005 indexExperiment(false, (int) fNbEvents
, signal
.getRange());
1012 public String
getPath() {
1013 // TODO Auto-generated method stub
1018 * Set the resource to be used for bookmarks on this experiment
1019 * @param resource the bookmarks resource
1021 public void setResource(IResource resource
) {
1022 fResource
= resource
;
1026 * Get the resource used for bookmarks on this experiment
1027 * @return the bookmarks resource or null if none is set
1029 public IResource
getResource() {