Commit | Line | Data |
---|---|---|
8c8bf09f | 1 | /******************************************************************************* |
09e86496 | 2 | * Copyright (c) 2009, 2010, 2012 Ericsson |
0bfb7d06 | 3 | * |
8c8bf09f ASL |
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 | |
0bfb7d06 | 8 | * |
8c8bf09f | 9 | * Contributors: |
20658947 FC |
10 | * Francois Chouinard - Initial API and implementation |
11 | * Francois Chouinard - Updated as per TMF Trace Model 1.0 | |
8c8bf09f ASL |
12 | *******************************************************************************/ |
13 | ||
6c13869b | 14 | package org.eclipse.linuxtools.tmf.core.trace; |
8c8bf09f | 15 | |
6f4a1d2b | 16 | import java.io.File; |
8c8bf09f | 17 | |
828e5592 | 18 | import org.eclipse.core.resources.IResource; |
faa38350 | 19 | import org.eclipse.core.runtime.CoreException; |
9b749023 | 20 | import org.eclipse.core.runtime.IPath; |
6c13869b | 21 | import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider; |
72f1e62a | 22 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
4df4581d | 23 | import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp; |
6c13869b FC |
24 | import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; |
25 | import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp; | |
b4f71e4a | 26 | import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; |
6c13869b FC |
27 | import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest; |
28 | import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; | |
d7ee91bb | 29 | import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal; |
faa38350 | 30 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; |
d7ee91bb | 31 | import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; |
faa38350 PT |
32 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal; |
33 | import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal; | |
7898bb21 | 34 | import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; |
200789b3 | 35 | import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics; |
1c0de632 | 36 | import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics; |
8c8bf09f ASL |
37 | |
38 | /** | |
09e86496 FC |
39 | * Abstract implementation of ITmfTrace. |
40 | * <p> | |
13cb5f43 FC |
41 | * Since the concept of 'location' is trace specific, the concrete classes have |
42 | * to provide the related methods, namely: | |
43 | * <ul> | |
44 | * <li> public ITmfLocation<?> getCurrentLocation() | |
45 | * <li> public double getLocationRatio(ITmfLocation<?> location) | |
46 | * <li> public ITmfContext seekEvent(ITmfLocation<?> location) | |
47 | * <li> public ITmfContext seekEvent(double ratio) | |
2848c377 | 48 | * <li> public boolean validate(IProject project, String path) |
13cb5f43 FC |
49 | * </ul> |
50 | * A concrete trace must provide its corresponding parser. A common way to | |
51 | * accomplish this is by making the concrete class extend TmfTrace and | |
52 | * implement ITmfEventParser. | |
53 | * <p> | |
54 | * The concrete class can either specify its own indexer or use the provided | |
55 | * TmfCheckpointIndexer (default). In this case, the trace cache size will be | |
56 | * used as checkpoint interval. | |
0bfb7d06 | 57 | * |
f7703ed6 FC |
58 | * @version 1.0 |
59 | * @author Francois Chouinard | |
60 | * | |
f7703ed6 FC |
61 | * @see ITmfEvent |
62 | * @see ITmfTraceIndexer | |
63 | * @see ITmfEventParser | |
8c8bf09f | 64 | */ |
6256d8ad | 65 | public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace { |
62d1696a | 66 | |
e31e01e8 | 67 | // ------------------------------------------------------------------------ |
8c8bf09f | 68 | // Attributes |
e31e01e8 | 69 | // ------------------------------------------------------------------------ |
8c8bf09f | 70 | |
09e86496 FC |
71 | // The resource used for persistent properties for this trace |
72 | private IResource fResource; | |
73 | ||
b0a282fb | 74 | // The trace path |
12c155f5 | 75 | private String fPath; |
b0a282fb | 76 | |
0316808c FC |
77 | // The trace cache page size |
78 | private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE; | |
62d1696a | 79 | |
0316808c FC |
80 | // The number of events collected (so far) |
81 | private long fNbEvents = 0; | |
62d1696a FC |
82 | |
83 | // The time span of the event stream | |
9cbe7899 | 84 | private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG; |
a4115405 | 85 | private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG; |
62d1696a | 86 | |
0316808c FC |
87 | // The trace streaming interval (0 = no streaming) |
88 | private long fStreamingInterval = 0; | |
085d898f | 89 | |
0316808c | 90 | // The trace indexer |
6256d8ad | 91 | private ITmfTraceIndexer fIndexer; |
20658947 | 92 | |
0316808c | 93 | // The trace parser |
6256d8ad | 94 | private ITmfEventParser fParser; |
7e6347b0 | 95 | |
200789b3 AM |
96 | // The trace's statistics |
97 | private ITmfStatistics fStatistics; | |
98 | ||
d7ee91bb PT |
99 | // The current selected time |
100 | private ITmfTimestamp fCurrentTime = TmfTimestamp.ZERO; | |
101 | ||
102 | // The current selected range | |
103 | private TmfTimeRange fCurrentRange = TmfTimeRange.NULL_RANGE; | |
104 | ||
e31e01e8 | 105 | // ------------------------------------------------------------------------ |
3791b5df | 106 | // Construction |
e31e01e8 | 107 | // ------------------------------------------------------------------------ |
8c8bf09f | 108 | |
62d1696a | 109 | /** |
3791b5df | 110 | * The default, parameterless, constructor |
62d1696a | 111 | */ |
3791b5df FC |
112 | public TmfTrace() { |
113 | super(); | |
05bd3318 FC |
114 | } |
115 | ||
116 | /** | |
13cb5f43 | 117 | * The standard constructor (non-live trace). Applicable when the trace |
0bfb7d06 MK |
118 | * implements its own parser and if at checkpoint-based index is OK. |
119 | * | |
20658947 FC |
120 | * @param resource the resource associated to the trace |
121 | * @param type the trace event type | |
122 | * @param path the trace path | |
123 | * @param cacheSize the trace cache size | |
6f4e8ec0 | 124 | * @throws TmfTraceException If something failed during the opening |
20658947 | 125 | */ |
6256d8ad | 126 | protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize) throws TmfTraceException { |
9e0640dc | 127 | this(resource, type, path, cacheSize, 0); |
20658947 FC |
128 | } |
129 | ||
130 | /** | |
13cb5f43 FC |
131 | * The standard constructor (live trace). Applicable when the trace |
132 | * implements its own parser and if at checkpoint-based index is OK. | |
0bfb7d06 | 133 | * |
20658947 | 134 | * @param resource the resource associated to the trace |
3791b5df FC |
135 | * @param type the trace event type |
136 | * @param path the trace path | |
20658947 FC |
137 | * @param cacheSize the trace cache size |
138 | * @param interval the trace streaming interval | |
6f4e8ec0 | 139 | * @throws TmfTraceException If something failed during the opening |
05bd3318 | 140 | */ |
6256d8ad | 141 | protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize, final long interval) throws TmfTraceException { |
20658947 | 142 | this(resource, type, path, cacheSize, interval, null); |
05bd3318 FC |
143 | } |
144 | ||
145 | /** | |
13cb5f43 FC |
146 | * The 'non-default indexer' constructor. Allows to provide a trace |
147 | * specific indexer. | |
0bfb7d06 | 148 | * |
20658947 | 149 | * @param resource the resource associated to the trace |
3791b5df FC |
150 | * @param type the trace event type |
151 | * @param path the trace path | |
20658947 | 152 | * @param cacheSize the trace cache size |
6f4e8ec0 | 153 | * @param interval the trace streaming interval |
20658947 | 154 | * @param indexer the trace indexer |
6f4e8ec0 | 155 | * @throws TmfTraceException If something failed during the opening |
05bd3318 | 156 | */ |
6256d8ad AM |
157 | protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize, |
158 | final long interval, final ITmfTraceIndexer indexer) throws TmfTraceException { | |
0316808c | 159 | this(resource, type, path, cacheSize, interval, indexer, null); |
13cb5f43 FC |
160 | } |
161 | ||
162 | /** | |
0bfb7d06 MK |
163 | * The full constructor where trace specific indexer/parser are provided. |
164 | * | |
13cb5f43 FC |
165 | * @param resource the resource associated to the trace |
166 | * @param type the trace event type | |
167 | * @param path the trace path | |
168 | * @param cacheSize the trace cache size | |
6f4e8ec0 | 169 | * @param interval the trace streaming interval |
13cb5f43 FC |
170 | * @param indexer the trace indexer |
171 | * @param parser the trace event parser | |
6f4e8ec0 | 172 | * @throws TmfTraceException If something failed during the opening |
13cb5f43 | 173 | */ |
6256d8ad AM |
174 | protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize, |
175 | final long interval, final ITmfTraceIndexer indexer, final ITmfEventParser parser) throws TmfTraceException { | |
00641a97 | 176 | super(); |
0316808c | 177 | fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE; |
3791b5df | 178 | fStreamingInterval = interval; |
7e6347b0 | 179 | fIndexer = (indexer != null) ? indexer : new TmfCheckpointIndexer(this, fCacheSize); |
13cb5f43 | 180 | fParser = parser; |
09e86496 | 181 | initialize(resource, path, type); |
8c8bf09f ASL |
182 | } |
183 | ||
3791b5df FC |
184 | /** |
185 | * Copy constructor | |
0bfb7d06 | 186 | * |
3791b5df | 187 | * @param trace the original trace |
063f0d27 | 188 | * @throws TmfTraceException Should not happen usually |
3791b5df | 189 | */ |
6256d8ad | 190 | public TmfTrace(final TmfTrace trace) throws TmfTraceException { |
3791b5df | 191 | super(); |
0316808c | 192 | if (trace == null) { |
3791b5df | 193 | throw new IllegalArgumentException(); |
0316808c | 194 | } |
20658947 FC |
195 | fCacheSize = trace.getCacheSize(); |
196 | fStreamingInterval = trace.getStreamingInterval(); | |
7e6347b0 | 197 | fIndexer = new TmfCheckpointIndexer(this); |
13cb5f43 FC |
198 | fParser = trace.fParser; |
199 | initialize(trace.getResource(), trace.getPath(), trace.getEventType()); | |
3791b5df FC |
200 | } |
201 | ||
7e6347b0 FC |
202 | // ------------------------------------------------------------------------ |
203 | // ITmfTrace - Initializers | |
204 | // ------------------------------------------------------------------------ | |
205 | ||
206 | /* (non-Javadoc) | |
207 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#initTrace(org.eclipse.core.resources.IResource, java.lang.String, java.lang.Class) | |
208 | */ | |
209 | @Override | |
6256d8ad | 210 | public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException { |
9dc3dee2 | 211 | fIndexer = new TmfCheckpointIndexer(this, fCacheSize); |
7e6347b0 | 212 | initialize(resource, path, type); |
7e6347b0 FC |
213 | } |
214 | ||
09e86496 | 215 | /** |
1703b536 | 216 | * Initialize the trace common attributes and the base component. |
0bfb7d06 MK |
217 | * |
218 | * @param resource the Eclipse resource (trace) | |
1703b536 FC |
219 | * @param path the trace path |
220 | * @param type the trace event type | |
0bfb7d06 | 221 | * |
6f4e8ec0 | 222 | * @throws TmfTraceException If something failed during the initialization |
3791b5df | 223 | */ |
6256d8ad | 224 | protected void initialize(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException { |
0316808c | 225 | if (path == null) { |
b4f71e4a | 226 | throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$ |
0316808c | 227 | } |
3791b5df | 228 | fPath = path; |
1703b536 | 229 | fResource = resource; |
25e48683 | 230 | String traceName = (resource != null) ? resource.getName() : null; |
1703b536 FC |
231 | // If no resource was provided, extract the display name the trace path |
232 | if (traceName == null) { | |
9b749023 | 233 | final int sep = path.lastIndexOf(IPath.SEPARATOR); |
1703b536 FC |
234 | traceName = (sep >= 0) ? path.substring(sep + 1) : path; |
235 | } | |
2352aed9 FC |
236 | if (fParser == null) { |
237 | if (this instanceof ITmfEventParser) { | |
6256d8ad | 238 | fParser = (ITmfEventParser) this; |
2352aed9 FC |
239 | } else { |
240 | throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$ | |
241 | } | |
242 | } | |
3791b5df FC |
243 | super.init(traceName, type); |
244 | } | |
245 | ||
2352aed9 FC |
246 | /** |
247 | * Indicates if the path points to an existing file/directory | |
0bfb7d06 | 248 | * |
2352aed9 FC |
249 | * @param path the path to test |
250 | * @return true if the file/directory exists | |
3791b5df | 251 | */ |
2352aed9 | 252 | protected boolean fileExists(final String path) { |
085d898f | 253 | final File file = new File(path); |
3791b5df FC |
254 | return file.exists(); |
255 | } | |
256 | ||
c7e1020d FC |
257 | /** |
258 | * Index the trace | |
0bfb7d06 | 259 | * |
c7e1020d FC |
260 | * @param waitForCompletion index synchronously (true) or not (false) |
261 | */ | |
262 | protected void indexTrace(boolean waitForCompletion) { | |
9e0640dc | 263 | getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion); |
c7e1020d FC |
264 | } |
265 | ||
200789b3 | 266 | /** |
6f4e8ec0 | 267 | * The default implementation of TmfTrace uses a TmfStatistics back-end. |
200789b3 AM |
268 | * Override this if you want to specify another type (or none at all). |
269 | * | |
6f4e8ec0 AM |
270 | * @throws TmfTraceException |
271 | * If there was a problem setting up the statistics | |
200789b3 AM |
272 | * @since 2.0 |
273 | */ | |
274 | protected void buildStatistics() throws TmfTraceException { | |
275 | /* | |
276 | * Initialize the statistics provider, but only if a Resource has been | |
277 | * set (so we don't build it for experiments, for unit tests, etc.) | |
278 | */ | |
1c0de632 | 279 | fStatistics = (fResource == null ? null : new TmfStateStatistics(this) ); |
200789b3 AM |
280 | } |
281 | ||
faa38350 PT |
282 | /** |
283 | * Build the state system(s) associated with this trace type. | |
284 | * | |
285 | * Suppressing the warning, because the 'throws' will usually happen in | |
286 | * sub-classes. | |
287 | * | |
288 | * @throws TmfTraceException | |
289 | * If there is a problem during the build | |
290 | * @since 2.0 | |
291 | */ | |
292 | @SuppressWarnings("unused") | |
293 | protected void buildStateSystem() throws TmfTraceException { | |
294 | /* | |
295 | * Nothing is done in the base implementation, please specify | |
296 | * how/if to build a state system in derived classes. | |
297 | */ | |
298 | return; | |
299 | } | |
300 | ||
b5ee6881 FC |
301 | /** |
302 | * Clears the trace | |
303 | */ | |
304 | @Override | |
305 | public synchronized void dispose() { | |
1a4205d9 | 306 | /* Clean up the index if applicable */ |
77551cc2 FC |
307 | if (getIndexer() != null) { |
308 | getIndexer().dispose(); | |
309 | } | |
1a4205d9 AM |
310 | |
311 | /* Clean up the statistics */ | |
312 | if (fStatistics != null) { | |
313 | fStatistics.dispose(); | |
314 | } | |
b5ee6881 FC |
315 | super.dispose(); |
316 | } | |
317 | ||
3791b5df | 318 | // ------------------------------------------------------------------------ |
09e86496 | 319 | // ITmfTrace - Basic getters |
e31e01e8 | 320 | // ------------------------------------------------------------------------ |
8c8bf09f | 321 | |
09e86496 | 322 | /* (non-Javadoc) |
13cb5f43 | 323 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEventType() |
25e48683 FC |
324 | */ |
325 | @Override | |
6256d8ad AM |
326 | public Class<ITmfEvent> getEventType() { |
327 | return (Class<ITmfEvent>) super.getType(); | |
25e48683 FC |
328 | } |
329 | ||
09e86496 FC |
330 | /* (non-Javadoc) |
331 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource() | |
62d1696a | 332 | */ |
d4011df2 | 333 | @Override |
09e86496 FC |
334 | public IResource getResource() { |
335 | return fResource; | |
8c8bf09f ASL |
336 | } |
337 | ||
09e86496 FC |
338 | /* (non-Javadoc) |
339 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getPath() | |
62d1696a | 340 | */ |
d4011df2 | 341 | @Override |
09e86496 FC |
342 | public String getPath() { |
343 | return fPath; | |
8c8bf09f ASL |
344 | } |
345 | ||
20658947 FC |
346 | /* (non-Javadoc) |
347 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getIndexPageSize() | |
348 | */ | |
349 | @Override | |
350 | public int getCacheSize() { | |
351 | return fCacheSize; | |
352 | } | |
353 | ||
354 | /* (non-Javadoc) | |
355 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStreamingInterval() | |
356 | */ | |
357 | @Override | |
358 | public long getStreamingInterval() { | |
359 | return fStreamingInterval; | |
360 | } | |
361 | ||
0316808c FC |
362 | /** |
363 | * @return the trace indexer | |
364 | */ | |
6256d8ad | 365 | protected ITmfTraceIndexer getIndexer() { |
0316808c FC |
366 | return fIndexer; |
367 | } | |
368 | ||
369 | /** | |
370 | * @return the trace parser | |
371 | */ | |
6256d8ad | 372 | protected ITmfEventParser getParser() { |
0316808c FC |
373 | return fParser; |
374 | } | |
375 | ||
200789b3 AM |
376 | /** |
377 | * @since 2.0 | |
378 | */ | |
379 | @Override | |
380 | public ITmfStatistics getStatistics() { | |
381 | return fStatistics; | |
382 | } | |
383 | ||
7898bb21 AM |
384 | /** |
385 | * @since 2.0 | |
386 | */ | |
387 | @Override | |
388 | public ITmfStateSystem getStateSystem() { | |
389 | /* | |
390 | * By default, no state system is used. Sub-classes can specify their | |
391 | * own behaviour. | |
392 | */ | |
393 | return null; | |
394 | } | |
395 | ||
09e86496 FC |
396 | // ------------------------------------------------------------------------ |
397 | // ITmfTrace - Trace characteristics getters | |
398 | // ------------------------------------------------------------------------ | |
399 | ||
400 | /* (non-Javadoc) | |
401 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNbEvents() | |
b0a282fb | 402 | */ |
d4011df2 | 403 | @Override |
afc86f78 | 404 | public synchronized long getNbEvents() { |
3791b5df | 405 | return fNbEvents; |
b0a282fb FC |
406 | } |
407 | ||
09e86496 FC |
408 | /* (non-Javadoc) |
409 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getTimeRange() | |
62d1696a | 410 | */ |
d4011df2 | 411 | @Override |
12c155f5 | 412 | public TmfTimeRange getTimeRange() { |
cb866e08 | 413 | return new TmfTimeRange(fStartTime, fEndTime); |
8c8bf09f ASL |
414 | } |
415 | ||
09e86496 FC |
416 | /* (non-Javadoc) |
417 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStartTime() | |
e31e01e8 | 418 | */ |
d4011df2 | 419 | @Override |
4df4581d | 420 | public ITmfTimestamp getStartTime() { |
4593bd5b | 421 | return fStartTime; |
146a887c FC |
422 | } |
423 | ||
09e86496 FC |
424 | /* (non-Javadoc) |
425 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEndTime() | |
e31e01e8 | 426 | */ |
d4011df2 | 427 | @Override |
4df4581d | 428 | public ITmfTimestamp getEndTime() { |
4593bd5b | 429 | return fEndTime; |
20658947 FC |
430 | } |
431 | ||
d7ee91bb PT |
432 | /* (non-Javadoc) |
433 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentTime() | |
434 | */ | |
435 | /** | |
436 | * @since 2.0 | |
437 | */ | |
438 | @Override | |
439 | public ITmfTimestamp getCurrentTime() { | |
440 | return fCurrentTime; | |
441 | } | |
442 | ||
443 | /* (non-Javadoc) | |
444 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentRange() | |
445 | */ | |
446 | /** | |
447 | * @since 2.0 | |
448 | */ | |
449 | @Override | |
450 | public TmfTimeRange getCurrentRange() { | |
451 | return fCurrentRange; | |
452 | } | |
453 | ||
66262ad8 BH |
454 | /* |
455 | * (non-Javadoc) | |
456 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getInitialRangeOffset() | |
457 | */ | |
d7ee91bb | 458 | /** |
d7ee91bb PT |
459 | * @since 2.0 |
460 | */ | |
66262ad8 BH |
461 | @Override |
462 | public ITmfTimestamp getInitialRangeOffset() { | |
d7ee91bb PT |
463 | final long DEFAULT_INITIAL_OFFSET_VALUE = (1L * 100 * 1000 * 1000); // .1sec |
464 | return new TmfTimestamp(DEFAULT_INITIAL_OFFSET_VALUE, ITmfTimestamp.NANOSECOND_SCALE); | |
465 | } | |
466 | ||
20658947 | 467 | // ------------------------------------------------------------------------ |
d7ee91bb | 468 | // Convenience setters |
20658947 FC |
469 | // ------------------------------------------------------------------------ |
470 | ||
0316808c FC |
471 | /** |
472 | * Set the trace cache size. Must be done at initialization time. | |
0bfb7d06 | 473 | * |
0316808c FC |
474 | * @param cacheSize The trace cache size |
475 | */ | |
476 | protected void setCacheSize(final int cacheSize) { | |
477 | fCacheSize = cacheSize; | |
478 | } | |
479 | ||
480 | /** | |
481 | * Set the trace known number of events. This can be quite dynamic | |
482 | * during indexing or for live traces. | |
0bfb7d06 | 483 | * |
0316808c FC |
484 | * @param nbEvents The number of events |
485 | */ | |
486 | protected synchronized void setNbEvents(final long nbEvents) { | |
487 | fNbEvents = (nbEvents > 0) ? nbEvents : 0; | |
488 | } | |
489 | ||
20658947 FC |
490 | /** |
491 | * Update the trace events time range | |
0bfb7d06 | 492 | * |
20658947 FC |
493 | * @param range the new time range |
494 | */ | |
495 | protected void setTimeRange(final TmfTimeRange range) { | |
4593bd5b AM |
496 | fStartTime = range.getStartTime(); |
497 | fEndTime = range.getEndTime(); | |
20658947 FC |
498 | } |
499 | ||
500 | /** | |
501 | * Update the trace chronologically first event timestamp | |
0bfb7d06 | 502 | * |
20658947 FC |
503 | * @param startTime the new first event timestamp |
504 | */ | |
505 | protected void setStartTime(final ITmfTimestamp startTime) { | |
4593bd5b | 506 | fStartTime = startTime; |
20658947 FC |
507 | } |
508 | ||
509 | /** | |
510 | * Update the trace chronologically last event timestamp | |
0bfb7d06 | 511 | * |
20658947 FC |
512 | * @param endTime the new last event timestamp |
513 | */ | |
514 | protected void setEndTime(final ITmfTimestamp endTime) { | |
4593bd5b | 515 | fEndTime = endTime; |
20658947 FC |
516 | } |
517 | ||
518 | /** | |
0316808c | 519 | * Set the polling interval for live traces (default = 0 = no streaming). |
0bfb7d06 | 520 | * |
20658947 FC |
521 | * @param interval the new trace streaming interval |
522 | */ | |
523 | protected void setStreamingInterval(final long interval) { | |
1703b536 | 524 | fStreamingInterval = (interval > 0) ? interval : 0; |
146a887c FC |
525 | } |
526 | ||
0316808c FC |
527 | /** |
528 | * Set the trace indexer. Must be done at initialization time. | |
0bfb7d06 | 529 | * |
0316808c FC |
530 | * @param indexer the trace indexer |
531 | */ | |
6256d8ad | 532 | protected void setIndexer(final ITmfTraceIndexer indexer) { |
0316808c FC |
533 | fIndexer = indexer; |
534 | } | |
535 | ||
536 | /** | |
537 | * Set the trace parser. Must be done at initialization time. | |
0bfb7d06 | 538 | * |
0316808c FC |
539 | * @param parser the new trace parser |
540 | */ | |
6256d8ad | 541 | protected void setParser(final ITmfEventParser parser) { |
0316808c FC |
542 | fParser = parser; |
543 | } | |
544 | ||
09e86496 | 545 | // ------------------------------------------------------------------------ |
7e6347b0 | 546 | // ITmfTrace - SeekEvent operations (returning a trace context) |
09e86496 FC |
547 | // ------------------------------------------------------------------------ |
548 | ||
549 | /* (non-Javadoc) | |
7e6347b0 | 550 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(long) |
1b70b6dc PT |
551 | */ |
552 | @Override | |
7e6347b0 | 553 | public synchronized ITmfContext seekEvent(final long rank) { |
09e86496 | 554 | |
7e6347b0 | 555 | // A rank <= 0 indicates to seek the first event |
2352aed9 | 556 | if (rank <= 0) { |
1e1bef82 | 557 | ITmfContext context = seekEvent((ITmfLocation) null); |
2352aed9 FC |
558 | context.setRank(0); |
559 | return context; | |
560 | } | |
09e86496 | 561 | |
09e86496 | 562 | // Position the trace at the checkpoint |
7e6347b0 | 563 | final ITmfContext context = fIndexer.seekIndex(rank); |
09e86496 FC |
564 | |
565 | // And locate the requested event context | |
7e6347b0 FC |
566 | long pos = context.getRank(); |
567 | if (pos < rank) { | |
c32744d6 | 568 | ITmfEvent event = getNext(context); |
0bfb7d06 | 569 | while ((event != null) && (++pos < rank)) { |
c32744d6 | 570 | event = getNext(context); |
7e6347b0 | 571 | } |
09e86496 FC |
572 | } |
573 | return context; | |
1b70b6dc PT |
574 | } |
575 | ||
09e86496 | 576 | /* (non-Javadoc) |
7e6347b0 | 577 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp) |
09e86496 FC |
578 | */ |
579 | @Override | |
7e6347b0 | 580 | public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) { |
09e86496 | 581 | |
7e6347b0 | 582 | // A null timestamp indicates to seek the first event |
2352aed9 | 583 | if (timestamp == null) { |
1e1bef82 | 584 | ITmfContext context = seekEvent((ITmfLocation) null); |
2352aed9 FC |
585 | context.setRank(0); |
586 | return context; | |
587 | } | |
09e86496 | 588 | |
1703b536 | 589 | // Position the trace at the checkpoint |
408e65d2 | 590 | ITmfContext context = fIndexer.seekIndex(timestamp); |
09e86496 FC |
591 | |
592 | // And locate the requested event context | |
7e6347b0 | 593 | final ITmfContext nextEventContext = context.clone(); // Must use clone() to get the right subtype... |
c32744d6 | 594 | ITmfEvent event = getNext(nextEventContext); |
7e6347b0 | 595 | while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) { |
4c9f2944 | 596 | context.dispose(); |
3cec7398 | 597 | context = nextEventContext.clone(); |
c32744d6 | 598 | event = getNext(nextEventContext); |
09e86496 | 599 | } |
4c9f2944 | 600 | nextEventContext.dispose(); |
0316808c FC |
601 | if (event == null) { |
602 | context.setLocation(null); | |
603 | context.setRank(ITmfContext.UNKNOWN_RANK); | |
604 | } | |
09e86496 FC |
605 | return context; |
606 | } | |
0283f7ff | 607 | |
09e86496 FC |
608 | // ------------------------------------------------------------------------ |
609 | // ITmfTrace - Read operations (returning an actual event) | |
610 | // ------------------------------------------------------------------------ | |
611 | ||
d337369a | 612 | /* (non-Javadoc) |
b4f71e4a | 613 | * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#readNextEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfContext) |
abfad0aa | 614 | */ |
d4011df2 | 615 | @Override |
6256d8ad | 616 | public synchronized ITmfEvent getNext(final ITmfContext context) { |
09e86496 | 617 | // parseEvent() does not update the context |
6256d8ad | 618 | final ITmfEvent event = fParser.parseEvent(context); |
09e86496 | 619 | if (event != null) { |
d337369a | 620 | updateAttributes(context, event.getTimestamp()); |
09e86496 FC |
621 | context.setLocation(getCurrentLocation()); |
622 | context.increaseRank(); | |
623 | processEvent(event); | |
624 | } | |
625 | return event; | |
626 | } | |
627 | ||
628 | /** | |
d337369a | 629 | * Hook for special event processing by the concrete class |
7e6347b0 | 630 | * (called by TmfTrace.getEvent()) |
0bfb7d06 | 631 | * |
d337369a | 632 | * @param event the event |
09e86496 FC |
633 | */ |
634 | protected void processEvent(final ITmfEvent event) { | |
d337369a | 635 | // Do nothing |
09e86496 FC |
636 | } |
637 | ||
d337369a FC |
638 | /** |
639 | * Update the trace attributes | |
0bfb7d06 | 640 | * |
d337369a | 641 | * @param context the current trace context |
2848c377 | 642 | * @param timestamp the corresponding timestamp |
d337369a FC |
643 | */ |
644 | protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) { | |
0bfb7d06 | 645 | if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) { |
4593bd5b | 646 | fStartTime = timestamp; |
09e86496 | 647 | } |
0bfb7d06 | 648 | if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) { |
4593bd5b | 649 | fEndTime = timestamp; |
09e86496 | 650 | } |
d7ee91bb PT |
651 | if (fCurrentRange == TmfTimeRange.NULL_RANGE) { |
652 | fCurrentTime = timestamp; | |
653 | ITmfTimestamp initialOffset = getInitialRangeOffset(); | |
654 | long endValue = timestamp.getValue() + initialOffset.normalize(0, timestamp.getScale()).getValue(); | |
655 | ITmfTimestamp endTimestamp = new TmfTimestamp(endValue, timestamp.getScale()); | |
656 | fCurrentRange = new TmfTimeRange(timestamp, endTimestamp); | |
657 | } | |
09e86496 | 658 | if (context.hasValidRank()) { |
d337369a | 659 | long rank = context.getRank(); |
09e86496 FC |
660 | if (fNbEvents <= rank) { |
661 | fNbEvents = rank + 1; | |
662 | } | |
200789b3 AM |
663 | if (fIndexer != null) { |
664 | fIndexer.updateIndex(context, timestamp); | |
665 | } | |
09e86496 | 666 | } |
abfad0aa FC |
667 | } |
668 | ||
3791b5df | 669 | // ------------------------------------------------------------------------ |
d337369a | 670 | // TmfDataProvider |
3791b5df FC |
671 | // ------------------------------------------------------------------------ |
672 | ||
d337369a FC |
673 | /* (non-Javadoc) |
674 | * @see org.eclipse.linuxtools.tmf.core.component.TmfDataProvider#armRequest(org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest) | |
675 | */ | |
3791b5df | 676 | @Override |
faa38350 PT |
677 | protected synchronized ITmfContext armRequest(final ITmfDataRequest request) { |
678 | if (executorIsShutdown()) { | |
679 | return null; | |
680 | } | |
6256d8ad AM |
681 | if ((request instanceof ITmfEventRequest) |
682 | && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest) request).getRange().getStartTime()) | |
0bfb7d06 | 683 | && (request.getIndex() == 0)) |
0316808c | 684 | { |
6256d8ad AM |
685 | final ITmfContext context = seekEvent(((ITmfEventRequest) request).getRange().getStartTime()); |
686 | ((ITmfEventRequest) request).setStartIndex((int) context.getRank()); | |
3791b5df FC |
687 | return context; |
688 | ||
689 | } | |
690 | return seekEvent(request.getIndex()); | |
691 | } | |
692 | ||
faa38350 PT |
693 | // ------------------------------------------------------------------------ |
694 | // Signal handlers | |
695 | // ------------------------------------------------------------------------ | |
696 | ||
697 | /** | |
698 | * Handler for the Trace Opened signal | |
699 | * | |
700 | * @param signal | |
701 | * The incoming signal | |
702 | * @since 2.0 | |
703 | */ | |
704 | @TmfSignalHandler | |
705 | public void traceOpened(TmfTraceOpenedSignal signal) { | |
706 | ITmfTrace trace = signal.getTrace(); | |
707 | if (signal.getTrace() instanceof TmfExperiment) { | |
708 | TmfExperiment experiment = (TmfExperiment) signal.getTrace(); | |
709 | for (ITmfTrace expTrace : experiment.getTraces()) { | |
710 | if (expTrace == this) { | |
711 | trace = expTrace; | |
712 | break; | |
713 | } | |
714 | } | |
715 | } | |
faa38350 PT |
716 | if (trace == this) { |
717 | /* the signal is for this trace or for an experiment containing this trace */ | |
718 | try { | |
719 | buildStatistics(); | |
720 | } catch (TmfTraceException e) { | |
721 | e.printStackTrace(); | |
722 | } | |
723 | try { | |
724 | buildStateSystem(); | |
725 | } catch (TmfTraceException e) { | |
726 | e.printStackTrace(); | |
727 | } | |
728 | ||
729 | /* Refresh the project, so it can pick up new files that got created. */ | |
730 | try { | |
731 | if (fResource != null) { | |
732 | fResource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null); | |
733 | } | |
734 | } catch (CoreException e) { | |
735 | e.printStackTrace(); | |
736 | } | |
737 | } | |
738 | if (signal.getTrace() == this) { | |
739 | /* the signal is for this trace or experiment */ | |
740 | if (getNbEvents() == 0) { | |
741 | return; | |
742 | } | |
743 | ||
744 | final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH); | |
745 | final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange); | |
746 | ||
747 | // Broadcast in separate thread to prevent deadlock | |
748 | new Thread() { | |
749 | @Override | |
750 | public void run() { | |
751 | broadcast(rangeUpdatedsignal); | |
752 | } | |
753 | }.start(); | |
754 | return; | |
755 | } | |
756 | } | |
757 | ||
758 | /** | |
759 | * Signal handler for the TmfTraceRangeUpdatedSignal signal | |
760 | * | |
761 | * @param signal The incoming signal | |
762 | * @since 2.0 | |
763 | */ | |
764 | @TmfSignalHandler | |
765 | public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) { | |
766 | if (signal.getTrace() == this) { | |
767 | getIndexer().buildIndex(getNbEvents(), signal.getRange(), false); | |
768 | } | |
769 | } | |
770 | ||
d7ee91bb PT |
771 | /** |
772 | * Signal handler for the TmfTimeSynchSignal signal | |
773 | * | |
774 | * @param signal The incoming signal | |
775 | * @since 2.0 | |
776 | */ | |
777 | @TmfSignalHandler | |
778 | public void synchToTime(final TmfTimeSynchSignal signal) { | |
779 | if (signal.getCurrentTime().compareTo(fStartTime) >= 0 && signal.getCurrentTime().compareTo(fEndTime) <= 0) { | |
780 | fCurrentTime = signal.getCurrentTime(); | |
781 | } | |
782 | } | |
783 | ||
784 | /** | |
785 | * Signal handler for the TmfRangeSynchSignal signal | |
786 | * | |
787 | * @param signal The incoming signal | |
788 | * @since 2.0 | |
789 | */ | |
790 | @TmfSignalHandler | |
791 | public void synchToRange(final TmfRangeSynchSignal signal) { | |
792 | if (signal.getCurrentTime().compareTo(fStartTime) >= 0 && signal.getCurrentTime().compareTo(fEndTime) <= 0) { | |
793 | fCurrentTime = signal.getCurrentTime(); | |
794 | } | |
795 | if (signal.getCurrentRange().getIntersection(getTimeRange()) != null) { | |
796 | fCurrentRange = signal.getCurrentRange().getIntersection(getTimeRange()); | |
797 | } | |
798 | } | |
799 | ||
3791b5df | 800 | // ------------------------------------------------------------------------ |
09e86496 | 801 | // toString |
3791b5df FC |
802 | // ------------------------------------------------------------------------ |
803 | ||
d337369a FC |
804 | /* (non-Javadoc) |
805 | * @see java.lang.Object#toString() | |
806 | */ | |
12c155f5 | 807 | @Override |
09e86496 | 808 | @SuppressWarnings("nls") |
afc86f78 | 809 | public synchronized String toString() { |
20658947 FC |
810 | return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize |
811 | + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime | |
812 | + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]"; | |
12c155f5 FC |
813 | } |
814 | ||
8c8bf09f | 815 | } |