1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Ericsson
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
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
15 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFReaderException
;
16 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFTraceReader
;
17 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.StreamInputReader
;
18 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.Activator
;
19 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.location
.ITmfLocation
;
23 * The CTF trace reader iterator.
25 * It doesn't reserve a file handle, so many iterators can be used without
26 * worries of I/O errors or resource exhaustion.
28 * @author Matthew Khouzam
30 public class CtfIterator
extends CTFTraceReader
31 implements ITmfContext
, Comparable
<CtfIterator
> {
33 /** An invalid location */
34 public static final CtfLocation NULL_LOCATION
= new CtfLocation(CtfLocation
.INVALID_LOCATION
);
36 private final CtfTmfTrace fTrace
;
38 private CtfLocation fCurLocation
;
39 private long fCurRank
;
41 // ------------------------------------------------------------------------
43 // ------------------------------------------------------------------------
46 * Create a new CTF trace iterator, which initially points at the first
50 * The trace to iterate over
51 * @throws CTFReaderException
52 * If the iterator couldn't not be instantiated, probably due to
55 public CtfIterator(CtfTmfTrace trace
) throws CTFReaderException
{
56 super(trace
.getCTFTrace());
58 if (this.hasMoreEvents()) {
59 fCurLocation
= new CtfLocation(trace
.getStartTime());
67 * Create a new CTF trace iterator, which will initially point to the given
71 * The trace to iterate over
72 * @param ctfLocationData
73 * The initial timestamp the iterator will be pointing to
76 * @throws CTFReaderException
77 * If the iterator couldn't not be instantiated, probably due to
81 public CtfIterator(CtfTmfTrace trace
, CtfLocationInfo ctfLocationData
, long rank
)
82 throws CTFReaderException
{
83 super(trace
.getCTFTrace());
86 if (this.hasMoreEvents()) {
87 this.fCurLocation
= new CtfLocation(ctfLocationData
);
88 if (this.getCurrentEvent().getTimestamp().getValue() != ctfLocationData
.getTimestamp()) {
89 this.seek(ctfLocationData
);
97 private void setUnknownLocation() {
98 fCurLocation
= NULL_LOCATION
;
99 fCurRank
= UNKNOWN_RANK
;
102 // ------------------------------------------------------------------------
104 // ------------------------------------------------------------------------
107 * Return this iterator's trace.
109 * @return CtfTmfTrace The iterator's trace
111 public CtfTmfTrace
getCtfTmfTrace() {
116 * Return the current event pointed to by the iterator.
118 * @return CtfTmfEvent The current event
120 public CtfTmfEvent
getCurrentEvent() {
121 final StreamInputReader top
= super.getPrio().peek();
123 return CtfTmfEventFactory
.createEvent(top
.getCurrentEvent(),
124 top
.getFilename(), fTrace
);
130 * Seek this iterator to a given location.
132 * @param ctfLocationData
133 * The LocationData representing the position to seek to
134 * @return boolean True if the seek was successful, false if there was an
138 public synchronized boolean seek(CtfLocationInfo ctfLocationData
) {
141 /* Avoid the cost of seeking at the current location. */
142 if (fCurLocation
.getLocationInfo().equals(ctfLocationData
)) {
143 return super.hasMoreEvents();
146 /* Adjust the timestamp depending on the trace's offset */
147 long currTimestamp
= ctfLocationData
.getTimestamp();
148 final long offsetTimestamp
= this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp
);
150 if (offsetTimestamp
< 0) {
151 ret
= super.seek(0L);
153 ret
= super.seek(offsetTimestamp
);
155 } catch (CTFReaderException e
) {
156 Activator
.logError(e
.getMessage(), e
);
160 * Check if there is already one or more events for that timestamp, and
161 * assign the location index correctly
164 final CtfTmfEvent currentEvent
= this.getCurrentEvent();
165 if (currentEvent
!= null) {
166 currTimestamp
= currentEvent
.getTimestamp().getValue();
168 for (long i
= 0; i
< ctfLocationData
.getIndex(); i
++) {
169 if (currTimestamp
== currentEvent
.getTimestamp().getValue()) {
179 /* Seek the current location accordingly */
181 fCurLocation
= new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index
));
183 fCurLocation
= NULL_LOCATION
;
189 // ------------------------------------------------------------------------
191 // ------------------------------------------------------------------------
194 public boolean seek(long timestamp
) {
195 return seek(new CtfLocationInfo(timestamp
, 0));
199 public synchronized boolean advance() {
200 long index
= fCurLocation
.getLocationInfo().getIndex();
201 long timestamp
= fCurLocation
.getLocationInfo().getTimestamp();
204 ret
= super.advance();
205 } catch (CTFReaderException e
) {
206 Activator
.logError(e
.getMessage(), e
);
210 final long timestampValue
= getCurrentEvent().getTimestamp().getValue();
211 if (timestamp
== timestampValue
) {
212 fCurLocation
= new CtfLocation(timestampValue
, index
+ 1);
214 fCurLocation
= new CtfLocation(timestampValue
, 0L);
217 fCurLocation
= NULL_LOCATION
;
222 // ------------------------------------------------------------------------
224 // ------------------------------------------------------------------------
227 public long getRank() {
232 public void setRank(long rank
) {
237 public void increaseRank() {
238 /* Only increase the rank if it's valid */
239 if (hasValidRank()) {
245 public boolean hasValidRank() {
246 return (getRank() >= 0);
253 public void setLocation(ITmfLocation location
) {
254 // FIXME alex: isn't there a cleaner way than a cast here?
255 fCurLocation
= (CtfLocation
) location
;
256 seek(((CtfLocation
) location
).getLocationInfo());
260 public CtfLocation
getLocation() {
264 // ------------------------------------------------------------------------
266 // ------------------------------------------------------------------------
269 public int compareTo(final CtfIterator o
) {
270 if (this.getRank() < o
.getRank()) {
272 } else if (this.getRank() > o
.getRank()) {
278 // ------------------------------------------------------------------------
280 // ------------------------------------------------------------------------
283 public int hashCode() {
284 final int prime
= 31;
285 int result
= super.hashCode();
286 result
= (prime
* result
)
287 + ((fTrace
== null) ?
0 : fTrace
.hashCode());
288 result
= (prime
* result
)
289 + ((fCurLocation
== null) ?
0 : fCurLocation
.hashCode());
290 result
= (prime
* result
) + (int) (fCurRank ^
(fCurRank
>>> 32));
295 public boolean equals(Object obj
) {
299 if (!super.equals(obj
)) {
302 if (!(obj
instanceof CtfIterator
)) {
305 CtfIterator other
= (CtfIterator
) obj
;
306 if (fTrace
== null) {
307 if (other
.fTrace
!= null) {
310 } else if (!fTrace
.equals(other
.fTrace
)) {
313 if (fCurLocation
== null) {
314 if (other
.fCurLocation
!= null) {
317 } else if (!fCurLocation
.equals(other
.fCurLocation
)) {
320 if (fCurRank
!= other
.fCurRank
) {