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