tmf/lttng: Update 2014 copyrights
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / StreamInputReader.java
CommitLineData
866e5b51 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2011, 2014 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 *
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.ctf.core.trace;
14
ce2388e0 15import java.nio.ByteOrder;
7ff6d3cf
MK
16import java.util.Collections;
17import java.util.HashMap;
18import java.util.Map;
866e5b51
FC
19
20import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
21import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
ce2388e0 22import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
866e5b51
FC
23
24/**
d37aaa7f 25 * A CTF trace event reader. Reads the events of a trace file.
32ede2ec 26 *
d37aaa7f
FC
27 * @version 1.0
28 * @author Matthew Khouzam
29 * @author Simon Marchi
866e5b51
FC
30 */
31public class StreamInputReader {
32
33 // ------------------------------------------------------------------------
34 // Attributes
35 // ------------------------------------------------------------------------
36
37 /**
38 * The StreamInput we are reading.
39 */
93a45b54 40 private final StreamInput fStreamInput;
866e5b51
FC
41
42 /**
43 * The packet reader used to read packets from this trace file.
44 */
93a45b54 45 private final StreamInputPacketReader fPacketReader;
866e5b51
FC
46
47 /**
48 * Iterator on the packet index
49 */
93a45b54 50 private int fPacketIndex;
866e5b51
FC
51
52 /**
53 * Reference to the current event of this trace file (iow, the last on that
54 * was read, the next one to be returned)
55 */
93a45b54 56 private EventDefinition fCurrentEvent = null;
866e5b51 57
93a45b54 58 private int fId;
866e5b51 59
93a45b54 60 private CTFTraceReader fParent;
bfe038ff 61
7ff6d3cf 62 /** Map of all the event types */
93a45b54 63 private final Map<Long, EventDefinition> fEventDefs = new HashMap<>();
bfe038ff 64
6a5251eb
MK
65 /**
66 * Live trace reading
67 */
68 private boolean fLive = false;
69
866e5b51
FC
70 // ------------------------------------------------------------------------
71 // Constructors
72 // ------------------------------------------------------------------------
73
74 /**
75 * Constructs a StreamInputReader that reads a StreamInput.
76 *
77 * @param streamInput
78 * The StreamInput to read.
db8e8f7d
AM
79 * @throws CTFReaderException
80 * if an error occurs
e6809677 81 * @since 2.0
866e5b51 82 */
db8e8f7d 83 public StreamInputReader(StreamInput streamInput) throws CTFReaderException {
93a45b54
MK
84 fStreamInput = streamInput;
85 fPacketReader = new StreamInputPacketReader(this);
866e5b51
FC
86 /*
87 * Get the iterator on the packet index.
88 */
93a45b54 89 fPacketIndex = 0;
866e5b51
FC
90 /*
91 * Make first packet the current one.
92 */
93 goToNextPacket();
94 }
95
5d1c6919
PT
96 /**
97 * Dispose the StreamInputReader
db8e8f7d 98 *
5d1c6919
PT
99 * @since 2.0
100 */
101 public void dispose() {
93a45b54 102 fPacketReader.dispose();
5d1c6919
PT
103 }
104
866e5b51
FC
105 // ------------------------------------------------------------------------
106 // Getters/Setters/Predicates
107 // ------------------------------------------------------------------------
108
9ac2eb62
MK
109 /**
110 * Gets the current event in this stream
111 *
112 * @return the current event in the stream, null if the stream is
113 * finished/empty/malformed
114 */
866e5b51 115 public EventDefinition getCurrentEvent() {
93a45b54 116 return fCurrentEvent;
866e5b51
FC
117 }
118
9ac2eb62 119 /**
ecb12461 120 * Gets the current packet context
9ac2eb62
MK
121 *
122 * @return the current packet context (size, lost events and such)
123 */
866e5b51 124 public StructDefinition getCurrentPacketContext() {
93a45b54 125 return fPacketReader.getStreamPacketContextDef();
866e5b51
FC
126 }
127
9ac2eb62
MK
128 /**
129 * Gets the byte order for a trace
130 *
131 * @return the trace byte order
132 */
ce2388e0 133 public ByteOrder getByteOrder() {
93a45b54 134 return fStreamInput.getStream().getTrace().getByteOrder();
866e5b51
FC
135 }
136
9ac2eb62
MK
137 /**
138 * Gets the name of the stream (it's an id and a number)
139 *
140 * @return gets the stream name (it's a number)
141 */
866e5b51 142 public int getName() {
93a45b54 143 return fId;
866e5b51
FC
144 }
145
9ac2eb62
MK
146 /**
147 * Sets the name of the stream
148 *
149 * @param name
150 * the name of the stream, (it's a number)
151 */
866e5b51 152 public void setName(int name) {
93a45b54 153 fId = name;
866e5b51
FC
154 }
155
9ac2eb62
MK
156 /**
157 * Gets the CPU of a stream. It's the same as the one in /proc or running
158 * the asm CPUID instruction
159 *
160 * @return The CPU id (a number)
161 */
866e5b51 162 public int getCPU() {
93a45b54 163 return fPacketReader.getCPU();
866e5b51
FC
164 }
165
9ac2eb62
MK
166 /**
167 * Gets the filename of the stream being read
db8e8f7d 168 *
9ac2eb62
MK
169 * @return The filename of the stream being read
170 */
ce2388e0 171 public String getFilename() {
93a45b54 172 return fStreamInput.getFilename();
ce2388e0
FC
173 }
174
175 /*
176 * for internal use only
177 */
178 StreamInput getStreamInput() {
93a45b54 179 return fStreamInput;
ce2388e0
FC
180 }
181
7ff6d3cf
MK
182 /**
183 * Gets the event definition hashmap for this StreamInput
184 *
185 * @return Unmodifiable map with the event definitions
186 * @since 2.1
187 */
188 public Map<Long, EventDefinition> getEventDefinitions() {
93a45b54 189 return Collections.unmodifiableMap(fEventDefs);
7ff6d3cf
MK
190 }
191
192 /**
193 * Add an event definition to this stream input reader.
194 *
195 * @param id
196 * The id of the event definition. This will overwrite any
197 * existing definition with the same id.
198 * @param def
199 * The matching event definition
200 * @since 2.1
201 */
202 public void addEventDefinition(Long id, EventDefinition def) {
93a45b54 203 fEventDefs.put(id, def);
7ff6d3cf
MK
204 }
205
6a5251eb
MK
206 /**
207 * Set the trace to live mode
208 *
209 * @param live
210 * whether the trace is read live or not
211 * @since 3.0
212 */
213 public void setLive(boolean live) {
214 fLive = live;
215 }
216
217 /**
218 * Get if the trace is to read live or not
219 *
220 * @return whether the trace is live or not
221 * @since 3.0
222 */
223 public boolean isLive() {
224 return fLive;
225 }
226
866e5b51
FC
227 // ------------------------------------------------------------------------
228 // Operations
229 // ------------------------------------------------------------------------
230 /**
231 * Reads the next event in the current event variable.
232 *
233 * @return If an event has been successfully read.
db8e8f7d
AM
234 * @throws CTFReaderException
235 * if an error occurs
6a5251eb 236 * @since 3.0
866e5b51 237 */
6a5251eb 238 public CTFResponse readNextEvent() throws CTFReaderException {
bfe038ff 239
866e5b51
FC
240 /*
241 * Change packet if needed
242 */
93a45b54
MK
243 if (!fPacketReader.hasMoreEvents()) {
244 final StreamInputPacketIndexEntry prevPacket = fPacketReader
bfe038ff 245 .getCurrentPacket();
6a5251eb 246 if (prevPacket != null || fLive ) {
bfe038ff 247 goToNextPacket();
bfe038ff 248 }
6a5251eb 249
866e5b51
FC
250 }
251
32ede2ec 252 /*
866e5b51
FC
253 * If an event is available, read it.
254 */
93a45b54 255 if (fPacketReader.hasMoreEvents()) {
6a5251eb
MK
256 setCurrentEvent(fPacketReader.readNextEvent());
257 return CTFResponse.OK;
866e5b51
FC
258 }
259 this.setCurrentEvent(null);
6a5251eb 260 return fLive ? CTFResponse.WAIT : CTFResponse.FINISH;
866e5b51
FC
261 }
262
263 /**
264 * Change the current packet of the packet reader to the next one.
db8e8f7d
AM
265 *
266 * @throws CTFReaderException
267 * if an error occurs
866e5b51 268 */
db8e8f7d 269 private void goToNextPacket() throws CTFReaderException {
93a45b54 270 fPacketIndex++;
6a5251eb 271 // did we already index the packet?
93a45b54
MK
272 if (getPacketSize() >= (fPacketIndex + 1)) {
273 fPacketReader.setCurrentPacket(getPacket());
866e5b51 274 } else {
6a5251eb 275 // go to the next packet if there is one, index it at the same time
93a45b54
MK
276 if (fStreamInput.addPacketHeaderIndex()) {
277 fPacketIndex = getPacketSize() - 1;
278 fPacketReader.setCurrentPacket(getPacket());
cf9a28da 279 } else {
6a5251eb 280 // out of packets
93a45b54 281 fPacketReader.setCurrentPacket(null);
bfe038ff 282 }
866e5b51
FC
283 }
284 }
285
bfe038ff
MK
286 /**
287 * @return
288 */
289 private int getPacketSize() {
93a45b54 290 return fStreamInput.getIndex().getEntries().size();
bfe038ff
MK
291 }
292
866e5b51
FC
293 /**
294 * Changes the location of the trace file reader so that the current event
ecb12461 295 * is the first event with a timestamp greater or equal the given timestamp.
866e5b51
FC
296 *
297 * @param timestamp
298 * The timestamp to seek to.
be6df2d8 299 * @return The offset compared to the current position
db8e8f7d
AM
300 * @throws CTFReaderException
301 * if an error occurs
866e5b51 302 */
db8e8f7d 303 public long seek(long timestamp) throws CTFReaderException {
ce2388e0 304 long offset = 0;
866e5b51 305
eb94f9c9 306 gotoPacket(timestamp);
866e5b51 307
0c59c1a6
MK
308 /*
309 * index up to the desired timestamp.
310 */
93a45b54
MK
311 while ((fPacketReader.getCurrentPacket() != null)
312 && (fPacketReader.getCurrentPacket().getTimestampEnd() < timestamp)) {
0c59c1a6 313 try {
93a45b54 314 fStreamInput.addPacketHeaderIndex();
0c59c1a6
MK
315 goToNextPacket();
316 } catch (CTFReaderException e) {
317 // do nothing here
318 }
319 }
93a45b54 320 if (fPacketReader.getCurrentPacket() == null) {
eb94f9c9
MK
321 gotoPacket(timestamp);
322 }
0c59c1a6 323
866e5b51 324 /*
6a5251eb
MK
325 * Advance until either of these conditions are met:
326 *
327 * - reached the end of the trace file (the given timestamp is after the
328 * last event)
329 *
330 * - found the first event with a timestamp greater or equal the given
331 * timestamp.
866e5b51
FC
332 */
333 readNextEvent();
334 boolean done = (this.getCurrentEvent() == null);
aa572e22 335 while (!done && (this.getCurrentEvent().getTimestamp() < timestamp)) {
866e5b51
FC
336 readNextEvent();
337 done = (this.getCurrentEvent() == null);
ce2388e0 338 offset++;
866e5b51 339 }
ce2388e0
FC
340 return offset;
341 }
342
eb94f9c9
MK
343 /**
344 * @param timestamp
6a5251eb 345 * the time to seek
db8e8f7d
AM
346 * @throws CTFReaderException
347 * if an error occurs
eb94f9c9 348 */
db8e8f7d 349 private void gotoPacket(long timestamp) throws CTFReaderException {
93a45b54 350 fPacketIndex = fStreamInput.getIndex().search(timestamp)
eb94f9c9
MK
351 .previousIndex();
352 /*
353 * Switch to this packet.
354 */
355 goToNextPacket();
356 }
357
9ac2eb62
MK
358 /**
359 * Seeks the last event of a stream and returns it.
db8e8f7d
AM
360 *
361 * @throws CTFReaderException
362 * if an error occurs
9ac2eb62 363 */
db8e8f7d 364 public void goToLastEvent() throws CTFReaderException {
866e5b51
FC
365 /*
366 * Search in the index for the packet to search in.
367 */
93a45b54 368 final int len = fStreamInput.getIndex().getEntries().size();
ec6f5beb 369
866e5b51 370 /*
ec6f5beb 371 * Go to beginning of trace.
866e5b51 372 */
ec6f5beb
MK
373 seek(0);
374 /*
375 * if the trace is empty.
376 */
93a45b54 377 if ((len == 0) || (fPacketReader.hasMoreEvents() == false)) {
ec6f5beb
MK
378 /*
379 * This means the trace is empty. abort.
380 */
381 return;
ce2388e0 382 }
ec6f5beb
MK
383 /*
384 * Go to the last packet that contains events.
385 */
bfe038ff 386 for (int pos = len - 1; pos > 0; pos--) {
93a45b54
MK
387 fPacketIndex = pos;
388 fPacketReader.setCurrentPacket(getPacket());
389 if (fPacketReader.hasMoreEvents()) {
ec6f5beb
MK
390 break;
391 }
866e5b51 392 }
ec6f5beb
MK
393
394 /*
395 * Go until the end of that packet
396 */
397 EventDefinition prevEvent = null;
93a45b54
MK
398 while (fCurrentEvent != null) {
399 prevEvent = fCurrentEvent;
ec6f5beb
MK
400 this.readNextEvent();
401 }
402 /*
403 * Go back to the previous event
404 */
405 this.setCurrentEvent(prevEvent);
866e5b51
FC
406 }
407
bfe038ff
MK
408 /**
409 * @return the parent
410 */
411 public CTFTraceReader getParent() {
93a45b54 412 return fParent;
bfe038ff
MK
413 }
414
415 /**
416 * @param parent
417 * the parent to set
418 */
419 public void setParent(CTFTraceReader parent) {
93a45b54 420 fParent = parent;
bfe038ff
MK
421 }
422
9ac2eb62
MK
423 /**
424 * Sets the current event in a stream input reader
db8e8f7d
AM
425 *
426 * @param currentEvent
427 * the event to set
9ac2eb62 428 */
866e5b51 429 public void setCurrentEvent(EventDefinition currentEvent) {
93a45b54 430 fCurrentEvent = currentEvent;
866e5b51
FC
431 }
432
ce2388e0
FC
433 /**
434 * @return the packetIndexIt
435 */
bfe038ff 436 private int getPacketIndex() {
93a45b54 437 return fPacketIndex;
bfe038ff
MK
438 }
439
440 private StreamInputPacketIndexEntry getPacket() {
93a45b54 441 return fStreamInput.getIndex().getEntries().get(getPacketIndex());
ce2388e0
FC
442 }
443
444 /**
445 * @return the packetReader
446 */
447 public StreamInputPacketReader getPacketReader() {
93a45b54 448 return fPacketReader;
ce2388e0
FC
449 }
450
81c8e6f7
MK
451 @Override
452 public int hashCode() {
453 final int prime = 31;
454 int result = 1;
93a45b54 455 result = (prime * result) + fId;
81c8e6f7 456 result = (prime * result)
93a45b54 457 + ((fStreamInput == null) ? 0 : fStreamInput.hashCode());
81c8e6f7
MK
458 return result;
459 }
460
81c8e6f7
MK
461 @Override
462 public boolean equals(Object obj) {
463 if (this == obj) {
464 return true;
465 }
466 if (obj == null) {
467 return false;
468 }
469 if (!(obj instanceof StreamInputReader)) {
470 return false;
471 }
472 StreamInputReader other = (StreamInputReader) obj;
93a45b54 473 if (fId != other.fId) {
81c8e6f7
MK
474 return false;
475 }
93a45b54
MK
476 if (fStreamInput == null) {
477 if (other.fStreamInput != null) {
81c8e6f7
MK
478 return false;
479 }
93a45b54 480 } else if (!fStreamInput.equals(other.fStreamInput)) {
81c8e6f7
MK
481 return false;
482 }
483 return true;
484 }
485
87b60a47
MK
486 @Override
487 public String toString() {
488 // this helps debugging
93a45b54 489 return fId + ' ' + fCurrentEvent.toString();
87b60a47 490 }
866e5b51 491}
This page took 0.063947 seconds and 5 git commands to generate.