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