c85db80e8f87f8a7b20afbfb48a0affef5743739
[deliverable/tracecompass.git] / ctf / org.eclipse.tracecompass.ctf.core / src / org / eclipse / tracecompass / internal / ctf / core / trace / StreamInputPacketIndexEntry.java
1 /*******************************************************************************
2 * Copyright (c) 2011, 2015 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 *******************************************************************************/
12
13 package org.eclipse.tracecompass.internal.ctf.core.trace;
14
15 import java.util.AbstractMap;
16 import java.util.Collections;
17 import java.util.Map;
18 import java.util.regex.Matcher;
19 import java.util.regex.Pattern;
20
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.eclipse.tracecompass.common.core.NonNullUtils;
23 import org.eclipse.tracecompass.ctf.core.CTFStrings;
24 import org.eclipse.tracecompass.ctf.core.event.types.EnumDefinition;
25 import org.eclipse.tracecompass.ctf.core.event.types.FloatDefinition;
26 import org.eclipse.tracecompass.ctf.core.event.types.IDefinition;
27 import org.eclipse.tracecompass.ctf.core.event.types.IntegerDefinition;
28 import org.eclipse.tracecompass.ctf.core.event.types.SimpleDatatypeDefinition;
29 import org.eclipse.tracecompass.ctf.core.event.types.StringDefinition;
30 import org.eclipse.tracecompass.ctf.core.event.types.StructDefinition;
31 import org.eclipse.tracecompass.ctf.core.trace.ICTFPacketDescriptor;
32 import org.eclipse.tracecompass.ctf.core.trace.IPacketReader;
33
34 import com.google.common.collect.ImmutableMap;
35 import com.google.common.collect.ImmutableMap.Builder;
36
37 /**
38 * <b><u>StreamInputPacketIndexEntry</u></b>
39 * <p>
40 * Represents an entry in the index of event packets.
41 */
42 public class StreamInputPacketIndexEntry implements ICTFPacketDescriptor {
43
44 private static final Pattern NUMBER_PATTERN = Pattern.compile("\\D*(\\d+)"); //$NON-NLS-1$
45
46 // ------------------------------------------------------------------------
47 // Attributes
48 // ------------------------------------------------------------------------
49
50 /**
51 * Position of the start of the packet header in the file, in bits
52 */
53 private final long fOffsetBits;
54
55 /**
56 * Position of the start of the packet header in the file, in bytes
57 */
58 private final long fOffsetBytes;
59
60 /**
61 * Packet size, in bits
62 */
63 private final long fPacketSizeBits;
64
65 /**
66 * Content size, in bits
67 */
68 private final long fContentSizeBits;
69
70 /**
71 * Begin timestamp
72 */
73 private final long fTimestampBegin;
74
75 /**
76 * End timestamp
77 */
78 private final long fTimestampEnd;
79
80 /**
81 * How many lost events are there?
82 */
83 private final long fLostEvents;
84
85 /**
86 * Which target is being traced
87 */
88 private final String fTarget;
89 private final long fTargetID;
90
91 /**
92 * Attributes of this index entry
93 */
94 private final @NonNull Map<String, Object> fAttributes;
95
96 private final long fEndPacketHeaderBits;
97
98 // ------------------------------------------------------------------------
99 // Constructors
100 // ------------------------------------------------------------------------
101
102 /**
103 * Constructs an index entry.
104 *
105 * @param dataOffsetBits
106 * offset in the file for the start of data in bits
107 * @param fileSizeBytes
108 * number of bytes in a file
109 *
110 * TODO: Remove
111 */
112
113 public StreamInputPacketIndexEntry(long dataOffsetBits, long fileSizeBytes) {
114 fAttributes = Collections.EMPTY_MAP;
115 fContentSizeBits = (fileSizeBytes * Byte.SIZE);
116 fPacketSizeBits = (fileSizeBytes * Byte.SIZE);
117 fOffsetBits = dataOffsetBits;
118 fOffsetBytes = dataOffsetBits / Byte.SIZE;
119 fLostEvents = 0;
120 fTarget = ""; //$NON-NLS-1$
121 fTargetID = 0;
122 fTimestampBegin = 0;
123 fTimestampEnd = Long.MAX_VALUE;
124 fEndPacketHeaderBits = dataOffsetBits;
125 }
126
127 /**
128 * full Constructor
129 *
130 * @param dataOffsetBits
131 * offset in the file for the start of data in bits
132 * @param streamPacketContextDef
133 * packet context
134 * @param fileSizeBytes
135 * number of bytes in a file
136 * @param lostSoFar
137 * number of lost events so far
138 *
139 * TODO: Remove
140 */
141 public StreamInputPacketIndexEntry(long dataOffsetBits, StructDefinition streamPacketContextDef, long fileSizeBytes, long lostSoFar) {
142 this(dataOffsetBits, streamPacketContextDef, fileSizeBytes, lostSoFar, dataOffsetBits);
143 }
144
145 /**
146 * full Constructor
147 *
148 * @param dataOffsetBits
149 * offset in the file for the start of data in bits
150 * @param streamPacketContextDef
151 * packet context
152 * @param fileSizeBytes
153 * number of bytes in a file
154 * @param lostSoFar
155 * number of lost events so far
156 * @param endPacketHeaderBits
157 * end of packet headers
158 */
159 public StreamInputPacketIndexEntry(long dataOffsetBits, StructDefinition streamPacketContextDef, long fileSizeBytes, long lostSoFar, long endPacketHeaderBits) {
160 fEndPacketHeaderBits = endPacketHeaderBits;
161 fAttributes = computeAttributeMap(streamPacketContextDef);
162 fContentSizeBits = computeContentSize(fileSizeBytes);
163 fPacketSizeBits = computePacketSize(fileSizeBytes);
164 fTimestampBegin = computeTsBegin();
165 fTimestampEnd = computeTsEnd();
166 fOffsetBits = dataOffsetBits;
167 fOffsetBytes = dataOffsetBits / Byte.SIZE;
168
169 // LTTng Specific
170 Target target = lookupTarget(streamPacketContextDef);
171 fTarget = target.string;
172 fTargetID = target.number;
173 fLostEvents = computeLostEvents(lostSoFar);
174 }
175
176 private @NonNull static ImmutableMap<String, Object> computeAttributeMap(StructDefinition streamPacketContextDef) {
177 Builder<String, Object> attributeBuilder = ImmutableMap.<String, Object> builder();
178 for (String field : streamPacketContextDef.getDeclaration().getFieldsList()) {
179 IDefinition id = streamPacketContextDef.lookupDefinition(field);
180 if (id instanceof IntegerDefinition) {
181 attributeBuilder.put(field, ((IntegerDefinition) id).getValue());
182 } else if (id instanceof FloatDefinition) {
183 attributeBuilder.put(field, ((FloatDefinition) id).getValue());
184 } else if (id instanceof EnumDefinition) {
185 final EnumDefinition enumDec = (EnumDefinition) id;
186 attributeBuilder.put(field, new AbstractMap.SimpleImmutableEntry<>(
187 NonNullUtils.checkNotNull(enumDec.getStringValue()),
188 NonNullUtils.checkNotNull(enumDec.getIntegerValue())));
189 } else if (id instanceof StringDefinition) {
190 attributeBuilder.put(field, ((StringDefinition) id).getValue());
191 }
192 }
193 return attributeBuilder.build();
194 }
195
196 private Long getPacketSize() {
197 return (Long) fAttributes.get(CTFStrings.PACKET_SIZE);
198 }
199
200 private long computeContentSize(long fileSizeBytes) {
201 Long contentSize = (Long) fAttributes.get(CTFStrings.CONTENT_SIZE);
202 /* Read the content size in bits */
203 if (contentSize != null) {
204 return contentSize.longValue();
205 }
206 Long packetSize = getPacketSize();
207 if (packetSize != null) {
208 return packetSize.longValue();
209 }
210 return fileSizeBytes * Byte.SIZE;
211 }
212
213 private long computePacketSize(long fileSizeBytes) {
214 Long packetSize = getPacketSize();
215 /* Read the packet size in bits */
216 if (packetSize != null) {
217 return packetSize.longValue();
218 }
219 long contentSizeBits = computeContentSize(fileSizeBytes);
220 if (contentSizeBits != 0) {
221 return contentSizeBits;
222 }
223 return fileSizeBytes * Byte.SIZE;
224 }
225
226 private long computeTsBegin() {
227 Long tsBegin = (Long) fAttributes.get(CTFStrings.TIMESTAMP_BEGIN);
228 /* Read the begin timestamp */
229 if (tsBegin != null) {
230 return tsBegin.longValue();
231 }
232 return 0;
233 }
234
235 private long computeTsEnd() {
236 Long tsEnd = (Long) fAttributes.get(CTFStrings.TIMESTAMP_END);
237 /* Read the end timestamp */
238 if (tsEnd != null) {
239 // check if tsEnd == unsigned long max value
240 if (tsEnd == -1) {
241 return Long.MAX_VALUE;
242 }
243 return tsEnd.longValue();
244 }
245 return Long.MAX_VALUE;
246 }
247
248 private long computeLostEvents(long lostSoFar) {
249 Long lostEvents = (Long) fAttributes.get(CTFStrings.EVENTS_DISCARDED);
250 if (lostEvents != null) {
251 return lostEvents - lostSoFar;
252 }
253 return 0;
254 }
255
256 private static class Target {
257 public String string;
258 public long number;
259
260 public Target() {
261 string = null;
262 number = IPacketReader.UNKNOWN_CPU;
263 }
264 }
265
266 private Target lookupTarget(StructDefinition streamPacketContextDef) {
267 Target ret = new Target();
268 boolean hasDevice = fAttributes.containsKey(CTFStrings.DEVICE);
269 if (hasDevice) {
270 IDefinition def = streamPacketContextDef.lookupDefinition(CTFStrings.DEVICE);
271 if (def instanceof SimpleDatatypeDefinition) {
272 SimpleDatatypeDefinition simpleDefinition = (SimpleDatatypeDefinition) def;
273 ret.string = simpleDefinition.getStringValue();
274 ret.number = simpleDefinition.getIntegerValue();
275 } else if (def instanceof StringDefinition) {
276 StringDefinition stringDefinition = (StringDefinition) def;
277 ret.string = stringDefinition.getValue();
278 final Matcher matcher = NUMBER_PATTERN.matcher(ret.string);
279 if (matcher.matches()) {
280 String number = matcher.group(1);
281 ret.number = Integer.parseInt(number);
282 }
283 }
284 } else {
285 Long cpuId = (Long) fAttributes.get(CTFStrings.CPU_ID);
286 if (cpuId != null) {
287 ret.string = ("CPU" + cpuId.toString()); //$NON-NLS-1$
288 ret.number = cpuId;
289 }
290 }
291 return ret;
292 }
293
294 // ------------------------------------------------------------------------
295 // Operations
296 // ------------------------------------------------------------------------
297
298 @Override
299 public boolean includes(long ts) {
300 return (ts >= fTimestampBegin) && (ts <= fTimestampEnd);
301 }
302
303 @Override
304 public String toString() {
305 return "StreamInputPacketIndexEntry [offsetBits=" + fOffsetBits //$NON-NLS-1$
306 + ", timestampBegin=" + fTimestampBegin + ", timestampEnd=" //$NON-NLS-1$ //$NON-NLS-2$
307 + fTimestampEnd + "]"; //$NON-NLS-1$
308 }
309
310 // ------------------------------------------------------------------------
311 // Getters and Setters
312 // ------------------------------------------------------------------------
313
314 @Override
315 public long getOffsetBits() {
316 return fOffsetBits;
317 }
318
319 @Override
320 public long getPacketSizeBits() {
321 return fPacketSizeBits;
322 }
323
324 @Override
325 public long getContentSizeBits() {
326 return fContentSizeBits;
327 }
328
329 @Override
330 public long getTimestampBegin() {
331 return fTimestampBegin;
332 }
333
334 @Override
335 public long getTimestampEnd() {
336 return fTimestampEnd;
337 }
338
339 @Override
340 public long getLostEvents() {
341 return fLostEvents;
342 }
343
344 @Override
345 public Map<String, Object> getAttributes() {
346 return fAttributes;
347 }
348
349 @Override
350 public String getTarget() {
351 return fTarget;
352 }
353
354 @Override
355 public long getTargetId() {
356 return fTargetID;
357 }
358
359 @Override
360 public long getOffsetBytes() {
361 return fOffsetBytes;
362 }
363
364 @Override
365 public long getPayloadStartBits() {
366 return fEndPacketHeaderBits;
367 }
368 }
This page took 0.046878 seconds and 5 git commands to generate.