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