tmf/lttng: Remove unneeded (non-Javadoc) comments
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfExperiment.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2013 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 * Francois Chouinard - Updated as per TMF Trace Model 1.0
12 * Patrick Tasse - Updated for removal of context clone
13 * Patrick Tasse - Updated for ranks in experiment location
14 *******************************************************************************/
15
16 package org.eclipse.linuxtools.tmf.core.trace;
17
18 import org.eclipse.core.resources.IFile;
19 import org.eclipse.core.resources.IProject;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.IStatus;
22 import org.eclipse.core.runtime.Status;
23 import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext;
24 import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation;
25 import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray;
26 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
27 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
28 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
29 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
30 import org.eclipse.linuxtools.tmf.core.signal.TmfClearExperimentSignal;
31 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
32 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
33 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
34 import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
35 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
36 import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
37
38 /**
39 * TmfExperiment presents a time-ordered, unified view of a set of ITmfTrace:s
40 * that are part of a tracing experiment.
41 *
42 * @version 1.0
43 * @author Francois Chouinard
44 */
45 public class TmfExperiment extends TmfTrace implements ITmfEventParser {
46
47 // ------------------------------------------------------------------------
48 // Constants
49 // ------------------------------------------------------------------------
50
51 /**
52 * The default index page size
53 */
54 public static final int DEFAULT_INDEX_PAGE_SIZE = 5000;
55
56 // ------------------------------------------------------------------------
57 // Attributes
58 // ------------------------------------------------------------------------
59
60 /**
61 * The set of traces that constitute the experiment
62 */
63 protected ITmfTrace[] fTraces;
64
65 /**
66 * The set of traces that constitute the experiment
67 */
68 private boolean fInitialized = false;
69
70 /**
71 * The experiment bookmarks file
72 */
73 private IFile fBookmarksFile;
74
75 // ------------------------------------------------------------------------
76 // Construction
77 // ------------------------------------------------------------------------
78
79 /**
80 * @param type the event type
81 * @param id the experiment id
82 * @param traces the experiment set of traces
83 */
84 public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces) {
85 this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, null);
86 }
87
88 /**
89 * Constructor of experiment taking type, path, traces and resource
90 *
91 * @param type
92 * the event type
93 * @param id
94 * the experiment id
95 * @param traces
96 * the experiment set of traces
97 * @param resource
98 * the resource associated to the experiment
99 */
100 public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces, IResource resource) {
101 this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, resource);
102 }
103
104
105 /**
106 * @param type the event type
107 * @param path the experiment path
108 * @param traces the experiment set of traces
109 * @param indexPageSize the experiment index page size
110 */
111 public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize) {
112 this(type, path, traces, indexPageSize, null);
113 }
114
115 /**
116 * Full constructor of an experiment, taking the type, path, traces,
117 * indexPageSize and resource
118 *
119 * @param type
120 * the event type
121 * @param path
122 * the experiment path
123 * @param traces
124 * the experiment set of traces
125 * @param indexPageSize
126 * the experiment index page size
127 * @param resource
128 * the resource associated to the experiment
129 */
130 public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize, IResource resource) {
131 setCacheSize(indexPageSize);
132 setStreamingInterval(0);
133 setIndexer(new TmfCheckpointIndexer(this, indexPageSize));
134 setParser(this);
135 try {
136 super.initialize(resource, path, type);
137 } catch (TmfTraceException e) {
138 e.printStackTrace();
139 }
140
141 fTraces = traces;
142 }
143
144 /**
145 * Clears the experiment
146 */
147 @Override
148 public synchronized void dispose() {
149
150 // Clean up the index if applicable
151 if (getIndexer() != null) {
152 getIndexer().dispose();
153 }
154
155 if (fTraces != null) {
156 for (final ITmfTrace trace : fTraces) {
157 trace.dispose();
158 }
159 fTraces = null;
160 }
161 super.dispose();
162 }
163
164 /**
165 * @param signal the clear view signal
166 * @since 2.0
167 */
168 @TmfSignalHandler
169 public void handleClearExperimentSignal(TmfClearExperimentSignal signal) {
170 dispose();
171 }
172
173 // ------------------------------------------------------------------------
174 // ITmfTrace - Initializers
175 // ------------------------------------------------------------------------
176
177 @Override
178 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) {
179 }
180
181 /**
182 * @since 2.0
183 */
184 @Override
185 public IStatus validate(final IProject project, final String path) {
186 return Status.OK_STATUS;
187 }
188
189 // ------------------------------------------------------------------------
190 // Accessors
191 // ------------------------------------------------------------------------
192
193 @Override
194 public ITmfTrace[] getTraces() {
195 return fTraces;
196 }
197
198 /**
199 * Returns the timestamp of the event at the requested index. If none,
200 * returns null.
201 *
202 * @param index the event index (rank)
203 * @return the corresponding event timestamp
204 * @since 2.0
205 */
206 public ITmfTimestamp getTimestamp(final int index) {
207 final ITmfContext context = seekEvent(index);
208 final ITmfEvent event = getNext(context);
209 context.dispose();
210 return (event != null) ? event.getTimestamp() : null;
211 }
212
213 /**
214 * Set the file to be used for bookmarks on this experiment
215 *
216 * @param file the bookmarks file
217 */
218 public void setBookmarksFile(final IFile file) {
219 fBookmarksFile = file;
220 }
221
222 /**
223 * Get the file used for bookmarks on this experiment
224 *
225 * @return the bookmarks file or null if none is set
226 */
227 public IFile getBookmarksFile() {
228 return fBookmarksFile;
229 }
230
231 // ------------------------------------------------------------------------
232 // Request management
233 // ------------------------------------------------------------------------
234
235 /**
236 * @since 2.0
237 */
238 @Override
239 public synchronized ITmfContext armRequest(final ITmfDataRequest request) {
240
241 // Make sure we have something to read from
242 if (fTraces == null) {
243 return null;
244 }
245
246 if (request instanceof ITmfEventRequest
247 && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest) request).getRange().getStartTime())
248 && request.getIndex() == 0)
249 {
250 final ITmfContext context = seekEvent(((ITmfEventRequest) request).getRange().getStartTime());
251 ((ITmfEventRequest) request).setStartIndex((int) context.getRank());
252 return context;
253
254 }
255
256 return seekEvent(request.getIndex());
257 }
258
259 // ------------------------------------------------------------------------
260 // ITmfTrace trace positioning
261 // ------------------------------------------------------------------------
262
263 @Override
264 public synchronized ITmfContext seekEvent(final ITmfLocation location) {
265 // Validate the location
266 if (location != null && !(location instanceof TmfExperimentLocation)) {
267 return null; // Throw an exception?
268 }
269 // Make sure we have something to read from
270 if (fTraces == null) {
271 return null;
272 }
273
274 // Initialize the location array if necessary
275 TmfLocationArray locationArray = ((location == null) ?
276 new TmfLocationArray(fTraces.length) :
277 ((TmfExperimentLocation) location).getLocationInfo());
278
279 ITmfLocation[] locations = locationArray.getLocations();
280 long[] ranks = locationArray.getRanks();
281
282 // Create and populate the context's traces contexts
283 final TmfExperimentContext context = new TmfExperimentContext(fTraces.length);
284
285 // Position the traces
286 long rank = 0;
287 for (int i = 0; i < fTraces.length; i++) {
288 // Get the relevant trace attributes
289 final ITmfContext traceContext = fTraces[i].seekEvent(locations[i]);
290 context.getContexts()[i] = traceContext;
291 traceContext.setRank(ranks[i]);
292 locations[i] = traceContext.getLocation(); // update location after seek
293 context.getEvents()[i] = fTraces[i].getNext(traceContext);
294 rank += ranks[i];
295 }
296
297 // Finalize context
298 context.setLocation(new TmfExperimentLocation(new TmfLocationArray(locations, ranks)));
299 context.setLastTrace(TmfExperimentContext.NO_TRACE);
300 context.setRank(rank);
301
302 return context;
303 }
304
305 // ------------------------------------------------------------------------
306 // ITmfTrace - SeekEvent operations (returning a trace context)
307 // ------------------------------------------------------------------------
308
309 @Override
310 public ITmfContext seekEvent(final double ratio) {
311 final ITmfContext context = seekEvent(Math.round(ratio * getNbEvents()));
312 return context;
313 }
314
315 @Override
316 public double getLocationRatio(final ITmfLocation location) {
317 if (location instanceof TmfExperimentLocation) {
318 long rank = 0;
319 TmfLocationArray locationArray = ((TmfExperimentLocation) location).getLocationInfo();
320 for (int i = 0; i < locationArray.size(); i++) {
321 rank += locationArray.getRank(i);
322 }
323 return (double) rank / getNbEvents();
324 }
325 return 0.0;
326 }
327
328 @Override
329 public ITmfLocation getCurrentLocation() {
330 // never used
331 return null;
332 }
333
334 // ------------------------------------------------------------------------
335 // ITmfTrace trace positioning
336 // ------------------------------------------------------------------------
337
338 @Override
339 public synchronized ITmfEvent parseEvent(final ITmfContext context) {
340 final ITmfContext tmpContext = seekEvent(context.getLocation());
341 final ITmfEvent event = getNext(tmpContext);
342 return event;
343 }
344
345 @Override
346 public synchronized ITmfEvent getNext(ITmfContext context) {
347
348 // Validate the context
349 if (!(context instanceof TmfExperimentContext)) {
350 return null; // Throw an exception?
351 }
352
353 // Make sure that we have something to read from
354 if (fTraces == null) {
355 return null;
356 }
357
358 TmfExperimentContext expContext = (TmfExperimentContext) context;
359
360 // If an event was consumed previously, first get the next one from that trace
361 final int lastTrace = expContext.getLastTrace();
362 if (lastTrace != TmfExperimentContext.NO_TRACE) {
363 final ITmfContext traceContext = expContext.getContexts()[lastTrace];
364 expContext.getEvents()[lastTrace] = fTraces[lastTrace].getNext(traceContext);
365 expContext.setLastTrace(TmfExperimentContext.NO_TRACE);
366 }
367
368 // Scan the candidate events and identify the "next" trace to read from
369 int trace = TmfExperimentContext.NO_TRACE;
370 ITmfTimestamp timestamp = TmfTimestamp.BIG_CRUNCH;
371 for (int i = 0; i < fTraces.length; i++) {
372 final ITmfEvent event = expContext.getEvents()[i];
373 if (event != null && event.getTimestamp() != null) {
374 final ITmfTimestamp otherTS = event.getTimestamp();
375 if (otherTS.compareTo(timestamp, true) < 0) {
376 trace = i;
377 timestamp = otherTS;
378 }
379 }
380 }
381
382 ITmfEvent event = null;
383 if (trace != TmfExperimentContext.NO_TRACE) {
384 event = expContext.getEvents()[trace];
385 if (event != null) {
386 updateAttributes(expContext, event.getTimestamp());
387 expContext.increaseRank();
388 expContext.setLastTrace(trace);
389 final ITmfContext traceContext = expContext.getContexts()[trace];
390
391 // Update the experiment location
392 TmfLocationArray locationArray = new TmfLocationArray(
393 ((TmfExperimentLocation) expContext.getLocation()).getLocationInfo(),
394 trace, traceContext.getLocation(), traceContext.getRank());
395 expContext.setLocation(new TmfExperimentLocation(locationArray));
396
397 processEvent(event);
398 }
399 }
400
401 return event;
402 }
403
404 /**
405 * @since 2.0
406 */
407 @Override
408 public ITmfTimestamp getInitialRangeOffset() {
409 if ((fTraces == null) || (fTraces.length == 0)) {
410 return super.getInitialRangeOffset();
411 }
412
413 ITmfTimestamp initTs = TmfTimestamp.BIG_CRUNCH;
414 for (int i = 0; i < fTraces.length; i++) {
415 ITmfTimestamp ts = fTraces[i].getInitialRangeOffset();
416 if (ts.compareTo(initTs) < 0) {
417 initTs = ts;
418 }
419 }
420 return initTs;
421 }
422
423 @Override
424 @SuppressWarnings("nls")
425 public synchronized String toString() {
426 return "[TmfExperiment (" + getName() + ")]";
427 }
428
429 // ------------------------------------------------------------------------
430 // Streaming support
431 // ------------------------------------------------------------------------
432
433 private synchronized void initializeStreamingMonitor() {
434
435 if (fInitialized) {
436 return;
437 }
438 fInitialized = true;
439
440 if (getStreamingInterval() == 0) {
441 final ITmfContext context = seekEvent(0);
442 final ITmfEvent event = getNext(context);
443 context.dispose();
444 if (event == null) {
445 return;
446 }
447 final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp(), TmfTimestamp.BIG_CRUNCH);
448 final TmfTraceRangeUpdatedSignal signal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
449
450 // Broadcast in separate thread to prevent deadlock
451 new Thread() {
452 @Override
453 public void run() {
454 broadcast(signal);
455 }
456 }.start();
457 return;
458 }
459
460 final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
461 private ITmfTimestamp safeTimestamp = null;
462 private ITmfTimestamp lastSafeTimestamp = null;
463 private TmfTimeRange timeRange = null;
464
465 @Override
466 public void run() {
467 while (!executorIsShutdown()) {
468 if (!getIndexer().isIndexing()) {
469 ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH;
470 ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG;
471 for (final ITmfTrace trace : fTraces) {
472 if (trace.getStartTime().compareTo(startTimestamp) < 0) {
473 startTimestamp = trace.getStartTime();
474 }
475 if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) {
476 endTimestamp = trace.getEndTime();
477 }
478 }
479 if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp, false) > 0)) {
480 timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
481 lastSafeTimestamp = safeTimestamp;
482 } else {
483 timeRange = null;
484 }
485 safeTimestamp = endTimestamp;
486 if (timeRange != null) {
487 final TmfTraceRangeUpdatedSignal signal =
488 new TmfTraceRangeUpdatedSignal(TmfExperiment.this, TmfExperiment.this, timeRange);
489 broadcast(signal);
490 }
491 }
492 try {
493 Thread.sleep(getStreamingInterval());
494 } catch (final InterruptedException e) {
495 e.printStackTrace();
496 }
497 }
498 }
499 };
500 thread.start();
501 }
502
503 @Override
504 public long getStreamingInterval() {
505 long interval = 0;
506 for (final ITmfTrace trace : fTraces) {
507 interval = Math.max(interval, trace.getStreamingInterval());
508 }
509 return interval;
510 }
511
512 // ------------------------------------------------------------------------
513 // Signal handlers
514 // ------------------------------------------------------------------------
515
516 @Override
517 @TmfSignalHandler
518 public void traceOpened(TmfTraceOpenedSignal signal) {
519 if (signal.getTrace() == this) {
520 initializeStreamingMonitor();
521 }
522 }
523
524 }
This page took 0.042419 seconds and 5 git commands to generate.