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