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
.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
;
39 public class CtfTmfTrace
extends TmfEventProvider
<CtfTmfEvent
> implements ITmfTrace
<CtfTmfEvent
> {
41 // ------------------------------------------------------------------------
43 // ------------------------------------------------------------------------
45 // ------------------------------------------------------------------------
47 // ------------------------------------------------------------------------
50 private CTFTrace fTrace
;
52 // The number of events collected
53 protected long fNbEvents
= 0;
55 // The time span of the event stream
56 private ITmfTimestamp fStartTime
= TmfTimestamp
.BIG_CRUNCH
;
57 private ITmfTimestamp fEndTime
= TmfTimestamp
.BIG_BANG
;
60 private IResource fResource
;
62 /* Reference to the state system assigned to this trace */
63 protected IStateSystemQuerier ss
= null;
65 // ------------------------------------------------------------------------
67 // ------------------------------------------------------------------------
69 public CtfTmfTrace() {
75 * @param resource IResource
77 * @param eventType Class<CtfTmfEvent>
78 * @throws TmfTraceException
79 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#initTrace(IResource, String, Class<CtfTmfEvent>)
82 public void initTrace(final IResource resource
, final String path
, final Class
<CtfTmfEvent
> eventType
)
83 throws TmfTraceException
{
85 ITmfEventField eventField
;
86 @SuppressWarnings("unused")
89 this.fResource
= resource
;
91 this.fTrace
= new CTFTrace(path
);
92 for( int i
=0 ; i
< this.fTrace
.getNbEventTypes(); i
++) {
93 ed
= this.fTrace
.getEventType(i
);
94 eventField
= parseDeclaration(ed
);
96 * Populate the event manager with event types that are there in
99 type
= new CtfTmfEventType(ed
.getName(), eventField
);
102 /* Set the start and (current) end times for this trace */
103 final CtfIterator iterator
= new CtfIterator(this, 0, 0);
104 if(iterator
.getLocation().equals(CtfIterator
.NULL_LOCATION
)) {
105 /* Handle the case where the trace is empty */
106 this.setStartTime(TmfTimestamp
.BIG_BANG
);
108 this.setStartTime(iterator
.getCurrentEvent().getTimestamp());
109 iterator
.goToLastEvent();
110 this.setEndTime(iterator
.getCurrentEvent().getTimestamp());
113 } catch (final CTFReaderException e
) {
115 * If it failed at the init(), we can assume it's because the file
116 * was not found or was not recognized as a CTF trace. Throw into
117 * the new type of exception expected by the rest of TMF.
119 throw new TmfTraceException(e
.getMessage());
122 TmfSignalManager
.register(this);
123 //FIXME This should be called via the ExperimentUpdated signal
126 /* Refresh the project, so it can pick up new files that got created. */
127 if ( resource
!= null) {
129 resource
.getProject().refreshLocal(IResource
.DEPTH_INFINITE
, null);
130 } catch (CoreException e
) {
131 throw new TmfTraceException(e
.getMessage());
136 private static ITmfEventField
parseDeclaration(EventDeclaration ed
) {
137 EventDefinition eventDef
= ed
.createDefinition(null);
138 return new CtfTmfContent(ITmfEventField
.ROOT_FIELD_ID
,
139 CtfTmfEvent
.parseFields(eventDef
));
144 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#dispose()
147 public void dispose() {
148 TmfSignalManager
.deregister(this);
153 * @param signal TmfSignal
154 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#broadcast(TmfSignal)
157 public void broadcast(final TmfSignal signal
) {
158 TmfSignalManager
.dispatchSignal(signal
);
163 * @param project IProject
166 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
169 public boolean validate(final IProject project
, final String path
) {
171 final CTFTrace temp
= new CTFTrace(path
);
172 return temp
.majortIsSet(); // random test
173 } catch (final CTFReaderException e
) {
174 /* Nope, not a CTF trace we can read */
179 // ------------------------------------------------------------------------
181 // ------------------------------------------------------------------------
184 * Method getEventType.
185 * @return the trace path
186 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEventType()
189 public Class
<CtfTmfEvent
> getEventType() {
194 * Method getNbEnvVars.
197 public int getNbEnvVars() {
198 return this.fTrace
.getEnvironment().size();
203 * Method getEnvNames.
206 public String
[] getEnvNames() {
207 final String
[] s
= new String
[getNbEnvVars()];
208 return this.fTrace
.getEnvironment().keySet().toArray(s
);
212 * Method getEnvValue.
216 public String
getEnvValue(final String key
) {
217 return this.fTrace
.getEnvironment().get(key
);
223 * @return the trace path * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getPath()
226 public String
getPath() {
227 return this.fTrace
.getPath();
233 * @see org.eclipse.linuxtools.tmf.core.component.ITmfComponent#getName()
236 public String
getName() {
237 String traceName
= (fResource
!= null) ? fResource
.getName() : null;
238 // If no resource was provided, extract the display name the trace path
239 if (traceName
== null) {
240 final String path
= this.fTrace
.getPath();
241 final int sep
= path
.lastIndexOf(IPath
.SEPARATOR
);
242 traceName
= (sep
>= 0) ? path
.substring(sep
+ 1) : path
;
248 * Method getCacheSize.
250 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCacheSize()
253 public int getCacheSize() {
254 return 50000; // not true, but it works
258 * Method getNbEvents.
260 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNbEvents()
263 public long getNbEvents() {
264 return this.fNbEvents
;
268 * Method getTimeRange.
269 * @return TmfTimeRange
270 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getTimeRange()
273 public TmfTimeRange
getTimeRange() {
274 return new TmfTimeRange(this.fStartTime
, this.fEndTime
);
278 * Method getStartTime.
279 * @return ITmfTimestamp
280 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStartTime()
283 public ITmfTimestamp
getStartTime() {
284 return this.fStartTime
;
289 * @return ITmfTimestamp
290 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEndTime()
293 public ITmfTimestamp
getEndTime() {
294 return this.fEndTime
;
298 * Method getCurrentLocation. This is not applicable in CTF
299 * @return null, since the trace has no knowledge of the current location
300 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
303 public ITmfLocation
<?
> getCurrentLocation() {
307 // ------------------------------------------------------------------------
309 // ------------------------------------------------------------------------
312 * Method setTimeRange.
313 * @param range TmfTimeRange
315 protected void setTimeRange(final TmfTimeRange range
) {
316 this.fStartTime
= range
.getStartTime();
317 this.fEndTime
= range
.getEndTime();
321 * Method setStartTime.
322 * @param startTime ITmfTimestamp
324 protected void setStartTime(final ITmfTimestamp startTime
) {
325 this.fStartTime
= startTime
;
330 * @param endTime ITmfTimestamp
332 protected void setEndTime(final ITmfTimestamp endTime
) {
333 this.fEndTime
= endTime
;
336 // ------------------------------------------------------------------------
338 // ------------------------------------------------------------------------
342 * @param request ITmfDataRequest<CtfTmfEvent>
343 * @return ITmfContext
346 public ITmfContext
armRequest(final ITmfDataRequest
<CtfTmfEvent
> request
) {
347 if ((request
instanceof ITmfEventRequest
<?
>)
348 && !TmfTimestamp
.BIG_BANG
349 .equals(((ITmfEventRequest
<CtfTmfEvent
>) request
)
350 .getRange().getStartTime())
351 && (request
.getIndex() == 0)) {
352 final ITmfContext context
= seekEvent(((ITmfEventRequest
<CtfTmfEvent
>) request
)
353 .getRange().getStartTime());
354 ((ITmfEventRequest
<CtfTmfEvent
>) request
)
355 .setStartIndex((int) context
.getRank());
358 return seekEvent(request
.getIndex());
362 * The trace reader keeps its own iterator: the "context" parameter here
365 * If you wish to specify a new context, instantiate a new CtfIterator and
366 * seek() it to where you want, and use that to read events.
368 * FIXME merge with getNextEvent below once they both use the same parameter
370 * @param context ITmfContext
371 * @return CtfTmfEvent
374 public CtfTmfEvent
getNext(final ITmfContext context
) {
375 return readNextEvent(context
);
378 // ------------------------------------------------------------------------
380 // ------------------------------------------------------------------------
384 * @param location ITmfLocation<?>
385 * @return ITmfContext
386 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(ITmfLocation<?>)
389 public ITmfContext
seekEvent(final ITmfLocation
<?
> location
) {
390 CtfLocation currentLocation
= (CtfLocation
) location
;
391 if (currentLocation
== null) {
392 currentLocation
= new CtfLocation(0L);
394 CtfIterator context
= new CtfIterator(this);
395 context
.setLocation(currentLocation
);
396 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
401 * Method getLocationRatio.
402 * @param location ITmfLocation<?>
404 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getLocationRatio(ITmfLocation<?>)
407 public double getLocationRatio(final ITmfLocation
<?
> location
) {
408 final CtfLocation curLocation
= (CtfLocation
) location
;
409 CtfIterator iterator
= new CtfIterator(this);
410 iterator
.seek(curLocation
.getLocation());
411 return ((double) iterator
.getCurrentEvent().getTimestampValue() - iterator
413 / (iterator
.getEndTime() - iterator
.getStartTime());
417 * Method getStreamingInterval.
419 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStreamingInterval()
422 public long getStreamingInterval() {
428 * @param timestamp ITmfTimestamp
429 * @return ITmfContext
430 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(ITmfTimestamp)
433 public ITmfContext
seekEvent(final ITmfTimestamp timestamp
) {
434 CtfIterator context
= new CtfIterator(this);
435 context
.seek(timestamp
.getValue());
436 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
443 * @return ITmfContext
444 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(long)
447 public ITmfContext
seekEvent(final long rank
) {
448 CtfIterator context
= new CtfIterator(this);
449 context
.seekRank(rank
);
450 context
.setRank(rank
);
456 * @param ratio double
457 * @return ITmfContext
458 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(double)
461 public ITmfContext
seekEvent(final double ratio
) {
462 CtfIterator context
= new CtfIterator(this);
463 context
.seek((long) (this.fNbEvents
* ratio
));
464 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
469 * Method readNextEvent.
470 * @param context ITmfContext
471 * @return CtfTmfEvent
472 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#readNextEvent(ITmfContext)
475 public CtfTmfEvent
readNextEvent(final ITmfContext context
) {
476 CtfTmfEvent event
= null;
477 if (context
instanceof CtfIterator
) {
478 CtfIterator ctfIterator
= (CtfIterator
) context
;
479 event
= ctfIterator
.getCurrentEvent();
480 ctfIterator
.advance();
486 * Method getResource.
488 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
491 public IResource
getResource() {
492 return this.fResource
;
496 * Method getStateSystem.
497 * @return IStateSystemQuerier
499 public IStateSystemQuerier
getStateSystem() {
504 * Method getCTFTrace.
507 CTFTrace
getCTFTrace() {
513 * Suppressing the warning, because the 'throws' will usually happen in
515 * @throws TmfTraceException
517 protected void buildStateSystem() throws TmfTraceException
{
519 * Nothing is done in the basic implementation, please specify
520 * how/if to build a state system in derived classes.