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