
org.zoodb.jdo.internal.query.QueryTreeIterator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of parent Show documentation
Show all versions of parent Show documentation
ZooDB Java JDO Object Database.
The newest version!
/*
* Copyright 2009-2013 Tilmann Zaeschke. All rights reserved.
*
* This file is part of ZooDB.
*
* ZooDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ZooDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ZooDB. If not, see .
*
* See the README and COPYING files for further information.
*/
package org.zoodb.jdo.internal.query;
import java.util.NoSuchElementException;
/**
* QueryIterator class. It iterates over the terms of a query tree. Useful for evaluating
* candidate objects with a query.
*
* @author Tilmann Zaeschke
*/
public final class QueryTreeIterator {
private QueryTreeNode currentNode;
//private boolean askFirst = true;
private final boolean[] askFirstA = new boolean[20]; //0==first; 1==2nd; 2==done
private int askFirstD = 0; //depth: 0=root
private QueryTerm nextElement = null;
QueryTreeIterator(QueryTreeNode node) {
currentNode = node;
for (int i = 0; i < askFirstA.length; i++) {
askFirstA[i] = true;
}
nextElement = findNext();
}
public boolean hasNext() {
return (nextElement != null);
}
/**
* To avoid duplicate work in next() and hasNext() (both can locate the next element),
* we automatically move to the next element when the previous is returned. The hasNext()
* method then becomes trivial.
* @return next element.
*/
public QueryTerm next() {
if (nextElement == null) {
throw new NoSuchElementException();
}
QueryTerm t = nextElement;
nextElement = findNext();
return t;
}
/**
* Also, ASK nur setzen wenn ich hoch komme?
* runter: true-> first; false second;
* hoch: true-> nextSecond; false-> nextUP
*/
private QueryTerm findNext() {
//Walk down first branch
if (askFirstA[askFirstD]) {
while (currentNode.firstTerm() == null) {
//remember that we already walked down the first branch
askFirstD++;
currentNode = currentNode.firstNode();
}
askFirstA[askFirstD] = false;
return currentNode.firstTerm();
}
//do we have a second branch?
if (currentNode.isUnary()) {
return findUpwards();
}
//walk down second branch
if (currentNode.secondTerm() != null) {
//dirty hack
if (currentNode.secondTerm() != nextElement) {
return currentNode.secondTerm();
}
//else: we have been here before!
//walk back up
return findUpwards();
} else {
currentNode = currentNode.secondNode();
askFirstD++;
return findNext();
}
}
private QueryTerm findUpwards() {
if (currentNode._p == null) {
return null;
}
do {
//clean up behind me before moving back up
askFirstA[askFirstD] = true;
askFirstD--;
currentNode = currentNode.parent();
} while (currentNode._p != null && (currentNode.isUnary() || !askFirstA[askFirstD]));
//remove, only for DEBUG
// if (_currentNode == null) {
// throw new NoSuchElementException();
// }
//if 'false' then we are finished
if (!askFirstA[askFirstD]) {
return null;
}
//indicate that we want the second branch now
askFirstA[askFirstD] = false;
//walk down second branch
return findNext();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy