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