ctf: Add missing @since to previous patch
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / CTFTrace.java
CommitLineData
866e5b51 1/*******************************************************************************
4311ac8b 2 * Copyright (c) 2011, 2013 Ericsson, Ecole Polytechnique de Montreal and others
866e5b51
FC
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 *
4311ac8b
MAL
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 * Alexandre Montplaisir - Initial API and implementation
890f9136 12 * Simon Delisle - Replace LinkedList by TreeSet in callsitesByName attribute
866e5b51
FC
13 *******************************************************************************/
14
15package org.eclipse.linuxtools.ctf.core.trace;
16
17import java.io.File;
18import java.io.FileFilter;
19import java.io.FileInputStream;
20import java.io.IOException;
debcffff 21import java.io.Serializable;
866e5b51
FC
22import java.nio.ByteOrder;
23import java.nio.MappedByteBuffer;
24import java.nio.channels.FileChannel;
25import java.nio.channels.FileChannel.MapMode;
26import java.util.Arrays;
a95fddf5 27import java.util.Collections;
866e5b51
FC
28import java.util.Comparator;
29import java.util.HashMap;
aa572e22 30import java.util.Iterator;
d0d3aa1b
AM
31import java.util.LinkedList;
32import java.util.List;
866e5b51 33import java.util.Map;
aa572e22 34import java.util.Map.Entry;
866e5b51 35import java.util.Set;
4c9d2941 36import java.util.TreeSet;
866e5b51
FC
37import java.util.UUID;
38
4c9d2941 39import org.eclipse.linuxtools.ctf.core.event.CTFCallsite;
866e5b51 40import org.eclipse.linuxtools.ctf.core.event.CTFClock;
788ddcbc 41import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
8e964be1 42import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
486efb2e 43import org.eclipse.linuxtools.ctf.core.event.io.BitBuffer;
866e5b51
FC
44import org.eclipse.linuxtools.ctf.core.event.types.ArrayDefinition;
45import org.eclipse.linuxtools.ctf.core.event.types.Definition;
46import org.eclipse.linuxtools.ctf.core.event.types.IDefinitionScope;
47import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
48import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
49import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
890f9136 50import org.eclipse.linuxtools.internal.ctf.core.event.CTFCallsiteComparator;
ce2388e0 51import org.eclipse.linuxtools.internal.ctf.core.event.metadata.exceptions.ParseException;
866e5b51
FC
52
53/**
d37aaa7f
FC
54 * A CTF trace on the file system.
55 *
866e5b51
FC
56 * Represents a trace on the filesystem. It is responsible of parsing the
57 * metadata, creating declarations data structures, indexing the event packets
58 * (in other words, all the work that can be shared between readers), but the
59 * actual reading of events is left to TraceReader.
debcffff 60 *
866e5b51
FC
61 * @author Matthew Khouzam
62 * @version $Revision: 1.0 $
63 */
64public class CTFTrace implements IDefinitionScope {
65
866e5b51
FC
66 @SuppressWarnings("nls")
67 @Override
68 public String toString() {
69 /* Only for debugging, shouldn't be externalized */
70 return "CTFTrace [path=" + path + ", major=" + major + ", minor="
71 + minor + ", uuid=" + uuid + "]";
72 }
73
74 /**
75 * The trace directory on the filesystem.
76 */
77 private final File path;
78
866e5b51
FC
79 /**
80 * Major CTF version number
81 */
82 private Long major;
83
84 /**
85 * Minor CTF version number
86 */
87 private Long minor;
88
89 /**
90 * Trace UUID
91 */
92 private UUID uuid;
93
94 /**
95 * Trace byte order
96 */
97 private ByteOrder byteOrder;
98
99 /**
100 * Packet header structure declaration
101 */
debcffff 102 private StructDeclaration packetHeaderDecl = null;
866e5b51 103
1d7277f3
MK
104 /**
105 * The clock of the trace
106 */
107 private CTFClock singleClock;
108
866e5b51
FC
109 /**
110 * Packet header structure definition
debcffff 111 *
866e5b51
FC
112 * This is only used when opening the trace files, to read the first packet
113 * header and see if they are valid trace files.
114 */
115 private StructDefinition packetHeaderDef;
116
117 /**
118 * Collection of streams contained in the trace.
119 */
a7297cd3 120 private final Map<Long, Stream> streams = new HashMap<Long, Stream>();
866e5b51
FC
121
122 /**
123 * Collection of environment variables set by the tracer
124 */
791072b0 125 private final Map<String, String> environment = new HashMap<String, String>();
866e5b51
FC
126
127 /**
128 * Collection of all the clocks in a system.
129 */
791072b0 130 private final Map<String, CTFClock> clocks = new HashMap<String, CTFClock>();
866e5b51 131
5d1c6919
PT
132 /** FileInputStreams to the streams */
133 private final List<FileInputStream> fileInputStreams = new LinkedList<FileInputStream>();
26ea03d2 134
c88e827d 135 /** Handlers for the metadata files */
0594c61c
AM
136 private static final FileFilter METADATA_FILE_FILTER = new MetadataFileFilter();
137 private static final Comparator<File> METADATA_COMPARATOR = new MetadataComparator();
866e5b51 138
4c9d2941 139 /** Callsite helpers */
890f9136
SD
140 private CTFCallsiteComparator ctfCallsiteComparator = new CTFCallsiteComparator();
141
142 private Map<String, TreeSet<CTFCallsite>> callsitesByName = new HashMap<String, TreeSet<CTFCallsite>>();
0594c61c 143
4c9d2941
MK
144 /** Callsite helpers */
145 private TreeSet<CTFCallsite> callsitesByIP = new TreeSet<CTFCallsite>();
788ddcbc 146
866e5b51
FC
147 // ------------------------------------------------------------------------
148 // Constructors
149 // ------------------------------------------------------------------------
150
151 /**
152 * Trace constructor.
debcffff 153 *
866e5b51 154 * @param path
be6df2d8
AM
155 * Filesystem path of the trace directory
156 * @throws CTFReaderException
157 * If no CTF trace was found at the path
866e5b51
FC
158 */
159 public CTFTrace(String path) throws CTFReaderException {
160 this(new File(path));
aa572e22 161
866e5b51
FC
162 }
163
164 /**
165 * Trace constructor.
debcffff 166 *
866e5b51
FC
167 * @param path
168 * Filesystem path of the trace directory.
169 * @throws CTFReaderException
be6df2d8 170 * If no CTF trace was found at the path
866e5b51 171 */
866e5b51
FC
172 public CTFTrace(File path) throws CTFReaderException {
173 this.path = path;
0594c61c 174 final Metadata metadata = new Metadata(this);
866e5b51 175
c88e827d 176 /* Set up the internal containers for this trace */
8a95ce5a
BH
177 if (!this.path.exists()) {
178 throw new CTFReaderException("Trace (" + path.getPath() + ") doesn't exist. Deleted or moved?"); //$NON-NLS-1$ //$NON-NLS-2$
179 }
d0d3aa1b
AM
180
181 if (!this.path.isDirectory()) {
182 throw new CTFReaderException("Path must be a valid directory"); //$NON-NLS-1$
183 }
c88e827d
AM
184
185 /* Open and parse the metadata file */
186 metadata.parse();
187
c88e827d
AM
188 /* Open all the trace files */
189 /* Create the definitions needed to read things from the files */
190 if (packetHeaderDecl != null) {
a7297cd3 191 packetHeaderDef = packetHeaderDecl.createDefinition(this, "packet.header"); //$NON-NLS-1$
c88e827d
AM
192 }
193
194 /* List files not called metadata and not hidden. */
0594c61c
AM
195 File[] files = path.listFiles(METADATA_FILE_FILTER);
196 Arrays.sort(files, METADATA_COMPARATOR);
c88e827d 197 /* Try to open each file */
d0d3aa1b
AM
198 for (File streamFile : files) {
199 openStreamInput(streamFile);
c88e827d 200 }
788ddcbc 201
c88e827d 202 /* Create their index */
f7c5789a
EB
203 for (Stream stream : getStreams()) {
204 Set<StreamInput> inputs = stream.getStreamInputs();
c88e827d 205 for (StreamInput s : inputs) {
aa572e22
MK
206 /*
207 * Copy the events
208 */
8e964be1 209 Iterator<Entry<Long, IEventDeclaration>> it = s.getStream()
aa572e22
MK
210 .getEvents().entrySet().iterator();
211 while (it.hasNext()) {
8e964be1 212 Entry<Long, IEventDeclaration> pairs = it.next();
aa572e22 213 Long eventNum = pairs.getKey();
8e964be1 214 IEventDeclaration eventDec = pairs.getValue();
788ddcbc 215 getEvents(s.getStream().getId()).put(eventNum, eventDec);
aa572e22
MK
216 }
217
218 /*
219 * index the trace
220 */
bfe038ff 221 s.setupIndex();
c88e827d
AM
222 }
223 }
866e5b51
FC
224 }
225
5d1c6919
PT
226 /**
227 * Dispose the trace
a7297cd3 228 *
5d1c6919
PT
229 * @since 2.0
230 */
231 public void dispose() {
232 for (FileInputStream fis : fileInputStreams) {
233 if (fis != null) {
26ea03d2 234 try {
5d1c6919 235 fis.close();
26ea03d2 236 } catch (IOException e) {
aa572e22 237 // do nothing it's ok, we tried to close it.
26ea03d2
AM
238 }
239 }
240 }
a7297cd3
SD
241 // Invoke GC to release MappedByteBuffer objects (Java bug JDK-4724038)
242 System.gc();
26ea03d2
AM
243 }
244
866e5b51
FC
245 // ------------------------------------------------------------------------
246 // Getters/Setters/Predicates
247 // ------------------------------------------------------------------------
248
aa572e22 249 /**
be6df2d8
AM
250 * Gets an event declaration hash map for a given streamID
251 *
252 * @param streamId
253 * The ID of the stream from which to read
254 * @return The Hash map with the event declarations
0594c61c 255 * @since 2.0
788ddcbc 256 */
0594c61c 257 public Map<Long, IEventDeclaration> getEvents(Long streamId) {
29a7d6ee 258 return streams.get(streamId).getEvents();
788ddcbc
MK
259 }
260
aa572e22 261 /**
788ddcbc 262 * Gets an event Declaration hashmap for a given StreamInput
7ff6d3cf
MK
263 *
264 * @param id
265 * the StreamInput
266 * @return an empty hashmap, please see deprecated
e6809677 267 * @since 2.0
a7297cd3
SD
268 * @deprecated You should be using
269 * {@link StreamInputReader#getEventDefinitions()} instead.
788ddcbc 270 */
7ff6d3cf 271 @Deprecated
0594c61c 272 public Map<Long, EventDefinition> getEventDefs(StreamInput id) {
7ff6d3cf 273 return new HashMap<Long, EventDefinition>();
788ddcbc
MK
274 }
275
276 /**
277 * Get an event by it's ID
aa572e22 278 *
be6df2d8
AM
279 * @param streamId
280 * The ID of the stream from which to read
788ddcbc
MK
281 * @param id
282 * the ID of the event
283 * @return the event declaration
8e964be1 284 * @since 2.0
aa572e22 285 */
8e964be1 286 public IEventDeclaration getEventType(long streamId, long id) {
788ddcbc 287 return getEvents(streamId).get(id);
aa572e22
MK
288 }
289
866e5b51
FC
290 /**
291 * Method getStream gets the stream for a given id
debcffff 292 *
866e5b51
FC
293 * @param id
294 * Long the id of the stream
295 * @return Stream the stream that we need
e6809677 296 * @since 2.0
866e5b51
FC
297 */
298 public Stream getStream(Long id) {
299 return streams.get(id);
300 }
301
302 /**
303 * Method nbStreams gets the number of available streams
debcffff 304 *
866e5b51
FC
305 * @return int the number of streams
306 */
307 public int nbStreams() {
308 return streams.size();
309 }
310
311 /**
312 * Method setMajor sets the major version of the trace (DO NOT USE)
debcffff 313 *
866e5b51
FC
314 * @param major
315 * long the major version
316 */
317 public void setMajor(long major) {
318 this.major = major;
319 }
320
321 /**
322 * Method setMinor sets the minor version of the trace (DO NOT USE)
debcffff 323 *
866e5b51
FC
324 * @param minor
325 * long the minor version
326 */
327 public void setMinor(long minor) {
328 this.minor = minor;
329 }
330
331 /**
332 * Method setUUID sets the UUID of a trace
debcffff 333 *
866e5b51
FC
334 * @param uuid
335 * UUID
336 */
337 public void setUUID(UUID uuid) {
338 this.uuid = uuid;
339 }
340
341 /**
342 * Method setByteOrder sets the byte order
debcffff 343 *
866e5b51
FC
344 * @param byteOrder
345 * ByteOrder of the trace, can be little-endian or big-endian
346 */
347 public void setByteOrder(ByteOrder byteOrder) {
348 this.byteOrder = byteOrder;
349 }
350
351 /**
352 * Method setPacketHeader sets the packet header of a trace (DO NOT USE)
debcffff 353 *
866e5b51
FC
354 * @param packetHeader
355 * StructDeclaration the header in structdeclaration form
356 */
357 public void setPacketHeader(StructDeclaration packetHeader) {
358 this.packetHeaderDecl = packetHeader;
359 }
360
361 /**
07804639 362 * Method majorIsSet is the major version number set?
debcffff 363 *
866e5b51 364 * @return boolean is the major set?
c4767854 365 * @since 3.0
866e5b51 366 */
07804639 367 public boolean majorIsSet() {
866e5b51
FC
368 return major != null;
369 }
370
371 /**
372 * Method minorIsSet. is the minor version number set?
debcffff 373 *
866e5b51
FC
374 * @return boolean is the minor set?
375 */
376 public boolean minorIsSet() {
377 return minor != null;
378 }
379
380 /**
381 * Method UUIDIsSet is the UUID set?
debcffff 382 *
866e5b51 383 * @return boolean is the UUID set?
0594c61c 384 * @since 2.0
866e5b51 385 */
0594c61c 386 public boolean uuidIsSet() {
866e5b51
FC
387 return uuid != null;
388 }
389
390 /**
391 * Method byteOrderIsSet is the byteorder set?
debcffff 392 *
866e5b51
FC
393 * @return boolean is the byteorder set?
394 */
395 public boolean byteOrderIsSet() {
396 return byteOrder != null;
397 }
398
399 /**
400 * Method packetHeaderIsSet is the packet header set?
debcffff 401 *
866e5b51
FC
402 * @return boolean is the packet header set?
403 */
404 public boolean packetHeaderIsSet() {
405 return packetHeaderDecl != null;
406 }
407
408 /**
409 * Method getUUID gets the trace UUID
debcffff 410 *
866e5b51
FC
411 * @return UUID gets the trace UUID
412 */
413 public UUID getUUID() {
414 return uuid;
415 }
416
417 /**
418 * Method getMajor gets the trace major version
debcffff 419 *
866e5b51
FC
420 * @return long gets the trace major version
421 */
422 public long getMajor() {
423 return major;
424 }
425
426 /**
427 * Method getMinor gets the trace minor version
debcffff 428 *
866e5b51
FC
429 * @return long gets the trace minor version
430 */
431 public long getMinor() {
432 return minor;
433 }
434
435 /**
436 * Method getByteOrder gets the trace byte order
debcffff 437 *
866e5b51
FC
438 * @return ByteOrder gets the trace byte order
439 */
0594c61c 440 public final ByteOrder getByteOrder() {
866e5b51
FC
441 return byteOrder;
442 }
443
444 /**
445 * Method getPacketHeader gets the trace packet header
debcffff 446 *
866e5b51
FC
447 * @return StructDeclaration gets the trace packet header
448 */
449 public StructDeclaration getPacketHeader() {
450 return packetHeaderDecl;
451 }
452
453 /**
454 * Method getTraceDirectory gets the trace directory
debcffff 455 *
866e5b51
FC
456 * @return File the path in "File" format.
457 */
458 public File getTraceDirectory() {
459 return path;
460 }
461
462 /**
f7c5789a 463 * Get all the streams as an iterable.
debcffff 464 *
f7c5789a 465 * @return Iterable<Stream> an iterable over streams.
951bb9d9 466 * @since 3.0
866e5b51 467 */
f7c5789a
EB
468 public Iterable<Stream> getStreams() {
469 return streams.values();
866e5b51
FC
470 }
471
472 /**
473 * Method getPath gets the path of the trace directory
debcffff 474 *
866e5b51
FC
475 * @return String the path of the trace directory, in string format.
476 * @see java.io.File#getPath()
477 */
478 @Override
479 public String getPath() {
480 return path.getPath();
481 }
482
483 // ------------------------------------------------------------------------
484 // Operations
485 // ------------------------------------------------------------------------
486
866e5b51
FC
487 /**
488 * Tries to open the given file, reads the first packet header of the file
489 * and check its validity.
debcffff 490 *
866e5b51
FC
491 * @param streamFile
492 * A trace file in the trace directory.
26ea03d2
AM
493 * @param index
494 * Which index in the class' streamFileChannel array this file
495 * must use
866e5b51
FC
496 * @throws CTFReaderException
497 */
aa572e22 498 private void openStreamInput(File streamFile) throws CTFReaderException {
866e5b51
FC
499 MappedByteBuffer byteBuffer;
500 BitBuffer streamBitBuffer;
d0d3aa1b
AM
501 Stream stream;
502 FileChannel fc;
866e5b51
FC
503
504 if (!streamFile.canRead()) {
505 throw new CTFReaderException("Unreadable file : " //$NON-NLS-1$
506 + streamFile.getPath());
507 }
508
509 try {
510 /* Open the file and get the FileChannel */
5d1c6919
PT
511 FileInputStream fis = new FileInputStream(streamFile);
512 fileInputStreams.add(fis);
513 fc = fis.getChannel();
866e5b51
FC
514
515 /* Map one memory page of 4 kiB */
92bdd7d4 516 byteBuffer = fc.map(MapMode.READ_ONLY, 0, (int) Math.min(fc.size(), 4096L));
866e5b51
FC
517 } catch (IOException e) {
518 /* Shouldn't happen at this stage if every other check passed */
0594c61c 519 throw new CTFReaderException(e);
866e5b51
FC
520 }
521
522 /* Create a BitBuffer with this mapping and the trace byte order */
523 streamBitBuffer = new BitBuffer(byteBuffer, this.getByteOrder());
524
525 if (packetHeaderDef != null) {
526 /* Read the packet header */
527 packetHeaderDef.read(streamBitBuffer);
528
529 /* Check the magic number */
aa572e22
MK
530 IntegerDefinition magicDef = (IntegerDefinition) packetHeaderDef
531 .lookupDefinition("magic"); //$NON-NLS-1$
866e5b51
FC
532 int magic = (int) magicDef.getValue();
533 if (magic != Utils.CTF_MAGIC) {
534 throw new CTFReaderException("CTF magic mismatch"); //$NON-NLS-1$
535 }
536
537 /* Check UUID */
aa572e22
MK
538 ArrayDefinition uuidDef = (ArrayDefinition) packetHeaderDef
539 .lookupDefinition("uuid"); //$NON-NLS-1$
866e5b51
FC
540 if (uuidDef != null) {
541 byte[] uuidArray = new byte[Utils.UUID_LEN];
542
543 for (int i = 0; i < Utils.UUID_LEN; i++) {
aa572e22
MK
544 IntegerDefinition uuidByteDef = (IntegerDefinition) uuidDef
545 .getElem(i);
866e5b51
FC
546 uuidArray[i] = (byte) uuidByteDef.getValue();
547 }
548
549 UUID otheruuid = Utils.makeUUID(uuidArray);
550
551 if (!this.uuid.equals(otheruuid)) {
552 throw new CTFReaderException("UUID mismatch"); //$NON-NLS-1$
553 }
554 }
555
1fbaecd1
AM
556 /* Read the stream ID */
557 Definition streamIDDef = packetHeaderDef.lookupDefinition("stream_id"); //$NON-NLS-1$
558
a7297cd3
SD
559 if (streamIDDef instanceof IntegerDefinition) { // this doubles as a
560 // null check
1fbaecd1
AM
561 long streamID = ((IntegerDefinition) streamIDDef).getValue();
562 stream = streams.get(streamID);
563 } else {
564 /* No stream_id in the packet header */
565 stream = streams.get(null);
566 }
567
866e5b51
FC
568 } else {
569 /* No packet header, we suppose there is only one stream */
d0d3aa1b
AM
570 stream = streams.get(null);
571 }
866e5b51 572
4311ac8b
MAL
573 if (stream == null) {
574 throw new CTFReaderException("Unexpected end of stream"); //$NON-NLS-1$
575 }
576
d0d3aa1b
AM
577 /* Create the stream input */
578 StreamInput streamInput = new StreamInput(stream, fc, streamFile);
866e5b51 579
d0d3aa1b
AM
580 /* Add a reference to the streamInput in the stream */
581 stream.addInput(streamInput);
866e5b51
FC
582 }
583
584 /**
585 * Looks up a definition from packet
debcffff 586 *
866e5b51
FC
587 * @param lookupPath
588 * String
589 * @return Definition
590 * @see org.eclipse.linuxtools.ctf.core.event.types.IDefinitionScope#lookupDefinition(String)
591 */
592 @Override
593 public Definition lookupDefinition(String lookupPath) {
594 if (lookupPath.equals("trace.packet.header")) { //$NON-NLS-1$
595 return packetHeaderDef;
596 }
597 return null;
598 }
599
600 /**
601 * Adds a new stream to the trace.
debcffff 602 *
866e5b51
FC
603 * @param stream
604 * A stream object.
866e5b51 605 * @throws ParseException
be6df2d8 606 * If there was some problem reading the metadata
e6809677 607 * @since 2.0
866e5b51
FC
608 */
609 public void addStream(Stream stream) throws ParseException {
610
611 /*
612 * If there is already a stream without id (the null key), it must be
613 * the only one
614 */
615 if (streams.get(null) != null) {
616 throw new ParseException("Stream without id with multiple streams"); //$NON-NLS-1$
617 }
618
619 /*
1d7277f3
MK
620 * If the stream we try to add has the null key, it must be the only
621 * one. Thus, if the streams container is not empty, it is not valid.
866e5b51
FC
622 */
623 if ((stream.getId() == null) && (streams.size() != 0)) {
624 throw new ParseException("Stream without id with multiple streams"); //$NON-NLS-1$
625 }
626
627 /* If a stream with the same ID already exists, it is not valid. */
628 if (streams.get(stream.getId()) != null) {
629 throw new ParseException("Stream id already exists"); //$NON-NLS-1$
630 }
631
29a7d6ee 632 /* This stream is valid and has a unique id. */
866e5b51
FC
633 streams.put(stream.getId(), stream);
634 }
635
9ac2eb62 636 /**
29a7d6ee 637 * Gets the Environment variables from the trace metadata (See CTF spec)
a7297cd3 638 *
a95fddf5
EB
639 * @return The environment variables in the form of an unmodifiable map
640 * (key, value)
486efb2e 641 * @since 2.0
9ac2eb62 642 */
791072b0 643 public Map<String, String> getEnvironment() {
a95fddf5 644 return Collections.unmodifiableMap(environment);
866e5b51
FC
645 }
646
9ac2eb62
MK
647 /**
648 * Add a variable to the environment variables
a7297cd3
SD
649 *
650 * @param varName
651 * the name of the variable
652 * @param varValue
653 * the value of the variable
9ac2eb62 654 */
c88e827d 655 public void addEnvironmentVar(String varName, String varValue) {
866e5b51
FC
656 environment.put(varName, varValue);
657 }
658
9ac2eb62
MK
659 /**
660 * Add a clock to the clock list
a7297cd3
SD
661 *
662 * @param nameValue
663 * the name of the clock (full name with scope)
664 * @param ctfClock
665 * the clock
9ac2eb62 666 */
866e5b51 667 public void addClock(String nameValue, CTFClock ctfClock) {
c88e827d 668 clocks.put(nameValue, ctfClock);
866e5b51
FC
669 }
670
9ac2eb62
MK
671 /**
672 * gets the clock with a specific name
a7297cd3
SD
673 *
674 * @param name
675 * the name of the clock.
9ac2eb62
MK
676 * @return the clock
677 */
c88e827d 678 public CTFClock getClock(String name) {
866e5b51
FC
679 return clocks.get(name);
680 }
681
9ac2eb62 682 /**
1d7277f3
MK
683 * gets the clock if there is only one. (this is 100% of the use cases as of
684 * June 2012)
685 *
9ac2eb62
MK
686 * @return the clock
687 */
8ecc80f3 688 public final CTFClock getClock() {
c88e827d 689 if (clocks.size() == 1) {
1d7277f3 690 singleClock = clocks.get(clocks.keySet().iterator().next());
8ecc80f3 691 return singleClock;
866e5b51
FC
692 }
693 return null;
694 }
695
9ac2eb62
MK
696 /**
697 * gets the time offset of a clock with respect to UTC in nanoseconds
1d7277f3 698 *
9ac2eb62
MK
699 * @return the time offset of a clock with respect to UTC in nanoseconds
700 */
8ecc80f3 701 public final long getOffset() {
c88e827d 702 if (getClock() == null) {
ce2388e0
FC
703 return 0;
704 }
1d7277f3
MK
705 return singleClock.getClockOffset();
706 }
707
708 /**
709 * gets the time offset of a clock with respect to UTC in nanoseconds
710 *
711 * @return the time offset of a clock with respect to UTC in nanoseconds
712 */
0594c61c 713 private double getTimeScale() {
1d7277f3
MK
714 if (getClock() == null) {
715 return 1.0;
716 }
717 return singleClock.getClockScale();
718 }
719
720 /**
721 * Does the trace need to time scale?
722 *
723 * @return if the trace is in ns or cycles.
724 */
0594c61c 725 private boolean clockNeedsScale() {
1d7277f3
MK
726 if (getClock() == null) {
727 return false;
728 }
729 return singleClock.isClockScaled();
730 }
731
732 /**
733 * the inverse clock for returning to a scale.
734 *
735 * @return 1.0 / scale
736 */
0594c61c 737 private double getInverseTimeScale() {
1d7277f3
MK
738 if (getClock() == null) {
739 return 1.0;
740 }
741 return singleClock.getClockAntiScale();
742 }
743
744 /**
745 * @param cycles
746 * clock cycles since boot
747 * @return time in nanoseconds UTC offset
486efb2e 748 * @since 2.0
1d7277f3
MK
749 */
750 public long timestampCyclesToNanos(long cycles) {
751 long retVal = cycles + getOffset();
752 /*
753 * this fix is since quite often the offset will be > than 53 bits and
754 * therefore the conversion will be lossy
755 */
756 if (clockNeedsScale()) {
757 retVal = (long) (retVal * getTimeScale());
758 }
759 return retVal;
760 }
761
762 /**
763 * @param nanos
764 * time in nanoseconds UTC offset
765 * @return clock cycles since boot.
486efb2e 766 * @since 2.0
1d7277f3
MK
767 */
768 public long timestampNanoToCycles(long nanos) {
769 long retVal;
770 /*
771 * this fix is since quite often the offset will be > than 53 bits and
772 * therefore the conversion will be lossy
773 */
774 if (clockNeedsScale()) {
775 retVal = (long) (nanos * getInverseTimeScale());
776 } else {
777 retVal = nanos;
778 }
779 return retVal - getOffset();
ce2388e0
FC
780 }
781
4c9d2941
MK
782 /**
783 * Adds a callsite
784 *
785 * @param eventName
786 * the event name of the callsite
787 * @param funcName
788 * the name of the callsite function
789 * @param ip
790 * the ip of the callsite
791 * @param fileName
792 * the filename of the callsite
793 * @param lineNumber
794 * the line number of the callsite
795 */
796 public void addCallsite(String eventName, String funcName, long ip,
797 String fileName, long lineNumber) {
798 final CTFCallsite cs = new CTFCallsite(eventName, funcName, ip,
799 fileName, lineNumber);
890f9136 800 TreeSet<CTFCallsite> csl = callsitesByName.get(eventName);
4c9d2941 801 if (csl == null) {
890f9136 802 csl = new TreeSet<CTFCallsite>(ctfCallsiteComparator);
4c9d2941
MK
803 callsitesByName.put(eventName, csl);
804 }
805
890f9136 806 csl.add(cs);
4c9d2941
MK
807
808 callsitesByIP.add(cs);
809 }
810
811 /**
890f9136 812 * Gets the set of callsites associated to an event name. O(1)
4c9d2941
MK
813 *
814 * @param eventName
815 * the event name
890f9136
SD
816 * @return the callsite set can be empty
817 * @since 3.0
4c9d2941 818 */
890f9136
SD
819 public TreeSet<CTFCallsite> getCallsiteCandidates(String eventName) {
820 TreeSet<CTFCallsite> retVal = callsitesByName.get(eventName);
821 if (retVal == null) {
822 retVal = new TreeSet<CTFCallsite>(ctfCallsiteComparator);
4c9d2941
MK
823 }
824 return retVal;
825 }
826
827 /**
828 * The I'm feeling lucky of getCallsiteCandidates O(1)
829 *
830 * @param eventName
831 * the event name
832 * @return the first callsite that has that event name, can be null
833 * @since 1.2
834 */
835 public CTFCallsite getCallsite(String eventName) {
890f9136 836 TreeSet<CTFCallsite> callsites = callsitesByName.get(eventName);
60fb38b8 837 if (callsites != null) {
890f9136 838 return callsites.first();
60fb38b8
PT
839 }
840 return null;
4c9d2941
MK
841 }
842
843 /**
844 * Gets a callsite from the instruction pointer O(log(n))
845 *
846 * @param ip
847 * the instruction pointer to lookup
848 * @return the callsite just before that IP in the list remember the IP is
849 * backwards on X86, can be null if no callsite is before the IP.
850 * @since 1.2
851 */
852 public CTFCallsite getCallsite(long ip) {
853 CTFCallsite cs = new CTFCallsite(null, null, ip, null, 0L);
854 return callsitesByIP.ceiling(cs);
855 }
856
857 /**
858 * Gets a callsite using the event name and instruction pointer O(log(n))
859 *
860 * @param eventName
861 * the name of the event
862 * @param ip
863 * the instruction pointer
864 * @return the closest matching callsite, can be null
865 */
866 public CTFCallsite getCallsite(String eventName, long ip) {
890f9136 867 final TreeSet<CTFCallsite> candidates = callsitesByName.get(eventName);
4c9d2941 868 final CTFCallsite dummyCs = new CTFCallsite(null, null, ip, null, -1);
890f9136
SD
869 final CTFCallsite callsite = candidates.ceiling(dummyCs);
870 if (callsite == null) {
871 return candidates.floor(dummyCs);
4c9d2941 872 }
890f9136 873 return callsite;
4c9d2941 874 }
866e5b51 875}
c88e827d
AM
876
877class MetadataFileFilter implements FileFilter {
878
879 @Override
880 public boolean accept(File pathname) {
881 if (pathname.isDirectory()) {
882 return false;
883 }
884 if (pathname.isHidden()) {
885 return false;
886 }
887 if (pathname.getName().equals("metadata")) { //$NON-NLS-1$
888 return false;
889 }
890 return true;
891 }
892
893}
894
debcffff 895class MetadataComparator implements Comparator<File>, Serializable {
c88e827d 896
8fd82db5
FC
897 private static final long serialVersionUID = 1L;
898
c88e827d
AM
899 @Override
900 public int compare(File o1, File o2) {
901 return o1.getName().compareTo(o2.getName());
902 }
903}
This page took 0.082284 seconds and 5 git commands to generate.