Merge branch 'master' into lttng-luna
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfIterator.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 Ericsson
3 *
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
8 *
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
12
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;
17
18 /**
19 * The CTF trace reader iterator.
20 *
21 * It doesn't reserve a file handle, so many iterators can be used without worries
22 * of I/O errors or resource exhaustion.
23 *
24 * @version 1.0
25 * @author Matthew Khouzam
26 */
27 public class CtfIterator extends CTFTraceReader implements ITmfContext,
28 Comparable<CtfIterator> {
29
30 private final CtfTmfTrace ctfTmfTrace;
31
32 /**
33 * An invalid location
34 */
35 final public static CtfLocation NULL_LOCATION = new CtfLocation(CtfLocation.INVALID_LOCATION);
36
37 private CtfLocation curLocation;
38 private long curRank;
39
40 /**
41 * Create a new CTF trace iterator, which initially points at the first
42 * event in the trace.
43 *
44 * @param trace
45 * the trace to iterate over
46 */
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());
52 this.curRank = 0;
53 } else {
54 setUnknownLocation();
55 }
56 }
57
58 private void setUnknownLocation() {
59 this.curLocation = NULL_LOCATION;
60 this.curRank = UNKNOWN_RANK;
61 }
62
63 /**
64 * Constructor for CtfIterator.
65 *
66 * @param trace
67 * CtfTmfTrace the trace
68 * @param ctfLocationData
69 * long the timestamp in ns of the trace for positioning
70 * @param rank
71 * long the index of the trace for positioning
72 * @since 2.0
73 */
74 public CtfIterator(final CtfTmfTrace trace,
75 final CtfLocationInfo ctfLocationData, final long rank) {
76 super(trace.getCTFTrace());
77
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);
83 this.curRank = rank;
84 }
85 } else {
86 setUnknownLocation();
87 }
88
89 }
90
91 /**
92 * Method getCtfTmfTrace. gets a CtfTmfTrace
93 * @return CtfTmfTrace
94 */
95 public CtfTmfTrace getCtfTmfTrace() {
96 return ctfTmfTrace;
97 }
98
99 /**
100 * Method getCurrentEvent. gets the current event
101 * @return CtfTmfEvent
102 */
103 public CtfTmfEvent getCurrentEvent() {
104 final StreamInputReader top = super.getPrio().peek();
105 if (top != null) {
106 return CtfTmfEventFactory.createEvent(top.getCurrentEvent(),
107 top.getFilename(), ctfTmfTrace);
108 }
109 return null;
110 }
111
112 @Override
113 public boolean seek(long timestamp) {
114 return seek(new CtfLocationInfo(timestamp, 0));
115 }
116
117 /**
118 * Seek this iterator to a given location.
119 *
120 * @param ctfLocationData
121 * The LocationData representing the position to seek to
122 * @return boolean
123 * @since 2.0
124 */
125 public synchronized boolean seek(final CtfLocationInfo ctfLocationData) {
126 boolean ret = false;
127
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);
133 } else {
134 ret = super.seek(offsetTimestamp);
135 }
136
137 /*
138 * Check if there is already one or more events for that timestamp, and
139 * assign the location index correctly
140 */
141 long index = 0;
142 final CtfTmfEvent currentEvent = this.getCurrentEvent();
143 if (currentEvent != null) {
144 currTimestamp = currentEvent.getTimestamp().getValue();
145
146 for (long i = 0; i < ctfLocationData.getIndex(); i++) {
147 if (currTimestamp == currentEvent.getTimestamp().getValue()) {
148 index++;
149 } else {
150 index = 0;
151 }
152 this.advance();
153 }
154 } else {
155 ret= false;
156 }
157 /* Seek the current location accordingly */
158 if (ret) {
159 curLocation = new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index));
160 } else {
161 curLocation = NULL_LOCATION;
162 }
163 return ret;
164 }
165
166 /**
167 * Method getRank.
168 * @return long
169 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getRank()
170 */
171 @Override
172 public long getRank() {
173 return curRank;
174 }
175
176 /**
177 * Method setRank.
178 * @param rank long
179 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#setRank(long)
180 */
181 @Override
182 public void setRank(final long rank) {
183 curRank = rank;
184 }
185
186 @Override
187 public CtfIterator clone() {
188 CtfIterator clone = null;
189 clone = new CtfIterator(ctfTmfTrace, this.getLocation().getLocationInfo(), curRank);
190 return clone;
191 }
192
193 /**
194 * Method dispose.
195 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#dispose()
196 */
197 @Override
198 public void dispose() {
199 super.dispose();
200 }
201
202 /**
203 * Method setLocation.
204 * @param location ITmfLocation<?>
205 * @since 3.0
206 */
207 @Override
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());
212 }
213
214 /**
215 * Method getLocation.
216 * @return CtfLocation
217 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getLocation()
218 */
219 @Override
220 public CtfLocation getLocation() {
221 return curLocation;
222 }
223
224 /**
225 * Method increaseRank.
226 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#increaseRank()
227 */
228 @Override
229 public void increaseRank() {
230 /* Only increase the rank if it's valid */
231 if(hasValidRank()) {
232 curRank++;
233 }
234 }
235
236 /**
237 * Method hasValidRank, if the iterator is valid
238 * @return boolean
239 * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#hasValidRank()
240 */
241 @Override
242 public boolean hasValidRank() {
243 return (getRank() >= 0);
244 }
245
246 /**
247 * Method advance go to the next event
248 * @return boolean successful or not
249 */
250 @Override
251 public synchronized boolean advance() {
252 long index = curLocation.getLocationInfo().getIndex();
253 long timestamp = curLocation.getLocationInfo().getTimestamp();
254 boolean ret = super.advance();
255
256 if (ret) {
257 final long timestampValue = getCurrentEvent().getTimestamp().getValue();
258 if (timestamp == timestampValue) {
259 curLocation = new CtfLocation(timestampValue, index + 1);
260 } else {
261 curLocation = new CtfLocation(timestampValue, 0L);
262 }
263 } else {
264 curLocation = NULL_LOCATION;
265 }
266 return ret;
267 }
268
269 /**
270 * Method compareTo.
271 * @param o CtfIterator
272 * @return int -1, 0, 1
273 */
274 @Override
275 public int compareTo(final CtfIterator o) {
276 if (this.getRank() < o.getRank()) {
277 return -1;
278 } else if (this.getRank() > o.getRank()) {
279 return 1;
280 }
281 return 0;
282 }
283
284 @Override
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));
293 return result;
294 }
295
296 @Override
297 public boolean equals(Object obj) {
298 if (this == obj) {
299 return true;
300 }
301 if (!super.equals(obj)) {
302 return false;
303 }
304 if (!(obj instanceof CtfIterator)) {
305 return false;
306 }
307 CtfIterator other = (CtfIterator) obj;
308 if (ctfTmfTrace == null) {
309 if (other.ctfTmfTrace != null) {
310 return false;
311 }
312 } else if (!ctfTmfTrace.equals(other.ctfTmfTrace)) {
313 return false;
314 }
315 if (curLocation == null) {
316 if (other.curLocation != null) {
317 return false;
318 }
319 } else if (!curLocation.equals(other.curLocation)) {
320 return false;
321 }
322 if (curRank != other.curRank) {
323 return false;
324 }
325 return true;
326 }
327 }
This page took 0.049133 seconds and 6 git commands to generate.