TMF: Add the concept of host id to a trace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfTrace.java
CommitLineData
b1baa808 1/*******************************************************************************
ea271da6 2 * Copyright (c) 2012, 2013 Ericsson
b1baa808
MK
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 *
ea271da6
PT
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 * Patrick Tasse - Updated for removal of context clone
b1baa808
MK
12 *******************************************************************************/
13
a3fc8213
AM
14package org.eclipse.linuxtools.tmf.core.ctfadaptor;
15
299e494e
AM
16import java.util.Collections;
17import java.util.Map;
18
a3fc8213
AM
19import org.eclipse.core.resources.IProject;
20import org.eclipse.core.resources.IResource;
a94410d9
MK
21import org.eclipse.core.runtime.IStatus;
22import org.eclipse.core.runtime.Status;
3480bf12 23import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
bb52f9bc 24import org.eclipse.linuxtools.ctf.core.event.CTFClock;
a3fc8213
AM
25import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
26import org.eclipse.linuxtools.ctf.core.trace.CTFTrace;
b5354daa 27import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader;
a94410d9 28import org.eclipse.linuxtools.internal.tmf.core.Activator;
6256d8ad 29import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
b4f71e4a 30import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
3bd46eef
AM
31import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
32import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
a3fc8213 33import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
4b7c469f 34import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
a3fc8213 35import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
3480bf12 36import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties;
4b7c469f 37import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
a3fc8213 38
9ac2eb62 39/**
d09f973b
FC
40 * The CTf trace handler
41 *
42 * @version 1.0
43 * @author Matthew khouzam
9ac2eb62 44 */
22307af3
AM
45public class CtfTmfTrace extends TmfTrace
46 implements ITmfEventParser, ITmfTraceProperties {
a3fc8213 47
a94410d9
MK
48 // -------------------------------------------
49 // Constants
50 // -------------------------------------------
324a6a4a
BH
51 /**
52 * Default cache size for CTF traces
53 */
54 protected static final int DEFAULT_CACHE_SIZE = 50000;
64c2cb4c 55
bb52f9bc
GB
56 /*
57 * The Ctf clock unique identifier field
58 */
59 private static final String CLOCK_HOST_PROPERTY = "uuid"; //$NON-NLS-1$
60
a94410d9
MK
61 // -------------------------------------------
62 // Fields
63 // -------------------------------------------
a3fc8213 64
4b7c469f
MK
65 /* Reference to the CTF Trace */
66 private CTFTrace fTrace;
a3fc8213 67
a94410d9
MK
68 // -------------------------------------------
69 // TmfTrace Overrides
70 // -------------------------------------------
b1baa808
MK
71 /**
72 * Method initTrace.
063f0d27
AM
73 *
74 * @param resource
75 * The resource associated with this trace
76 * @param path
77 * The path to the trace file
78 * @param eventType
79 * The type of events that will be read from this trace
b1baa808 80 * @throws TmfTraceException
063f0d27 81 * If something when wrong while reading the trace
b1baa808 82 */
a3fc8213 83 @Override
6256d8ad 84 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType)
b4f71e4a 85 throws TmfTraceException {
4a110860
AM
86 /*
87 * Set the cache size. This has to be done before the call to super()
88 * because the super needs to know the cache size.
89 */
90 setCacheSize();
324a6a4a 91
32c16b50
GB
92 super.initTrace(resource, path, eventType);
93
e30ce12e
AM
94 @SuppressWarnings("unused")
95 CtfTmfEventType type;
96
a3fc8213
AM
97 try {
98 this.fTrace = new CTFTrace(path);
53b235e1 99 CtfIteratorManager.addTrace(this);
81a2d02e 100 CtfTmfContext ctx;
99b483fe 101 /* Set the start and (current) end times for this trace */
81a2d02e 102 ctx = (CtfTmfContext) seekEvent(0L);
132a02b0 103 CtfTmfEvent event = getNext(ctx);
a94410d9 104 if ((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) {
99b483fe
AM
105 /* Handle the case where the trace is empty */
106 this.setStartTime(TmfTimestamp.BIG_BANG);
107 } else {
132a02b0 108 final ITmfTimestamp curTime = event.getTimestamp();
21fb02fa
MK
109 this.setStartTime(curTime);
110 this.setEndTime(curTime);
99b483fe
AM
111 }
112
25e48683 113 } catch (final CTFReaderException e) {
a3fc8213
AM
114 /*
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.
118 */
9fa32496 119 throw new TmfTraceException(e.getMessage(), e);
a3fc8213 120 }
a3fc8213
AM
121 }
122
53b235e1
MK
123 @Override
124 public synchronized void dispose() {
125 CtfIteratorManager.removeTrace(this);
5d1c6919
PT
126 if (fTrace != null) {
127 fTrace.dispose();
128 fTrace = null;
129 }
53b235e1
MK
130 super.dispose();
131 }
132
b1baa808
MK
133 /**
134 * Method validate.
a94410d9
MK
135 *
136 * @param project
137 * IProject
138 * @param path
139 * String
140 * @return IStatus IStatus.error or Status.OK_STATUS
b1baa808 141 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
a94410d9 142 * @since 2.0
b1baa808 143 */
a3fc8213 144 @Override
a94410d9
MK
145 public IStatus validate(final IProject project, final String path) {
146 IStatus validTrace = Status.OK_STATUS;
a3fc8213
AM
147 try {
148 final CTFTrace temp = new CTFTrace(path);
b5354daa 149 if (!temp.majortIsSet()) {
a94410d9 150 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet);
b5354daa
MAL
151 } else {
152 CTFTraceReader ctfTraceReader = new CTFTraceReader(temp);
153 if (!ctfTraceReader.hasMoreEvents()) {
154 // TODO: This will need an additional check when we support live traces
155 // because having no event is valid for a live trace
156 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent);
157 }
158 ctfTraceReader.dispose();
a94410d9 159 }
b5354daa 160 temp.dispose();
25e48683 161 } catch (final CTFReaderException e) {
a94410d9 162 validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError +": " + e.toString()); //$NON-NLS-1$
a3fc8213 163 }
a94410d9 164 return validTrace;
a3fc8213
AM
165 }
166
b1baa808 167 /**
f474d36b 168 * Method getCurrentLocation. This is not applicable in CTF
a94410d9 169 *
f474d36b 170 * @return null, since the trace has no knowledge of the current location
b1baa808
MK
171 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
172 */
a3fc8213 173 @Override
1e1bef82 174 public ITmfLocation getCurrentLocation() {
f474d36b 175 return null;
a3fc8213
AM
176 }
177
a3fc8213 178 @Override
1e1bef82 179 public double getLocationRatio(ITmfLocation location) {
4b7c469f 180 final CtfLocation curLocation = (CtfLocation) location;
81a2d02e 181 final CtfTmfContext context = new CtfTmfContext(this);
53b235e1 182 context.setLocation(curLocation);
5976d44a 183 context.seek(curLocation.getLocationInfo());
a94410d9 184 final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo());
53b235e1
MK
185 final long startTime = getIterator(this, context).getStartTime();
186 final long endTime = getIterator(this, context).getEndTime();
132a02b0 187 return ((double) currentTime.getTimestamp() - startTime)
53b235e1 188 / (endTime - startTime);
a3fc8213
AM
189 }
190
b1baa808
MK
191 /**
192 * Method seekEvent.
a94410d9
MK
193 *
194 * @param location
195 * ITmfLocation<?>
b1baa808 196 * @return ITmfContext
b1baa808 197 */
a3fc8213 198 @Override
76643eb7 199 public synchronized ITmfContext seekEvent(final ITmfLocation location) {
ce2388e0 200 CtfLocation currentLocation = (CtfLocation) location;
81a2d02e 201 CtfTmfContext context = new CtfTmfContext(this);
76643eb7
BH
202 if (fTrace == null) {
203 context.setLocation(null);
204 context.setRank(ITmfContext.UNKNOWN_RANK);
205 return context;
206 }
4a110860
AM
207 /*
208 * The rank is set to 0 if the iterator seeks the beginning. If not, it
209 * will be set to UNKNOWN_RANK, since CTF traces don't support seeking
210 * by rank for now.
211 */
11d6f468 212 if (currentLocation == null) {
f5df94f8 213 currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L));
4a110860 214 context.setRank(0);
11d6f468 215 }
5976d44a 216 if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) {
d62bb185 217 currentLocation = new CtfLocation(getEndTime().getValue() + 1, 0L);
1191a574 218 }
f474d36b 219 context.setLocation(currentLocation);
7f0bab07
PT
220 if (location == null) {
221 CtfTmfEvent event = getIterator(this, context).getCurrentEvent();
222 if (event != null) {
d62bb185 223 currentLocation = new CtfLocation(event.getTimestamp().getValue(), 0);
7f0bab07
PT
224 }
225 }
a94410d9 226 if (context.getRank() != 0) {
3bd44ac8 227 context.setRank(ITmfContext.UNKNOWN_RANK);
64c2cb4c 228 }
f474d36b 229 return context;
a3fc8213
AM
230 }
231
a3fc8213 232 @Override
76643eb7 233 public synchronized ITmfContext seekEvent(double ratio) {
81a2d02e 234 CtfTmfContext context = new CtfTmfContext(this);
76643eb7
BH
235 if (fTrace == null) {
236 context.setLocation(null);
237 context.setRank(ITmfContext.UNKNOWN_RANK);
238 return context;
239 }
b2dc9e02
MK
240 final long end = this.getEndTime().getValue();
241 final long start = this.getStartTime().getValue();
242 final long diff = end - start;
15e89960 243 final long ratioTs = Math.round(diff * ratio) + start;
b2dc9e02 244 context.seek(ratioTs);
f474d36b
PT
245 context.setRank(ITmfContext.UNKNOWN_RANK);
246 return context;
a3fc8213
AM
247 }
248
b1baa808
MK
249 /**
250 * Method readNextEvent.
a94410d9
MK
251 *
252 * @param context
253 * ITmfContext
b1baa808 254 * @return CtfTmfEvent
c32744d6 255 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
b1baa808 256 */
a3fc8213 257 @Override
4b7c469f 258 public synchronized CtfTmfEvent getNext(final ITmfContext context) {
faa38350
PT
259 if (fTrace == null) {
260 return null;
261 }
f474d36b 262 CtfTmfEvent event = null;
81a2d02e 263 if (context instanceof CtfTmfContext) {
575beffc 264 if (context.getLocation() == null || CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationInfo())) {
ae09313d
PT
265 return null;
266 }
81a2d02e 267 CtfTmfContext ctfContext = (CtfTmfContext) context;
788ddcbc 268 event = ctfContext.getCurrentEvent();
4a110860 269
324a6a4a
BH
270 if (event != null) {
271 updateAttributes(context, event.getTimestamp());
788ddcbc
MK
272 ctfContext.advance();
273 ctfContext.increaseRank();
324a6a4a 274 }
f474d36b 275 }
4a110860 276
aa572e22 277 return event;
a3fc8213
AM
278 }
279
4b7c469f
MK
280 /**
281 * gets the CTFtrace that this is wrapping
a94410d9 282 *
4b7c469f
MK
283 * @return the CTF trace
284 */
285 public CTFTrace getCTFTrace() {
a3fc8213
AM
286 return fTrace;
287 }
a1a24d68 288
bb52f9bc
GB
289 /**
290 * Ctf traces have a clock with a unique uuid that will be used to identify
291 * the host. Traces with the same clock uuid will be known to have been made
292 * on the same machine.
293 *
294 * Note: uuid is an optional field, it may not be there for a clock.
295 */
296 @Override
297 public String getHostId() {
298 CTFClock clock = getCTFTrace().getClock();
299 if (clock != null) {
300 String clockHost = (String) clock.getProperty(CLOCK_HOST_PROPERTY);
301 if (clockHost != null) {
302 return clockHost;
303 }
304 }
305 return super.getHostId();
306 }
307
a94410d9 308 // -------------------------------------------
22307af3 309 // ITmfTraceProperties
a94410d9 310 // -------------------------------------------
4b7c469f
MK
311
312 /**
299e494e 313 * @since 2.0
4b7c469f 314 */
22307af3
AM
315 @Override
316 public Map<String, String> getTraceProperties() {
299e494e 317 return Collections.unmodifiableMap(fTrace.getEnvironment());
4b7c469f
MK
318 }
319
a94410d9
MK
320 // -------------------------------------------
321 // Clocks
322 // -------------------------------------------
bfe038ff 323
9ac2eb62
MK
324 /**
325 * gets the clock offset
a94410d9 326 *
9ac2eb62
MK
327 * @return the clock offset in ns
328 */
a94410d9
MK
329 public long getOffset() {
330 if (fTrace != null) {
bfe038ff
MK
331 return fTrace.getOffset();
332 }
333 return 0;
334 }
335
3480bf12
GB
336 /**
337 * Returns whether or not an event is in the metadata of the trace,
338 * therefore if it can possibly be in the trace. It does not verify whether
339 * or not the event is actually in the trace
340 *
341 * @param eventName
342 * The name of the event to check
343 * @return Whether the event is in the metadata or not
0295e843 344 * @since 3.0
3480bf12
GB
345 */
346 public boolean hasEvent(final String eventName) {
347 Map<Long, IEventDeclaration> events = fTrace.getEvents(0L);
348 if (events != null) {
349 for (IEventDeclaration decl : events.values()) {
350 if (decl.getName().equals(eventName)) {
351 return true;
352 }
353 }
354 }
355 return false;
356 }
357
358 /**
359 * Return whether all requested events are in the metadata
360 *
361 * @param names
362 * The array of events to check for
363 * @return Whether all events are in the metadata
0295e843 364 * @since 3.0
3480bf12
GB
365 */
366 public boolean hasAllEvents(String[] names) {
367 for (String name : names) {
368 if (!hasEvent(name)) {
369 return false;
370 }
371 }
372 return true;
373 }
374
375 /**
376 * Returns whether the metadata contains at least one of the requested
377 * events
378 *
379 * @param names
380 * The array of event names of check for
381 * @return Whether one of the event is present in trace metadata
0295e843 382 * @since 3.0
3480bf12
GB
383 */
384 public boolean hasAtLeastOneOfEvents(String[] names) {
385 for (String name : names) {
386 if (hasEvent(name)) {
387 return true;
388 }
389 }
390 return false;
391 }
392
a94410d9
MK
393 // -------------------------------------------
394 // Parser
395 // -------------------------------------------
4b7c469f
MK
396
397 @Override
bfe038ff 398 public CtfTmfEvent parseEvent(ITmfContext context) {
4b7c469f 399 CtfTmfEvent event = null;
ea271da6
PT
400 if (context instanceof CtfTmfContext) {
401 final ITmfContext tmpContext = seekEvent(context.getLocation());
402 event = getNext(tmpContext);
4b7c469f
MK
403 }
404 return event;
11d6f468 405 }
64c2cb4c 406
324a6a4a 407 /**
64c2cb4c 408 * Sets the cache size for a CtfTmfTrace.
324a6a4a
BH
409 */
410 protected void setCacheSize() {
411 setCacheSize(DEFAULT_CACHE_SIZE);
412 }
ce2388e0 413
a94410d9
MK
414 // -------------------------------------------
415 // Helpers
416 // -------------------------------------------
53b235e1 417
a94410d9 418 private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfContext context) {
53b235e1
MK
419 return CtfIteratorManager.getIterator(trace, context);
420 }
36dd544c
MK
421
422 /**
423 * Get an iterator to the trace
424 *
425 * @return an iterator to the trace
ed59ab27 426 * @since 2.0
36dd544c 427 */
a94410d9 428 public CtfIterator createIterator() {
36dd544c
MK
429 return new CtfIterator(this);
430 }
a3fc8213 431}
This page took 0.064543 seconds and 5 git commands to generate.