/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.indexStructures;
import java.util.Stack;
import xxl.core.cursors.AbstractCursor;
/** This class represents lazy <tt>Cursors</tt> which can be used to perform queries on a <tt>Tree</tt>. For example
* see {@link BPlusTree.QueryCursor}.
*/
public abstract class QueryCursor extends AbstractCursor {
/** The <tt>Tree</tt> in which the query has to be executed.
*/
protected Tree tree;
/** The <tt>IndexEntry</tt> refering to the current <tt>Node</tt>.
*/
protected Tree.IndexEntry indexEntry;
/** A <tt>Descriptor</tt> which specifies the query.
*/
protected Descriptor queryRegion;
/** The target level of the query.
*/
protected int targetLevel;
/** A <tt>Stack</tt> to hold the path from the root to the current <tt>Node</tt>.
*/
protected Stack path;
/** The current <tt>Node</tt> in which the query is at the moment executed.
*/
protected Tree.Node currentNode;
/** Creates a new <tt>QueryCursor</tt>.
*
* @param tree the <tt>Tree</tt> in which the query has to be executed
* @param subRootEntry the <tt>IndexEntry</tt> which is the root of the subtree in which the query has to be
* exectuted
* @param queryRegion a <tt>Descriptor</tt> which specifies the query
* @param targetLevel the target level of the query
*/
public QueryCursor(Tree tree, Tree.IndexEntry subRootEntry, Descriptor queryRegion, int targetLevel) {
this.tree= tree;
this.indexEntry= subRootEntry;
this.queryRegion= queryRegion;
this.targetLevel= targetLevel;
path= null;
currentNode=null;
}
/** In the default implementation it returns <tt>true</tt>.
*
* @return <tt>true</tt>
*
* @see AbstractCursor#supportsRemove()
*/
public boolean supportsRemove() {
return true;
}
/** In the default implementation it returns <tt>true</tt>.
*
* @return <tt>true</tt>
* @see AbstractCursor#supportsUpdate()
*/
public boolean supportsUpdate() {
return true;
}
/** Removes from the underlying <tt>Tree</tt> the last element returned by
* the method next(). The default implementation is equivalent to:
* <pre><code>
super.remove();
removeObject();
</code></pre>
*/
public void remove() {
super.remove();
removeObject();
}
/** Replaces the last element returned by the method next() by the given data object. The default implementation
* is equivalent to:
* <pre><code>
super.update(data);
updateObject(data);
</code></pre>
*
* @param data the object replacing the last object returned by next()
*/
public void update(Object data) {
super.update(data);
updateObject(data);
}
/** It is used to empty the path.
*/
protected void abolishPath() {
if(hasPath()) {
while(!path.isEmpty()) tree.up(path);
path=null;
}
}
/** Gives the current path.
*
* @return the current path
*/
public Stack path() {
return path;
}
/** Checks whether the path to the current <tt>Node</tt> exists.
*
* @return <tt>false</tt> if path is <tt>null</tt> and <tt>true</tt> otherwise.
*/
protected boolean hasPath(){
return this.path()!=null;
}
/** This method is called from the method {@link QueryCursor#remove()} and takes over the real work to
* remove an element from the <tt>QueryCursor</tt>. The user has to implement it so that it makes sense in the
* respective <tt>Tree</tt>.
*/
protected abstract void removeObject();
/** This method is called from the method {@link QueryCursor#update(Object)} and takes over the real work to
* update an element from the <tt>QueryCursor</tt>. The user has to implement it so that it makes sense in the
* respective <tt>Tree</tt>.
*
* @param data the new object by which the old object has to be replaced
*/
protected abstract void updateObject(Object data);
}