Refactor TmfTrace and dependencies - introduce ITmfTraceIndexer
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.core / src / org / eclipse / linuxtools / internal / lttng / core / trace / LTTngTextTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made 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:
10 * William Bourque (wbourque@gmail.com) - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.internal.lttng.core.trace;
14
15 import java.io.BufferedReader;
16 import java.io.FileReader;
17 import java.io.IOException;
18 import java.util.HashMap;
19
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent;
22 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventContent;
23 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventField;
24 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventType;
25 import org.eclipse.linuxtools.internal.lttng.core.event.LttngTimestamp;
26 import org.eclipse.linuxtools.lttng.jni.JniEvent;
27 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
28 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
29 import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
30 import org.eclipse.linuxtools.tmf.core.trace.TmfCheckpoint;
31 import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
32 import org.eclipse.linuxtools.tmf.core.trace.TmfLocation;
33 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
34
35 public class LTTngTextTrace extends TmfTrace<LttngEvent> {
36 private LttngTimestamp eventTimestamp = null;
37 private String eventSource = null;
38 private LttngEventType eventType = null;
39 private TextLttngEventContent eventContent = null;
40 private String eventReference = null;
41 // The actual event
42 private TextLttngEvent currentLttngEvent = null;
43
44 private HashMap<String, LttngEventType> traceTypes = null;
45
46 private String tracepath = ""; //$NON-NLS-1$
47 private FileReader fr = null;
48 private BufferedReader br = null;
49 private Long nbCharRead = 0L;
50
51 private int cpuNumber = -1;
52
53 private final boolean showDebug = false;
54
55 public LTTngTextTrace(final IResource resource, final String path) throws Exception {
56 this(resource, path, true); // false);
57 }
58
59 public LTTngTextTrace(final IResource resource, final String path, final boolean skipIndexing) throws Exception {
60 // super(null, LttngEvent.class, path, 1, !skipIndexing);
61 super(null, LttngEvent.class, path, 1);
62
63 tracepath = path;
64 traceTypes = new HashMap<String, LttngEventType>();
65
66 eventTimestamp = new LttngTimestamp();
67 eventSource = "Kernel Core"; //$NON-NLS-1$
68 eventType = new LttngEventType();
69 eventContent = new TextLttngEventContent(currentLttngEvent);
70 eventReference = getName();
71
72 currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference);
73 eventContent.setEvent(currentLttngEvent);
74
75 if ( positionToFirstEvent() == false )
76 throw new IOException("Fail to position to the beginning of the trace"); //$NON-NLS-1$
77 else {
78 fCacheSize = 1000;
79
80 // Skip indexing if asked
81 // if ( skipIndexing == true ) {
82 fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation<Long>(0L)));
83 // }
84 // else {
85 // indexTrace(true);
86 // }
87
88 final Long endTime = currentLttngEvent.getTimestamp().getValue();
89 positionToFirstEvent();
90
91 getNextEvent(new TmfContext(null, 0));
92 final Long starTime = currentLttngEvent.getTimestamp().getValue();
93 positionToFirstEvent();
94
95 setTimeRange( new TmfTimeRange( new LttngTimestamp(starTime),
96 new LttngTimestamp(endTime)
97 ) );
98 }
99 }
100
101
102 public LTTngTextTrace(final LTTngTextTrace oldTrace) throws Exception {
103 this(oldTrace.getResource(), oldTrace.getPath(), true);
104
105 // *** VERIFY ***
106 // Is this safe?
107 fCheckpoints = oldTrace.fCheckpoints;
108 }
109
110 private boolean positionToFirstEvent() {
111
112 boolean isSuccessful = true;
113
114 try {
115 if ( br != null ) {
116 br.close();
117 fr.close();
118 }
119
120 fr = new FileReader(tracepath);
121 br = new BufferedReader(fr);
122
123 // Skip the 2 lines header
124 br.readLine();
125 br.readLine();
126
127 // Make sure the event time is consistent
128 eventTimestamp.setValue(0L);
129 }
130 catch (final IOException e) {
131 isSuccessful = false;
132 }
133
134 return isSuccessful;
135 }
136
137 private void skipToPosition(final TmfLocation<Long> skip) {
138 try {
139 long skipPosition = skip.getLocation();
140 if ( skipPosition < 0 )
141 skipPosition = 0L;
142
143 if ( showDebug == true ) {
144 System.out.println("skipToPosition(Long skipPosition)"); //$NON-NLS-1$
145 System.out.println("\tSkipping to : " + skipPosition); //$NON-NLS-1$
146 System.out.println();
147 }
148 positionToFirstEvent();
149 final long nbSkipped = br.skip(skipPosition);
150 if ( nbSkipped != skipPosition)
151 throw new IOException("Too few characters skipped, positionning failed! (skipToPosition)"); //$NON-NLS-1$
152
153 nbCharRead = skipPosition;
154 }
155 catch (final Exception e) {
156 e.printStackTrace();
157 }
158 }
159
160 @Override
161 @SuppressWarnings("unchecked")
162 public TmfContext seekLocation(ITmfLocation<?> location) {
163 if (location == null)
164 location = new TmfLocation<Long>(0L);
165
166 if (!((TmfLocation<Long>) location).getLocation().equals(nbCharRead))
167 skipToPosition((TmfLocation<Long>) location);
168
169 final TmfContext tmpTraceContext = new TmfContext(location, 0L);
170
171 return tmpTraceContext;
172 }
173
174 @Override
175 public TmfContext seekLocation(final double ratio) {
176 // TODO Auto-generated method stub
177 return null;
178 }
179
180 @Override
181 public double getLocationRatio(final ITmfLocation<?> location) {
182 // TODO Auto-generated method stub
183 return 0;
184 }
185
186 private LttngEvent parseMyNextEvent(final ITmfContext context) {
187
188 // All parsing variables declared here so to be able to print them into the catch if needed
189 String tmpContent = null;
190 int tmpCurIndex = 0;
191 int tmpPrevIndex = 0;
192
193 String tracefile = ""; //$NON-NLS-1$
194 long tmpCpu = 0;
195 String marker = ""; //$NON-NLS-1$
196
197 long tmpSecond = 0;
198 long tmpNanosecond = 0;
199
200 String parsedPayload = ""; //$NON-NLS-1$
201 String markerName = ""; //$NON-NLS-1$
202 Object payload = ""; //$NON-NLS-1$
203
204 HashMap<String, LttngEventField> fieldsMap = null;
205
206 LttngEvent returnedEvent = null;
207
208 try {
209 tmpContent = br.readLine();
210
211 if (tmpContent != null) {
212 // *** NOTE :
213 // -1 is the skip the end of line (\n)
214 nbCharRead += (tmpContent.length()+1);
215
216 if ( (currentLttngEvent != null) && (currentLttngEvent.getContent().getMapContent() != null) )
217 currentLttngEvent.getContent().emptyContent();
218
219 // Tracefile and marker are first in the file
220 // Sound like :
221 // kernel.syscall_entry:
222 tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex); //$NON-NLS-1$
223
224 // *** HACK ***
225 // Evil exit case here : the two last line of the text dump does not contain "."
226 // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more
227 // Conclusion : this is ugly but fast.
228 if ( tmpCurIndex < 0 ) {
229 if ( showDebug == true ) {
230 System.out.println("END OF FILE."); //$NON-NLS-1$
231 System.out.println();
232 }
233 return null;
234 }
235
236 tracefile = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
237 /*System.out.println(tracefile);*/
238
239 tmpPrevIndex = tmpCurIndex;
240 tmpCurIndex = tmpContent.indexOf(":", tmpPrevIndex); //$NON-NLS-1$
241 marker = tmpContent.substring(tmpPrevIndex+1, tmpCurIndex ).trim();
242 /*System.out.println(marker);*/
243
244 // Timestamp is next but is presented in second.milisecond format, we have to split them
245 // Sound like :
246 // 952.162637168
247 tmpPrevIndex = tmpCurIndex+1;
248 tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex); //$NON-NLS-1$
249 tmpSecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
250 /*System.out.println(tmpSecond);*/
251
252 tmpPrevIndex = tmpCurIndex+1;
253 tmpCurIndex = tmpContent.indexOf(" ", tmpPrevIndex); //$NON-NLS-1$
254 tmpNanosecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
255 /*System.out.println(tmpNanosecond);*/
256
257 // We have enough information here to set the timestamp
258 eventTimestamp.setValue( (tmpSecond * 1000000000) + tmpNanosecond );
259 /*System.out.println(eventTimestamp.toString());*/
260
261 // Next field is the reference
262 // A long string enclosed by parenthesis and ending with a comma
263 // (/home/william/workspace/org.eclipse.linuxtools.lttng.tests/traceset/trace-618339events-1293lost-1cpu/kernel_0),
264 tmpPrevIndex = tmpCurIndex+1;
265 tmpCurIndex = tmpContent.indexOf("(", tmpPrevIndex); //$NON-NLS-1$
266 tmpPrevIndex = tmpCurIndex+1;
267 tmpCurIndex = tmpContent.indexOf("),", tmpPrevIndex); //$NON-NLS-1$
268 final String fullTracePath = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
269 /*System.out.println(fullTracePath);*/
270
271 final String traceName = fullTracePath.substring(fullTracePath.lastIndexOf("/")+1).trim(); //$NON-NLS-1$
272 /*System.out.println(traceName);*/
273 eventReference = traceName;
274 currentLttngEvent.setReference(traceName);
275
276
277 // The next few fields are relatives to the state system (pid, ppid, etc...) we need to skip them.
278 // They should be like the following :
279 // 4175, 4175, hal-acl-tool, , 4168,
280
281 // 1st comma
282 tmpPrevIndex = tmpCurIndex+1;
283 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
284 // 2nd comma
285 tmpPrevIndex = tmpCurIndex+1;
286 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
287 // 3rd comma
288 tmpPrevIndex = tmpCurIndex+1;
289 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
290 // 4th comma
291 tmpPrevIndex = tmpCurIndex+1;
292 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
293 // 5th comma
294 tmpPrevIndex = tmpCurIndex+1;
295 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
296 // 6th comma
297 tmpPrevIndex = tmpCurIndex+1;
298 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
299
300 // The next field is the CPU, in hexadecimal format
301 // Should be like :
302 // 0x0,
303 tmpPrevIndex = tmpCurIndex+1;
304 tmpCurIndex = tmpContent.indexOf("0x", tmpPrevIndex); //$NON-NLS-1$
305 tmpPrevIndex = tmpCurIndex+2;
306
307 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
308 tmpCpu = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
309
310 // Set the cpu number of trace if we found a "new" cpu
311 if ( cpuNumber < (tmpCpu + 1) )
312 cpuNumber = (int)(tmpCpu+1);
313
314
315 // The last field is the parsed content
316 // It is enclosed by { }
317 // Look like :
318 // SYSCALL { ip = 0xb7f05422, syscall_id = 221 [sys_fcntl64+0x0/0x79] }
319 //
320 // NOTE : it seems some state system events do not respect this format as they have no payload.
321 // We will create empty payload then.
322 final int tmpIndex = tmpContent.indexOf("{", tmpPrevIndex); //$NON-NLS-1$
323 if ( tmpIndex != -1 ) {
324 tmpPrevIndex = tmpCurIndex+1;
325 tmpCurIndex = tmpIndex;
326 tmpPrevIndex = tmpCurIndex+1;
327 tmpCurIndex = tmpContent.indexOf("}", tmpPrevIndex); //$NON-NLS-1$
328 parsedPayload = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
329
330 // Now add each LttngField
331 boolean isDone = false;
332 int tmpIndexBegin = 0;
333 int tmpIndexEqual = 0;
334 int tmpIndexEnd = 0;
335
336 fieldsMap = new HashMap<String, LttngEventField>();
337
338 while ( isDone == false ) {
339 tmpIndexEqual = parsedPayload.indexOf("=", tmpIndexBegin); //$NON-NLS-1$
340 tmpIndexEnd = parsedPayload.indexOf(", ", tmpIndexEqual); //$NON-NLS-1$
341 if ( tmpIndexEnd == -1 ) {
342 tmpIndexEnd = parsedPayload.length();
343 isDone = true;
344 }
345
346 markerName = parsedPayload.substring(tmpIndexBegin, tmpIndexEqual-1 ).trim();
347 payload = parsedPayload.substring(tmpIndexEqual+1, tmpIndexEnd ).replace("\"", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$
348
349 // Try to cast the payload into the correct type
350 try {
351 payload = Long.parseLong((String)payload);
352 }
353 catch (final NumberFormatException e) { }
354
355 final LttngEventField tmpField = new LttngEventField(markerName, payload);
356 fieldsMap.put(markerName, tmpField);
357
358 tmpIndexBegin = tmpIndexEnd+1;
359 }
360 }
361 else {
362 fieldsMap = new HashMap<String, LttngEventField>();
363
364 markerName = ""; //$NON-NLS-1$
365 payload = ""; //$NON-NLS-1$
366
367 final LttngEventField tmpField = new LttngEventField(markerName, payload);
368 fieldsMap.put(markerName, tmpField);
369 }
370
371 eventContent = new TextLttngEventContent(currentLttngEvent, fieldsMap);
372
373 // We now have what we need for the type
374 final String tmpTypeKey = tracefile + "/" + tmpCpu + "/" + marker; //$NON-NLS-1$ //$NON-NLS-2$
375 if ( traceTypes.get(tmpTypeKey) == null )
376 traceTypes.put(tmpTypeKey, new LttngEventType(tracefile, tmpCpu, marker, 0, fieldsMap.keySet().toArray(new String[fieldsMap.size()] )) );
377
378 currentLttngEvent.setContent(eventContent);
379 currentLttngEvent.setType(traceTypes.get(tmpTypeKey));
380
381 returnedEvent = currentLttngEvent;
382 }
383 else if ( showDebug == true ) {
384 System.out.println("NULL READING"); //$NON-NLS-1$
385 System.out.println();
386 returnedEvent = null;
387 }
388 }
389 catch (final Exception e) {
390 System.out.println("Pos is :" + nbCharRead); //$NON-NLS-1$
391 if ( tmpContent != null )
392 System.out.println("Erroneous content is :" + tmpContent); //$NON-NLS-1$
393
394 tmpContent = null;
395 e.printStackTrace();
396 returnedEvent = null;
397 }
398
399 return returnedEvent;
400 }
401
402 @Override
403 public ITmfLocation<?> getCurrentLocation() {
404 return new TmfLocation<Long>(nbCharRead);
405 }
406
407 @Override
408 public LttngEvent parseEvent(ITmfContext context) {
409 context = seekLocation(context.getLocation());
410 return parseMyNextEvent(context);
411
412 }
413
414 public int getCpuNumber() {
415 return cpuNumber;
416 }
417
418 }
419
420
421 // Redefine event to override method we know won't work with a Text tracefile
422 class TextLttngEvent extends LttngEvent {
423
424 public TextLttngEvent( final TmfTrace<LttngEvent> parent,
425 final LttngTimestamp timestamp,
426 final String source,
427 final LttngEventType type,
428 final LttngEventContent content,
429 final String reference)
430 {
431 super(parent, timestamp, source, type, content, reference, null);
432 }
433
434 @SuppressWarnings("unchecked")
435 public TextLttngEvent(final TextLttngEvent oldEvent) {
436 this(
437 (TmfTrace<LttngEvent>) oldEvent.getTrace(),
438 (LttngTimestamp)oldEvent.getTimestamp(),
439 oldEvent.getSource(),
440 oldEvent.getType(),
441 oldEvent.getContent(),
442 oldEvent.getReference()
443 );
444 }
445
446 @Override
447 public JniEvent convertEventTmfToJni() {
448 // System.out.println("WARNING : Cannot use convertEventTmfToJni() on a trace in text format."); //$NON-NLS-1$
449 return null;
450 }
451
452 @Override
453 public void updateJniEventReference(final JniEvent newJniEventReference) {
454 // System.out.println("WARNING : Cannot use updateJniEventReference on a trace in text format. Using null."); //$NON-NLS-1$
455 }
456 }
457
458
459 class TextLttngEventContent extends LttngEventContent {
460
461 public TextLttngEventContent() {
462 super();
463 }
464
465 public TextLttngEventContent(final TextLttngEvent thisParent) {
466 super(thisParent, null);
467 }
468
469 public TextLttngEventContent(final TextLttngEvent thisParent, final HashMap<String, LttngEventField> thisContent) {
470 super(thisParent, thisContent);
471 }
472
473 public TextLttngEventContent(final TextLttngEventContent oldContent) {
474 this(((TextLttngEvent) oldContent.getEvent()), oldContent.getMapContent());
475 }
476
477 @Override
478 public LttngEventField[] getFields() {
479 return getMapContent().values().toArray(new LttngEventField[getMapContent().size()]);
480 }
481
482 @Override
483 public LttngEventField getField(final String name) {
484 final LttngEventField returnedField = getMapContent().get(name);
485
486 return returnedField;
487 }
488
489 @Override
490 public LttngEventField getField(final int position) {
491 LttngEventField returnedField = null;
492 String label = null;
493 // try {
494 label = getEvent().getType().getFieldName(position);
495 returnedField = this.getField(label);
496 // }
497 // catch (TmfNoSuchFieldException e) {
498 // System.out.println("Invalid field position requested : " + position + ", ignoring (getField)."); //$NON-NLS-1$ //$NON-NLS-2$
499 // }
500
501 return returnedField;
502 }
503 }
This page took 0.134944 seconds and 5 git commands to generate.