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