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.
83 @SuppressWarnings("unused")
87 this.fTrace
= new CTFTrace(path
);
88 CtfIteratorManager
.addTrace(this);
89 CtfTmfLightweightContext ctx
;
90 /* Set the start and (current) end times for this trace */
91 ctx
= (CtfTmfLightweightContext
) seekEvent(0L);
92 CtfTmfEvent event
= getNext(ctx
);
93 if((ctx
.getLocation().equals(CtfIterator
.NULL_LOCATION
)) || (ctx
.getCurrentEvent() == null)) {
94 /* Handle the case where the trace is empty */
95 this.setStartTime(TmfTimestamp
.BIG_BANG
);
97 final ITmfTimestamp curTime
= event
.getTimestamp();
98 this.setStartTime(curTime
);
99 this.setEndTime(curTime
);
102 } catch (final CTFReaderException e
) {
104 * If it failed at the init(), we can assume it's because the file
105 * was not found or was not recognized as a CTF trace. Throw into
106 * the new type of exception expected by the rest of TMF.
108 throw new TmfTraceException(e
.getMessage(), e
);
111 super.initTrace(resource
, path
, eventType
);
113 //FIXME This should be called via the ExperimentUpdated signal
116 /* Refresh the project, so it can pick up new files that got created. */
117 if ( resource
!= null) {
119 resource
.getProject().refreshLocal(IResource
.DEPTH_INFINITE
, null);
120 } catch (CoreException e
) {
121 throw new TmfTraceException(e
.getMessage(), e
);
127 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#dispose()
130 public synchronized void dispose() {
131 CtfIteratorManager
.removeTrace(this);
137 * @param project IProject
140 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
143 public boolean validate(final IProject project
, final String path
) {
145 final CTFTrace temp
= new CTFTrace(path
);
146 return temp
.majortIsSet(); // random test
147 } catch (final CTFReaderException e
) {
148 /* Nope, not a CTF trace we can read */
154 * Method getCurrentLocation. This is not applicable in CTF
155 * @return null, since the trace has no knowledge of the current location
156 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
159 public ITmfLocation
getCurrentLocation() {
166 public double getLocationRatio(ITmfLocation location
) {
167 final CtfLocation curLocation
= (CtfLocation
) location
;
168 final CtfTmfLightweightContext context
= new CtfTmfLightweightContext(this);
169 context
.setLocation(curLocation
);
170 context
.seek(curLocation
.getLocationInfo());
171 final CtfLocationData currentTime
= ((CtfLocationData
)context
.getLocation().getLocationInfo());
172 final long startTime
= getIterator(this, context
).getStartTime();
173 final long endTime
= getIterator(this, context
).getEndTime();
174 return ((double) currentTime
.getTimestamp() - startTime
)
175 / (endTime
- startTime
);
183 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
186 public synchronized ITmfContext
seekEvent(ITmfTimestamp timestamp
) {
187 if( timestamp
instanceof CtfTmfTimestamp
){
188 CtfTmfLightweightContext iter
= new CtfTmfLightweightContext(this);
189 iter
.seek(timestamp
.getValue());
192 return super.seekEvent(timestamp
);
197 * @param location ITmfLocation<?>
198 * @return ITmfContext
201 public ITmfContext
seekEvent(final ITmfLocation location
) {
202 CtfLocation currentLocation
= (CtfLocation
) location
;
203 CtfTmfLightweightContext context
= new CtfTmfLightweightContext(this);
205 * The rank is set to 0 if the iterator seeks the beginning. If not, it
206 * will be set to UNKNOWN_RANK, since CTF traces don't support seeking
209 if (currentLocation
== null) {
210 currentLocation
= new CtfLocation(new CtfLocationData(0L, 0L));
213 if (currentLocation
.getLocationInfo() == CtfLocation
.INVALID_LOCATION
) {
214 ((CtfTmfTimestamp
) getEndTime()).setType(TimestampType
.NANOS
);
215 currentLocation
= new CtfLocation(getEndTime().getValue() + 1, 0L);
217 context
.setLocation(currentLocation
);
218 if (location
== null) {
219 CtfTmfEvent event
= getIterator(this, context
).getCurrentEvent();
221 currentLocation
= new CtfLocation(event
.getTimestamp().getValue(), 0);
224 if(context
.getRank() != 0) {
225 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
232 public ITmfContext
seekEvent(double ratio
) {
233 CtfTmfLightweightContext context
= new CtfTmfLightweightContext(this);
234 final long end
= this.getEndTime().getValue();
235 final long start
= this.getStartTime().getValue();
236 final long diff
= end
- start
;
237 final long ratioTs
= (long) (diff
* ratio
) + start
;
238 context
.seek(ratioTs
);
239 context
.setRank(ITmfContext
.UNKNOWN_RANK
);
244 * Method readNextEvent.
245 * @param context ITmfContext
246 * @return CtfTmfEvent
247 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
250 public synchronized CtfTmfEvent
getNext(final ITmfContext context
) {
251 CtfTmfEvent event
= null;
252 if (context
instanceof CtfTmfLightweightContext
) {
253 if (CtfLocation
.INVALID_LOCATION
.equals(context
.getLocation().getLocationInfo())) {
256 CtfTmfLightweightContext ctfContext
= (CtfTmfLightweightContext
) context
;
257 event
= ctfContext
.getCurrentEvent();
260 updateAttributes(context
, event
.getTimestamp());
261 ctfContext
.advance();
262 ctfContext
.increaseRank();
270 * Suppressing the warning, because the 'throws' will usually happen in
273 * @throws TmfTraceException
275 @SuppressWarnings("unused")
276 protected void buildStateSystem() throws TmfTraceException
{
278 * Nothing is done in the basic implementation, please specify
279 * how/if to build a state system in derived classes.
288 public ITmfStateSystem
getStateSystem() {
293 * gets the CTFtrace that this is wrapping
294 * @return the CTF trace
296 public CTFTrace
getCTFTrace() {
301 //-------------------------------------------
302 // Environment Parameters
303 //-------------------------------------------
305 * Method getNbEnvVars.
309 public int getNbEnvVars() {
310 return this.fTrace
.getEnvironment().size();
314 * Method getEnvNames.
318 public String
[] getEnvNames() {
319 final String
[] s
= new String
[getNbEnvVars()];
320 return this.fTrace
.getEnvironment().keySet().toArray(s
);
324 * Method getEnvValue.
330 public String
getEnvValue(final String key
) {
331 return this.fTrace
.getEnvironment().get(key
);
334 //-------------------------------------------
336 //-------------------------------------------
339 * gets the clock offset
340 * @return the clock offset in ns
342 public long getOffset(){
343 if( fTrace
!= null ) {
344 return fTrace
.getOffset();
349 //-------------------------------------------
351 //-------------------------------------------
354 public CtfTmfEvent
parseEvent(ITmfContext context
) {
355 CtfTmfEvent event
= null;
356 if( context
instanceof CtfTmfLightweightContext
){
357 CtfTmfLightweightContext itt
= (CtfTmfLightweightContext
) context
.clone();
358 event
= itt
.getCurrentEvent();
364 * Sets the cache size for a CtfTmfTrace.
366 protected void setCacheSize() {
367 setCacheSize(DEFAULT_CACHE_SIZE
);
370 //-------------------------------------------
372 //-------------------------------------------
374 private static CtfIterator
getIterator(CtfTmfTrace trace
, CtfTmfLightweightContext context
) {
375 return CtfIteratorManager
.getIterator(trace
, context
);