1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
12 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
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
.ctfadaptor
.CtfTmfTimestamp
.TimestampType
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEventField
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimeRange
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TmfTraceException
;
29 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfDataRequest
;
30 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignal
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.signal
.TmfSignalManager
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.IStateSystemQuerier
;
34 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfLocation
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
40 public class CtfTmfTrace
extends TmfEventProvider
<CtfTmfEvent
> implements ITmfTrace
<CtfTmfEvent
> {
42 // ------------------------------------------------------------------------
44 // ------------------------------------------------------------------------
46 // ------------------------------------------------------------------------
48 // ------------------------------------------------------------------------
51 private CTFTrace fTrace
;
53 // The number of events collected
54 protected long fNbEvents
= 0;
56 // The time span of the event stream
57 private ITmfTimestamp fStartTime
= TmfTimestamp
.BIG_CRUNCH
;
58 private ITmfTimestamp fEndTime
= TmfTimestamp
.BIG_BANG
;
61 private IResource fResource
;
63 /* Reference to the state system assigned to this trace */
64 protected IStateSystemQuerier ss
= null;
66 // ------------------------------------------------------------------------
68 // ------------------------------------------------------------------------
70 public CtfTmfTrace() {
76 * @param resource IResource
78 * @param eventType Class<CtfTmfEvent>
79 * @throws TmfTraceException
80 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#initTrace(IResource, String, Class<CtfTmfEvent>)
83 public void initTrace(final IResource resource
, final String path
, final Class
<CtfTmfEvent
> eventType
)
84 throws TmfTraceException
{
86 ITmfEventField eventField
;
87 @SuppressWarnings("unused")
90 this.fResource
= resource
;
92 this.fTrace
= new CTFTrace(path
);
93 for( int i
=0 ; i
< this.fTrace
.getNbEventTypes(); i
++) {
94 ed
= this.fTrace
.getEventType(i
);
95 eventField
= parseDeclaration(ed
);
97 * Populate the event manager with event types that are there in
100 type
= new CtfTmfEventType(ed
.getName(), eventField
);
103 /* Set the start and (current) end times for this trace */
104 final CtfIterator iterator
= new CtfIterator(this, 0, 0);
105 if(iterator
.getLocation().equals(CtfIterator
.NULL_LOCATION
)) {
106 /* Handle the case where the trace is empty */
107 this.setStartTime(TmfTimestamp
.BIG_BANG
);
109 this.setStartTime(iterator
.getCurrentEvent().getTimestamp());
110 iterator
.goToLastEvent();
111 this.setEndTime(iterator
.getCurrentEvent().getTimestamp());
114 } catch (final CTFReaderException e
) {
116 * If it failed at the init(), we can assume it's because the file
117 * was not found or was not recognized as a CTF trace. Throw into
118 * the new type of exception expected by the rest of TMF.
120 throw new TmfTraceException(e
.getMessage());
123 TmfSignalManager
.register(this);
124 //FIXME This should be called via the ExperimentUpdated signal
127 /* Refresh the project, so it can pick up new files that got created. */
128 if ( resource
!= null) {
130 resource
.getProject().refreshLocal(IResource
.DEPTH_INFINITE
, null);
131 } catch (CoreException e
) {
132 throw new TmfTraceException(e
.getMessage());
137 private static ITmfEventField
parseDeclaration(EventDeclaration ed
) {
138 EventDefinition eventDef
= ed
.createDefinition(null);
139 return new CtfTmfContent(ITmfEventField
.ROOT_FIELD_ID
,
140 CtfTmfEvent
.parseFields(eventDef
));
145 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#dispose()
148 public void dispose() {
149 TmfSignalManager
.deregister(this);
154 * @param signal TmfSignal
155 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#broadcast(TmfSignal)
158 public void broadcast(final TmfSignal signal
) {
159 TmfSignalManager
.dispatchSignal(signal
);
164 * @param project IProject
167 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
170 public boolean validate(final IProject project
, final String path
) {
172 final CTFTrace temp
= new CTFTrace(path
);
173 return temp
.majortIsSet(); // random test
174 } catch (final CTFReaderException e
) {
175 /* Nope, not a CTF trace we can read */
180 // ------------------------------------------------------------------------
182 // ------------------------------------------------------------------------
185 * Method getEventType.
186 * @return the trace path
187 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEventType()
190 public Class
<CtfTmfEvent
> getEventType() {
195 * Method getNbEnvVars.
198 public int getNbEnvVars() {
199 return this.fTrace
.getEnvironment().size();
204 * Method getEnvNames.
207 public String
[] getEnvNames() {
208 final String
[] s
= new String
[getNbEnvVars()];
209 return this.fTrace
.getEnvironment().keySet().toArray(s
);
213 * Method getEnvValue.
217 public String
getEnvValue(final String key
) {
218 return this.fTrace
.getEnvironment().get(key
);
224 * @return the trace path * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getPath()
227 public String
getPath() {
228 return this.fTrace
.getPath();
234 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#getName()
237 public String
getName() {
238 String traceName
= (fResource
!= null) ? fResource
.getName() : null;
239 // If no resource was provided, extract the display name the trace path
240 if (traceName
== null) {
241 final String path
= this.fTrace
.getPath();
242 final int sep
= path
.lastIndexOf(IPath
.SEPARATOR
);
243 traceName
= (sep
>= 0) ? path
.substring(sep
+ 1) : path
;
249 * Method getCacheSize.
251 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCacheSize()
254 public int getCacheSize() {
255 return 50000; // not true, but it works
259 * Method getNbEvents.
261 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNbEvents()
264 public long getNbEvents() {
265 return this.fNbEvents
;
269 * Method getTimeRange.
270 * @return TmfTimeRange
271 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getTimeRange()
274 public TmfTimeRange
getTimeRange() {
275 return new TmfTimeRange(this.fStartTime
, this.fEndTime
);
279 * Method getStartTime.
280 * @return ITmfTimestamp
281 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStartTime()
284 public ITmfTimestamp
getStartTime() {
285 return this.fStartTime
;
290 * @return ITmfTimestamp
291 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEndTime()
294 public ITmfTimestamp
getEndTime() {
295 return this.fEndTime
;
299 * Method getCurrentLocation. This is not applicable in CTF
300 * @return null, since the trace has no knowledge of the current location
301 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
304 public ITmfLocation
<?
> getCurrentLocation() {
308 // ------------------------------------------------------------------------
310 // ------------------------------------------------------------------------
313 * Method setTimeRange.
314 * @param range TmfTimeRange
316 protected void setTimeRange(final TmfTimeRange range
) {
317 this.fStartTime
= range
.getStartTime();
318 this.fEndTime
= range
.getEndTime();
322 * Method setStartTime.
323 * @param startTime ITmfTimestamp
325 protected void setStartTime(final ITmfTimestamp startTime
) {
326 this.fStartTime
= startTime
;
331 * @param endTime ITmfTimestamp
333 protected void setEndTime(final ITmfTimestamp endTime
) {
334 this.fEndTime
= endTime
;
337 // ------------------------------------------------------------------------
339 // ------------------------------------------------------------------------
343 * @param request ITmfDataRequest<CtfTmfEvent>
344 * @return ITmfContext
347 public ITmfContext
armRequest(final ITmfDataRequest
<CtfTmfEvent
> request
) {
348 if ((request
instanceof ITmfEventRequest
<?
>)
349 && !TmfTimestamp
.BIG_BANG
350 .equals(((ITmfEventRequest
<CtfTmfEvent
>) request
)
351 .getRange().getStartTime())
352 && (request
.getIndex() == 0)) {
353 final ITmfContext context
= seekEvent(((ITmfEventRequest
<CtfTmfEvent
>) request
)
354 .getRange().getStartTime());
355 ((ITmfEventRequest
<CtfTmfEvent
>) request
)
356 .setStartIndex((int) context
.getRank());
359 return seekEvent(request
.getIndex());
363 // * The trace reader keeps its own iterator: the "context" parameter here
364 // * will be ignored.
366 // * If you wish to specify a new context, instantiate a new CtfIterator and
367 // * seek() it to where you want, and use that to read events.
369 // * FIXME merge with getNextEvent below once they both use the same parameter
371 // * @param context ITmfContext
372 // * @return CtfTmfEvent
375 // public CtfTmfEvent getNext(final ITmfContext context) {
376 // return readNextEvent(context);
379 // ------------------------------------------------------------------------
381 // ------------------------------------------------------------------------
385 * @param location ITmfLocation<?>
386 * @return ITmfContext
387 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(ITmfLocation<?>)
390 public ITmfContext
seekEvent(final ITmfLocation
<?
> location
) {
391 CtfLocation currentLocation
= (CtfLocation
) location
;
392 if (currentLocation
== null) {
393 currentLocation
= new CtfLocation(0L);
395 CtfIterator context
= new CtfIterator(this);
397 if (currentLocation
.getLocation() == CtfLocation
.INVALID_LOCATION
) {
398 ((CtfTmfTimestamp
)getEndTime()).setType(TimestampType
.NANOS
);
399 currentLocation
.setLocation( getEndTime().getValue() + 1);
401 context
.setLocation(currentLocation
);
402 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
407 * Method getLocationRatio.
408 * @param location ITmfLocation<?>
410 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getLocationRatio(ITmfLocation<?>)
413 public double getLocationRatio(final ITmfLocation
<?
> location
) {
414 final CtfLocation curLocation
= (CtfLocation
) location
;
415 CtfIterator iterator
= new CtfIterator(this);
416 iterator
.seek(curLocation
.getLocation());
417 return ((double) iterator
.getCurrentEvent().getTimestampValue() - iterator
419 / (iterator
.getEndTime() - iterator
.getStartTime());
423 * Method getStreamingInterval.
425 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStreamingInterval()
428 public long getStreamingInterval() {
434 * @param timestamp ITmfTimestamp
435 * @return ITmfContext
436 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(ITmfTimestamp)
439 public ITmfContext
seekEvent(final ITmfTimestamp timestamp
) {
440 CtfIterator context
= new CtfIterator(this);
441 context
.seek(timestamp
.getValue());
442 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
449 * @return ITmfContext
450 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(long)
453 public ITmfContext
seekEvent(final long rank
) {
454 CtfIterator context
= new CtfIterator(this);
455 context
.seekRank(rank
);
456 context
.setRank(rank
);
462 * @param ratio double
463 * @return ITmfContext
464 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(double)
467 public ITmfContext
seekEvent(final double ratio
) {
468 CtfIterator context
= new CtfIterator(this);
469 context
.seek((long) (this.fNbEvents
* ratio
));
470 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
475 * Method readNextEvent.
476 * @param context ITmfContext
477 * @return CtfTmfEvent
478 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
481 public CtfTmfEvent
getNext(final ITmfContext context
) {
482 CtfTmfEvent event
= null;
483 if (context
instanceof CtfIterator
) {
484 CtfIterator ctfIterator
= (CtfIterator
) context
;
485 event
= ctfIterator
.getCurrentEvent();
486 ctfIterator
.advance();
492 * Method getResource.
494 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
497 public IResource
getResource() {
498 return this.fResource
;
502 * Method getStateSystem.
503 * @return IStateSystemQuerier
505 public IStateSystemQuerier
getStateSystem() {
510 * Method getCTFTrace.
513 CTFTrace
getCTFTrace() {
519 * Suppressing the warning, because the 'throws' will usually happen in
521 * @throws TmfTraceException
523 protected void buildStateSystem() throws TmfTraceException
{
525 * Nothing is done in the basic implementation, please specify
526 * how/if to build a state system in derived classes.