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
.linuxtools
.ctf
.core
.trace
.CTFReaderException
;
18 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFTrace
;
19 import org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
.CtfTmfTimestamp
.TimestampType
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfTimestamp
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
22 import org
.eclipse
.linuxtools
.tmf
.core
.event
.TmfTimestamp
;
23 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TmfTraceException
;
24 import org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.ITmfStateSystem
;
25 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
26 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfEventParser
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfLocation
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfTrace
;
31 * The CTf trace handler
34 * @author Matthew khouzam
36 public class CtfTmfTrace
extends TmfTrace
implements ITmfEventParser
{
39 //-------------------------------------------
41 //-------------------------------------------
43 * Default cache size for CTF traces
45 protected static final int DEFAULT_CACHE_SIZE
= 50000;
47 //-------------------------------------------
49 //-------------------------------------------
51 /** Reference to the state system assigned to this trace */
52 protected ITmfStateSystem ss
= null;
54 /* Reference to the CTF Trace */
55 private CTFTrace fTrace
;
59 //-------------------------------------------
61 //-------------------------------------------
66 * The resource associated with this trace
68 * The path to the trace file
70 * The type of events that will be read from this trace
71 * @throws TmfTraceException
72 * If something when wrong while reading the trace
75 public void initTrace(final IResource resource
, final String path
, final Class
<?
extends ITmfEvent
> eventType
)
76 throws TmfTraceException
{
78 * Set the cache size. This has to be done before the call to super()
79 * because the super needs to know the cache size.
82 super.initTrace(resource
, path
, eventType
);
84 @SuppressWarnings("unused")
88 this.fTrace
= new CTFTrace(path
);
89 CtfIteratorManager
.addTrace(this);
90 CtfTmfLightweightContext ctx
;
91 /* Set the start and (current) end times for this trace */
92 ctx
= (CtfTmfLightweightContext
) seekEvent(0L);
93 CtfTmfEvent event
= getNext(ctx
);
94 if((ctx
.getLocation().equals(CtfIterator
.NULL_LOCATION
)) || (ctx
.getCurrentEvent() == null)) {
95 /* Handle the case where the trace is empty */
96 this.setStartTime(TmfTimestamp
.BIG_BANG
);
98 final ITmfTimestamp curTime
= event
.getTimestamp();
99 this.setStartTime(curTime
);
100 this.setEndTime(curTime
);
103 } catch (final CTFReaderException e
) {
105 * If it failed at the init(), we can assume it's because the file
106 * was not found or was not recognized as a CTF trace. Throw into
107 * the new type of exception expected by the rest of TMF.
109 throw new TmfTraceException(e
.getMessage(), e
);
112 //FIXME This should be called via the ExperimentUpdated signal
115 /* Refresh the project, so it can pick up new files that got created. */
116 if ( resource
!= null) {
118 resource
.getProject().refreshLocal(IResource
.DEPTH_INFINITE
, null);
119 } catch (CoreException e
) {
120 throw new TmfTraceException(e
.getMessage(), e
);
126 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#dispose()
129 public synchronized void dispose() {
130 CtfIteratorManager
.removeTrace(this);
136 * @param project IProject
139 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
142 public boolean validate(final IProject project
, final String path
) {
144 final CTFTrace temp
= new CTFTrace(path
);
145 return temp
.majortIsSet(); // random test
146 } catch (final CTFReaderException e
) {
147 /* Nope, not a CTF trace we can read */
153 * Method getCurrentLocation. This is not applicable in CTF
154 * @return null, since the trace has no knowledge of the current location
155 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
158 public ITmfLocation
getCurrentLocation() {
165 public double getLocationRatio(ITmfLocation location
) {
166 final CtfLocation curLocation
= (CtfLocation
) location
;
167 final CtfTmfLightweightContext context
= new CtfTmfLightweightContext(this);
168 context
.setLocation(curLocation
);
169 context
.seek(curLocation
.getLocationInfo());
170 final CtfLocationData currentTime
= ((CtfLocationData
)context
.getLocation().getLocationInfo());
171 final long startTime
= getIterator(this, context
).getStartTime();
172 final long endTime
= getIterator(this, context
).getEndTime();
173 return ((double) currentTime
.getTimestamp() - startTime
)
174 / (endTime
- startTime
);
182 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
185 public synchronized ITmfContext
seekEvent(ITmfTimestamp timestamp
) {
186 if( timestamp
instanceof CtfTmfTimestamp
){
187 CtfTmfLightweightContext iter
= new CtfTmfLightweightContext(this);
188 iter
.seek(timestamp
.getValue());
191 return super.seekEvent(timestamp
);
196 * @param location ITmfLocation<?>
197 * @return ITmfContext
200 public ITmfContext
seekEvent(final ITmfLocation location
) {
201 CtfLocation currentLocation
= (CtfLocation
) location
;
202 CtfTmfLightweightContext context
= new CtfTmfLightweightContext(this);
204 * The rank is set to 0 if the iterator seeks the beginning. If not, it
205 * will be set to UNKNOWN_RANK, since CTF traces don't support seeking
208 if (currentLocation
== null) {
209 currentLocation
= new CtfLocation(new CtfLocationData(0L, 0L));
212 if (currentLocation
.getLocationInfo() == CtfLocation
.INVALID_LOCATION
) {
213 ((CtfTmfTimestamp
) getEndTime()).setType(TimestampType
.NANOS
);
214 currentLocation
= new CtfLocation(getEndTime().getValue() + 1, 0L);
216 context
.setLocation(currentLocation
);
217 if (location
== null) {
218 CtfTmfEvent event
= getIterator(this, context
).getCurrentEvent();
220 currentLocation
= new CtfLocation(event
.getTimestamp().getValue(), 0);
223 if(context
.getRank() != 0) {
224 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
231 public ITmfContext
seekEvent(double ratio
) {
232 CtfTmfLightweightContext context
= new CtfTmfLightweightContext(this);
233 final long end
= this.getEndTime().getValue();
234 final long start
= this.getStartTime().getValue();
235 final long diff
= end
- start
;
236 final long ratioTs
= (long) (diff
* ratio
) + start
;
237 context
.seek(ratioTs
);
238 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
243 * Method readNextEvent.
244 * @param context ITmfContext
245 * @return CtfTmfEvent
246 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
249 public synchronized CtfTmfEvent
getNext(final ITmfContext context
) {
250 CtfTmfEvent event
= null;
251 if (context
instanceof CtfTmfLightweightContext
) {
252 if (CtfLocation
.INVALID_LOCATION
.equals(context
.getLocation().getLocationInfo())) {
255 CtfTmfLightweightContext ctfContext
= (CtfTmfLightweightContext
) context
;
256 event
= ctfContext
.getCurrentEvent();
259 updateAttributes(context
, event
.getTimestamp());
260 ctfContext
.advance();
261 ctfContext
.increaseRank();
269 * Suppressing the warning, because the 'throws' will usually happen in
272 * @throws TmfTraceException
274 @SuppressWarnings("unused")
275 protected void buildStateSystem() throws TmfTraceException
{
277 * Nothing is done in the basic implementation, please specify
278 * how/if to build a state system in derived classes.
287 public ITmfStateSystem
getStateSystem() {
292 * gets the CTFtrace that this is wrapping
293 * @return the CTF trace
295 public CTFTrace
getCTFTrace() {
300 //-------------------------------------------
301 // Environment Parameters
302 //-------------------------------------------
304 * Method getNbEnvVars.
308 public int getNbEnvVars() {
309 return this.fTrace
.getEnvironment().size();
313 * Method getEnvNames.
317 public String
[] getEnvNames() {
318 final String
[] s
= new String
[getNbEnvVars()];
319 return this.fTrace
.getEnvironment().keySet().toArray(s
);
323 * Method getEnvValue.
329 public String
getEnvValue(final String key
) {
330 return this.fTrace
.getEnvironment().get(key
);
333 //-------------------------------------------
335 //-------------------------------------------
338 * gets the clock offset
339 * @return the clock offset in ns
341 public long getOffset(){
342 if( fTrace
!= null ) {
343 return fTrace
.getOffset();
348 //-------------------------------------------
350 //-------------------------------------------
353 public CtfTmfEvent
parseEvent(ITmfContext context
) {
354 CtfTmfEvent event
= null;
355 if( context
instanceof CtfTmfLightweightContext
){
356 CtfTmfLightweightContext itt
= (CtfTmfLightweightContext
) context
.clone();
357 event
= itt
.getCurrentEvent();
363 * Sets the cache size for a CtfTmfTrace.
365 protected void setCacheSize() {
366 setCacheSize(DEFAULT_CACHE_SIZE
);
369 //-------------------------------------------
371 //-------------------------------------------
373 private static CtfIterator
getIterator(CtfTmfTrace trace
, CtfTmfLightweightContext context
) {
374 return CtfIteratorManager
.getIterator(trace
, context
);