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