Monster merge from the integration branch. Still some problems left and JUnits failing.
[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
fc6ccf6f 20import org.eclipse.linuxtools.tmf.component.TmfEventProvider;
8c8bf09f
ASL
21import org.eclipse.linuxtools.tmf.event.TmfEvent;
22import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
23import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
2fb2eb37
FC
24import org.eclipse.linuxtools.tmf.request.ITmfDataRequest;
25import org.eclipse.linuxtools.tmf.request.ITmfEventRequest;
8c8bf09f
ASL
26
27/**
146a887c 28 * <b><u>TmfTrace</u></b>
8c8bf09f 29 * <p>
146a887c
FC
30 * Abstract implementation of ITmfTrace. It should be sufficient to extend this
31 * class and provide implementation for <code>getCurrentLocation()</code> and
32 * <code>seekLocation()</code>, as well as a proper parser, to have a working
4e3aa37d 33 * concrete implementation.
ff4ed569 34 * <p>
54d55ced 35 * Note: The notion of event rank is still under heavy discussion. Although
ff4ed569 36 * used by the Events View and probably useful in the general case, there
54d55ced 37 * is no easy way to implement it for LTTng (actually a strong case is being
ff4ed569
FC
38 * made that this is useless).
39 * <p>
40 * That it is not supported by LTTng does by no mean indicate that it is not
41 * useful for (just about) every other tracing tool. Therefore, this class
42 * provides a minimal (and partial) implementation of rank. However, the current
43 * implementation should not be relied on in the general case.
54d55ced 44 *
4e3aa37d 45 * TODO: Add support for live streaming (notifications, incremental indexing, ...)
8c8bf09f 46 */
ff4ed569 47public abstract class TmfTrace<T extends TmfEvent> extends TmfEventProvider<T> implements ITmfTrace, Cloneable {
62d1696a 48
e31e01e8 49 // ------------------------------------------------------------------------
62d1696a 50 // Constants
e31e01e8 51 // ------------------------------------------------------------------------
62d1696a
FC
52
53 // The default number of events to cache
e31e01e8 54 // TODO: Make the DEFAULT_CACHE_SIZE a preference
8d2e2848 55 public static final int DEFAULT_CACHE_SIZE = 1000;
8c8bf09f 56
e31e01e8 57 // ------------------------------------------------------------------------
8c8bf09f 58 // Attributes
e31e01e8 59 // ------------------------------------------------------------------------
8c8bf09f 60
b0a282fb
FC
61 // The trace path
62 private final String fPath;
63
8d2e2848 64 // The cache page size AND checkpoints interval
9f584e4c 65 protected int fIndexPageSize;
62d1696a
FC
66
67 // The set of event stream checkpoints (for random access)
9f584e4c 68 protected Vector<TmfCheckpoint> fCheckpoints = new Vector<TmfCheckpoint>();
62d1696a
FC
69
70 // The number of events collected
a3fe52fc 71 protected long fNbEvents = 0;
62d1696a
FC
72
73 // The time span of the event stream
74 private TmfTimeRange fTimeRange = new TmfTimeRange(TmfTimestamp.BigBang, TmfTimestamp.BigBang);
75
e31e01e8 76 // ------------------------------------------------------------------------
50adc88e 77 // Constructors
e31e01e8 78 // ------------------------------------------------------------------------
8c8bf09f 79
ff4ed569
FC
80 /**
81 * @param path
82 * @throws FileNotFoundException
83 */
ce785d7d
FC
84 protected TmfTrace(String name, Class<T> type, String path) throws FileNotFoundException {
85 this(name, type, path, DEFAULT_CACHE_SIZE);
ff4ed569
FC
86 }
87
62d1696a 88 /**
e31e01e8
FC
89 * @param path
90 * @param cacheSize
62d1696a
FC
91 * @throws FileNotFoundException
92 */
ce785d7d
FC
93 protected TmfTrace(String name, Class<T> type, String path, int cacheSize) throws FileNotFoundException {
94 super(name, type);
b0a282fb 95 int sep = path.lastIndexOf(File.separator);
ce785d7d
FC
96 String simpleName = (sep >= 0) ? path.substring(sep + 1) : path;
97 setName(simpleName);
b0a282fb 98 fPath = path;
9f584e4c 99 fIndexPageSize = (cacheSize > 0) ? cacheSize : DEFAULT_CACHE_SIZE;
550d787e
FC
100
101 try {
102 fClone = clone();
103 } catch (CloneNotSupportedException e) {
104 e.printStackTrace();
105 }
8c8bf09f
ASL
106 }
107
ff4ed569
FC
108 /* (non-Javadoc)
109 * @see java.lang.Object#clone()
62d1696a 110 */
ff4ed569
FC
111 @SuppressWarnings("unchecked")
112 @Override
113 public TmfTrace<T> clone() throws CloneNotSupportedException {
114 TmfTrace<T> clone = (TmfTrace<T>) super.clone();
115 clone.fCheckpoints = (Vector<TmfCheckpoint>) fCheckpoints.clone();
116 clone.fTimeRange = new TmfTimeRange(fTimeRange);
117 return clone;
8c8bf09f
ASL
118 }
119
e31e01e8 120 // ------------------------------------------------------------------------
8c8bf09f 121 // Accessors
e31e01e8 122 // ------------------------------------------------------------------------
8c8bf09f 123
62d1696a 124 /**
b0a282fb 125 * @return the trace path
62d1696a 126 */
b0a282fb
FC
127 public String getPath() {
128 return fPath;
8c8bf09f
ASL
129 }
130
62d1696a
FC
131 /* (non-Javadoc)
132 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getNbEvents()
133 */
4e3aa37d 134 public long getNbEvents() {
62d1696a 135 return fNbEvents;
8c8bf09f
ASL
136 }
137
b0a282fb
FC
138 /**
139 * @return the size of the cache
140 */
8d2e2848 141 public int getCacheSize() {
9f584e4c 142 return fIndexPageSize;
b0a282fb
FC
143 }
144
62d1696a
FC
145 /* (non-Javadoc)
146 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getTimeRange()
147 */
8c8bf09f 148 public TmfTimeRange getTimeRange() {
62d1696a 149 return fTimeRange;
8c8bf09f
ASL
150 }
151
e31e01e8
FC
152 /* (non-Javadoc)
153 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getStartTime()
154 */
146a887c
FC
155 public TmfTimestamp getStartTime() {
156 return fTimeRange.getStartTime();
157 }
158
e31e01e8
FC
159 /* (non-Javadoc)
160 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getEndTime()
161 */
146a887c
FC
162 public TmfTimestamp getEndTime() {
163 return fTimeRange.getEndTime();
164 }
165
ff4ed569
FC
166 @SuppressWarnings("unchecked")
167 public Vector<TmfCheckpoint> getCheckpoints() {
168 return (Vector<TmfCheckpoint>) fCheckpoints.clone();
54d55ced
FC
169 }
170
e31e01e8 171 // ------------------------------------------------------------------------
8c8bf09f 172 // Operators
e31e01e8 173 // ------------------------------------------------------------------------
8c8bf09f 174
4e3aa37d
FC
175 protected void setTimeRange(TmfTimeRange range) {
176 fTimeRange = range;
177 }
178
179 protected void setStartTime(TmfTimestamp startTime) {
180 fTimeRange = new TmfTimeRange(startTime, fTimeRange.getEndTime());
181 }
182
183 protected void setEndTime(TmfTimestamp endTime) {
184 fTimeRange = new TmfTimeRange(fTimeRange.getStartTime(), endTime);
185 }
186
e31e01e8
FC
187 // ------------------------------------------------------------------------
188 // TmfProvider
189 // ------------------------------------------------------------------------
190
191 @Override
2fb2eb37
FC
192 public ITmfContext armRequest(ITmfDataRequest<T> request) {
193 if (request instanceof ITmfEventRequest<?>) {
194 return seekEvent(((ITmfEventRequest<T>) request).getRange().getStartTime());
e31e01e8 195 }
ff4ed569 196 return seekEvent(request.getIndex());
e31e01e8
FC
197 }
198
199 /**
200 * Return the next piece of data based on the context supplied. The context
201 * would typically be updated for the subsequent read.
202 *
203 * @param context
204 * @return
205 */
206 @SuppressWarnings("unchecked")
207 @Override
208 public T getNext(ITmfContext context) {
9f584e4c
FC
209 if (context instanceof TmfContext) {
210 return (T) getNextEvent((TmfContext) context);
e31e01e8
FC
211 }
212 return null;
213 }
214
e31e01e8
FC
215 // ------------------------------------------------------------------------
216 // ITmfTrace
217 // ------------------------------------------------------------------------
218
146a887c
FC
219 /* (non-Javadoc)
220 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.event.TmfTimestamp)
221 */
9f584e4c 222 public TmfContext seekEvent(TmfTimestamp timestamp) {
62d1696a 223
4e3aa37d
FC
224 if (timestamp == null) {
225 timestamp = TmfTimestamp.BigBang;
226 }
227
228 // First, find the right checkpoint
9f584e4c 229 int index = Collections.binarySearch(fCheckpoints, new TmfCheckpoint(timestamp, null));
62d1696a 230
8d2e2848 231 // In the very likely case that the checkpoint was not found, bsearch
62d1696a
FC
232 // returns its negated would-be location (not an offset...). From that
233 // index, we can then position the stream and get the event.
234 if (index < 0) {
235 index = Math.max(0, -(index + 2));
236 }
237
238 // Position the stream at the checkpoint
452ad365 239 ITmfLocation<?> location;
e31e01e8
FC
240 synchronized (fCheckpoints) {
241 if (fCheckpoints.size() > 0) {
242 if (index >= fCheckpoints.size()) {
243 index = fCheckpoints.size() - 1;
244 }
245 location = fCheckpoints.elementAt(index).getLocation();
246 }
247 else {
248 location = null;
249 }
8d2e2848 250 }
54d55ced
FC
251 TmfContext context = seekLocation(location);
252 context.setRank(index * fIndexPageSize);
62d1696a 253
54d55ced 254 // And locate the event
ff4ed569 255 TmfContext nextEventContext = context.clone(); // Must use clone() to get the right subtype...
62d1696a
FC
256 TmfEvent event = getNextEvent(nextEventContext);
257 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
54d55ced
FC
258 context.setLocation(nextEventContext.getLocation().clone());
259 context.updateRank(1);
62d1696a
FC
260 event = getNextEvent(nextEventContext);
261 }
262
54d55ced 263 return context;
62d1696a
FC
264 }
265
146a887c
FC
266 /* (non-Javadoc)
267 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#seekEvent(int)
268 */
9f584e4c 269 public TmfContext seekEvent(long rank) {
62d1696a
FC
270
271 // Position the stream at the previous checkpoint
9f584e4c 272 int index = (int) rank / fIndexPageSize;
452ad365 273 ITmfLocation<?> location;
e31e01e8 274 synchronized (fCheckpoints) {
54d55ced
FC
275 if (fCheckpoints.size() == 0) {
276 location = null;
277 }
278 else {
e31e01e8 279 if (index >= fCheckpoints.size()) {
54d55ced 280 index = fCheckpoints.size() - 1;
e31e01e8
FC
281 }
282 location = fCheckpoints.elementAt(index).getLocation();
283 }
8d2e2848 284 }
54d55ced 285
9f584e4c
FC
286 TmfContext context = seekLocation(location);
287 long pos = index * fIndexPageSize;
288 context.setRank(pos);
e31e01e8 289
9f584e4c 290 if (pos < rank) {
e31e01e8 291 TmfEvent event = getNextEvent(context);
9f584e4c 292 while (event != null && ++pos < rank) {
e31e01e8
FC
293 event = getNextEvent(context);
294 }
165c977c 295 }
62d1696a 296
8f50c396 297 return context;
8c8bf09f
ASL
298 }
299
146a887c
FC
300 /* (non-Javadoc)
301 * @see org.eclipse.linuxtools.tmf.trace.ITmfTrace#getNextEvent(org.eclipse.linuxtools.tmf.trace.ITmfTrace.TraceContext)
302 */
9f584e4c 303 public synchronized TmfEvent getNextEvent(TmfContext context) {
e31e01e8 304 // parseEvent() does not update the context
cc6eec3e 305 TmfEvent event = parseEvent(context);
4e3aa37d 306 if (event != null) {
54d55ced 307 context.setLocation(getCurrentLocation());
550d787e 308 updateIndex(context, context.getRank(), event.getTimestamp());
54d55ced 309 context.updateRank(1);
4e3aa37d
FC
310 processEvent(event);
311 }
146a887c
FC
312 return event;
313 }
8c8bf09f 314
550d787e
FC
315 public synchronized void updateIndex(ITmfContext context, long rank, TmfTimestamp timestamp) {
316 // Build the index as we go along
317 if (context.isValidRank() && (rank % fIndexPageSize) == 0) {
318 // Determine the table position
319 long position = rank / fIndexPageSize;
320 // Add new entry at proper location (if empty)
321 if (fCheckpoints.size() == position) {
322 ITmfLocation<?> location = getCurrentLocation().clone();
323 fCheckpoints.add(new TmfCheckpoint(timestamp, location));
324// System.out.println(getName() + "[" + (fCheckpoints.size() - 1) + "] " + timestamp + ", " + location.toString());
325 }
326 }
327 }
328
4e3aa37d 329 /**
e31e01e8
FC
330 * Hook for "special" processing by the concrete class
331 * (called by getNextEvent())
332 *
146a887c
FC
333 * @param event
334 */
ff4ed569 335 protected void processEvent(TmfEvent event) {
146a887c 336 // Do nothing by default
62d1696a 337 }
4e3aa37d 338
e31e01e8
FC
339 /**
340 * To be implemented by the concrete class
4e3aa37d 341 */
452ad365
FC
342 public abstract TmfContext seekLocation(ITmfLocation<?> location);
343 public abstract ITmfLocation<?> getCurrentLocation();
9f584e4c 344 public abstract TmfEvent parseEvent(TmfContext context);
4e3aa37d 345
e31e01e8
FC
346 // ------------------------------------------------------------------------
347 // toString
348 // ------------------------------------------------------------------------
8d2e2848
FC
349
350 /* (non-Javadoc)
351 * @see java.lang.Object#toString()
352 */
353 @Override
354 public String toString() {
ce785d7d 355 return "[TmfTrace (" + getName() + ")]";
8d2e2848 356 }
146a887c 357
8c8bf09f 358}
This page took 0.051414 seconds and 5 git commands to generate.