Fix seek behaviour in CtfAdaptor
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * 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: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
11
12 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
13
14 import org.eclipse.core.resources.IProject;
15 import org.eclipse.core.resources.IResource;
16 import org.eclipse.core.runtime.CoreException;
17 import org.eclipse.core.runtime.IPath;
18 import org.eclipse.linuxtools.ctf.core.event.EventDeclaration;
19 import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
20 import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
21 import org.eclipse.linuxtools.ctf.core.trace.CTFTrace;
22 import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
23 import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
24 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
25 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
26 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
27 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
28 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
29 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
30 import org.eclipse.linuxtools.tmf.core.signal.TmfSignal;
31 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
32 import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;
33 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
34 import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
35 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
36
37 /**
38 */
39 public class CtfTmfTrace extends TmfEventProvider<CtfTmfEvent> implements ITmfTrace<CtfTmfEvent> {
40
41 // ------------------------------------------------------------------------
42 // Constants
43 // ------------------------------------------------------------------------
44
45 // ------------------------------------------------------------------------
46 // Attributes
47 // ------------------------------------------------------------------------
48
49 // the Ctf Trace
50 private CTFTrace fTrace;
51
52 // The number of events collected
53 protected long fNbEvents = 0;
54
55 // The time span of the event stream
56 private ITmfTimestamp fStartTime = TmfTimestamp.BIG_CRUNCH;
57 private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
58
59 // The trace resource
60 private IResource fResource;
61
62 /* Reference to the state system assigned to this trace */
63 protected IStateSystemQuerier ss = null;
64
65 // ------------------------------------------------------------------------
66 // Constructors
67 // ------------------------------------------------------------------------
68
69 public CtfTmfTrace() {
70 super();
71 }
72
73 /**
74 * Method initTrace.
75 * @param resource IResource
76 * @param path String
77 * @param eventType Class<CtfTmfEvent>
78 * @throws TmfTraceException
79 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#initTrace(IResource, String, Class<CtfTmfEvent>)
80 */
81 @Override
82 public void initTrace(final IResource resource, final String path, final Class<CtfTmfEvent> eventType)
83 throws TmfTraceException {
84 this.fResource = resource;
85 try {
86 this.fTrace = new CTFTrace(path);
87 for( int i =0 ; i< this.fTrace.getNbEventTypes(); i++) {
88 EventDeclaration ed = this.fTrace.getEventType(i);
89 ITmfEventField eventField = parseDeclaration(ed);
90 new CtfTmfEventType(ed.getName(), eventField);
91 }
92 } catch (final CTFReaderException e) {
93 /*
94 * If it failed at the init(), we can assume it's because the file
95 * was not found or was not recognized as a CTF trace. Throw into
96 * the new type of exception expected by the rest of TMF.
97 */
98 throw new TmfTraceException(e.getMessage());
99 }
100 CtfIterator iterator = new CtfIterator(this, 0, 0);
101 setStartTime(TmfTimestamp.BIG_BANG);
102 if( !iterator.getLocation().equals(CtfIterator.NULL_LOCATION)) {
103 setStartTime(iterator.getCurrentEvent().getTimestamp());
104 }
105 TmfSignalManager.register(this);
106 // FIXME this should become a request
107 buildStateSystem();
108
109 /* Refresh the project, so it can pick up new files that got created. */
110 if ( resource != null) {
111 try {
112 resource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
113 } catch (CoreException e) {
114 throw new TmfTraceException(e.getMessage());
115 }
116 }
117 }
118
119 private static ITmfEventField parseDeclaration(EventDeclaration ed) {
120 EventDefinition eventDef = ed.createDefinition(null);
121 return new CtfTmfContent(ITmfEventField.ROOT_FIELD_ID,
122 CtfTmfEvent.parseFields(eventDef));
123 }
124
125 /**
126 * Method dispose.
127 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#dispose()
128 */
129 @Override
130 public void dispose() {
131 TmfSignalManager.deregister(this);
132 }
133
134 /**
135 * Method broadcast.
136 * @param signal TmfSignal
137 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#broadcast(TmfSignal)
138 */
139 @Override
140 public void broadcast(final TmfSignal signal) {
141 TmfSignalManager.dispatchSignal(signal);
142 }
143
144 /**
145 * Method validate.
146 * @param project IProject
147 * @param path String
148 * @return boolean
149 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
150 */
151 @Override
152 public boolean validate(final IProject project, final String path) {
153 try {
154 final CTFTrace temp = new CTFTrace(path);
155 return temp.majortIsSet(); // random test
156 } catch (final CTFReaderException e) {
157 /* Nope, not a CTF trace we can read */
158 return false;
159 }
160 }
161
162 // ------------------------------------------------------------------------
163 // Accessors
164 // ------------------------------------------------------------------------
165
166 /**
167 * Method getEventType.
168 * @return the trace path
169 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEventType()
170 */
171 @Override
172 public Class<CtfTmfEvent> getEventType() {
173 return fType;
174 }
175
176 /**
177 * Method getNbEnvVars.
178 * @return int
179 */
180 public int getNbEnvVars() {
181 return this.fTrace.getEnvironment().size();
182 }
183
184
185 /**
186 * Method getEnvNames.
187 * @return String[]
188 */
189 public String[] getEnvNames() {
190 final String[] s = new String[getNbEnvVars()];
191 return this.fTrace.getEnvironment().keySet().toArray(s);
192 }
193
194 /**
195 * Method getEnvValue.
196 * @param key String
197 * @return String
198 */
199 public String getEnvValue(final String key) {
200 return this.fTrace.getEnvironment().get(key);
201 }
202
203
204 /**
205
206 * @return the trace path * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getPath()
207 */
208 @Override
209 public String getPath() {
210 return this.fTrace.getPath();
211 }
212
213 /**
214 * Method getName.
215 * @return String
216 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#getName()
217 */
218 @Override
219 public String getName() {
220 String traceName = (fResource != null) ? fResource.getName() : null;
221 // If no resource was provided, extract the display name the trace path
222 if (traceName == null) {
223 final String path = this.fTrace.getPath();
224 final int sep = path.lastIndexOf(IPath.SEPARATOR);
225 traceName = (sep >= 0) ? path.substring(sep + 1) : path;
226 }
227 return traceName;
228 }
229
230 /**
231 * Method getCacheSize.
232 * @return int
233 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCacheSize()
234 */
235 @Override
236 public int getCacheSize() {
237 return 50000; // not true, but it works
238 }
239
240 /**
241 * Method getNbEvents.
242 * @return long
243 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNbEvents()
244 */
245 @Override
246 public long getNbEvents() {
247 return this.fNbEvents;
248 }
249
250 /**
251 * Method getTimeRange.
252 * @return TmfTimeRange
253 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getTimeRange()
254 */
255 @Override
256 public TmfTimeRange getTimeRange() {
257 return new TmfTimeRange(this.fStartTime, this.fEndTime);
258 }
259
260 /**
261 * Method getStartTime.
262 * @return ITmfTimestamp
263 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStartTime()
264 */
265 @Override
266 public ITmfTimestamp getStartTime() {
267 return this.fStartTime;
268 }
269
270 /**
271 * Method getEndTime.
272 * @return ITmfTimestamp
273 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEndTime()
274 */
275 @Override
276 public ITmfTimestamp getEndTime() {
277 return this.fEndTime;
278 }
279
280 /**
281 * Method getCurrentLocation. This is not applicable in CTF
282 * @return null, since the trace has no knowledge of the current location
283 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
284 */
285 @Override
286 public ITmfLocation<?> getCurrentLocation() {
287 return null;
288 }
289
290 // ------------------------------------------------------------------------
291 // Operators
292 // ------------------------------------------------------------------------
293
294 /**
295 * Method setTimeRange.
296 * @param range TmfTimeRange
297 */
298 protected void setTimeRange(final TmfTimeRange range) {
299 this.fStartTime = range.getStartTime();
300 this.fEndTime = range.getEndTime();
301 }
302
303 /**
304 * Method setStartTime.
305 * @param startTime ITmfTimestamp
306 */
307 protected void setStartTime(final ITmfTimestamp startTime) {
308 this.fStartTime = startTime;
309 }
310
311 /**
312 * Method setEndTime.
313 * @param endTime ITmfTimestamp
314 */
315 protected void setEndTime(final ITmfTimestamp endTime) {
316 this.fEndTime = endTime;
317 }
318
319 // ------------------------------------------------------------------------
320 // TmfProvider
321 // ------------------------------------------------------------------------
322
323 /**
324 * Method armRequest.
325 * @param request ITmfDataRequest<CtfTmfEvent>
326 * @return ITmfContext
327 */
328 @Override
329 public ITmfContext armRequest(final ITmfDataRequest<CtfTmfEvent> request) {
330 if ((request instanceof ITmfEventRequest<?>)
331 && !TmfTimestamp.BIG_BANG
332 .equals(((ITmfEventRequest<CtfTmfEvent>) request)
333 .getRange().getStartTime())
334 && (request.getIndex() == 0)) {
335 final ITmfContext context = seekEvent(((ITmfEventRequest<CtfTmfEvent>) request)
336 .getRange().getStartTime());
337 ((ITmfEventRequest<CtfTmfEvent>) request)
338 .setStartIndex((int) context.getRank());
339 return context;
340 }
341 return seekEvent(request.getIndex());
342 }
343
344 /**
345 * The trace reader keeps its own iterator: the "context" parameter here
346 * will be ignored.
347 *
348 * If you wish to specify a new context, instantiate a new CtfIterator and
349 * seek() it to where you want, and use that to read events.
350 *
351 * FIXME merge with getNextEvent below once they both use the same parameter
352 * type.
353 * @param context ITmfContext
354 * @return CtfTmfEvent
355 */
356 @Override
357 public CtfTmfEvent getNext(final ITmfContext context) {
358 return readNextEvent(context);
359 }
360
361 // ------------------------------------------------------------------------
362 // ITmfTrace
363 // ------------------------------------------------------------------------
364
365 /**
366 * Method seekEvent.
367 * @param location ITmfLocation<?>
368 * @return ITmfContext
369 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(ITmfLocation<?>)
370 */
371 @Override
372 public ITmfContext seekEvent(final ITmfLocation<?> location) {
373 CtfLocation currentLocation = (CtfLocation) location;
374 if (currentLocation == null) {
375 currentLocation = new CtfLocation(0L);
376 }
377 CtfIterator context = new CtfIterator(this);
378 context.setLocation(currentLocation);
379 context.setRank(ITmfContext.UNKNOWN_RANK);
380 return context;
381 }
382
383 /**
384 * Method getLocationRatio.
385 * @param location ITmfLocation<?>
386 * @return double
387 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getLocationRatio(ITmfLocation<?>)
388 */
389 @Override
390 public double getLocationRatio(final ITmfLocation<?> location) {
391 final CtfLocation curLocation = (CtfLocation) location;
392 CtfIterator iterator = new CtfIterator(this);
393 iterator.seek(curLocation.getLocation());
394 return ((double) iterator.getCurrentEvent().getTimestampValue() - iterator
395 .getStartTime())
396 / (iterator.getEndTime() - iterator.getStartTime());
397 }
398
399 /**
400 * Method getStreamingInterval.
401 * @return long
402 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStreamingInterval()
403 */
404 @Override
405 public long getStreamingInterval() {
406 return 0;
407 }
408
409 /**
410 * Method seekEvent.
411 * @param timestamp ITmfTimestamp
412 * @return ITmfContext
413 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(ITmfTimestamp)
414 */
415 @Override
416 public ITmfContext seekEvent(final ITmfTimestamp timestamp) {
417 CtfIterator context = new CtfIterator(this);
418 context.seek(timestamp.getValue());
419 context.setRank(ITmfContext.UNKNOWN_RANK);
420 return context;
421 }
422
423 /**
424 * Seek by rank
425 * @param rank long
426 * @return ITmfContext
427 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(long)
428 */
429 @Override
430 public ITmfContext seekEvent(final long rank) {
431 CtfIterator context = new CtfIterator(this);
432 context.seekRank(rank);
433 context.setRank(rank);
434 return context;
435 }
436
437 /**
438 * Seek rank ratio
439 * @param ratio double
440 * @return ITmfContext
441 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(double)
442 */
443 @Override
444 public ITmfContext seekEvent(final double ratio) {
445 CtfIterator context = new CtfIterator(this);
446 context.seek((long) (this.fNbEvents * ratio));
447 context.setRank(ITmfContext.UNKNOWN_RANK);
448 return context;
449 }
450
451 /**
452 * Method readNextEvent.
453 * @param context ITmfContext
454 * @return CtfTmfEvent
455 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#readNextEvent(ITmfContext)
456 */
457 @Override
458 public CtfTmfEvent readNextEvent(final ITmfContext context) {
459 CtfTmfEvent event = null;
460 if (context instanceof CtfIterator) {
461 CtfIterator ctfIterator = (CtfIterator) context;
462 event = ctfIterator.getCurrentEvent();
463 ctfIterator.advance();
464 }
465 return event;
466 }
467
468 /**
469 * Method getResource.
470 * @return IResource
471 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
472 */
473 @Override
474 public IResource getResource() {
475 return this.fResource;
476 }
477
478 /**
479 * Method getStateSystem.
480 * @return IStateSystemQuerier
481 */
482 public IStateSystemQuerier getStateSystem() {
483 return this.ss;
484 }
485
486 /**
487 * Method getCTFTrace.
488 * @return CTFTrace
489 */
490 CTFTrace getCTFTrace() {
491 return fTrace;
492 }
493
494
495 /**
496 * Suppressing the warning, because the 'throws' will usually happen in
497 * sub-classes.
498 * @throws TmfTraceException
499 */
500 protected void buildStateSystem() throws TmfTraceException {
501 /*
502 * Nothing is done in the basic implementation, please specify
503 * how/if to build a state system in derived classes.
504 */
505 return;
506 }
507
508 }
This page took 0.04264 seconds and 6 git commands to generate.