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