*
* Contributors: Matthew Khouzam - Initial API and implementation
* Contributors: Simon Marchi - Initial API and implementation
+ * Contributors: Etienne Bergeron <etienne.bergeron@gmail.com>
+ * Contributors: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
*******************************************************************************/
package org.eclipse.linuxtools.internal.ctf.core.trace;
// Getters/Setters/Predicates
// ------------------------------------------------------------------------
+ /**
+ * Gets the entries
+ *
+ * @return the entries
+ */
public Vector<StreamInputPacketIndexEntry> getEntries() {
return this.entries;
}
+ /**
+ * Gets an iterator to the entries
+ *
+ * @return an iterator to the entries
+ */
public ListIterator<StreamInputPacketIndexEntry> listIterator() {
return this.entries.listIterator();
}
+ /**
+ * Gets an iterator to the entries at a given position
+ *
+ * @param n
+ * the position to get
+ * @return the iterator
+ */
public ListIterator<StreamInputPacketIndexEntry> listIterator(int n) {
return this.entries.listIterator(n);
}
* @param entry
* The entry to add
* @throws CTFReaderException
+ * If there was a problem reading the entry
*/
public void addEntry(StreamInputPacketIndexEntry entry)
throws CTFReaderException {
assert (entry.getContentSizeBits() != 0);
- assert (entry.getContentSizeBits() != 0);
+ /* Validate consistent entry. */
if (entry.getTimestampBegin() > entry.getTimestampEnd()) {
- throw new CTFReaderException(
- "Packet begin timestamp is after end timestamp"); //$NON-NLS-1$
+ throw new CTFReaderException("Packet begin timestamp is after end timestamp"); //$NON-NLS-1$
}
+ /* Validate entries are inserted in monotonic increasing timestamp order. */
if (!this.entries.isEmpty()) {
- if (entry.getTimestampBegin() < this.entries.lastElement().getTimestampBegin()) {
- throw new CTFReaderException(
- "Packets begin timestamp decreasing"); //$NON-NLS-1$
+ if (entry.getTimestampBegin() < this.entries.lastElement()
+ .getTimestampBegin()) {
+ throw new CTFReaderException("Packets begin timestamp decreasing"); //$NON-NLS-1$
}
}
-
this.entries.add(entry);
}
/**
- * Given a timestamp, this methods returns the first PacketIndexEntry that
- * could include the timestamp, that is the last packet with a begin
- * timestamp smaller than the given timestamp.
+ * Returns the first PacketIndexEntry that could include the timestamp,
+ * that is the last packet with a begin timestamp smaller than the given timestamp.
*
* @param timestamp
* The timestamp to look for.
int guessI;
StreamInputPacketIndexEntry guessEntry = null;
- if (timestamp < 0) {
- throw new IllegalArgumentException("timestamp is negative"); //$NON-NLS-1$
- }
-
- for (;;) {
- /*
- * Guess in the middle of min and max. The +1 is so that in case
- * (min + 1 == max), we choose the packet at the subscript "max"
- * instead of the one at "min". Otherwise, it would give an infinite
- * loop.
- */
- guessI = (max + min + 1) / 2;
- guessEntry = this.entries.get(guessI);
-
- /*
- * If we reached the point where we focus on a single packet, our
- * search is done.
- */
- if (min == max) {
- break;
- }
-
- if (timestamp < guessEntry.getTimestampBegin()) {
- /*
- * If the timestamp if before the begin timestamp, we know that
- * the packet to return is before the guess.
- */
- max = guessI - 1;
- } else if (timestamp >= guessEntry.getTimestampBegin()) {
- /*
- * If the timestamp is after the begin timestamp, we know that
- * the packet to return is after the guess or is the guess.
- */
- min = guessI;
- }
- }
-
- return this.entries.listIterator(guessI);
- }
- /**
- * Given a rank, this methods returns the first PacketIndexEntry that
- * could include the rank, that is the last packet with a begin
- * rank smaller than the given rank.
- *
- * @param index
- * The rank to look for.
- * @return The StreamInputPacketEntry that corresponds to the packet that
- * includes the given timestamp.
- */
- public ListIterator<StreamInputPacketIndexEntry> searchIndex(final long index) {
/*
- * Start with min and max covering all the elements.
+ * If the index is empty, return the iterator at the very beginning.
*/
- int max = this.entries.size() - 1;
- int min = 0;
-
- int guessI;
- StreamInputPacketIndexEntry guessEntry = null;
+ if (this.getEntries().isEmpty()) {
+ return this.getEntries().listIterator();
+ }
- if (index < 0) {
- throw new IllegalArgumentException("rank is negative"); //$NON-NLS-1$
+ if (timestamp < 0) {
+ throw new IllegalArgumentException("timestamp is negative"); //$NON-NLS-1$
}
+ /* Binary search */
for (;;) {
/*
- * Guess in the middle of min and max. The +1 is so that in case
- * (min + 1 == max), we choose the packet at the subscript "max"
- * instead of the one at "min". Otherwise, it would give an infinite
- * loop.
+ * Guess in the middle of min and max.
*/
- guessI = (max + min + 1) / 2;
+ guessI = min + ((max - min) / 2);
guessEntry = this.entries.get(guessI);
/*
break;
}
- if (index < guessEntry.getIndexBegin()) {
+ if (timestamp <= guessEntry.getTimestampEnd()) {
/*
- * If the timestamp if before the begin timestamp, we know that
- * the packet to return is before the guess.
+ * If the timestamp is lower or equal to the end of the guess packet,
+ * then the guess packet becomes the new inclusive max.
*/
- max = guessI - 1;
- } else if (index >= guessEntry.getIndexBegin()) {
+ max = guessI;
+ } else {
/*
- * If the timestamp is after the begin timestamp, we know that
- * the packet to return is after the guess or is the guess.
+ * If the timestamp is greater than the end of the guess packet, then
+ * the new inclusive min is the packet after the guess packet.
*/
- min = guessI;
+ min = guessI + 1;
}
}