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