1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
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
10 * Francois Chouinard - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.trace
;
15 import java
.io
.FileNotFoundException
;
16 import java
.io
.IOException
;
17 import java
.util
.Collections
;
18 import java
.util
.Vector
;
20 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
21 import org
.eclipse
.core
.runtime
.IStatus
;
22 import org
.eclipse
.core
.runtime
.Status
;
23 import org
.eclipse
.core
.runtime
.jobs
.Job
;
24 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
25 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
26 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
27 import org
.eclipse
.linuxtools
.tmf
.signal
.TmfSignalManager
;
30 * <b><u>TmfEventStream</u></b>
32 * TODO: Implement me. Please.
34 public abstract class TmfTrace
implements ITmfTrace
{
36 // ========================================================================
38 // ========================================================================
40 // The default number of events to cache
41 public static final int DEFAULT_CACHE_SIZE
= 1000;
43 // ========================================================================
45 // ========================================================================
48 private final String fName
;
51 private final ITmfEventParser fParser
;
54 private final int fCacheSize
;
56 // The set of event stream checkpoints (for random access)
57 private Vector
<TmfStreamCheckpoint
> fCheckpoints
= new Vector
<TmfStreamCheckpoint
>();
59 // The number of events collected
60 private int fNbEvents
= 0;
62 // The time span of the event stream
63 private TmfTimeRange fTimeRange
= new TmfTimeRange(TmfTimestamp
.BigBang
, TmfTimestamp
.BigBang
);
65 // ========================================================================
67 // ========================================================================
73 * @throws FileNotFoundException
75 protected TmfTrace(String filename
, ITmfEventParser parser
, int cacheSize
) throws FileNotFoundException
{
78 fCacheSize
= cacheSize
;
84 * @throws FileNotFoundException
86 protected TmfTrace(String filename
, ITmfEventParser parser
) throws FileNotFoundException
{
87 this(filename
, parser
, DEFAULT_CACHE_SIZE
);
90 // ========================================================================
92 // ========================================================================
97 public int getCacheSize() {
104 public String
getName() {
109 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getNbEvents()
111 public int getNbEvents() {
116 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getTimeRange()
118 public TmfTimeRange
getTimeRange() {
123 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getIndex(org.eclipse.linuxtools.tmf.event.TmfTimestamp)
125 public int getIndex(TmfTimestamp timestamp
) {
126 StreamContext context
= seekEvent(timestamp
);
127 return context
.index
;
131 * @see org.eclipse.linuxtools.tmf.stream.ITmfEventStream#getTimestamp(int)
133 public TmfTimestamp
getTimestamp(int index
) {
134 StreamContext context
= seekEvent(index
);
135 TmfEvent event
= peekEvent(context
);
136 return event
.getTimestamp();
139 // ========================================================================
141 // ========================================================================
143 public StreamContext
seekEvent(TmfTimestamp timestamp
) {
145 // First, find the right checkpoint
146 int index
= Collections
.binarySearch(fCheckpoints
, new TmfStreamCheckpoint(timestamp
, 0));
148 // In the very likely event that the checkpoint was not found, bsearch
149 // returns its negated would-be location (not an offset...). From that
150 // index, we can then position the stream and get the event.
152 index
= Math
.max(0, -(index
+ 2));
155 // Position the stream at the checkpoint
156 Object location
= (index
< fCheckpoints
.size()) ? fCheckpoints
.elementAt(index
).getLocation() : null;
157 StreamContext nextEventContext
;
159 nextEventContext
= seekLocation(location
);
161 StreamContext currentEventContext
= new StreamContext(nextEventContext
.location
, index
* fCacheSize
);
164 TmfEvent event
= getNextEvent(nextEventContext
);
165 while (event
!= null && event
.getTimestamp().compareTo(timestamp
, false) < 0) {
166 currentEventContext
.location
= nextEventContext
.location
;
167 currentEventContext
.index
++;
168 event
= getNextEvent(nextEventContext
);
171 return currentEventContext
;
174 public StreamContext
seekEvent(int position
) {
176 // Position the stream at the previous checkpoint
177 int index
= position
/ fCacheSize
;
178 Object location
= (index
< fCheckpoints
.size()) ? fCheckpoints
.elementAt(index
).getLocation() : null;
179 StreamContext nextEventContext
;
181 nextEventContext
= seekLocation(location
);
183 StreamContext currentEventContext
= new StreamContext(nextEventContext
);
185 // And locate the event (if it exists)
186 int current
= index
* fCacheSize
;
187 TmfEvent event
= getNextEvent(nextEventContext
);
188 while (event
!= null && current
< position
) {
189 currentEventContext
.location
= nextEventContext
.location
;
190 event
= getNextEvent(nextEventContext
);
194 return currentEventContext
;
197 public TmfEvent
peekEvent(StreamContext context
) {
198 StreamContext ctx
= new StreamContext(context
);
199 return getNextEvent(ctx
);
202 public TmfEvent
getEvent(StreamContext context
, TmfTimestamp timestamp
) {
204 // Position the stream and update the context object
205 StreamContext ctx
= seekEvent(timestamp
);
206 context
.location
= ctx
.location
;
208 return getNextEvent(context
);
211 public TmfEvent
getEvent(StreamContext context
, int position
) {
213 // Position the stream and update the context object
214 StreamContext ctx
= seekEvent(position
);
215 context
.location
= ctx
.location
;
217 return getNextEvent(context
);
220 public synchronized TmfEvent
getNextEvent(StreamContext context
) {
222 seekLocation(context
.location
);
223 TmfEvent event
= fParser
.getNextEvent(this);
224 context
.location
= getCurrentLocation();
226 } catch (IOException e
) {
232 private void notifyListeners(TmfTimeRange range
) {
233 TmfSignalManager
.dispatchSignal(new TmfStreamUpdatedSignal(this, this, range
));
237 * @see org.eclipse.linuxtools.tmf.eventlog.ITmfEventStream#indexStream()
239 public void indexStream(boolean waitForCompletion
) {
240 IndexingJob job
= new IndexingJob(fName
);
242 if (waitForCompletion
) {
245 } catch (InterruptedException e
) {
246 // TODO Auto-generated catch block
252 private class IndexingJob
extends Job
{
254 public IndexingJob(String name
) {
259 * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
262 protected IStatus
run(IProgressMonitor monitor
) {
265 TmfTimestamp startTime
= new TmfTimestamp();
266 TmfTimestamp lastTime
= new TmfTimestamp();
267 TmfTimestamp rangeStartTime
= new TmfTimestamp();
269 monitor
.beginTask("Indexing " + fName
, IProgressMonitor
.UNKNOWN
);
272 StreamContext nextEventContext
;
274 nextEventContext
= seekLocation(null);
276 StreamContext currentEventContext
= new StreamContext(nextEventContext
);
277 TmfEvent event
= getNextEvent(nextEventContext
);
279 startTime
= event
.getTimestamp();
280 lastTime
= event
.getTimestamp();
283 rangeStartTime
= startTime
;
284 while (event
!= null) {
285 lastTime
= event
.getTimestamp();
286 if ((nbEvents
++ % fCacheSize
) == 0) {
287 TmfStreamCheckpoint bookmark
= new TmfStreamCheckpoint(lastTime
, currentEventContext
.location
);
289 fCheckpoints
.add(bookmark
);
290 fNbEvents
= nbEvents
;
291 fTimeRange
= new TmfTimeRange(startTime
, lastTime
);
293 notifyListeners(new TmfTimeRange(rangeStartTime
, lastTime
));
295 // Check monitor *after* fCheckpoints has been updated
296 if (monitor
.isCanceled()) {
297 return Status
.CANCEL_STATUS
;
301 currentEventContext
.location
= nextEventContext
.location
;
302 event
= getNextEvent(nextEventContext
);
307 fNbEvents
= nbEvents
;
308 fTimeRange
= new TmfTimeRange(startTime
, lastTime
);
310 notifyListeners(new TmfTimeRange(rangeStartTime
, lastTime
));
314 return Status
.OK_STATUS
;