lttng: Update @since annotations for 3.0
[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:
10 * Matthew Khouzam - Initial API and implementation
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
14
15 import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
16 import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader;
17 import org.eclipse.linuxtools.ctf.core.trace.StreamInputReader;
18 import org.eclipse.linuxtools.internal.tmf.core.Activator;
19 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
20 import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
21
22 /**
23 * The CTF trace reader iterator.
24 *
25 * It doesn't reserve a file handle, so many iterators can be used without
26 * worries of I/O errors or resource exhaustion.
27 *
28 * @author Matthew Khouzam
29 */
30 public class CtfIterator extends CTFTraceReader
31 implements ITmfContext, Comparable<CtfIterator> {
32
33 /** An invalid location */
34 public static final CtfLocation NULL_LOCATION = new CtfLocation(CtfLocation.INVALID_LOCATION);
35
36 private final CtfTmfTrace fTrace;
37
38 private CtfLocation fCurLocation;
39 private long fCurRank;
40
41 // ------------------------------------------------------------------------
42 // Constructors
43 // ------------------------------------------------------------------------
44
45 /**
46 * Create a new CTF trace iterator, which initially points at the first
47 * event in the trace.
48 *
49 * @param trace
50 * The trace to iterate over
51 * @throws CTFReaderException
52 * If the iterator couldn't not be instantiated, probably due to
53 * a read error.
54 */
55 public CtfIterator(CtfTmfTrace trace) throws CTFReaderException {
56 super(trace.getCTFTrace());
57 fTrace = trace;
58 if (this.hasMoreEvents()) {
59 fCurLocation = new CtfLocation(trace.getStartTime());
60 fCurRank = 0;
61 } else {
62 setUnknownLocation();
63 }
64 }
65
66 /**
67 * Create a new CTF trace iterator, which will initially point to the given
68 * location/rank.
69 *
70 * @param trace
71 * The trace to iterate over
72 * @param ctfLocationData
73 * The initial timestamp the iterator will be pointing to
74 * @param rank
75 * The initial rank
76 * @throws CTFReaderException
77 * If the iterator couldn't not be instantiated, probably due to
78 * a read error.
79 * @since 2.0
80 */
81 public CtfIterator(CtfTmfTrace trace, CtfLocationInfo ctfLocationData, long rank)
82 throws CTFReaderException {
83 super(trace.getCTFTrace());
84
85 this.fTrace = trace;
86 if (this.hasMoreEvents()) {
87 this.fCurLocation = new CtfLocation(ctfLocationData);
88 if (this.getCurrentEvent().getTimestamp().getValue() != ctfLocationData.getTimestamp()) {
89 this.seek(ctfLocationData);
90 this.fCurRank = rank;
91 }
92 } else {
93 setUnknownLocation();
94 }
95 }
96
97 private void setUnknownLocation() {
98 fCurLocation = NULL_LOCATION;
99 fCurRank = UNKNOWN_RANK;
100 }
101
102 // ------------------------------------------------------------------------
103 // Accessors
104 // ------------------------------------------------------------------------
105
106 /**
107 * Return this iterator's trace.
108 *
109 * @return CtfTmfTrace The iterator's trace
110 */
111 public CtfTmfTrace getCtfTmfTrace() {
112 return fTrace;
113 }
114
115 /**
116 * Return the current event pointed to by the iterator.
117 *
118 * @return CtfTmfEvent The current event
119 */
120 public CtfTmfEvent getCurrentEvent() {
121 final StreamInputReader top = super.getPrio().peek();
122 if (top != null) {
123 return CtfTmfEventFactory.createEvent(top.getCurrentEvent(),
124 top.getFilename(), fTrace);
125 }
126 return null;
127 }
128
129 /**
130 * Seek this iterator to a given location.
131 *
132 * @param ctfLocationData
133 * The LocationData representing the position to seek to
134 * @return boolean True if the seek was successful, false if there was an
135 * error seeking.
136 * @since 2.0
137 */
138 public synchronized boolean seek(CtfLocationInfo ctfLocationData) {
139 boolean ret = false;
140
141 /* Avoid the cost of seeking at the current location. */
142 if (fCurLocation.getLocationInfo().equals(ctfLocationData)) {
143 return super.hasMoreEvents();
144 }
145
146 /* Adjust the timestamp depending on the trace's offset */
147 long currTimestamp = ctfLocationData.getTimestamp();
148 final long offsetTimestamp = this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp);
149 try {
150 if (offsetTimestamp < 0) {
151 ret = super.seek(0L);
152 } else {
153 ret = super.seek(offsetTimestamp);
154 }
155 } catch (CTFReaderException e) {
156 Activator.logError(e.getMessage(), e);
157 return false;
158 }
159 /*
160 * Check if there is already one or more events for that timestamp, and
161 * assign the location index correctly
162 */
163 long index = 0;
164 final CtfTmfEvent currentEvent = this.getCurrentEvent();
165 if (currentEvent != null) {
166 currTimestamp = currentEvent.getTimestamp().getValue();
167
168 for (long i = 0; i < ctfLocationData.getIndex(); i++) {
169 if (currTimestamp == currentEvent.getTimestamp().getValue()) {
170 index++;
171 } else {
172 index = 0;
173 }
174 this.advance();
175 }
176 } else {
177 ret = false;
178 }
179 /* Seek the current location accordingly */
180 if (ret) {
181 fCurLocation = new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index));
182 } else {
183 fCurLocation = NULL_LOCATION;
184 }
185
186 return ret;
187 }
188
189 // ------------------------------------------------------------------------
190 // CTFTraceReader
191 // ------------------------------------------------------------------------
192
193 @Override
194 public boolean seek(long timestamp) {
195 return seek(new CtfLocationInfo(timestamp, 0));
196 }
197
198 @Override
199 public synchronized boolean advance() {
200 long index = fCurLocation.getLocationInfo().getIndex();
201 long timestamp = fCurLocation.getLocationInfo().getTimestamp();
202 boolean ret = false;
203 try {
204 ret = super.advance();
205 } catch (CTFReaderException e) {
206 Activator.logError(e.getMessage(), e);
207 }
208
209 if (ret) {
210 final long timestampValue = getCurrentEvent().getTimestamp().getValue();
211 if (timestamp == timestampValue) {
212 fCurLocation = new CtfLocation(timestampValue, index + 1);
213 } else {
214 fCurLocation = new CtfLocation(timestampValue, 0L);
215 }
216 } else {
217 fCurLocation = NULL_LOCATION;
218 }
219 return ret;
220 }
221
222 // ------------------------------------------------------------------------
223 // ITmfContext
224 // ------------------------------------------------------------------------
225
226 @Override
227 public long getRank() {
228 return fCurRank;
229 }
230
231 @Override
232 public void setRank(long rank) {
233 fCurRank = rank;
234 }
235
236 @Override
237 public void increaseRank() {
238 /* Only increase the rank if it's valid */
239 if (hasValidRank()) {
240 fCurRank++;
241 }
242 }
243
244 @Override
245 public boolean hasValidRank() {
246 return (getRank() >= 0);
247 }
248
249 /**
250 * @since 3.0
251 */
252 @Override
253 public void setLocation(ITmfLocation location) {
254 // FIXME alex: isn't there a cleaner way than a cast here?
255 fCurLocation = (CtfLocation) location;
256 seek(((CtfLocation) location).getLocationInfo());
257 }
258
259 @Override
260 public CtfLocation getLocation() {
261 return fCurLocation;
262 }
263
264 // ------------------------------------------------------------------------
265 // Comparable
266 // ------------------------------------------------------------------------
267
268 @Override
269 public int compareTo(final CtfIterator o) {
270 if (this.getRank() < o.getRank()) {
271 return -1;
272 } else if (this.getRank() > o.getRank()) {
273 return 1;
274 }
275 return 0;
276 }
277
278 // ------------------------------------------------------------------------
279 // Object
280 // ------------------------------------------------------------------------
281
282 @Override
283 public int hashCode() {
284 final int prime = 31;
285 int result = super.hashCode();
286 result = (prime * result)
287 + ((fTrace == null) ? 0 : fTrace.hashCode());
288 result = (prime * result)
289 + ((fCurLocation == null) ? 0 : fCurLocation.hashCode());
290 result = (prime * result) + (int) (fCurRank ^ (fCurRank >>> 32));
291 return result;
292 }
293
294 @Override
295 public boolean equals(Object obj) {
296 if (this == obj) {
297 return true;
298 }
299 if (!super.equals(obj)) {
300 return false;
301 }
302 if (!(obj instanceof CtfIterator)) {
303 return false;
304 }
305 CtfIterator other = (CtfIterator) obj;
306 if (fTrace == null) {
307 if (other.fTrace != null) {
308 return false;
309 }
310 } else if (!fTrace.equals(other.fTrace)) {
311 return false;
312 }
313 if (fCurLocation == null) {
314 if (other.fCurLocation != null) {
315 return false;
316 }
317 } else if (!fCurLocation.equals(other.fCurLocation)) {
318 return false;
319 }
320 if (fCurRank != other.fCurRank) {
321 return false;
322 }
323 return true;
324 }
325 }
This page took 0.036541 seconds and 5 git commands to generate.