|
|
@ -305,11 +305,7 @@ public class kelondroTree extends kelondroRecords implements kelondroIndex {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// System.out.println("DEBUG: search for " + new String(key) + "
|
|
|
|
// System.out.println("DEBUG: search for " + new String(key) + " ended with status=" + ((found) ? "found" : "not-found") + ", node=" + ((thenode == null) ? "NULL" : thenode.toString()) + ", parent=" + ((parentnode == null) ? "NULL" : parentnode.toString()));
|
|
|
|
// ended with status=" + ((found) ? "found" : "not-found") + ",
|
|
|
|
|
|
|
|
// node=" + ((thenode == null) ? "NULL" : thenode.toString()) + ",
|
|
|
|
|
|
|
|
// parent=" + ((parentnode == null) ? "NULL" :
|
|
|
|
|
|
|
|
// parentnode.toString()));
|
|
|
|
|
|
|
|
// we reached a node where we must insert the new value
|
|
|
|
// we reached a node where we must insert the new value
|
|
|
|
// the parent of this new value can be obtained by getParent()
|
|
|
|
// the parent of this new value can be obtained by getParent()
|
|
|
|
// all values are set, just return
|
|
|
|
// all values are set, just return
|
|
|
@ -812,115 +808,91 @@ public class kelondroTree extends kelondroRecords implements kelondroIndex {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public synchronized Iterator nodeIterator(boolean up, boolean rotating) {
|
|
|
|
public synchronized Iterator nodeIterator(boolean up, boolean rotating) {
|
|
|
|
// iterates the elements in a sorted way. returns Node - type Objects
|
|
|
|
// iterates the elements in a sorted way. returns Node - type Objects
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
return new nodeIterator(up, rotating);
|
|
|
|
return new nodeIterator(up, rotating);
|
|
|
|
} catch (IOException e) {
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new RuntimeException("error creating an iteration: " + e.getMessage());
|
|
|
|
throw new RuntimeException("error creating an iteration: " + e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public synchronized Iterator nodeIterator(boolean up, boolean rotating, byte[] firstKey) {
|
|
|
|
public synchronized Iterator nodeIterator(boolean up, boolean rotating, byte[] firstKey) {
|
|
|
|
// iterates the elements in a sorted way. returns Node - type Objects
|
|
|
|
// iterates the elements in a sorted way. returns Node - type Objects
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
|
|
|
|
return new nodeIterator(up, rotating, firstKey, true);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
throw new RuntimeException("error creating an iteration: " + e.getMessage());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class nodeIterator implements Iterator {
|
|
|
|
|
|
|
|
// we implement an iteration! (not a recursive function as the structure would suggest...)
|
|
|
|
|
|
|
|
// the iterator iterates Node objects
|
|
|
|
|
|
|
|
Node nextNode = null;
|
|
|
|
|
|
|
|
boolean up, rot;
|
|
|
|
|
|
|
|
LinkedList nodeStack;
|
|
|
|
|
|
|
|
int count;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public nodeIterator(boolean up, boolean rotating) throws IOException {
|
|
|
|
|
|
|
|
this.count = 0;
|
|
|
|
|
|
|
|
this.up = up;
|
|
|
|
|
|
|
|
this.rot = rotating;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// initialize iterator
|
|
|
|
|
|
|
|
init((up) ? firstNode() : lastNode());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public nodeIterator(boolean up, boolean rotating, byte[] firstKey, boolean including) throws IOException {
|
|
|
|
|
|
|
|
this.count = 0;
|
|
|
|
|
|
|
|
this.up = up;
|
|
|
|
|
|
|
|
this.rot = rotating;
|
|
|
|
|
|
|
|
|
|
|
|
Search search = new Search();
|
|
|
|
Search search = new Search();
|
|
|
|
search.process(firstKey);
|
|
|
|
search.process(firstKey);
|
|
|
|
if (search.found()) {
|
|
|
|
if (search.found()) {
|
|
|
|
Node matcher = search.getMatcher();
|
|
|
|
init(search.getMatcher());
|
|
|
|
return new nodeIterator(up, rotating, matcher);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
Node nn = search.getParent();
|
|
|
|
Node nn = search.getParent();
|
|
|
|
if (nn == null) {
|
|
|
|
if (nn == null) {
|
|
|
|
return (new HashSet()).iterator(); // an empty iterator
|
|
|
|
this.nextNode = null;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// the node nn may be greater or smaller than the firstKey
|
|
|
|
// the node nn may be greater or smaller than the firstKey
|
|
|
|
// depending on the ordering direction,
|
|
|
|
// depending on the ordering direction,
|
|
|
|
// we must find the next smaller or greater node
|
|
|
|
// we must find the next smaller or greater node
|
|
|
|
return new correctedNodeIterator(up, rotating, nn, firstKey);
|
|
|
|
// this is corrected in the initializer of nodeIterator
|
|
|
|
|
|
|
|
init(nn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
throw new RuntimeException("error creating an iteration: " + e.getMessage());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class correctedNodeIterator implements Iterator {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Iterator ii;
|
|
|
|
|
|
|
|
Node nextNode;
|
|
|
|
|
|
|
|
boolean asc, rot;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public correctedNodeIterator(boolean up, boolean rotating, Node start, byte[] firstKey) throws IOException {
|
|
|
|
// correct nextNode upon start
|
|
|
|
this.asc = up;
|
|
|
|
// this happens, if the start node was not proper, or could not be found
|
|
|
|
this.rot = rotating;
|
|
|
|
while ((nextNode != null) && (nextNode.getKey() != null)) {
|
|
|
|
ii = new nodeIterator(asc, rot, start);
|
|
|
|
|
|
|
|
nextNode = (ii.hasNext()) ? (Node) ii.next() : null;
|
|
|
|
|
|
|
|
if ((nextNode != null) && (nextNode.getKey() != null)) {
|
|
|
|
|
|
|
|
int c = objectOrder.compare(firstKey, nextNode.getKey());
|
|
|
|
int c = objectOrder.compare(firstKey, nextNode.getKey());
|
|
|
|
if ((c > 0) && (asc)) {
|
|
|
|
if (c == 0) {
|
|
|
|
// firstKey > nextNode.getKey()
|
|
|
|
if (including) {
|
|
|
|
logFine("CORRECTING ITERATOR: firstKey=" + new String(firstKey) + ", nextNode=" + new String(nextNode.getKey()));
|
|
|
|
break; // correct + finished
|
|
|
|
nextNode = (ii.hasNext()) ? (Node) ii.next() : null;
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
if (hasNext()) next(); else nextNode = null;
|
|
|
|
if ((c < 0) && (!(asc))) {
|
|
|
|
break; // corrected + finished
|
|
|
|
logFine("CORRECTING ITERATOR: firstKey=" + new String(firstKey) + ", nextNode=" + new String(nextNode.getKey()));
|
|
|
|
}
|
|
|
|
nextNode = (ii.hasNext()) ? (Node) ii.next() : null;
|
|
|
|
} else if (c < 0) {
|
|
|
|
}
|
|
|
|
if (up) {
|
|
|
|
}
|
|
|
|
break; // correct + finished
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
// firstKey < nextNode.getKey(): correct once
|
|
|
|
public void finalize() {
|
|
|
|
if (hasNext()) next(); else nextNode = null;
|
|
|
|
ii = null;
|
|
|
|
}
|
|
|
|
nextNode = null;
|
|
|
|
} else if (c > 0) {
|
|
|
|
}
|
|
|
|
if (up) {
|
|
|
|
|
|
|
|
// firstKey > nextNode.getKey(): correct once
|
|
|
|
public boolean hasNext() {
|
|
|
|
if (hasNext()) next(); else nextNode = null;
|
|
|
|
return nextNode != null;
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
break; // correct + finished
|
|
|
|
|
|
|
|
|
|
|
|
public Object next() {
|
|
|
|
|
|
|
|
Node r = nextNode;
|
|
|
|
|
|
|
|
nextNode = (ii.hasNext()) ? (Node) ii.next() : null;
|
|
|
|
|
|
|
|
if ((nextNode != null) && (asc == (objectOrder.compare(r, nextNode) == 1))) {
|
|
|
|
|
|
|
|
// correct wrong order (this should not happen)
|
|
|
|
|
|
|
|
logWarning("STOPPING ITERATOR: currentNode=" + new String(r.getKey()) + ", nextNode=" + new String(nextNode.getKey()));
|
|
|
|
|
|
|
|
if (rot) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
ii = new nodeIterator(asc, rot);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
nextNode = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
nextNode = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void remove() {
|
|
|
|
|
|
|
|
throw new java.lang.UnsupportedOperationException("kelondroTree: remove in kelondro Tables not yet supported");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private class nodeIterator implements Iterator {
|
|
|
|
|
|
|
|
// we implement an iteration! (not a recursive function as the structure would suggest...)
|
|
|
|
|
|
|
|
// the iterator iterates Node objects
|
|
|
|
|
|
|
|
Node nextNode = null;
|
|
|
|
|
|
|
|
boolean up, rot;
|
|
|
|
|
|
|
|
LinkedList nodeStack;
|
|
|
|
|
|
|
|
int count;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public nodeIterator(boolean up, boolean rotating) throws IOException {
|
|
|
|
|
|
|
|
this(up, rotating, (up) ? firstNode() : lastNode());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public nodeIterator(boolean up, boolean rotating, Node start) throws IOException {
|
|
|
|
|
|
|
|
this.count = 0;
|
|
|
|
|
|
|
|
this.up = up;
|
|
|
|
|
|
|
|
this.rot = rotating;
|
|
|
|
|
|
|
|
init(start);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void init(Node start) throws IOException {
|
|
|
|
private void init(Node start) throws IOException {
|
|
|
|
this.nextNode = start;
|
|
|
|
this.nextNode = start;
|
|
|
|
|
|
|
|
|
|
|
@ -952,23 +924,22 @@ public class kelondroTree extends kelondroRecords implements kelondroIndex {
|
|
|
|
nodeStack = null;
|
|
|
|
nodeStack = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public boolean hasNext() {
|
|
|
|
public boolean hasNext() {
|
|
|
|
return (rot && (size() > 0)) || (nextNode != null);
|
|
|
|
return (rot && (size() > 0)) || (nextNode != null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public Object next() {
|
|
|
|
public Object next() {
|
|
|
|
count++;
|
|
|
|
count++;
|
|
|
|
if ((rot) && (nextNode == null)) try {
|
|
|
|
if ((rot) && (nextNode == null)) try {
|
|
|
|
init((up) ? firstNode() : lastNode());
|
|
|
|
init((up) ? firstNode() : lastNode());
|
|
|
|
} catch (IOException e) {
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new kelondroException(filename, "io-error while rot");
|
|
|
|
throw new kelondroException(filename, "io-error while rot");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nextNode == null) throw new kelondroException(filename, "nodeIterator.next: no more entries available");
|
|
|
|
if (nextNode == null) throw new kelondroException(filename, "nodeIterator.next: no more entries available");
|
|
|
|
if ((count > size()) && (!(rot))) throw new kelondroException(filename, "nodeIterator.next: internal loopback; database corrupted");
|
|
|
|
if ((count > size()) && (!(rot))) throw new kelondroException(filename, "nodeIterator.next: internal loopback; database corrupted");
|
|
|
|
Object ret = nextNode;
|
|
|
|
Object ret = nextNode;
|
|
|
|
|
|
|
|
|
|
|
|
// middle-case
|
|
|
|
// middle-case
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
int childtype = (up) ? rightchild : leftchild;
|
|
|
|
int childtype = (up) ? rightchild : leftchild;
|
|
|
|
Handle childHandle = nextNode.getOHHandle(childtype);
|
|
|
|
Handle childHandle = nextNode.getOHHandle(childtype);
|
|
|
@ -1033,7 +1004,7 @@ public class kelondroTree extends kelondroRecords implements kelondroIndex {
|
|
|
|
|
|
|
|
|
|
|
|
public void remove() {
|
|
|
|
public void remove() {
|
|
|
|
throw new java.lang.UnsupportedOperationException("kelondroTree: remove in kelondro Tables not yet supported");
|
|
|
|
throw new java.lang.UnsupportedOperationException("kelondroTree: remove in kelondro Tables not yet supported");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public synchronized Iterator rows(boolean up, boolean rotating) throws IOException {
|
|
|
|
public synchronized Iterator rows(boolean up, boolean rotating) throws IOException {
|
|
|
|