Fix Statistics JUnit test
[deliverable/tracecompass.git] / org.eclipse.linuxtools.ctf.core / src / org / eclipse / linuxtools / ctf / core / trace / StreamInputPacketReader.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: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
12package org.eclipse.linuxtools.ctf.core.trace;
13
14import java.io.IOException;
15import java.nio.MappedByteBuffer;
16import java.nio.channels.FileChannel.MapMode;
17import java.util.Collection;
18import java.util.HashMap;
19
20import org.eclipse.linuxtools.ctf.core.event.EventDeclaration;
21import org.eclipse.linuxtools.ctf.core.event.EventDefinition;
866e5b51 22import org.eclipse.linuxtools.ctf.core.event.types.Definition;
866e5b51
FC
23import org.eclipse.linuxtools.ctf.core.event.types.IDefinitionScope;
24import org.eclipse.linuxtools.ctf.core.event.types.IntegerDefinition;
21fb02fa 25import org.eclipse.linuxtools.ctf.core.event.types.SimpleDatatypeDefinition;
866e5b51
FC
26import org.eclipse.linuxtools.ctf.core.event.types.StructDeclaration;
27import org.eclipse.linuxtools.ctf.core.event.types.StructDefinition;
28import org.eclipse.linuxtools.ctf.core.event.types.VariantDefinition;
ce2388e0
FC
29import org.eclipse.linuxtools.internal.ctf.core.event.io.BitBuffer;
30import org.eclipse.linuxtools.internal.ctf.core.trace.Stream;
31import org.eclipse.linuxtools.internal.ctf.core.trace.StreamInputPacketIndexEntry;
866e5b51
FC
32
33/**
d37aaa7f 34 * CTF trace packet reader. Reads the events of a packet of a trace file.
5c7202b5 35 *
d37aaa7f
FC
36 * @version 1.0
37 * @author Matthew Khouzam
38 * @author Simon Marchi
866e5b51 39 */
bfe038ff 40public class StreamInputPacketReader implements IDefinitionScope {
866e5b51
FC
41
42 // ------------------------------------------------------------------------
43 // Constants
44 // ------------------------------------------------------------------------
45
46 /**
47 * Reference to the index entry of the current packet.
48 */
49 private StreamInputPacketIndexEntry currentPacket = null;
50
51 /**
52 * BitBuffer used to read the trace file.
53 */
54 private final BitBuffer bitBuffer = new BitBuffer();
55
56 /**
57 * StreamInputReader that uses this StreamInputPacketReader.
58 */
59 private final StreamInputReader streamInputReader;
60
61 /**
62 * Last timestamp recorded.
63 *
64 * Needed to calculate the complete timestamp values for the events with
65 * compact headers.
66 */
67 private long lastTimestamp = 0;
68
69 /**
70 * Trace packet header.
71 */
72 private StructDefinition tracePacketHeaderDef = null;
73
74 /**
75 * Stream packet context definition.
76 */
77 private StructDefinition streamPacketContextDef = null;
78
79 /**
80 * Stream event header definition.
81 */
82 private StructDefinition streamEventHeaderDef = null;
83
84 /**
85 * Stream event context definition.
86 */
87 private StructDefinition streamEventContextDef = null;
88
89 /**
90 * Maps event ID to event definitions.
91 */
788ddcbc 92 private final HashMap<Long, EventDefinition> events;
866e5b51
FC
93
94 /**
95 * CPU id of current packet.
96 */
97 private int currentCpu = 0;
98
33656d8e
MK
99 /**
100 * number of lost events in this packet
101 */
102 private int lostEvents;
103
104 private int lostSoFar;
105
5c7202b5
MK
106 private int lostEventsInThisPacket;
107
866e5b51
FC
108 // ------------------------------------------------------------------------
109 // Attributes
110 // ------------------------------------------------------------------------
111
112 /**
113 * Constructs a StreamInputPacketReader.
114 *
115 * @param streamInputReader
116 * The StreamInputReader to which this packet reader belongs to.
117 */
118 public StreamInputPacketReader(StreamInputReader streamInputReader) {
119 this.streamInputReader = streamInputReader;
120
121 /*
122 * Set the BitBuffer's byte order.
123 */
ce2388e0 124 getBitBuffer().setByteOrder(streamInputReader.getByteOrder());
866e5b51 125
788ddcbc
MK
126 events = streamInputReader.getStreamInput().getStream().getTrace()
127 .getEventDefs(streamInputReader.getStreamInput());
866e5b51
FC
128 /*
129 * Create definitions needed to read the events.
130 */
131 createDefinitions();
33656d8e 132
788ddcbc
MK
133 lostEvents = 0;
134 lostSoFar = 0;
866e5b51
FC
135 }
136
137 // ------------------------------------------------------------------------
138 // Constructors
139 // ------------------------------------------------------------------------
140
141 // ------------------------------------------------------------------------
142 // Getters/Setters/Predicates
143 // ------------------------------------------------------------------------
144
9ac2eb62
MK
145 /**
146 * Gets the current packet
147 *
148 * @return the current packet
149 */
866e5b51
FC
150 public StreamInputPacketIndexEntry getCurrentPacket() {
151 return this.currentPacket;
152 }
153
9ac2eb62
MK
154 /**
155 * Gets the steamPacketContext Definition
156 *
157 * @return steamPacketContext Definition
158 */
866e5b51
FC
159 public StructDefinition getStreamPacketContextDef() {
160 return this.streamPacketContextDef;
161 }
162
9ac2eb62
MK
163 /**
164 * Gets the CPU (core) number
165 *
166 * @return the CPU (core) number
167 */
866e5b51
FC
168 public int getCPU() {
169 return this.currentCpu;
170 }
171
172 @Override
173 public String getPath() {
174 return ""; //$NON-NLS-1$
175 }
176
177 // ------------------------------------------------------------------------
178 // Operations
179 // ------------------------------------------------------------------------
180
181 /**
182 * Creates definitions needed to read events (stream-defined and
183 * event-defined).
184 */
185 private void createDefinitions() {
186 /*
187 * Create trace packet header definition.
188 */
788ddcbc
MK
189 final Stream currentStream = getStreamInputReader().getStreamInput()
190 .getStream();
191 StructDeclaration tracePacketHeaderDecl = currentStream.getTrace()
192 .getPacketHeader();
866e5b51 193 if (tracePacketHeaderDecl != null) {
788ddcbc
MK
194 setTracePacketHeaderDef(tracePacketHeaderDecl.createDefinition(
195 this, "trace.packet.header")); //$NON-NLS-1$
866e5b51
FC
196 }
197
198 /*
199 * Create stream packet context definition.
200 */
788ddcbc
MK
201 StructDeclaration streamPacketContextDecl = currentStream
202 .getPacketContextDecl();
866e5b51
FC
203 if (streamPacketContextDecl != null) {
204 setStreamPacketContextDef(streamPacketContextDecl.createDefinition(
205 this, "stream.packet.context")); //$NON-NLS-1$
206 }
207
208 /*
209 * Create stream event header definition.
210 */
788ddcbc
MK
211 StructDeclaration streamEventHeaderDecl = currentStream
212 .getEventHeaderDecl();
866e5b51 213 if (streamEventHeaderDecl != null) {
788ddcbc
MK
214 setStreamEventHeaderDef(streamEventHeaderDecl.createDefinition(
215 this, "stream.event.header")); //$NON-NLS-1$
866e5b51
FC
216 }
217
218 /*
219 * Create stream event context definition.
220 */
788ddcbc
MK
221 StructDeclaration streamEventContextDecl = currentStream
222 .getEventContextDecl();
866e5b51
FC
223 if (streamEventContextDecl != null) {
224 setStreamEventContextDef(streamEventContextDecl.createDefinition(
225 this, "stream.event.context")); //$NON-NLS-1$
226 }
227
228 createEventDefinitions();
229 }
230
231 /**
232 * Creates definitions needed to read the event. (event-defined).
233 */
234 private void createEventDefinitions() {
788ddcbc
MK
235 Collection<EventDeclaration> eventDecls = getStreamInputReader()
236 .getStreamInput().getStream().getEvents().values();
866e5b51
FC
237
238 /*
239 * Create definitions for each event.
240 */
241 for (EventDeclaration event : eventDecls) {
788ddcbc
MK
242 if (!events.containsKey(event.getId())) {
243 EventDefinition eventDef = event
244 .createDefinition(getStreamInputReader());
245 events.put(event.getId(), eventDef);
246 }
866e5b51
FC
247 }
248 }
249
250 /**
251 * Changes the current packet to the given one.
252 *
253 * @param currentPacket
254 * The index entry of the packet to switch to.
255 */
256 public void setCurrentPacket(StreamInputPacketIndexEntry currentPacket) {
257 this.currentPacket = currentPacket;
258
259 if (this.currentPacket != null) {
260 /*
261 * Change the map of the BitBuffer.
262 */
263 MappedByteBuffer bb = null;
264 try {
788ddcbc
MK
265 bb = getStreamInputReader()
266 .getStreamInput()
267 .getFileChannel()
268 .map(MapMode.READ_ONLY,
269 this.currentPacket.getOffsetBytes(),
270 (this.currentPacket.getPacketSizeBits() + 7) / 8);
866e5b51
FC
271 } catch (IOException e) {
272 /*
273 * The streamInputReader object is already allocated, so this
274 * shouldn't fail bar some very bad kernel or RAM errors...
275 */
276 e.printStackTrace();
277 }
278
279 getBitBuffer().setByteBuffer(bb);
280
281 /*
282 * Read trace packet header.
283 */
284 if (getTracePacketHeaderDef() != null) {
285 getTracePacketHeaderDef().read(getBitBuffer());
286 }
287
288 /*
289 * Read stream packet context.
290 */
291 if (getStreamPacketContextDef() != null) {
292 getStreamPacketContextDef().read(getBitBuffer());
33656d8e
MK
293 /*
294 * Read CPU ID
295 */
296
21fb02fa
MK
297 if (this.getCurrentPacket().getTarget() != null) {
298 this.currentCpu = (int) this.getCurrentPacket()
299 .getTargetId();
866e5b51 300 }
33656d8e
MK
301 /*
302 * Read number of lost events
303 */
21fb02fa
MK
304
305 int totalLostEvents = (int) this.getCurrentPacket()
306 .getLostEvents();
307 lostEventsInThisPacket = totalLostEvents - lostEvents;
308 lostEvents = totalLostEvents;
309 currentPacket.setLostEvents(lostEventsInThisPacket);
310 lostSoFar = 0;
311
866e5b51
FC
312 }
313
314 /*
315 * Use the timestamp begin of the packet as the reference for the
316 * timestamp reconstitution.
317 */
ce2388e0 318 lastTimestamp = currentPacket.getTimestampBegin();
866e5b51
FC
319 } else {
320 getBitBuffer().setByteBuffer(null);
321
322 lastTimestamp = 0;
323 }
324 }
325
326 /**
327 * Returns whether it is possible to read any more events from this packet.
328 *
329 * @return True if it is possible to read any more events from this packet.
330 */
331 public boolean hasMoreEvents() {
332 if (currentPacket != null) {
788ddcbc
MK
333 return getBitBuffer().position() < currentPacket
334 .getContentSizeBits();
866e5b51
FC
335 }
336 return false;
337 }
338
339 /**
340 * Reads the next event of the packet into the right event definition.
341 *
342 * @return The event definition containing the event data that was just
343 * read.
344 * @throws CTFReaderException
be6df2d8 345 * If there was a problem reading the trace
866e5b51
FC
346 */
347 public EventDefinition readNextEvent() throws CTFReaderException {
21fb02fa 348 /* WARNING: This is still LTTng-specific. */
866e5b51
FC
349 Long eventID = null;
350 long timestamp = 0;
351
5c7202b5 352 if (lostEventsInThisPacket > lostSoFar) {
788ddcbc
MK
353 EventDefinition eventDef = EventDeclaration
354 .getLostEventDeclaration().createDefinition(
355 streamInputReader);
aa572e22 356 eventDef.setTimestamp(this.lastTimestamp);
33656d8e
MK
357 ++lostSoFar;
358 return eventDef;
359 }
788ddcbc
MK
360 StructDefinition sehd = getStreamEventHeaderDef(); // acronym for a long
361 // variable name
2b7f6f09 362 BitBuffer currentBitBuffer = getBitBuffer();
866e5b51 363 /*
fd74e6c1 364 * Read the stream event header.
866e5b51 365 */
2b7f6f09
MK
366
367 if (sehd != null) {
368 sehd.read(currentBitBuffer);
866e5b51
FC
369
370 /*
371 * Check for an event id.
372 */
21fb02fa 373 SimpleDatatypeDefinition idDef = (SimpleDatatypeDefinition) sehd
788ddcbc 374 .lookupDefinition("id"); //$NON-NLS-1$
21fb02fa
MK
375 IntegerDefinition timestampDef = sehd.lookupInteger("timestamp"); //$NON-NLS-1$
376 eventID = idDef.getIntegerValue();
866e5b51
FC
377
378 /*
379 * Check for the variant v.
380 */
788ddcbc
MK
381 VariantDefinition variantDef = (VariantDefinition) sehd
382 .lookupDefinition("v"); //$NON-NLS-1$
21fb02fa 383 if (variantDef != null) {
866e5b51 384
21fb02fa
MK
385 /*
386 * Get the variant current field
387 */
388 StructDefinition variantCurrentField = (StructDefinition) variantDef
389 .getCurrentField();
866e5b51 390
21fb02fa
MK
391 /*
392 * Try to get the id field in the current field of the variant.
393 * If it is present, it overrides the previously read event id.
394 */
395 IntegerDefinition idIntegerDef = (IntegerDefinition) variantCurrentField
396 .lookupDefinition("id"); //$NON-NLS-1$
397 if (idIntegerDef != null) {
398 eventID = idIntegerDef.getValue();
399 }
400 /*
401 * Get the timestamp.
402 */
403 timestampDef = (IntegerDefinition) variantCurrentField
404 .lookupDefinition("timestamp"); //$NON-NLS-1$
866e5b51 405
21fb02fa 406 }
866e5b51
FC
407
408 /*
409 * Calculate the event timestamp.
410 */
411 timestamp = calculateTimestamp(timestampDef);
412 }
413
414 /*
415 * Read the stream event context.
416 */
417 if (getStreamEventContextDef() != null) {
2b7f6f09 418 getStreamEventContextDef().read(currentBitBuffer);
866e5b51
FC
419 }
420
421 /*
422 * Get the right event definition using the event id.
423 */
424 EventDefinition eventDef = events.get(eventID);
425 if (eventDef == null) {
426 throw new CTFReaderException("Incorrect event id : " + eventID); //$NON-NLS-1$
427 }
428
429 /*
430 * Read the event context.
431 */
aa572e22
MK
432 if (eventDef.getContext() != null) {
433 eventDef.getContext().read(currentBitBuffer);
866e5b51
FC
434 }
435
436 /*
437 * Read the event fields.
438 */
aa572e22
MK
439 if (eventDef.getFields() != null) {
440 eventDef.getFields().read(currentBitBuffer);
866e5b51
FC
441 }
442
443 /*
444 * Set the event timestamp using the timestamp calculated by
445 * updateTimestamp.
446 */
aa572e22 447 eventDef.setTimestamp(timestamp);
866e5b51
FC
448
449 return eventDef;
450 }
451
452 /**
453 * Calculates the timestamp value of the event, possibly using the timestamp
454 * from the last event.
455 *
456 * @param timestampDef
457 * Integer definition of the timestamp.
458 * @return The calculated timestamp value.
459 */
460 private long calculateTimestamp(IntegerDefinition timestampDef) {
461 long newval;
462 long majorasbitmask;
463 int len = timestampDef.getDeclaration().getLength();
464
465 /*
466 * If the timestamp length is 64 bits, it is a full timestamp.
467 */
468 if (timestampDef.getDeclaration().getLength() == 64) {
469 lastTimestamp = timestampDef.getValue();
470 return lastTimestamp;
471 }
472
473 /*
474 * Bit mask to keep / remove all old / new bits.
475 */
476 majorasbitmask = (1L << len) - 1;
477
478 /*
479 * If the new value is smaller than the corresponding bits of the last
480 * timestamp, we assume an overflow of the compact representation.
481 */
482 newval = timestampDef.getValue();
483 if (newval < (lastTimestamp & majorasbitmask)) {
484 newval = newval + (1L << len);
485 }
486
487 /* Keep only the high bits of the old value */
488 lastTimestamp = lastTimestamp & ~majorasbitmask;
489
490 /* Then add the low bits of the new value */
491 lastTimestamp = lastTimestamp + newval;
492
493 return lastTimestamp;
494 }
495
496 @Override
497 public Definition lookupDefinition(String lookupPath) {
498 // TODO Auto-generated method stub
499 return null;
500 }
501
9ac2eb62
MK
502 /**
503 * Gets the stream event context definition (see CTF specs)
504 *
505 * @return the definition of the stream event context (the form not the
506 * content)
507 */
866e5b51
FC
508 public StructDefinition getStreamEventContextDef() {
509 return this.streamEventContextDef;
510 }
511
9ac2eb62
MK
512 /**
513 * Sets the stream event context definition
514 *
515 * @param streamEventContextDef
516 * The stream event context definition
517 */
866e5b51
FC
518 public void setStreamEventContextDef(StructDefinition streamEventContextDef) {
519 this.streamEventContextDef = streamEventContextDef;
520 }
521
9ac2eb62
MK
522 /**
523 * Gets the stream event header definition
524 *
525 * @return the stream event header definition
526 */
866e5b51
FC
527 public StructDefinition getStreamEventHeaderDef() {
528 return this.streamEventHeaderDef;
529 }
530
9ac2eb62
MK
531 /**
532 * Sets the stream event header definition
533 *
534 * @param streamEventHeaderDef
535 * the stream event header definition
536 */
866e5b51
FC
537 public void setStreamEventHeaderDef(StructDefinition streamEventHeaderDef) {
538 this.streamEventHeaderDef = streamEventHeaderDef;
539 }
540
9ac2eb62
MK
541 /**
542 * Sets the stream packet context definition
543 *
544 * @param streamPacketContextDef
545 * the stream packet context definition
546 */
788ddcbc
MK
547 public void setStreamPacketContextDef(
548 StructDefinition streamPacketContextDef) {
866e5b51
FC
549 this.streamPacketContextDef = streamPacketContextDef;
550 }
551
9ac2eb62
MK
552 /**
553 * Gets the trace packet header definition
554 *
555 * @return the trace packet header definition
556 */
866e5b51
FC
557 public StructDefinition getTracePacketHeaderDef() {
558 return this.tracePacketHeaderDef;
559 }
560
9ac2eb62
MK
561 /**
562 * Sets the trace packet header definition
563 *
564 * @param tracePacketHeaderDef
565 * the trace packet header definition
566 */
866e5b51
FC
567 public void setTracePacketHeaderDef(StructDefinition tracePacketHeaderDef) {
568 this.tracePacketHeaderDef = tracePacketHeaderDef;
569 }
570
9ac2eb62
MK
571 /**
572 * @return the parent stream input reader
573 */
866e5b51
FC
574 public StreamInputReader getStreamInputReader() {
575 return this.streamInputReader;
576 }
577
9ac2eb62
MK
578 /**
579 *
580 * @return THe bit buffer that reads the file.
581 */
866e5b51
FC
582 public BitBuffer getBitBuffer() {
583 return bitBuffer;
584 }
585}
This page took 0.054979 seconds and 5 git commands to generate.