Fix for bug 391277: Rounding error in seekEvent by ratio.
[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.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.TmfTimestamp;
22 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
23 import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier;
24 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
25 import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
26 import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
27 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
28
29 /**
30 * The CTf trace handler
31 *
32 * @version 1.0
33 * @author Matthew khouzam
34 */
35 public class CtfTmfTrace extends TmfTrace<CtfTmfEvent> implements ITmfEventParser<CtfTmfEvent>{
36
37
38 //-------------------------------------------
39 // Constants
40 //-------------------------------------------
41 /**
42 * Default cache size for CTF traces
43 */
44 protected static final int DEFAULT_CACHE_SIZE = 50000;
45
46 //-------------------------------------------
47 // Fields
48 //-------------------------------------------
49
50 /** Reference to the state system assigned to this trace */
51 protected IStateSystemQuerier ss = null;
52
53 /* Reference to the CTF Trace */
54 private CTFTrace fTrace;
55
56
57
58 //-------------------------------------------
59 // TmfTrace Overrides
60 //-------------------------------------------
61 /**
62 * Method initTrace.
63 *
64 * @param resource
65 * The resource associated with this trace
66 * @param path
67 * The path to the trace file
68 * @param eventType
69 * The type of events that will be read from this trace
70 * @throws TmfTraceException
71 * If something when wrong while reading the trace
72 */
73 @Override
74 public void initTrace(final IResource resource, final String path, final Class<CtfTmfEvent> eventType)
75 throws TmfTraceException {
76 /*
77 * Set the cache size. This has to be done before the call to super()
78 * because the super needs to know the cache size.
79 */
80 setCacheSize();
81 super.initTrace(resource, path, eventType);
82
83 @SuppressWarnings("unused")
84 CtfTmfEventType type;
85
86 try {
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 = new CtfTmfLightweightContext(this);
92 ctx.setLocation(new CtfLocation(0L));
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);
96 } else {
97 final ITmfTimestamp curTime = ctx.getCurrentEvent().getTimestamp();
98 this.setStartTime(curTime);
99 this.setEndTime(curTime);
100 }
101
102 } catch (final CTFReaderException e) {
103 /*
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.
107 */
108 throw new TmfTraceException(e.getMessage(), e);
109 }
110
111 //FIXME This should be called via the ExperimentUpdated signal
112 buildStateSystem();
113
114 /* Refresh the project, so it can pick up new files that got created. */
115 if ( resource != null) {
116 try {
117 resource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
118 } catch (CoreException e) {
119 throw new TmfTraceException(e.getMessage(), e);
120 }
121 }
122 }
123
124 /* (non-Javadoc)
125 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#dispose()
126 */
127 @Override
128 public synchronized void dispose() {
129 CtfIteratorManager.removeTrace(this);
130 super.dispose();
131 }
132
133 /**
134 * Method validate.
135 * @param project IProject
136 * @param path String
137 * @return boolean
138 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
139 */
140 @Override
141 public boolean validate(final IProject project, final String path) {
142 try {
143 final CTFTrace temp = new CTFTrace(path);
144 return temp.majortIsSet(); // random test
145 } catch (final CTFReaderException e) {
146 /* Nope, not a CTF trace we can read */
147 return false;
148 }
149 }
150
151 /**
152 * Method getCurrentLocation. This is not applicable in CTF
153 * @return null, since the trace has no knowledge of the current location
154 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
155 */
156 @Override
157 public ITmfLocation<?> getCurrentLocation() {
158 return null;
159 }
160
161
162
163 @Override
164 public double getLocationRatio(ITmfLocation<?> location) {
165 final CtfLocation curLocation = (CtfLocation) location;
166 final CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
167 context.setLocation(curLocation);
168 context.seek(curLocation.getLocation());
169 final long currentTime = ((Long)context.getLocation().getLocation());
170 final long startTime = getIterator(this, context).getStartTime();
171 final long endTime = getIterator(this, context).getEndTime();
172 return ((double) currentTime - startTime)
173 / (endTime - startTime);
174 }
175
176
177
178
179
180 /* (non-Javadoc)
181 * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
182 */
183 @Override
184 public synchronized ITmfContext seekEvent(ITmfTimestamp timestamp) {
185 if( timestamp instanceof CtfTmfTimestamp){
186 CtfTmfLightweightContext iter = new CtfTmfLightweightContext(this);
187 iter.seek(timestamp.getValue());
188 return iter;
189 }
190 return super.seekEvent(timestamp);
191 }
192
193 /**
194 * Method seekEvent.
195 * @param location ITmfLocation<?>
196 * @return ITmfContext
197 */
198 @Override
199 public ITmfContext seekEvent(final ITmfLocation<?> location) {
200 CtfLocation currentLocation = (CtfLocation) location;
201 CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
202 /*
203 * The rank is set to 0 if the iterator seeks the beginning. If not, it
204 * will be set to UNKNOWN_RANK, since CTF traces don't support seeking
205 * by rank for now.
206 */
207 if (currentLocation == null) {
208 currentLocation = new CtfLocation(0L);
209 context.setRank(0);
210 }
211 if (currentLocation.getLocation() == CtfLocation.INVALID_LOCATION) {
212 ((CtfTmfTimestamp) getEndTime()).setType(TimestampType.NANOS);
213 currentLocation.setLocation(getEndTime().getValue() + 1);
214 }
215 context.setLocation(currentLocation);
216 if(context.getRank() != 0) {
217 context.setRank(ITmfContext.UNKNOWN_RANK);
218 }
219 return context;
220 }
221
222
223 @Override
224 public ITmfContext seekEvent(double ratio) {
225 CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
226 context.seek(Math.round(this.getNbEvents() * ratio));
227 context.setRank(ITmfContext.UNKNOWN_RANK);
228 return context;
229 }
230
231 /**
232 * Method readNextEvent.
233 * @param context ITmfContext
234 * @return CtfTmfEvent
235 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
236 */
237 @Override
238 public synchronized CtfTmfEvent getNext(final ITmfContext context) {
239 CtfTmfEvent event = null;
240 if (context instanceof CtfTmfLightweightContext) {
241 if (CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocation())) {
242 return null;
243 }
244 CtfTmfLightweightContext ctfContext = (CtfTmfLightweightContext) context;
245 event = ctfContext.getCurrentEvent();
246
247 if (event != null) {
248 updateAttributes(context, event.getTimestamp());
249 ctfContext.advance();
250 ctfContext.increaseRank();
251 }
252 }
253
254 return event;
255 }
256
257 /**
258 * Suppressing the warning, because the 'throws' will usually happen in
259 * sub-classes.
260 *
261 * @throws TmfTraceException
262 */
263 @SuppressWarnings("unused")
264 protected void buildStateSystem() throws TmfTraceException {
265 /*
266 * Nothing is done in the basic implementation, please specify
267 * how/if to build a state system in derived classes.
268 */
269 return;
270 }
271
272 /**
273 * Method getStateSystem.
274 *
275 * @return IStateSystemQuerier
276 */
277 public IStateSystemQuerier getStateSystem() {
278 return this.ss;
279 }
280
281 /**
282 * gets the CTFtrace that this is wrapping
283 * @return the CTF trace
284 */
285 public CTFTrace getCTFTrace() {
286 return fTrace;
287 }
288
289
290 //-------------------------------------------
291 // Environment Parameters
292 //-------------------------------------------
293 /**
294 * Method getNbEnvVars.
295 *
296 * @return int
297 */
298 public int getNbEnvVars() {
299 return this.fTrace.getEnvironment().size();
300 }
301
302 /**
303 * Method getEnvNames.
304 *
305 * @return String[]
306 */
307 public String[] getEnvNames() {
308 final String[] s = new String[getNbEnvVars()];
309 return this.fTrace.getEnvironment().keySet().toArray(s);
310 }
311
312 /**
313 * Method getEnvValue.
314 *
315 * @param key
316 * String
317 * @return String
318 */
319 public String getEnvValue(final String key) {
320 return this.fTrace.getEnvironment().get(key);
321 }
322
323 //-------------------------------------------
324 // Clocks
325 //-------------------------------------------
326
327 /**
328 * gets the clock offset
329 * @return the clock offset in ns
330 */
331 public long getOffset(){
332 if( fTrace != null ) {
333 return fTrace.getOffset();
334 }
335 return 0;
336 }
337
338 //-------------------------------------------
339 // Parser
340 //-------------------------------------------
341
342 @Override
343 public CtfTmfEvent parseEvent(ITmfContext context) {
344 CtfTmfEvent event = null;
345 if( context instanceof CtfTmfLightweightContext ){
346 CtfTmfLightweightContext itt = (CtfTmfLightweightContext) context.clone();
347 event = itt.getCurrentEvent();
348 }
349 return event;
350 }
351
352 /**
353 * Sets the cache size for a CtfTmfTrace.
354 */
355 protected void setCacheSize() {
356 setCacheSize(DEFAULT_CACHE_SIZE);
357 }
358
359 //-------------------------------------------
360 // Helpers
361 //-------------------------------------------
362
363 private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfLightweightContext context) {
364 return CtfIteratorManager.getIterator(trace, context);
365 }
366 }
This page took 0.038686 seconds and 6 git commands to generate.