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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
11 package org
.eclipse
.linuxtools
.tmf
.core
.ctfadaptor
;
13 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.CTFTraceReader
;
14 import org
.eclipse
.linuxtools
.ctf
.core
.trace
.StreamInputReader
;
15 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfContext
;
16 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.location
.ITmfLocation
;
19 * The CTF trace reader iterator.
21 * It doesn't reserve a file handle, so many iterators can be used without worries
22 * of I/O errors or resource exhaustion.
25 * @author Matthew Khouzam
27 public class CtfIterator
extends CTFTraceReader
implements ITmfContext
,
28 Comparable
<CtfIterator
> {
30 private final CtfTmfTrace ctfTmfTrace
;
35 final public static CtfLocation NULL_LOCATION
= new CtfLocation(CtfLocation
.INVALID_LOCATION
);
37 private CtfLocation curLocation
;
41 * Create a new CTF trace iterator, which initially points at the first
45 * the trace to iterate over
47 public CtfIterator(final CtfTmfTrace trace
) {
48 super(trace
.getCTFTrace());
49 this.ctfTmfTrace
= trace
;
50 if (this.hasMoreEvents()) {
51 this.curLocation
= new CtfLocation(trace
.getStartTime());
58 private void setUnknownLocation() {
59 this.curLocation
= NULL_LOCATION
;
60 this.curRank
= UNKNOWN_RANK
;
64 * Constructor for CtfIterator.
67 * CtfTmfTrace the trace
68 * @param ctfLocationData
69 * long the timestamp in ns of the trace for positioning
71 * long the index of the trace for positioning
74 public CtfIterator(final CtfTmfTrace trace
,
75 final CtfLocationInfo ctfLocationData
, final long rank
) {
76 super(trace
.getCTFTrace());
78 this.ctfTmfTrace
= trace
;
79 if (this.hasMoreEvents()) {
80 this.curLocation
= new CtfLocation(ctfLocationData
);
81 if (this.getCurrentEvent().getTimestamp().getValue() != ctfLocationData
.getTimestamp()) {
82 this.seek(ctfLocationData
);
92 * Method getCtfTmfTrace. gets a CtfTmfTrace
95 public CtfTmfTrace
getCtfTmfTrace() {
100 * Method getCurrentEvent. gets the current event
101 * @return CtfTmfEvent
103 public CtfTmfEvent
getCurrentEvent() {
104 final StreamInputReader top
= super.getPrio().peek();
106 return CtfTmfEventFactory
.createEvent(top
.getCurrentEvent(),
107 top
.getFilename(), ctfTmfTrace
);
113 public boolean seek(long timestamp
) {
114 return seek(new CtfLocationInfo(timestamp
, 0));
118 * Seek this iterator to a given location.
120 * @param ctfLocationData
121 * The LocationData representing the position to seek to
125 public synchronized boolean seek(final CtfLocationInfo ctfLocationData
) {
128 /* Adjust the timestamp depending on the trace's offset */
129 long currTimestamp
= ctfLocationData
.getTimestamp();
130 final long offsetTimestamp
= this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp
);
131 if (offsetTimestamp
< 0) {
132 ret
= super.seek(0L);
134 ret
= super.seek(offsetTimestamp
);
138 * Check if there is already one or more events for that timestamp, and
139 * assign the location index correctly
142 final CtfTmfEvent currentEvent
= this.getCurrentEvent();
143 if (currentEvent
!= null) {
144 currTimestamp
= currentEvent
.getTimestamp().getValue();
146 for (long i
= 0; i
< ctfLocationData
.getIndex(); i
++) {
147 if (currTimestamp
== currentEvent
.getTimestamp().getValue()) {
157 /* Seek the current location accordingly */
159 curLocation
= new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index
));
161 curLocation
= NULL_LOCATION
;
169 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getRank()
172 public long getRank() {
179 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#setRank(long)
182 public void setRank(final long rank
) {
187 public CtfIterator
clone() {
188 CtfIterator clone
= null;
189 clone
= new CtfIterator(ctfTmfTrace
, this.getLocation().getLocationInfo(), curRank
);
195 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#dispose()
198 public void dispose() {
203 * Method setLocation.
204 * @param location ITmfLocation<?>
208 public void setLocation(final ITmfLocation location
) {
209 // FIXME alex: isn't there a cleaner way than a cast here?
210 this.curLocation
= (CtfLocation
) location
;
211 seek(((CtfLocation
) location
).getLocationInfo());
215 * Method getLocation.
216 * @return CtfLocation
217 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getLocation()
220 public CtfLocation
getLocation() {
225 * Method increaseRank.
226 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#increaseRank()
229 public void increaseRank() {
230 /* Only increase the rank if it's valid */
237 * Method hasValidRank, if the iterator is valid
239 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#hasValidRank()
242 public boolean hasValidRank() {
243 return (getRank() >= 0);
247 * Method advance go to the next event
248 * @return boolean successful or not
251 public synchronized boolean advance() {
252 long index
= curLocation
.getLocationInfo().getIndex();
253 long timestamp
= curLocation
.getLocationInfo().getTimestamp();
254 boolean ret
= super.advance();
257 final long timestampValue
= getCurrentEvent().getTimestamp().getValue();
258 if (timestamp
== timestampValue
) {
259 curLocation
= new CtfLocation(timestampValue
, index
+ 1);
261 curLocation
= new CtfLocation(timestampValue
, 0L);
264 curLocation
= NULL_LOCATION
;
271 * @param o CtfIterator
272 * @return int -1, 0, 1
275 public int compareTo(final CtfIterator o
) {
276 if (this.getRank() < o
.getRank()) {
278 } else if (this.getRank() > o
.getRank()) {
285 public int hashCode() {
286 final int prime
= 31;
287 int result
= super.hashCode();
288 result
= (prime
* result
)
289 + ((ctfTmfTrace
== null) ?
0 : ctfTmfTrace
.hashCode());
290 result
= (prime
* result
)
291 + ((curLocation
== null) ?
0 : curLocation
.hashCode());
292 result
= (prime
* result
) + (int) (curRank ^
(curRank
>>> 32));
297 public boolean equals(Object obj
) {
301 if (!super.equals(obj
)) {
304 if (!(obj
instanceof CtfIterator
)) {
307 CtfIterator other
= (CtfIterator
) obj
;
308 if (ctfTmfTrace
== null) {
309 if (other
.ctfTmfTrace
!= null) {
312 } else if (!ctfTmfTrace
.equals(other
.ctfTmfTrace
)) {
315 if (curLocation
== null) {
316 if (other
.curLocation
!= null) {
319 } else if (!curLocation
.equals(other
.curLocation
)) {
322 if (curRank
!= other
.curRank
) {