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