Change ITmfTrace<T extends TmfEvent> to ITmfTrace<T extends ITmfEvent>
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfTrace.java
CommitLineData
8c8bf09f 1/*******************************************************************************
e31e01e8 2 * Copyright (c) 2009, 2010 Ericsson
8c8bf09f
ASL
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
6c13869b 13package org.eclipse.linuxtools.tmf.core.trace;
8c8bf09f 14
6f4a1d2b 15import java.io.File;
62d1696a 16import java.io.FileNotFoundException;
62d1696a 17import java.util.Collections;
8c8bf09f
ASL
18import java.util.Vector;
19
12c155f5 20import org.eclipse.core.resources.IProject;
828e5592 21import org.eclipse.core.resources.IResource;
05bd3318
FC
22import org.eclipse.core.runtime.IProgressMonitor;
23import org.eclipse.core.runtime.IStatus;
c7e2f194 24import org.eclipse.core.runtime.Path;
05bd3318
FC
25import org.eclipse.core.runtime.Status;
26import org.eclipse.core.runtime.jobs.Job;
6c13869b 27import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
72f1e62a 28import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
4df4581d 29import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
6c13869b
FC
30import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
31import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
32import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
33import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
34import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
35import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
36import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal;
8c8bf09f
ASL
37
38/**
146a887c 39 * <b><u>TmfTrace</u></b>
8c8bf09f 40 * <p>
12c155f5
FC
41 * Abstract implementation of ITmfTrace. It should be sufficient to extend this class and provide implementation for
42 * <code>getCurrentLocation()</code> and <code>seekLocation()</code>, as well as a proper parser, to have a working
4e3aa37d 43 * concrete implementation.
ff4ed569 44 * <p>
12c155f5
FC
45 * Note: The notion of event rank is still under heavy discussion. Although used by the Events View and probably useful
46 * in the general case, there is no easy way to implement it for LTTng (actually a strong case is being made that this
47 * is useless).
ff4ed569 48 * <p>
12c155f5
FC
49 * That it is not supported by LTTng does by no mean indicate that it is not useful for (just about) every other tracing
50 * tool. Therefore, this class provides a minimal (and partial) implementation of rank. However, the current
ff4ed569 51 * implementation should not be relied on in the general case.
54d55ced 52 *
4e3aa37d 53 * TODO: Add support for live streaming (notifications, incremental indexing, ...)
8c8bf09f 54 */
72f1e62a 55public abstract class TmfTrace<T extends ITmfEvent> extends TmfEventProvider<T> implements ITmfTrace<T>, Cloneable {
62d1696a 56
e31e01e8 57 // ------------------------------------------------------------------------
62d1696a 58 // Constants
e31e01e8 59 // ------------------------------------------------------------------------
62d1696a
FC
60
61 // The default number of events to cache
12c155f5 62 // TODO: Make the DEFAULT_CACHE_SIZE a preference
b12f4544 63 public static final int DEFAULT_INDEX_PAGE_SIZE = 50000;
8c8bf09f 64
e31e01e8 65 // ------------------------------------------------------------------------
8c8bf09f 66 // Attributes
e31e01e8 67 // ------------------------------------------------------------------------
8c8bf09f 68
b0a282fb 69 // The trace path
12c155f5 70 private String fPath;
b0a282fb 71
00641a97 72 // The trace name
c5b45b39 73 private String fTraceName;
00641a97 74
8d2e2848 75 // The cache page size AND checkpoints interval
12c155f5 76 protected int fIndexPageSize = DEFAULT_INDEX_PAGE_SIZE;
62d1696a
FC
77
78 // The set of event stream checkpoints (for random access)
9f584e4c 79 protected Vector<TmfCheckpoint> fCheckpoints = new Vector<TmfCheckpoint>();
62d1696a
FC
80
81 // The number of events collected
a3fe52fc 82 protected long fNbEvents = 0;
62d1696a
FC
83
84 // The time span of the event stream
4df4581d 85 private ITmfTimestamp fStartTime = TmfTimestamp.BigCrunch;
86 private ITmfTimestamp fEndTime = TmfTimestamp.BigBang;
62d1696a 87
828e5592
PT
88 // The trace resource
89 private IResource fResource;
90
e31e01e8 91 // ------------------------------------------------------------------------
50adc88e 92 // Constructors
e31e01e8 93 // ------------------------------------------------------------------------
8c8bf09f 94
12c155f5 95 public TmfTrace() {
00641a97 96 super();
12c155f5
FC
97 }
98
99 @Override
0710697b
PT
100 public void initTrace(String name, String path, Class<T> eventType) throws FileNotFoundException {
101 initTmfTrace(name, path, eventType, DEFAULT_INDEX_PAGE_SIZE, false);
12c155f5
FC
102 }
103
104 @Override
0710697b
PT
105 public void initTrace(String name, String path, Class<T> eventType, int cacheSize) throws FileNotFoundException {
106 initTmfTrace(name, path, eventType, cacheSize, false);
12c155f5
FC
107 }
108
109 @Override
0710697b
PT
110 public void initTrace(String name, String path, Class<T> eventType, boolean indexTrace) throws FileNotFoundException {
111 initTmfTrace(name, path, eventType, DEFAULT_INDEX_PAGE_SIZE, indexTrace);
12c155f5
FC
112 }
113
114 @Override
0710697b
PT
115 public void initTrace(String name, String path, Class<T> eventType, int cacheSize, boolean indexTrace) throws FileNotFoundException {
116 initTmfTrace(name, path, eventType, cacheSize, indexTrace);
c5b45b39
FC
117 }
118
0710697b 119 private void initTmfTrace(String name, String path, Class<T> eventType, int cacheSize, boolean indexTrace) throws FileNotFoundException {
12c155f5 120 fPath = path;
96c6806f
PT
121 if (name != null) {
122 fTraceName = name;
123 }
c5b45b39
FC
124 if (fTraceName == null) {
125 fTraceName = ""; //$NON-NLS-1$
00641a97 126 if (path != null) {
c7e2f194 127 int sep = path.lastIndexOf(Path.SEPARATOR);
c5b45b39 128 fTraceName = (sep >= 0) ? path.substring(sep + 1) : path;
00641a97 129 }
12c155f5 130 }
c5b45b39 131 super.init(fTraceName, eventType);
12c155f5 132 fIndexPageSize = (cacheSize > 0) ? cacheSize : DEFAULT_INDEX_PAGE_SIZE;
12c155f5
FC
133 if (indexTrace)
134 indexTrace(false);
135 }
136
137 @Override
138 public boolean validate(IProject project, String path) {
139 File file = new File(path);
140 return file.exists();
141 }
142
ff4ed569
FC
143 /**
144 * @param path
145 * @throws FileNotFoundException
146 */
ce785d7d 147 protected TmfTrace(String name, Class<T> type, String path) throws FileNotFoundException {
12c155f5 148 this(name, type, path, DEFAULT_INDEX_PAGE_SIZE, true);
ff4ed569
FC
149 }
150
62d1696a 151 /**
e31e01e8
FC
152 * @param path
153 * @param cacheSize
62d1696a
FC
154 * @throws FileNotFoundException
155 */
ce785d7d 156 protected TmfTrace(String name, Class<T> type, String path, int cacheSize) throws FileNotFoundException {
12c155f5 157 this(name, type, path, cacheSize, true);
05bd3318
FC
158 }
159
160 /**
161 * @param path
162 * @param indexTrace
163 * @throws FileNotFoundException
164 */
165 protected TmfTrace(String name, Class<T> type, String path, boolean indexTrace) throws FileNotFoundException {
12c155f5 166 this(name, type, path, DEFAULT_INDEX_PAGE_SIZE, indexTrace);
05bd3318
FC
167 }
168
169 /**
170 * @param path
171 * @param cacheSize
172 * @param indexTrace
173 * @throws FileNotFoundException
174 */
175 protected TmfTrace(String name, Class<T> type, String path, int cacheSize, boolean indexTrace) throws FileNotFoundException {
00641a97 176 super();
c5b45b39 177 fTraceName = name;
0710697b 178 initTrace(name, path, type, cacheSize, indexTrace);
8c8bf09f
ASL
179 }
180
ff4ed569 181 @SuppressWarnings("unchecked")
12c155f5
FC
182 @Override
183 public TmfTrace<T> clone() throws CloneNotSupportedException {
184 TmfTrace<T> clone = (TmfTrace<T>) super.clone();
185 clone.fCheckpoints = fCheckpoints;
4df4581d 186 clone.fStartTime = fStartTime.clone();
187 clone.fEndTime = fEndTime.clone();
12c155f5 188 return clone;
8c8bf09f
ASL
189 }
190
e31e01e8 191 // ------------------------------------------------------------------------
8c8bf09f 192 // Accessors
e31e01e8 193 // ------------------------------------------------------------------------
8c8bf09f 194
62d1696a 195 /**
b0a282fb 196 * @return the trace path
62d1696a 197 */
d4011df2 198 @Override
12c155f5 199 public String getPath() {
b0a282fb 200 return fPath;
8c8bf09f
ASL
201 }
202
62d1696a
FC
203 /* (non-Javadoc)
204 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getNbEvents()
205 */
d4011df2 206 @Override
12c155f5 207 public long getNbEvents() {
62d1696a 208 return fNbEvents;
8c8bf09f
ASL
209 }
210
b0a282fb
FC
211 /**
212 * @return the size of the cache
213 */
d4011df2 214 @Override
12c155f5 215 public int getCacheSize() {
9f584e4c 216 return fIndexPageSize;
b0a282fb
FC
217 }
218
62d1696a
FC
219 /* (non-Javadoc)
220 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getTimeRange()
221 */
d4011df2 222 @Override
12c155f5 223 public TmfTimeRange getTimeRange() {
cb866e08 224 return new TmfTimeRange(fStartTime, fEndTime);
8c8bf09f
ASL
225 }
226
e31e01e8
FC
227 /* (non-Javadoc)
228 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStartTime()
229 */
d4011df2 230 @Override
4df4581d 231 public ITmfTimestamp getStartTime() {
12c155f5 232 return fStartTime;
146a887c
FC
233 }
234
e31e01e8
FC
235 /* (non-Javadoc)
236 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getEndTime()
237 */
d4011df2 238 @Override
4df4581d 239 public ITmfTimestamp getEndTime() {
12c155f5 240 return fEndTime;
146a887c
FC
241 }
242
1b70b6dc
PT
243 /* (non-Javadoc)
244 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStreamingInterval()
245 */
246 @Override
247 public long getStreamingInterval() {
248 return 0;
249 }
250
ff4ed569 251 @SuppressWarnings("unchecked")
12c155f5
FC
252 public Vector<TmfCheckpoint> getCheckpoints() {
253 return (Vector<TmfCheckpoint>) fCheckpoints.clone();
54d55ced
FC
254 }
255
abfad0aa 256 /**
12c155f5
FC
257 * Returns the rank of the first event with the requested timestamp. If none, returns the index of the next event
258 * (if any).
259 *
abfad0aa
FC
260 * @param timestamp
261 * @return
262 */
d4011df2 263 @Override
4df4581d 264 public long getRank(ITmfTimestamp timestamp) {
abfad0aa
FC
265 TmfContext context = seekEvent(timestamp);
266 return context.getRank();
267 }
268
e31e01e8 269 // ------------------------------------------------------------------------
8c8bf09f 270 // Operators
e31e01e8 271 // ------------------------------------------------------------------------
8c8bf09f 272
4e3aa37d 273 protected void setTimeRange(TmfTimeRange range) {
12c155f5
FC
274 fStartTime = range.getStartTime();
275 fEndTime = range.getEndTime();
4e3aa37d
FC
276 }
277
d7dbf09a 278 protected void setStartTime(ITmfTimestamp startTime) {
12c155f5 279 fStartTime = startTime;
4e3aa37d
FC
280 }
281
dfee01ae 282 protected void setEndTime(ITmfTimestamp endTime) {
12c155f5
FC
283 fEndTime = endTime;
284 }
285
286 // ------------------------------------------------------------------------
287 // TmfProvider
288 // ------------------------------------------------------------------------
289
290 @Override
291 public ITmfContext armRequest(ITmfDataRequest<T> request) {
292 if (request instanceof ITmfEventRequest<?>
293 && !TmfTimestamp.BigBang.equals(((ITmfEventRequest<T>) request).getRange().getStartTime()) && request.getIndex() == 0) {
294 ITmfContext context = seekEvent(((ITmfEventRequest<T>) request).getRange().getStartTime());
295 ((ITmfEventRequest<T>) request).setStartIndex((int) context.getRank());
296 return context;
297
298 }
299 return seekEvent(request.getIndex());
300 }
301
302 /**
303 * Return the next piece of data based on the context supplied. The context would typically be updated for the
304 * subsequent read.
305 *
306 * @param context
307 * @return
308 */
309 @SuppressWarnings("unchecked")
310 @Override
311 public T getNext(ITmfContext context) {
312 if (context instanceof TmfContext) {
313 return (T) getNextEvent((TmfContext) context);
314 }
315 return null;
316 }
317
318 // ------------------------------------------------------------------------
319 // ITmfTrace
320 // ------------------------------------------------------------------------
e31e01e8 321
146a887c
FC
322 /* (non-Javadoc)
323 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.event.TmfTimestamp)
324 */
d4011df2 325 @Override
4df4581d 326 public TmfContext seekEvent(ITmfTimestamp timestamp) {
62d1696a 327
12c155f5
FC
328 if (timestamp == null) {
329 timestamp = TmfTimestamp.BigBang;
330 }
4e3aa37d 331
12c155f5
FC
332 // First, find the right checkpoint
333 int index = Collections.binarySearch(fCheckpoints, new TmfCheckpoint(timestamp, null));
62d1696a 334
8d2e2848 335 // In the very likely case that the checkpoint was not found, bsearch
62d1696a
FC
336 // returns its negated would-be location (not an offset...). From that
337 // index, we can then position the stream and get the event.
338 if (index < 0) {
339 index = Math.max(0, -(index + 2));
340 }
341
342 // Position the stream at the checkpoint
452ad365 343 ITmfLocation<?> location;
e31e01e8 344 synchronized (fCheckpoints) {
12c155f5
FC
345 if (fCheckpoints.size() > 0) {
346 if (index >= fCheckpoints.size()) {
347 index = fCheckpoints.size() - 1;
348 }
349 location = fCheckpoints.elementAt(index).getLocation();
350 } else {
351 location = null;
352 }
8d2e2848 353 }
54d55ced
FC
354 TmfContext context = seekLocation(location);
355 context.setRank(index * fIndexPageSize);
62d1696a 356
54d55ced 357 // And locate the event
ff4ed569 358 TmfContext nextEventContext = context.clone(); // Must use clone() to get the right subtype...
72f1e62a 359 ITmfEvent event = getNextEvent(nextEventContext);
62d1696a 360 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
12c155f5
FC
361 context.setLocation(nextEventContext.getLocation().clone());
362 context.updateRank(1);
363 event = getNextEvent(nextEventContext);
62d1696a
FC
364 }
365
54d55ced 366 return context;
62d1696a
FC
367 }
368
146a887c
FC
369 /* (non-Javadoc)
370 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(int)
371 */
d4011df2 372 @Override
12c155f5 373 public TmfContext seekEvent(long rank) {
62d1696a
FC
374
375 // Position the stream at the previous checkpoint
9f584e4c 376 int index = (int) rank / fIndexPageSize;
452ad365 377 ITmfLocation<?> location;
e31e01e8 378 synchronized (fCheckpoints) {
12c155f5
FC
379 if (fCheckpoints.size() == 0) {
380 location = null;
381 } else {
382 if (index >= fCheckpoints.size()) {
383 index = fCheckpoints.size() - 1;
384 }
385 location = fCheckpoints.elementAt(index).getLocation();
386 }
8d2e2848 387 }
54d55ced 388
9f584e4c
FC
389 TmfContext context = seekLocation(location);
390 long pos = index * fIndexPageSize;
391 context.setRank(pos);
e31e01e8 392
9f584e4c 393 if (pos < rank) {
72f1e62a 394 ITmfEvent event = getNextEvent(context);
9f584e4c 395 while (event != null && ++pos < rank) {
12c155f5 396 event = getNextEvent(context);
e31e01e8 397 }
165c977c 398 }
62d1696a 399
8f50c396 400 return context;
8c8bf09f
ASL
401 }
402
12c155f5
FC
403 /*
404 * (non-Javadoc)
405 *
406 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getNextEvent(org.eclipse.
407 * linuxtools.tmf.trace.ITmfTrace.TraceContext)
408 */
409 @Override
72f1e62a 410 public synchronized ITmfEvent getNextEvent(TmfContext context) {
12c155f5 411 // parseEvent() does not update the context
72f1e62a 412 ITmfEvent event = parseEvent(context);
12c155f5
FC
413 if (event != null) {
414 updateIndex(context, context.getRank(), event.getTimestamp());
415 context.setLocation(getCurrentLocation());
416 context.updateRank(1);
417 processEvent(event);
418 }
419 return event;
420 }
550d787e 421
4df4581d 422 protected synchronized void updateIndex(ITmfContext context, long rank, ITmfTimestamp timestamp) {
12c155f5
FC
423 if (fStartTime.compareTo(timestamp, false) > 0)
424 fStartTime = timestamp;
425 if (fEndTime.compareTo(timestamp, false) < 0)
426 fEndTime = timestamp;
427 if (context.isValidRank()) {
428 if (fNbEvents <= rank)
429 fNbEvents = rank + 1;
430 // Build the index as we go along
431 if ((rank % fIndexPageSize) == 0) {
432 // Determine the table position
433 long position = rank / fIndexPageSize;
434 // Add new entry at proper location (if empty)
435 if (fCheckpoints.size() == position) {
436 ITmfLocation<?> location = context.getLocation().clone();
437 fCheckpoints.add(new TmfCheckpoint(timestamp.clone(), location));
438 // System.out.println(getName() + "[" + (fCheckpoints.size()
439 // - 1) + "] " + timestamp + ", " + location.toString());
440 }
441 }
442 }
443 }
4e3aa37d 444
e31e01e8 445 /**
12c155f5
FC
446 * Hook for special processing by the concrete class (called by getNextEvent())
447 *
448 * @param event
449 */
72f1e62a 450 protected void processEvent(ITmfEvent event) {
12c155f5
FC
451 // Do nothing by default
452 }
453
454 // ------------------------------------------------------------------------
455 // toString
456 // ------------------------------------------------------------------------
457
458 /* (non-Javadoc)
459 * @see java.lang.Object#toString()
4e3aa37d 460 */
d4011df2 461 @Override
12c155f5
FC
462 @SuppressWarnings("nls")
463 public String toString() {
464 return "[TmfTrace (" + getName() + ")]";
465 }
466
664902f7
FC
467 // ------------------------------------------------------------------------
468 // Indexing
469 // ------------------------------------------------------------------------
470
12c155f5
FC
471 /*
472 * The purpose of the index is to keep the information needed to rapidly
473 * restore the traces contexts at regular intervals (every INDEX_PAGE_SIZE
474 * event).
475 */
83e13355 476
8e31f2d2 477 @SuppressWarnings({ "unchecked" })
a79913eb 478 protected void indexTrace(boolean waitForCompletion) {
83e13355 479
12c155f5
FC
480 final Job job = new Job("Indexing " + getName() + "...") { //$NON-NLS-1$ //$NON-NLS-2$
481 @Override
482 protected IStatus run(IProgressMonitor monitor) {
483 while (!monitor.isCanceled()) {
484 try {
485 Thread.sleep(100);
486 } catch (InterruptedException e) {
487 return Status.OK_STATUS;
488 }
489 }
490 monitor.done();
491 return Status.OK_STATUS;
492 }
493 };
494 job.schedule();
495
496 fCheckpoints.clear();
72f1e62a 497 ITmfEventRequest<ITmfEvent> request = new TmfEventRequest<ITmfEvent>(ITmfEvent.class, TmfTimeRange.Eternity, TmfDataRequest.ALL_DATA,
12c155f5
FC
498 fIndexPageSize, ITmfDataRequest.ExecutionType.BACKGROUND) {
499
4df4581d 500 ITmfTimestamp startTime = null;
501 ITmfTimestamp lastTime = null;
83e13355
FC
502
503 @Override
72f1e62a 504 public void handleData(ITmfEvent event) {
83e13355
FC
505 super.handleData(event);
506 if (event != null) {
4df4581d 507 ITmfTimestamp ts = event.getTimestamp();
83e13355 508 if (startTime == null)
4df4581d 509 startTime = ts.clone();
510 lastTime = ts.clone();
83e13355 511
64267c9d 512 if ((getNbRead() % fIndexPageSize) == 0) {
83e13355
FC
513 updateTrace();
514 }
515 }
516 }
517
518 @Override
519 public void handleSuccess() {
520 updateTrace();
521 }
522
05bd3318
FC
523 @Override
524 public void handleCompleted() {
12c155f5
FC
525 job.cancel();
526 super.handleCompleted();
05bd3318
FC
527 }
528
83e13355
FC
529 private void updateTrace() {
530 int nbRead = getNbRead();
531 if (nbRead != 0) {
532 fStartTime = startTime;
533 fEndTime = lastTime;
12c155f5 534 fNbEvents = nbRead;
83e13355
FC
535 notifyListeners();
536 }
537 }
538 };
539
540 sendRequest((ITmfDataRequest<T>) request);
541 if (waitForCompletion)
542 try {
543 request.waitForCompletion();
544 } catch (InterruptedException e) {
545 e.printStackTrace();
546 }
547 }
548
12c155f5
FC
549 protected void notifyListeners() {
550 broadcast(new TmfTraceUpdatedSignal(this, this, new TmfTimeRange(fStartTime, fEndTime)));
551 }
828e5592
PT
552
553 /**
554 * Set the resource to be used for bookmarks on this trace
555 * @param resource the bookmarks resource
556 */
557 public void setResource(IResource resource) {
558 fResource = resource;
559 }
560
561 /**
562 * Get the resource used for bookmarks on this trace
563 * @return the bookmarks resource or null if none is set
564 */
565 public IResource getResource() {
566 return fResource;
567 }
8c8bf09f 568}
This page took 0.069046 seconds and 5 git commands to generate.