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