[Bug293101] Context menu fix: removed the unimplemented menu choices and enabled...
[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
b0a282fb 15import java.io.File;
62d1696a 16import java.io.FileNotFoundException;
62d1696a 17import java.util.Collections;
8c8bf09f
ASL
18import java.util.Vector;
19
62d1696a
FC
20import org.eclipse.core.runtime.IProgressMonitor;
21import org.eclipse.core.runtime.IStatus;
22import org.eclipse.core.runtime.Status;
23import org.eclipse.core.runtime.jobs.Job;
e31e01e8
FC
24import org.eclipse.linuxtools.tmf.component.ITmfContext;
25import org.eclipse.linuxtools.tmf.component.TmfProvider;
8c8bf09f
ASL
26import org.eclipse.linuxtools.tmf.event.TmfEvent;
27import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
28import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
4e3aa37d 29import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
e31e01e8 30import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
8c8bf09f
ASL
31
32/**
146a887c 33 * <b><u>TmfTrace</u></b>
8c8bf09f 34 * <p>
146a887c
FC
35 * Abstract implementation of ITmfTrace. It should be sufficient to extend this
36 * class and provide implementation for <code>getCurrentLocation()</code> and
37 * <code>seekLocation()</code>, as well as a proper parser, to have a working
4e3aa37d
FC
38 * concrete implementation.
39 *
40 * TODO: Add support for live streaming (notifications, incremental indexing, ...)
8c8bf09f 41 */
e31e01e8 42public abstract class TmfTrace<T extends TmfEvent> extends TmfProvider<T> implements ITmfTrace {
62d1696a 43
e31e01e8 44 // ------------------------------------------------------------------------
62d1696a 45 // Constants
e31e01e8 46 // ------------------------------------------------------------------------
62d1696a
FC
47
48 // The default number of events to cache
e31e01e8 49 // TODO: Make the DEFAULT_CACHE_SIZE a preference
8d2e2848 50 public static final int DEFAULT_CACHE_SIZE = 1000;
8c8bf09f 51
e31e01e8 52 // ------------------------------------------------------------------------
8c8bf09f 53 // Attributes
e31e01e8 54 // ------------------------------------------------------------------------
8c8bf09f 55
b0a282fb
FC
56 // The trace path
57 private final String fPath;
58
59 // The trace name
62d1696a
FC
60 private final String fName;
61
8d2e2848 62 // The cache page size AND checkpoints interval
a3fe52fc 63 protected int fCacheSize;
62d1696a
FC
64
65 // The set of event stream checkpoints (for random access)
146a887c 66 protected Vector<TmfTraceCheckpoint> fCheckpoints = new Vector<TmfTraceCheckpoint>();
62d1696a
FC
67
68 // The number of events collected
a3fe52fc 69 protected long fNbEvents = 0;
62d1696a
FC
70
71 // The time span of the event stream
72 private TmfTimeRange fTimeRange = new TmfTimeRange(TmfTimestamp.BigBang, TmfTimestamp.BigBang);
73
e31e01e8 74 // ------------------------------------------------------------------------
50adc88e 75 // Constructors
e31e01e8 76 // ------------------------------------------------------------------------
8c8bf09f 77
62d1696a 78 /**
e31e01e8
FC
79 * @param path
80 * @param cacheSize
62d1696a
FC
81 * @throws FileNotFoundException
82 */
e31e01e8
FC
83 protected TmfTrace(Class<T> type, String path, int cacheSize) throws FileNotFoundException {
84 super(type);
b0a282fb
FC
85 int sep = path.lastIndexOf(File.separator);
86 fName = (sep >= 0) ? path.substring(sep + 1) : path;
87 fPath = path;
e31e01e8 88 fCacheSize = (cacheSize > 0) ? cacheSize : DEFAULT_CACHE_SIZE;
8c8bf09f
ASL
89 }
90
62d1696a 91 /**
e31e01e8 92 * @param path
62d1696a
FC
93 * @throws FileNotFoundException
94 */
e31e01e8
FC
95 protected TmfTrace(Class<T> type, String path) throws FileNotFoundException {
96 this(type, path, DEFAULT_CACHE_SIZE);
8c8bf09f
ASL
97 }
98
e31e01e8 99 // ------------------------------------------------------------------------
8c8bf09f 100 // Accessors
e31e01e8 101 // ------------------------------------------------------------------------
8c8bf09f 102
62d1696a 103 /**
b0a282fb 104 * @return the trace path
62d1696a 105 */
b0a282fb
FC
106 public String getPath() {
107 return fPath;
8c8bf09f
ASL
108 }
109
62d1696a 110 /**
146a887c 111 * @return the trace name
62d1696a
FC
112 */
113 public String getName() {
114 return fName;
8c8bf09f
ASL
115 }
116
62d1696a
FC
117 /* (non-Javadoc)
118 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getNbEvents()
119 */
4e3aa37d 120 public long getNbEvents() {
62d1696a 121 return fNbEvents;
8c8bf09f
ASL
122 }
123
b0a282fb
FC
124 /**
125 * @return the size of the cache
126 */
8d2e2848
FC
127 public int getCacheSize() {
128 return fCacheSize;
b0a282fb
FC
129 }
130
62d1696a
FC
131 /* (non-Javadoc)
132 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getTimeRange()
133 */
8c8bf09f 134 public TmfTimeRange getTimeRange() {
62d1696a 135 return fTimeRange;
8c8bf09f
ASL
136 }
137
e31e01e8
FC
138 /* (non-Javadoc)
139 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStartTime()
140 */
146a887c
FC
141 public TmfTimestamp getStartTime() {
142 return fTimeRange.getStartTime();
143 }
144
e31e01e8
FC
145 /* (non-Javadoc)
146 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getEndTime()
147 */
146a887c
FC
148 public TmfTimestamp getEndTime() {
149 return fTimeRange.getEndTime();
150 }
151
e31e01e8
FC
152// /**
153// * Return the event rank based on its timestamp
154// *
155// * @param timestamp
156// * @return
157// */
158// protected long getIndex(TmfTimestamp timestamp) {
159// TmfTraceContext context = seekEvent(timestamp);
160// return context.getIndex();
161// }
162
163// /**
164// * Return the event timestamp based on its rank
165// * @param index
166// * @return
167// */
168// protected TmfTimestamp getTimestamp(int index) {
169// TmfTraceContext context = seekEvent(index);
170// return context.getTimestamp();
171// }
172
173 // ------------------------------------------------------------------------
8c8bf09f 174 // Operators
e31e01e8 175 // ------------------------------------------------------------------------
8c8bf09f 176
4e3aa37d
FC
177 protected void setTimeRange(TmfTimeRange range) {
178 fTimeRange = range;
179 }
180
181 protected void setStartTime(TmfTimestamp startTime) {
182 fTimeRange = new TmfTimeRange(startTime, fTimeRange.getEndTime());
183 }
184
185 protected void setEndTime(TmfTimestamp endTime) {
186 fTimeRange = new TmfTimeRange(fTimeRange.getStartTime(), endTime);
187 }
188
e31e01e8
FC
189 // ------------------------------------------------------------------------
190 // TmfProvider
191 // ------------------------------------------------------------------------
192
193 @Override
194 public ITmfContext setContext(TmfDataRequest<T> request) {
195 if (request instanceof TmfEventRequest<?>) {
196 return seekEvent(((TmfEventRequest<T>) request).getRange().getStartTime());
197 }
198 return null;
199 }
200
201 /**
202 * Return the next piece of data based on the context supplied. The context
203 * would typically be updated for the subsequent read.
204 *
205 * @param context
206 * @return
207 */
208 @SuppressWarnings("unchecked")
209 @Override
210 public T getNext(ITmfContext context) {
211 if (context instanceof TmfTraceContext) {
212 return (T) getNextEvent((TmfTraceContext) context);
213 }
214 return null;
215 }
216
217 @Override
218 public boolean isCompleted(TmfDataRequest<T> request, T data) {
219 if (request instanceof TmfEventRequest<?> && data != null) {
220 return data.getTimestamp().compareTo(((TmfEventRequest<T>) request).getRange().getEndTime(), false) > 0;
221 }
222 return true;
223 }
224
225
226 // ------------------------------------------------------------------------
227 // ITmfTrace
228 // ------------------------------------------------------------------------
229
146a887c
FC
230 /* (non-Javadoc)
231 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.event.TmfTimestamp)
232 */
233 public TmfTraceContext seekEvent(TmfTimestamp timestamp) {
62d1696a 234
4e3aa37d
FC
235 if (timestamp == null) {
236 timestamp = TmfTimestamp.BigBang;
237 }
238
239 // First, find the right checkpoint
146a887c 240 int index = Collections.binarySearch(fCheckpoints, new TmfTraceCheckpoint(timestamp, 0));
62d1696a 241
8d2e2848 242 // In the very likely case that the checkpoint was not found, bsearch
62d1696a
FC
243 // returns its negated would-be location (not an offset...). From that
244 // index, we can then position the stream and get the event.
245 if (index < 0) {
246 index = Math.max(0, -(index + 2));
247 }
248
249 // Position the stream at the checkpoint
8d2e2848 250 Object location;
e31e01e8
FC
251 synchronized (fCheckpoints) {
252 if (fCheckpoints.size() > 0) {
253 if (index >= fCheckpoints.size()) {
254 index = fCheckpoints.size() - 1;
255 }
256 location = fCheckpoints.elementAt(index).getLocation();
257 }
258 else {
259 location = null;
260 }
8d2e2848 261 }
4e3aa37d 262 TmfTraceContext nextEventContext = seekLocation(location);
e31e01e8 263 nextEventContext.setRank(index * fCacheSize);
4e3aa37d 264 TmfTraceContext currentEventContext = new TmfTraceContext(nextEventContext);
62d1696a
FC
265
266 // And get the event
267 TmfEvent event = getNextEvent(nextEventContext);
268 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
8d2e2848 269 currentEventContext.setLocation(nextEventContext.getLocation());
e31e01e8 270 currentEventContext.incrRank();
62d1696a
FC
271 event = getNextEvent(nextEventContext);
272 }
273
274 return currentEventContext;
275 }
276
146a887c
FC
277 /* (non-Javadoc)
278 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(int)
279 */
4e3aa37d 280 public TmfTraceContext seekEvent(long position) {
62d1696a
FC
281
282 // Position the stream at the previous checkpoint
8d2e2848
FC
283 int index = (int) position / fCacheSize;
284 Object location;
e31e01e8
FC
285 synchronized (fCheckpoints) {
286 if (fCheckpoints.size() > 0) {
287 if (index >= fCheckpoints.size()) {
288 index = fCheckpoints.size() - 1;
289 }
290 location = fCheckpoints.elementAt(index).getLocation();
291 }
292 else {
293 location = null;
294 }
8d2e2848 295 }
e31e01e8
FC
296 TmfTraceContext context = seekLocation(location);
297 long rank = index * fCacheSize;
298 context.setRank(rank);
299
300 if (rank < position) {
301 TmfEvent event = getNextEvent(context);
302 while (event != null && ++rank < position) {
303 event = getNextEvent(context);
304 }
165c977c 305 }
62d1696a 306
e31e01e8 307 return new TmfTraceContext(context.getLocation(), context.getRank());
8c8bf09f
ASL
308 }
309
146a887c
FC
310 /* (non-Javadoc)
311 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getNextEvent(org.eclipse.linuxtools.tmf.trace.ITmfTrace.TraceContext)
312 */
e31e01e8
FC
313 public synchronized TmfEvent getNextEvent(TmfTraceContext context) {
314 // parseEvent() does not update the context
cc6eec3e 315 TmfEvent event = parseEvent(context);
e31e01e8 316 context.setLocation(getCurrentLocation());
4e3aa37d 317 if (event != null) {
e31e01e8 318 context.incrRank();
4e3aa37d
FC
319 processEvent(event);
320 }
146a887c
FC
321 return event;
322 }
8c8bf09f 323
4e3aa37d 324 /**
e31e01e8
FC
325 * Hook for "special" processing by the concrete class
326 * (called by getNextEvent())
327 *
146a887c
FC
328 * @param event
329 */
330 public void processEvent(TmfEvent event) {
331 // Do nothing by default
62d1696a 332 }
4e3aa37d 333
e31e01e8
FC
334 /**
335 * To be implemented by the concrete class
4e3aa37d 336 */
e31e01e8
FC
337 public abstract Object getCurrentLocation();
338 public abstract TmfEvent parseEvent(TmfTraceContext context);
4e3aa37d 339
e31e01e8
FC
340 // ------------------------------------------------------------------------
341 // toString
342 // ------------------------------------------------------------------------
8d2e2848
FC
343
344 /* (non-Javadoc)
345 * @see java.lang.Object#toString()
346 */
347 @Override
348 public String toString() {
349 return "[TmfTrace (" + fName + "]";
350 }
351
e31e01e8
FC
352 // ------------------------------------------------------------------------
353 // Indexing
354 // ------------------------------------------------------------------------
146a887c 355
e31e01e8
FC
356 /*
357 * The purpose of the index is to keep the information needed to rapidly
358 * access a trace event based on its timestamp or rank.
359 *
360 * NOTE: As it is, doesn't work for streaming traces.
361 */
362
363 private IndexingJob job;
4e3aa37d 364 private Boolean fIndexing = false;
e31e01e8
FC
365
366 public void indexTrace(boolean waitForCompletion) {
4e3aa37d
FC
367 synchronized (fIndexing) {
368 if (fIndexing) {
369 return;
370 }
371 fIndexing = true;
372 }
373
e31e01e8 374 job = new IndexingJob("Indexing " + fName);
62d1696a 375 job.schedule();
4e3aa37d 376
e31e01e8 377 if (waitForCompletion) {
4e3aa37d
FC
378 try {
379 job.join();
380 } catch (InterruptedException e) {
4e3aa37d
FC
381 e.printStackTrace();
382 }
52e28818 383 }
62d1696a
FC
384 }
385
386 private class IndexingJob extends Job {
387
388 public IndexingJob(String name) {
389 super(name);
390 }
391
392 /* (non-Javadoc)
393 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
394 */
395 @Override
396 protected IStatus run(IProgressMonitor monitor) {
397
62d1696a
FC
398 monitor.beginTask("Indexing " + fName, IProgressMonitor.UNKNOWN);
399
e31e01e8
FC
400 int nbEvents = 0;
401 TmfTimestamp startTime = null;
402 TmfTimestamp lastTime = null;
403
404 fCheckpoints = new Vector<TmfTraceCheckpoint>();
405
98029bc9
FC
406 try {
407 // Position the trace at the beginning
408 TmfTraceContext context = seekLocation(null);
e31e01e8
FC
409 Object location = context.getLocation();
410
411 TmfEvent event = getNextEvent(context);
412 startTime = new TmfTimestamp(event.getTimestamp());
413 lastTime = new TmfTimestamp(startTime);
414 while (event != null) {
415 lastTime = event.getTimestamp();
416 if ((nbEvents++ % fCacheSize) == 0) {
417 lastTime = new TmfTimestamp(event.getTimestamp());
418 fCheckpoints.add(new TmfTraceCheckpoint(lastTime, location));
419 fNbEvents = nbEvents;
98029bc9
FC
420 fTimeRange = new TmfTimeRange(startTime, lastTime);
421 notifyListeners(new TmfTimeRange(startTime, lastTime));
4e3aa37d 422
62d1696a 423 monitor.worked(1);
4e3aa37d 424
62d1696a
FC
425 // Check monitor *after* fCheckpoints has been updated
426 if (monitor.isCanceled()) {
4e3aa37d 427 monitor.done();
62d1696a
FC
428 return Status.CANCEL_STATUS;
429 }
165c977c 430 }
165c977c 431
e31e01e8
FC
432 // We will need this location at the next iteration
433 if ((nbEvents % fCacheSize) == 0) {
434 location = context.getLocation();
435 }
436
437 event = getNextEvent(context);
62d1696a
FC
438 }
439 }
440 finally {
441 synchronized(this) {
98029bc9 442 fNbEvents = nbEvents;
62d1696a 443 fTimeRange = new TmfTimeRange(startTime, lastTime);
4e3aa37d 444 fIndexing = false;
62d1696a 445 }
98029bc9 446 notifyListeners(new TmfTimeRange(startTime, lastTime));
62d1696a 447 monitor.done();
8c8bf09f 448 }
62d1696a 449
98029bc9 450// createOffsetsFile();
e31e01e8 451// dumpTraceCheckpoints();
98029bc9 452
4e3aa37d 453 return Status.OK_STATUS;
62d1696a 454 }
8c8bf09f
ASL
455 }
456
a3fe52fc 457 protected void notifyListeners(TmfTimeRange range) {
e31e01e8 458 broadcast(new TmfTraceUpdatedSignal(this, this, range));
146a887c
FC
459 }
460
e31e01e8
FC
461// // ------------------------------------------------------------------------
462// // Toubleshooting code
463// // ------------------------------------------------------------------------
464//
465// private void dumpTraceCheckpoints() {
98029bc9
FC
466// System.out.println("-----");
467// System.out.println("Checkpoints of " + fName);
468// for (int i = 0; i < fCheckpoints.size(); i++) {
469// TmfTraceCheckpoint checkpoint = fCheckpoints.get(i);
470// TmfTraceContext context = new TmfTraceContext(checkpoint.getLocation());
e31e01e8 471// TmfEvent event = getNext(context);
98029bc9
FC
472// System.out.println(" Entry: " + i + " timestamp: " + checkpoint.getTimestamp() + ", event: " + event.getTimestamp());
473// assert((checkpoint.getTimestamp().compareTo(event.getTimestamp(), false) == 0));
474// }
475// System.out.println();
476// }
477
478// private void createOffsetsFile() {
479//
480// try {
e31e01e8
FC
481// // The trace context validation file is read by TmfTraceContext
482// ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("TmfTraceContext.dat")));
98029bc9
FC
483//
484// TmfTraceContext context = null;
485// context = seekLocation(null);
486// out.writeObject(context.getLocation());
487//
488// int nbEvents = 0;
489// while (getNextEvent(context) != null) {
490// out.writeObject(context.getLocation());
491// nbEvents++;
492// }
493// out.close();
494// System.out.println("TmfTrace wrote " + nbEvents + " events");
495// } catch (FileNotFoundException e) {
496// // TODO Auto-generated catch block
497// e.printStackTrace();
498// } catch (IOException e) {
499// // TODO Auto-generated catch block
500// e.printStackTrace();
501// }
502// }
e31e01e8 503//
98029bc9
FC
504// private void createOffsetsFile() {
505//
506// try {
507// DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("LTTngOffsets.dat")));
508//
509// TmfTraceContext context = null;
510// context = seekLocation(null);
511//
512// TmfEvent event;
513// int nbEvents = 0;
514// while ((event = getNextEvent(context)) != null) {
515// out.writeUTF(event.getTimestamp().toString());
516// nbEvents++;
517// }
518// out.close();
519// System.out.println("TmfTrace wrote " + nbEvents + " events");
520// } catch (FileNotFoundException e) {
521// // TODO Auto-generated catch block
522// e.printStackTrace();
523// } catch (IOException e) {
524// // TODO Auto-generated catch block
525// e.printStackTrace();
526// }
527// }
528
8c8bf09f 529}
This page took 0.055447 seconds and 5 git commands to generate.