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
.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.prio
.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 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 if (this.getCurrentEvent() != null) {
143 currTimestamp
= this.getCurrentEvent().getTimestamp().getValue();
145 for (long i
= 0; i
< ctfLocationData
.getIndex(); i
++) {
146 if (currTimestamp
== this.getCurrentEvent().getTimestamp().getValue()) {
156 /* Seek the current location accordingly */
158 curLocation
= new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index
));
160 curLocation
= NULL_LOCATION
;
168 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getRank()
171 public long getRank() {
178 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#setRank(long)
181 public void setRank(final long rank
) {
186 public CtfIterator
clone() {
187 CtfIterator clone
= null;
188 clone
= new CtfIterator(ctfTmfTrace
, this.getLocation().getLocationInfo(), curRank
);
194 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#dispose()
197 public void dispose() {
202 * Method setLocation.
203 * @param location ITmfLocation<?>
206 public void setLocation(final ITmfLocation location
) {
207 // FIXME alex: isn't there a cleaner way than a cast here?
208 this.curLocation
= (CtfLocation
) location
;
209 seek(((CtfLocation
) location
).getLocationInfo());
213 * Method getLocation.
214 * @return CtfLocation
215 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getLocation()
218 public CtfLocation
getLocation() {
223 * Method increaseRank.
224 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#increaseRank()
227 public void increaseRank() {
228 /* Only increase the rank if it's valid */
235 * Method hasValidRank, if the iterator is valid
237 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#hasValidRank()
240 public boolean hasValidRank() {
241 return (getRank() >= 0);
245 * Method advance go to the next event
246 * @return boolean successful or not
249 public boolean advance() {
250 long index
= curLocation
.getLocationInfo().getIndex();
251 long timestamp
= curLocation
.getLocationInfo().getTimestamp();
252 boolean ret
= super.advance();
255 final long timestampValue
= getCurrentEvent().getTimestamp().getValue();
256 if (timestamp
== timestampValue
) {
257 curLocation
= new CtfLocation(timestampValue
, index
+ 1);
259 curLocation
= new CtfLocation(timestampValue
, 0L);
262 curLocation
= NULL_LOCATION
;
269 * @param o CtfIterator
270 * @return int -1, 0, 1
273 public int compareTo(final CtfIterator o
) {
274 if (this.getRank() < o
.getRank()) {
276 } else if (this.getRank() > o
.getRank()) {
283 public int hashCode() {
284 final int prime
= 31;
285 int result
= super.hashCode();
286 result
= (prime
* result
)
287 + ((ctfTmfTrace
== null) ?
0 : ctfTmfTrace
.hashCode());
288 result
= (prime
* result
)
289 + ((curLocation
== null) ?
0 : curLocation
.hashCode());
290 result
= (prime
* result
) + (int) (curRank ^
(curRank
>>> 32));
295 public boolean equals(Object obj
) {
299 if (!super.equals(obj
)) {
302 if (!(obj
instanceof CtfIterator
)) {
305 CtfIterator other
= (CtfIterator
) obj
;
306 if (ctfTmfTrace
== null) {
307 if (other
.ctfTmfTrace
!= null) {
310 } else if (!ctfTmfTrace
.equals(other
.ctfTmfTrace
)) {
313 if (curLocation
== null) {
314 if (other
.curLocation
!= null) {
317 } else if (!curLocation
.equals(other
.curLocation
)) {
320 if (curRank
!= other
.curRank
) {