in src/main/java/org/apache/commons/collections4/trie/AbstractPatriciaTrie.java [1832:1919]
TrieEntry<K, V> nextEntryImpl(final TrieEntry<K, V> start,
final TrieEntry<K, V> previous, final TrieEntry<K, V> tree) {
TrieEntry<K, V> current = start;
// Only look at the left if this was a recursive or
// the first check, otherwise we know we've already looked
// at the left.
if (previous == null || start != previous.predecessor) {
while (!current.left.isEmpty()) {
// stop traversing if we've already
// returned the left of this node.
if (previous == current.left) {
break;
}
if (isValidUplink(current.left, current)) {
return current.left;
}
current = current.left;
}
}
// If there's no data at all, exit.
if (current.isEmpty()) {
return null;
}
// If we've already returned the left,
// and the immediate right is null,
// there's only one entry in the Trie
// which is stored at the root.
//
// / ("") <-- root
// \_/ \
// null <-- 'current'
//
if (current.right == null) {
return null;
}
// If nothing valid on the left, try the right.
if (previous != current.right) {
// See if it immediately is valid.
if (isValidUplink(current.right, current)) {
return current.right;
}
// Must search on the right's side if it wasn't initially valid.
return nextEntryImpl(current.right, previous, tree);
}
// Neither left nor right are valid, find the first parent
// whose child did not come from the right & traverse it.
while (current == current.parent.right) {
// If we're going to traverse to above the subtree, stop.
if (current == tree) {
return null;
}
current = current.parent;
}
// If we're on the top of the subtree, we can't go any higher.
if (current == tree) {
return null;
}
// If there's no right, the parent must be root, so we're done.
if (current.parent.right == null) {
return null;
}
// If the parent's right points to itself, we've found one.
if (previous != current.parent.right
&& isValidUplink(current.parent.right, current.parent)) {
return current.parent.right;
}
// If the parent's right is itself, there can't be any more nodes.
if (current.parent.right == current.parent) {
return null;
}
// We need to traverse down the parent's right's path.
return nextEntryImpl(current.parent.right, previous, tree);
}