Merge branch 'master' into lttng-kepler
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfTrace.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2012 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 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Updated as per TMF Trace Model 1.0
12 *******************************************************************************/
13
14 package org.eclipse.linuxtools.tmf.core.trace;
15
16 import java.io.File;
17
18 import org.eclipse.core.resources.IResource;
19 import org.eclipse.core.runtime.CoreException;
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
22 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
23 import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
24 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
25 import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
26 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
27 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
28 import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
29 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
30 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
31 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
32 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
33 import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
34 import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics;
35
36 /**
37 * Abstract implementation of ITmfTrace.
38 * <p>
39 * Since the concept of 'location' is trace specific, the concrete classes have
40 * to provide the related methods, namely:
41 * <ul>
42 * <li> public ITmfLocation<?> getCurrentLocation()
43 * <li> public double getLocationRatio(ITmfLocation<?> location)
44 * <li> public ITmfContext seekEvent(ITmfLocation<?> location)
45 * <li> public ITmfContext seekEvent(double ratio)
46 * <li> public boolean validate(IProject project, String path)
47 * </ul>
48 * A concrete trace must provide its corresponding parser. A common way to
49 * accomplish this is by making the concrete class extend TmfTrace and
50 * implement ITmfEventParser.
51 * <p>
52 * The concrete class can either specify its own indexer or use the provided
53 * TmfCheckpointIndexer (default). In this case, the trace cache size will be
54 * used as checkpoint interval.
55 *
56 * @version 1.0
57 * @author Francois Chouinard
58 *
59 * @see ITmfEvent
60 * @see ITmfTraceIndexer
61 * @see ITmfEventParser
62 */
63 public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
64
65 // ------------------------------------------------------------------------
66 // Attributes
67 // ------------------------------------------------------------------------
68
69 // The resource used for persistent properties for this trace
70 private IResource fResource;
71
72 // The trace path
73 private String fPath;
74
75 // The trace cache page size
76 private int fCacheSize = ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
77
78 // The number of events collected (so far)
79 private long fNbEvents = 0;
80
81 // The time span of the event stream
82 private ITmfTimestamp fStartTime = TmfTimestamp.BIG_BANG;
83 private ITmfTimestamp fEndTime = TmfTimestamp.BIG_BANG;
84
85 // The trace streaming interval (0 = no streaming)
86 private long fStreamingInterval = 0;
87
88 // The trace indexer
89 private ITmfTraceIndexer fIndexer;
90
91 // The trace parser
92 private ITmfEventParser fParser;
93
94 // The trace's statistics
95 private ITmfStatistics fStatistics;
96
97 // ------------------------------------------------------------------------
98 // Construction
99 // ------------------------------------------------------------------------
100
101 /**
102 * The default, parameterless, constructor
103 */
104 public TmfTrace() {
105 super();
106 }
107
108 /**
109 * The standard constructor (non-live trace). Applicable when the trace
110 * implements its own parser and if at checkpoint-based index is OK.
111 *
112 * @param resource the resource associated to the trace
113 * @param type the trace event type
114 * @param path the trace path
115 * @param cacheSize the trace cache size
116 * @throws TmfTraceException If something failed during the opening
117 */
118 protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize) throws TmfTraceException {
119 this(resource, type, path, cacheSize, 0);
120 }
121
122 /**
123 * The standard constructor (live trace). Applicable when the trace
124 * implements its own parser and if at checkpoint-based index is OK.
125 *
126 * @param resource the resource associated to the trace
127 * @param type the trace event type
128 * @param path the trace path
129 * @param cacheSize the trace cache size
130 * @param interval the trace streaming interval
131 * @throws TmfTraceException If something failed during the opening
132 */
133 protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize, final long interval) throws TmfTraceException {
134 this(resource, type, path, cacheSize, interval, null);
135 }
136
137 /**
138 * The 'non-default indexer' constructor. Allows to provide a trace
139 * specific indexer.
140 *
141 * @param resource the resource associated to the trace
142 * @param type the trace event type
143 * @param path the trace path
144 * @param cacheSize the trace cache size
145 * @param interval the trace streaming interval
146 * @param indexer the trace indexer
147 * @throws TmfTraceException If something failed during the opening
148 */
149 protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize,
150 final long interval, final ITmfTraceIndexer indexer) throws TmfTraceException {
151 this(resource, type, path, cacheSize, interval, indexer, null);
152 }
153
154 /**
155 * The full constructor where trace specific indexer/parser are provided.
156 *
157 * @param resource the resource associated to the trace
158 * @param type the trace event type
159 * @param path the trace path
160 * @param cacheSize the trace cache size
161 * @param interval the trace streaming interval
162 * @param indexer the trace indexer
163 * @param parser the trace event parser
164 * @throws TmfTraceException If something failed during the opening
165 */
166 protected TmfTrace(final IResource resource, final Class<? extends ITmfEvent> type, final String path, final int cacheSize,
167 final long interval, final ITmfTraceIndexer indexer, final ITmfEventParser parser) throws TmfTraceException {
168 super();
169 fCacheSize = (cacheSize > 0) ? cacheSize : ITmfTrace.DEFAULT_TRACE_CACHE_SIZE;
170 fStreamingInterval = interval;
171 fIndexer = (indexer != null) ? indexer : new TmfCheckpointIndexer(this, fCacheSize);
172 fParser = parser;
173 initialize(resource, path, type);
174 }
175
176 /**
177 * Copy constructor
178 *
179 * @param trace the original trace
180 * @throws TmfTraceException Should not happen usually
181 */
182 public TmfTrace(final TmfTrace trace) throws TmfTraceException {
183 super();
184 if (trace == null) {
185 throw new IllegalArgumentException();
186 }
187 fCacheSize = trace.getCacheSize();
188 fStreamingInterval = trace.getStreamingInterval();
189 fIndexer = new TmfCheckpointIndexer(this);
190 fParser = trace.fParser;
191 initialize(trace.getResource(), trace.getPath(), trace.getEventType());
192 }
193
194 // ------------------------------------------------------------------------
195 // ITmfTrace - Initializers
196 // ------------------------------------------------------------------------
197
198 /* (non-Javadoc)
199 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#initTrace(org.eclipse.core.resources.IResource, java.lang.String, java.lang.Class)
200 */
201 @Override
202 public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
203 fIndexer = new TmfCheckpointIndexer(this, fCacheSize);
204 initialize(resource, path, type);
205 }
206
207 /**
208 * Initialize the trace common attributes and the base component.
209 *
210 * @param resource the Eclipse resource (trace)
211 * @param path the trace path
212 * @param type the trace event type
213 *
214 * @throws TmfTraceException If something failed during the initialization
215 */
216 protected void initialize(final IResource resource, final String path, final Class<? extends ITmfEvent> type) throws TmfTraceException {
217 if (path == null) {
218 throw new TmfTraceException("Invalid trace path"); //$NON-NLS-1$
219 }
220 fPath = path;
221 fResource = resource;
222 String traceName = (resource != null) ? resource.getName() : null;
223 // If no resource was provided, extract the display name the trace path
224 if (traceName == null) {
225 final int sep = path.lastIndexOf(IPath.SEPARATOR);
226 traceName = (sep >= 0) ? path.substring(sep + 1) : path;
227 }
228 if (fParser == null) {
229 if (this instanceof ITmfEventParser) {
230 fParser = (ITmfEventParser) this;
231 } else {
232 throw new TmfTraceException("Invalid trace parser"); //$NON-NLS-1$
233 }
234 }
235 super.init(traceName, type);
236 }
237
238 /**
239 * Indicates if the path points to an existing file/directory
240 *
241 * @param path the path to test
242 * @return true if the file/directory exists
243 */
244 protected boolean fileExists(final String path) {
245 final File file = new File(path);
246 return file.exists();
247 }
248
249 /**
250 * Index the trace
251 *
252 * @param waitForCompletion index synchronously (true) or not (false)
253 */
254 protected void indexTrace(boolean waitForCompletion) {
255 getIndexer().buildIndex(0, TmfTimeRange.ETERNITY, waitForCompletion);
256 }
257
258 /**
259 * The default implementation of TmfTrace uses a TmfStatistics back-end.
260 * Override this if you want to specify another type (or none at all).
261 *
262 * @throws TmfTraceException
263 * If there was a problem setting up the statistics
264 * @since 2.0
265 */
266 protected void buildStatistics() throws TmfTraceException {
267 /*
268 * Initialize the statistics provider, but only if a Resource has been
269 * set (so we don't build it for experiments, for unit tests, etc.)
270 */
271 fStatistics = (fResource == null ? null : new TmfStateStatistics(this) );
272 }
273
274 /**
275 * Build the state system(s) associated with this trace type.
276 *
277 * Suppressing the warning, because the 'throws' will usually happen in
278 * sub-classes.
279 *
280 * @throws TmfTraceException
281 * If there is a problem during the build
282 * @since 2.0
283 */
284 @SuppressWarnings("unused")
285 protected void buildStateSystem() throws TmfTraceException {
286 /*
287 * Nothing is done in the base implementation, please specify
288 * how/if to build a state system in derived classes.
289 */
290 return;
291 }
292
293 /**
294 * Clears the trace
295 */
296 @Override
297 public synchronized void dispose() {
298 /* Clean up the index if applicable */
299 if (getIndexer() != null) {
300 getIndexer().dispose();
301 }
302
303 /* Clean up the statistics */
304 if (fStatistics != null) {
305 fStatistics.dispose();
306 }
307 super.dispose();
308 }
309
310 // ------------------------------------------------------------------------
311 // ITmfTrace - Basic getters
312 // ------------------------------------------------------------------------
313
314 /* (non-Javadoc)
315 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEventType()
316 */
317 @Override
318 public Class<ITmfEvent> getEventType() {
319 return (Class<ITmfEvent>) super.getType();
320 }
321
322 /* (non-Javadoc)
323 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getResource()
324 */
325 @Override
326 public IResource getResource() {
327 return fResource;
328 }
329
330 /* (non-Javadoc)
331 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getPath()
332 */
333 @Override
334 public String getPath() {
335 return fPath;
336 }
337
338 /* (non-Javadoc)
339 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getIndexPageSize()
340 */
341 @Override
342 public int getCacheSize() {
343 return fCacheSize;
344 }
345
346 /* (non-Javadoc)
347 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStreamingInterval()
348 */
349 @Override
350 public long getStreamingInterval() {
351 return fStreamingInterval;
352 }
353
354 /**
355 * @return the trace indexer
356 */
357 protected ITmfTraceIndexer getIndexer() {
358 return fIndexer;
359 }
360
361 /**
362 * @return the trace parser
363 */
364 protected ITmfEventParser getParser() {
365 return fParser;
366 }
367
368 /**
369 * @since 2.0
370 */
371 @Override
372 public ITmfStatistics getStatistics() {
373 return fStatistics;
374 }
375
376 /**
377 * @since 2.0
378 */
379 @Override
380 public ITmfStateSystem getStateSystem() {
381 /*
382 * By default, no state system is used. Sub-classes can specify their
383 * own behaviour.
384 */
385 return null;
386 }
387
388 // ------------------------------------------------------------------------
389 // ITmfTrace - Trace characteristics getters
390 // ------------------------------------------------------------------------
391
392 /* (non-Javadoc)
393 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNbEvents()
394 */
395 @Override
396 public synchronized long getNbEvents() {
397 return fNbEvents;
398 }
399
400 /* (non-Javadoc)
401 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getTimeRange()
402 */
403 @Override
404 public TmfTimeRange getTimeRange() {
405 return new TmfTimeRange(fStartTime, fEndTime);
406 }
407
408 /* (non-Javadoc)
409 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getStartTime()
410 */
411 @Override
412 public ITmfTimestamp getStartTime() {
413 return fStartTime;
414 }
415
416 /* (non-Javadoc)
417 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getEndTime()
418 */
419 @Override
420 public ITmfTimestamp getEndTime() {
421 return fEndTime;
422 }
423
424 // ------------------------------------------------------------------------
425 // Convenience setters/getters
426 // ------------------------------------------------------------------------
427
428 /**
429 * Set the trace cache size. Must be done at initialization time.
430 *
431 * @param cacheSize The trace cache size
432 */
433 protected void setCacheSize(final int cacheSize) {
434 fCacheSize = cacheSize;
435 }
436
437 /**
438 * Set the trace known number of events. This can be quite dynamic
439 * during indexing or for live traces.
440 *
441 * @param nbEvents The number of events
442 */
443 protected synchronized void setNbEvents(final long nbEvents) {
444 fNbEvents = (nbEvents > 0) ? nbEvents : 0;
445 }
446
447 /**
448 * Update the trace events time range
449 *
450 * @param range the new time range
451 */
452 protected void setTimeRange(final TmfTimeRange range) {
453 fStartTime = range.getStartTime();
454 fEndTime = range.getEndTime();
455 }
456
457 /**
458 * Update the trace chronologically first event timestamp
459 *
460 * @param startTime the new first event timestamp
461 */
462 protected void setStartTime(final ITmfTimestamp startTime) {
463 fStartTime = startTime;
464 }
465
466 /**
467 * Update the trace chronologically last event timestamp
468 *
469 * @param endTime the new last event timestamp
470 */
471 protected void setEndTime(final ITmfTimestamp endTime) {
472 fEndTime = endTime;
473 }
474
475 /**
476 * Set the polling interval for live traces (default = 0 = no streaming).
477 *
478 * @param interval the new trace streaming interval
479 */
480 protected void setStreamingInterval(final long interval) {
481 fStreamingInterval = (interval > 0) ? interval : 0;
482 }
483
484 /**
485 * Set the trace indexer. Must be done at initialization time.
486 *
487 * @param indexer the trace indexer
488 */
489 protected void setIndexer(final ITmfTraceIndexer indexer) {
490 fIndexer = indexer;
491 }
492
493 /**
494 * Set the trace parser. Must be done at initialization time.
495 *
496 * @param parser the new trace parser
497 */
498 protected void setParser(final ITmfEventParser parser) {
499 fParser = parser;
500 }
501
502 // ------------------------------------------------------------------------
503 // ITmfTrace - SeekEvent operations (returning a trace context)
504 // ------------------------------------------------------------------------
505
506 /* (non-Javadoc)
507 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(long)
508 */
509 @Override
510 public synchronized ITmfContext seekEvent(final long rank) {
511
512 // A rank <= 0 indicates to seek the first event
513 if (rank <= 0) {
514 ITmfContext context = seekEvent((ITmfLocation) null);
515 context.setRank(0);
516 return context;
517 }
518
519 // Position the trace at the checkpoint
520 final ITmfContext context = fIndexer.seekIndex(rank);
521
522 // And locate the requested event context
523 long pos = context.getRank();
524 if (pos < rank) {
525 ITmfEvent event = getNext(context);
526 while ((event != null) && (++pos < rank)) {
527 event = getNext(context);
528 }
529 }
530 return context;
531 }
532
533 /* (non-Javadoc)
534 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
535 */
536 @Override
537 public synchronized ITmfContext seekEvent(final ITmfTimestamp timestamp) {
538
539 // A null timestamp indicates to seek the first event
540 if (timestamp == null) {
541 ITmfContext context = seekEvent((ITmfLocation) null);
542 context.setRank(0);
543 return context;
544 }
545
546 // Position the trace at the checkpoint
547 ITmfContext context = fIndexer.seekIndex(timestamp);
548
549 // And locate the requested event context
550 final ITmfContext nextEventContext = context.clone(); // Must use clone() to get the right subtype...
551 ITmfEvent event = getNext(nextEventContext);
552 while (event != null && event.getTimestamp().compareTo(timestamp, false) < 0) {
553 context.dispose();
554 context = nextEventContext.clone();
555 event = getNext(nextEventContext);
556 }
557 nextEventContext.dispose();
558 if (event == null) {
559 context.setLocation(null);
560 context.setRank(ITmfContext.UNKNOWN_RANK);
561 }
562 return context;
563 }
564
565 // ------------------------------------------------------------------------
566 // ITmfTrace - Read operations (returning an actual event)
567 // ------------------------------------------------------------------------
568
569 /* (non-Javadoc)
570 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#readNextEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
571 */
572 @Override
573 public synchronized ITmfEvent getNext(final ITmfContext context) {
574 // parseEvent() does not update the context
575 final ITmfEvent event = fParser.parseEvent(context);
576 if (event != null) {
577 updateAttributes(context, event.getTimestamp());
578 context.setLocation(getCurrentLocation());
579 context.increaseRank();
580 processEvent(event);
581 }
582 return event;
583 }
584
585 /**
586 * Hook for special event processing by the concrete class
587 * (called by TmfTrace.getEvent())
588 *
589 * @param event the event
590 */
591 protected void processEvent(final ITmfEvent event) {
592 // Do nothing
593 }
594
595 /**
596 * Update the trace attributes
597 *
598 * @param context the current trace context
599 * @param timestamp the corresponding timestamp
600 */
601 protected synchronized void updateAttributes(final ITmfContext context, final ITmfTimestamp timestamp) {
602 if (fStartTime.equals(TmfTimestamp.BIG_BANG) || (fStartTime.compareTo(timestamp, false) > 0)) {
603 fStartTime = timestamp;
604 }
605 if (fEndTime.equals(TmfTimestamp.BIG_CRUNCH) || (fEndTime.compareTo(timestamp, false) < 0)) {
606 fEndTime = timestamp;
607 }
608 if (context.hasValidRank()) {
609 long rank = context.getRank();
610 if (fNbEvents <= rank) {
611 fNbEvents = rank + 1;
612 }
613 if (fIndexer != null) {
614 fIndexer.updateIndex(context, timestamp);
615 }
616 }
617 }
618
619 // ------------------------------------------------------------------------
620 // TmfDataProvider
621 // ------------------------------------------------------------------------
622
623 /* (non-Javadoc)
624 * @see org.eclipse.linuxtools.tmf.core.component.TmfDataProvider#armRequest(org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest)
625 */
626 @Override
627 protected synchronized ITmfContext armRequest(final ITmfDataRequest request) {
628 if (executorIsShutdown()) {
629 return null;
630 }
631 if ((request instanceof ITmfEventRequest)
632 && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest) request).getRange().getStartTime())
633 && (request.getIndex() == 0))
634 {
635 final ITmfContext context = seekEvent(((ITmfEventRequest) request).getRange().getStartTime());
636 ((ITmfEventRequest) request).setStartIndex((int) context.getRank());
637 return context;
638
639 }
640 return seekEvent(request.getIndex());
641 }
642
643 // ------------------------------------------------------------------------
644 // Signal handlers
645 // ------------------------------------------------------------------------
646
647 /**
648 * Handler for the Trace Opened signal
649 *
650 * @param signal
651 * The incoming signal
652 * @since 2.0
653 */
654 @TmfSignalHandler
655 public void traceOpened(TmfTraceOpenedSignal signal) {
656 ITmfTrace trace = signal.getTrace();
657 if (signal.getTrace() instanceof TmfExperiment) {
658 TmfExperiment experiment = (TmfExperiment) signal.getTrace();
659 for (ITmfTrace expTrace : experiment.getTraces()) {
660 if (expTrace == this) {
661 trace = expTrace;
662 break;
663 }
664 }
665 }
666 if (signal.getTrace() == this || trace == this) {
667 /* the signal is for this trace or experiment or for an experiment containing this trace */
668
669 /* ensure start time is set */
670 final ITmfContext context = seekEvent(0);
671 getNext(context);
672 context.dispose();
673 }
674 if (trace == this) {
675 /* the signal is for this trace or for an experiment containing this trace */
676 try {
677 buildStatistics();
678 } catch (TmfTraceException e) {
679 e.printStackTrace();
680 }
681 try {
682 buildStateSystem();
683 } catch (TmfTraceException e) {
684 e.printStackTrace();
685 }
686
687 /* Refresh the project, so it can pick up new files that got created. */
688 try {
689 if (fResource != null) {
690 fResource.getProject().refreshLocal(IResource.DEPTH_INFINITE, null);
691 }
692 } catch (CoreException e) {
693 e.printStackTrace();
694 }
695 }
696 if (signal.getTrace() == this) {
697 /* the signal is for this trace or experiment */
698 if (getNbEvents() == 0) {
699 return;
700 }
701
702 final TmfTimeRange timeRange = new TmfTimeRange(getStartTime(), TmfTimestamp.BIG_CRUNCH);
703 final TmfTraceRangeUpdatedSignal rangeUpdatedsignal = new TmfTraceRangeUpdatedSignal(this, this, timeRange);
704
705 // Broadcast in separate thread to prevent deadlock
706 new Thread() {
707 @Override
708 public void run() {
709 broadcast(rangeUpdatedsignal);
710 }
711 }.start();
712 return;
713 }
714 }
715
716 /**
717 * Signal handler for the TmfTraceRangeUpdatedSignal signal
718 *
719 * @param signal The incoming signal
720 * @since 2.0
721 */
722 @TmfSignalHandler
723 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
724 if (signal.getTrace() == this) {
725 getIndexer().buildIndex(getNbEvents(), signal.getRange(), false);
726 }
727 }
728
729 // ------------------------------------------------------------------------
730 // toString
731 // ------------------------------------------------------------------------
732
733 /* (non-Javadoc)
734 * @see java.lang.Object#toString()
735 */
736 @Override
737 @SuppressWarnings("nls")
738 public synchronized String toString() {
739 return "TmfTrace [fPath=" + fPath + ", fCacheSize=" + fCacheSize
740 + ", fNbEvents=" + fNbEvents + ", fStartTime=" + fStartTime
741 + ", fEndTime=" + fEndTime + ", fStreamingInterval=" + fStreamingInterval + "]";
742 }
743
744 }
This page took 0.048133 seconds and 6 git commands to generate.