All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.sirix.index.art.PrivateEntryIterator Maven / Gradle / Ivy

package io.sirix.index.art;

import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Base class for AdaptiveRadixTree Iterators
 * note: taken from TreeMap
 */
abstract class PrivateEntryIterator implements Iterator {
	private final AdaptiveRadixTree m;
	private LeafNode next;
	private LeafNode lastReturned;
	private int expectedModCount;

	PrivateEntryIterator(AdaptiveRadixTree m, LeafNode first) {
		expectedModCount = m.getModCount();
		lastReturned = null;
		next = first;
		this.m = m;
	}

	public final boolean hasNext() {
		return next != null;
	}

	final LeafNode nextEntry() {
		LeafNode e = next;
		if (e == null)
			throw new NoSuchElementException();
		if (m.getModCount() != expectedModCount)
			throw new ConcurrentModificationException();
		next = AdaptiveRadixTree.successor(e);
		lastReturned = e;
		return e;
	}

	final LeafNode prevEntry() {
		LeafNode e = next;
		if (e == null)
			throw new NoSuchElementException();
		if (m.getModCount() != expectedModCount)
			throw new ConcurrentModificationException();
		next = AdaptiveRadixTree.predecessor(e);
		lastReturned = e;
		return e;
	}

	public void remove() {
		if (lastReturned == null)
			throw new IllegalStateException();
		if (m.getModCount() != expectedModCount)
			throw new ConcurrentModificationException();
		/*
			next already points to the next leaf node (that might be a sibling to this lastReturned).
			if next is the only sibling left, then the parent gets path compressed.
			BUT the reference that next holds to the sibling leaf node remains the same, just it's parent changes.
			Therefore at all times, next is a valid reference to be simply returned on the
			next call to next().
			Is there any scenario in which the next leaf pointer gets changed and iterator next
			points to a stale leaf?
			No.
			Infact the LeafNode ctor is only ever called in a put and that too for the newer leaf
			to be created/entered.
			So references to an existing LeafNode won't get stale.
		 */
		m.deleteEntry(lastReturned);
		expectedModCount = m.getModCount();
		lastReturned = null;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy