1 /*******************************************************************************
2 * Copyright (c) 2012 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
>, Cloneable
{
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 CtfLocationData 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 new CtfTmfEvent(top
.getCurrentEvent(), top
.getFilename(),
113 * @see org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader#seek(long)
116 public boolean seek(long timestamp
) {
117 return seek(new CtfLocationData(timestamp
, 0));
121 * Seek this iterator to a given location.
123 * @param ctfLocationData
124 * The LocationData representing the position to seek to
128 public boolean seek(final CtfLocationData ctfLocationData
) {
131 /* Adjust the timestamp depending on the trace's offset */
132 long currTimestamp
= ctfLocationData
.getTimestamp();
133 final long offsetTimestamp
= this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp
);
134 if (offsetTimestamp
< 0) {
135 ret
= super.seek(0L);
137 ret
= super.seek(offsetTimestamp
);
141 * Check if there is already one or more events for that timestamp, and
142 * assign the location index correctly
145 if (this.getCurrentEvent() != null) {
146 currTimestamp
= this.getCurrentEvent().getTimestamp().getValue();
148 for (long i
= 0; i
< ctfLocationData
.getIndex(); i
++) {
149 if (currTimestamp
== this.getCurrentEvent().getTimestamp().getValue()) {
159 /* Seek the current location accordingly */
161 curLocation
= new CtfLocation(new CtfLocationData(getCurrentEvent().getTimestamp().getValue(), index
));
163 curLocation
= NULL_LOCATION
;
171 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getRank()
174 public long getRank() {
181 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#setRank(long)
184 public void setRank(final long rank
) {
191 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext#clone()
194 public CtfIterator
clone() {
195 CtfIterator clone
= null;
196 clone
= new CtfIterator(ctfTmfTrace
, this.getLocation().getLocationInfo(), curRank
);
202 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#dispose()
205 public void dispose() {
206 // FIXME add dispose() stuff to CTFTrace and call it here...
211 * Method setLocation.
212 * @param location ITmfLocation<?>
215 public void setLocation(final ITmfLocation location
) {
216 // FIXME alex: isn't there a cleaner way than a cast here?
217 this.curLocation
= (CtfLocation
) location
;
218 seek(((CtfLocation
) location
).getLocationInfo());
222 * Method getLocation.
223 * @return CtfLocation
224 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getLocation()
227 public CtfLocation
getLocation() {
232 * Method increaseRank.
233 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#increaseRank()
236 public void increaseRank() {
237 /* Only increase the rank if it's valid */
244 * Method hasValidRank, if the iterator is valid
246 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#hasValidRank()
249 public boolean hasValidRank() {
250 return (getRank() >= 0);
254 * Method advance go to the next event
255 * @return boolean successful or not
258 public boolean advance() {
259 long index
= curLocation
.getLocationInfo().getIndex();
260 long timestamp
= curLocation
.getLocationInfo().getTimestamp();
261 boolean ret
= super.advance();
264 final long timestampValue
= getCurrentEvent().getTimestamp().getValue();
265 if (timestamp
== timestampValue
) {
266 curLocation
= new CtfLocation(timestampValue
, index
+ 1);
268 curLocation
= new CtfLocation(timestampValue
, 0L);
271 curLocation
= NULL_LOCATION
;
278 * @param o CtfIterator
279 * @return int -1, 0, 1
282 public int compareTo(final CtfIterator o
) {
283 if (this.getRank() < o
.getRank()) {
285 } else if (this.getRank() > o
.getRank()) {
292 * @see java.lang.Object#hashCode()
295 public int hashCode() {
296 final int prime
= 31;
297 int result
= super.hashCode();
298 result
= (prime
* result
)
299 + ((ctfTmfTrace
== null) ?
0 : ctfTmfTrace
.hashCode());
300 result
= (prime
* result
)
301 + ((curLocation
== null) ?
0 : curLocation
.hashCode());
302 result
= (prime
* result
) + (int) (curRank ^
(curRank
>>> 32));
307 * @see java.lang.Object#equals(java.lang.Object)
310 public boolean equals(Object obj
) {
314 if (!super.equals(obj
)) {
317 if (!(obj
instanceof CtfIterator
)) {
320 CtfIterator other
= (CtfIterator
) obj
;
321 if (ctfTmfTrace
== null) {
322 if (other
.ctfTmfTrace
!= null) {
325 } else if (!ctfTmfTrace
.equals(other
.ctfTmfTrace
)) {
328 if (curLocation
== null) {
329 if (other
.curLocation
!= null) {
332 } else if (!curLocation
.equals(other
.curLocation
)) {
335 if (curRank
!= other
.curRank
) {