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