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 * Seek this iterator to a given location.
115 * @param ctfLocationData
116 * The LocationData representing the position to seek to
120 public boolean seek(final CtfLocationData ctfLocationData
) {
123 /* Adjust the timestamp depending on the trace's offset */
124 long currTimestamp
= ctfLocationData
.getTimestamp();
125 final long offsetTimestamp
= this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp
);
126 if (offsetTimestamp
< 0) {
127 ret
= super.seek(0L);
129 ret
= super.seek(offsetTimestamp
);
133 * Check if there is already one or more events for that timestamp, and
134 * assign the location index correctly
137 if (this.getCurrentEvent() != null) {
138 currTimestamp
= this.getCurrentEvent().getTimestamp().getValue();
140 for (long i
= 0; i
< ctfLocationData
.getIndex(); i
++) {
141 if (currTimestamp
== this.getCurrentEvent().getTimestamp().getValue()) {
151 /* Seek the current location accordingly */
153 curLocation
= new CtfLocation(new CtfLocationData(getCurrentEvent().getTimestamp().getValue(), index
));
155 curLocation
= NULL_LOCATION
;
163 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getRank()
166 public long getRank() {
173 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#setRank(long)
176 public void setRank(final long rank
) {
183 * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext#clone()
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() {
198 // FIXME add dispose() stuff to CTFTrace and call it here...
203 * Method setLocation.
204 * @param location ITmfLocation<?>
207 public void setLocation(final ITmfLocation location
) {
208 // FIXME alex: isn't there a cleaner way than a cast here?
209 this.curLocation
= (CtfLocation
) location
;
210 seek(((CtfLocation
) location
).getLocationInfo());
214 * Method getLocation.
215 * @return CtfLocation
216 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getLocation()
219 public CtfLocation
getLocation() {
224 * Method increaseRank.
225 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#increaseRank()
228 public void increaseRank() {
229 /* Only increase the rank if it's valid */
236 * Method hasValidRank, if the iterator is valid
238 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#hasValidRank()
241 public boolean hasValidRank() {
242 return (getRank() >= 0);
246 * Method advance go to the next event
247 * @return boolean successful or not
250 public boolean advance() {
251 long index
= curLocation
.getLocationInfo().getIndex();
252 long timestamp
= curLocation
.getLocationInfo().getTimestamp();
253 boolean ret
= super.advance();
256 final long timestampValue
= getCurrentEvent().getTimestamp().getValue();
257 if (timestamp
== timestampValue
) {
258 curLocation
= new CtfLocation(timestampValue
, index
+ 1);
260 curLocation
= new CtfLocation(timestampValue
, 0L);
263 curLocation
= NULL_LOCATION
;
270 * @param o CtfIterator
271 * @return int -1, 0, 1
274 public int compareTo(final CtfIterator o
) {
275 if (this.getRank() < o
.getRank()) {
277 } else if (this.getRank() > o
.getRank()) {
284 * @see java.lang.Object#hashCode()
287 public int hashCode() {
288 final int prime
= 31;
289 int result
= super.hashCode();
290 result
= (prime
* result
)
291 + ((ctfTmfTrace
== null) ?
0 : ctfTmfTrace
.hashCode());
292 result
= (prime
* result
)
293 + ((curLocation
== null) ?
0 : curLocation
.hashCode());
294 result
= (prime
* result
) + (int) (curRank ^
(curRank
>>> 32));
299 * @see java.lang.Object#equals(java.lang.Object)
302 public boolean equals(Object obj
) {
306 if (!super.equals(obj
)) {
309 if (!(obj
instanceof CtfIterator
)) {
312 CtfIterator other
= (CtfIterator
) obj
;
313 if (ctfTmfTrace
== null) {
314 if (other
.ctfTmfTrace
!= null) {
317 } else if (!ctfTmfTrace
.equals(other
.ctfTmfTrace
)) {
320 if (curLocation
== null) {
321 if (other
.curLocation
!= null) {
324 } else if (!curLocation
.equals(other
.curLocation
)) {
327 if (curRank
!= other
.curRank
) {