*/
package io.atomix.storage.journal.index;
+import com.google.common.base.MoreObjects;
import java.util.TreeMap;
+import org.eclipse.jdt.annotation.Nullable;
/**
* A {@link JournalIndex} maintaining target density.
public final class SparseJournalIndex implements JournalIndex {
private static final int MIN_DENSITY = 1000;
- private final int density;
private final TreeMap<Long, Integer> positions = new TreeMap<>();
+ private final int density;
+
+ // Last known position. May not be accurate immediately after a truncate() or construction
+ private @Nullable Position last;
public SparseJournalIndex() {
density = MIN_DENSITY;
}
@Override
- public void index(final long index, final int position) {
+ public Position index(final long index, final int position) {
+ final var newLast = new Position(index, position);
+ last = newLast;
if (index % density == 0) {
positions.put(index, position);
}
+ return newLast;
+ }
+
+ @Override
+ public Position last() {
+ return last;
}
@Override
@Override
public Position truncate(final long index) {
- positions.tailMap(index, false).clear();
- return Position.ofNullable(positions.lastEntry());
+ // Clear all indexes unto and including index, saving the first removed entry
+ final var tailMap = positions.tailMap(index, true);
+ final var firstRemoved = tailMap.firstEntry();
+ tailMap.clear();
+
+ // Update last position to the last entry, but make sure to return a pointer to index if that is what we have
+ // indexed.
+ final var newLast = Position.ofNullable(positions.lastEntry());
+ last = newLast;
+ return firstRemoved != null && firstRemoved.getKey() == index ? new Position(firstRemoved) : newLast;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this).add("positions", positions).toString();
}
}