⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtree.java

📁 一个java实现的R树
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package rtree;import java.util.*;/** * To create a new RTree use the first two constructors. You must specify the dimension, the fill factor as * a float between 0 and 0.5 (0 to 50% capacity) and the variant of the RTree which is one of: * <ul> *  <li>RTREE_QUADRATIC</li> * </ul> * The first constructor creates by default a new memory resident page file. The second constructor takes * the page file as an argument. If the given page file is not empty, then all data are deleted. * <p> * The third constructor initializes the RTree from an already filled page file. Thus, you may store the * RTree into a persistent page file and recreate it again at any time. * <p> * Created: Tue May 18 12:57:35 1999 * <p> * @author Hadjieleftheriou Marios * @version 1.003 */public class RTree {    public final String version = "1.003";    public final String date = "December 7th 1999";    /** Page file where data is stored. */    protected PageFile file = null;    /** static identifier used for the parent of the root node. */    public static final int NIL = -1;    /** Available RTree variants. */    public static final int RTREE_LINEAR = 0;    public static final int RTREE_QUADRATIC = 1;    public static final int RTREE_EXPONENTIAL = 2;    public static final int RSTAR = 3;    /**      * Creates a memory resident RTree with an empty root node, which is stored in page 0 and has a      * parent identifier equal to NIL. A new memory page file is created and used as a storage manager     * by default.     *     * @param  dimension  The data dimension.     * @param  fillFactor A percentage between 0 and 0.5. Used to calculate minimum number of entries     *                    present in each node.     * @param  capacity   The maximun number of entries that each node can hold.     * @param  type       The RTree variant to use.     */    public RTree(int dimension, float fillFactor, int capacity, int type) {	this(dimension, fillFactor, capacity, new MemoryPageFile(), type);    }    /**      * Creates a new RTree with an empty root node, which is stored in page 0 and has     * a parent identifier equal to NIL. The given page file is used for storing the rtree nodes.     * If the page file is not empty, than all entries will be overwritten.     *     * @param  dimension  The data dimension.     * @param  fillFactor A percentage between 0 and 0.5. Used to calculate minimum number of entries     *                    present in each node.     * @param  capacity   The maximun number of entries that each node can hold.     * @param  file       The page file to use for storing the nodes of the rtree.     * @param  type       The RTree variant to use.     */    public RTree(int dimension, float fillFactor, int capacity, PageFile file, int type) {	if (dimension <= 1) {	    throw new IllegalArgumentException("Dimension must be larger than 1.");	}	if (fillFactor < 0 || fillFactor > 0.5) {	    throw new IllegalArgumentException("Fill factor must be between 0 and 0.5.");	}	if (capacity <= 1) {	    throw new IllegalArgumentException("Capacity must be larger than 1.");	}	if (type != RTREE_QUADRATIC /*&& type != RTREE_LINEAR && type != RTREE_EXPONENTIAL && type != RSTAR*/) {	    throw new IllegalArgumentException("Invalid tree type.");	}	if (file.tree != null) {	    throw new IllegalArgumentException("PageFile already in use by another rtree instance.");	}	file.initialize(this, dimension, fillFactor, capacity, type);	this.file = file;	Leaf root = new Leaf(this, NIL, 0);	file.writeNode(root);    }    /**     * Creates an rtree from an already initialized page file, probably stored into persistent storage.     */    public RTree(PageFile file) {	if (file.tree != null) {	    throw new IllegalArgumentException("PageFile already in use by another rtree instance.");	}	if (file.treeType == -1) {	    throw new IllegalArgumentException("PageFile is empty. Use some other RTree constructor.");	}	file.tree = this;	this.file = file;    }    /**     * Retruns the maximun capacity of each Node.     */    public int getNodeCapacity() {	return file.nodeCapacity;    }    /**      * Returns the percentage between 0 and 0.5, used to calculate minimum number of entries     * present in each node.     */    public float getFillFactor() {	return file.fillFactor;    }    /**      * Returns the data dimension.     */    public int getDimension() {	return file.dimension;    }    /**      * Returns the page length.     */    public int getPageSize() {	return file.pageSize;    }    /**      * Returns the level of the root Node, which signifies the level of the whole tree. Loads one     * page into main memory.     */    public int getTreeLevel() {	return  file.readNode(0).getLevel();    }    /**      * Returns the RTree variant used.      */    public int getTreeType() {	return file.treeType;    }    /**     * Inserts a HyperCube into the tree, pointing to the data stored at the given page number.     *     * @param h The hypercube to insert.     * @param page The page where the real data is stored.     * @return The page number of the Leaf where the hypercube was inserted (the parent of the     *         data entry.)     */    public int insert(HyperCube h, int page) {	if (h  == null) {	    throw new IllegalArgumentException("HyperCube cannot be null.");	}	if (h.getDimension() != file.dimension) {	    throw new IllegalArgumentException("HyperCube dimension different than RTree dimension.");	}	AbstractNode root = file.readNode(0);	Leaf l = root.chooseLeaf(h);	return l.insert(h, page);    }    /**     * Deletes a HyperCube from the leaf level of the tree. If there is no leaf containg a hypercube     * that matches the given hypercube, the tree is left intact.     *     * @param h The HyperCube to delete.     * @return The data pointer of the deleted entry, NIL if no matching entry was found.     */    public int delete(HyperCube h) {	if (h == null) {	    throw new IllegalArgumentException("HyperCube cannot be null.");	}	if (h.getDimension() != file.dimension) {	    throw new IllegalArgumentException("HyperCube dimension different than RTree dimension.");	}	AbstractNode root = file.readNode(0);	Leaf l = root.findLeaf(h);	if (l != null) {	    return l.delete(h);	}	return NIL;    }    /**     * Returns a Vector containing all tree nodes from bottom to top, left to right.     * CAUTION: If the tree is not memory resident, all nodes will be loaded into main memory.     *     * @param root The node from which the traverse should begin.     * @return A Vector containing all Nodes in the correct order.     */    public Vector traverseByLevel(AbstractNode root) {	if (root == null) {	    throw new IllegalArgumentException("Node cannot be null.");	}	Vector ret = new Vector();	Vector v = traversePostOrder(root);	for (int i = 0; i <= getTreeLevel(); i++) {	    Vector a = new Vector();	    for (int j = 0; j < v.size(); j++) {		Node n = (Node) v.elementAt(j);		if (n.getLevel() == i) {		    a.addElement(n);		}	    }	    for (int j = 0; j < a.size(); j++) {		ret.addElement(a.elementAt(j));	    }	}	return ret;    }    /**     * Returns an Enumeration containing all tree nodes from bottom to top, left to right.     *     * @return An Enumeration containing all Nodes in the correct order.     */    public Enumeration traverseByLevel() {	class ByLevelEnum implements Enumeration {	    // there is at least one node, the root node.	    private boolean hasNext = true;	    private Vector nodes;	    private int index = 0;	    public ByLevelEnum() {		AbstractNode root = file.readNode(0);		nodes = traverseByLevel(root);	    }	    public boolean hasMoreElements() {		return hasNext;	    }	    public Object nextElement() {		if (! hasNext) {		    throw new NoSuchElementException("traverseByLevel");		}		Object n = nodes.elementAt(index);		index++;		if (index == nodes.size()) {		    hasNext = false;		}		return n;	    }	};	return new ByLevelEnum();    }    /**     * Post order traverse of tree nodes.      * CAUTION: If the tree is not memory resident, all nodes will be loaded into main memory.     *     * @param root The node where the traversing should begin.     * @return A Vector containing all tree nodes in the correct order.     */    public Vector traversePostOrder(AbstractNode root) {	if (root == null) {	    throw new IllegalArgumentException("Node cannot be null.");	}	Vector v = new Vector();	v.addElement(root);	if (root.isLeaf()) {	} else {	    for (int i = 0; i < root.usedSpace; i++) {		Vector a = traversePostOrder(((Index) root).getChild(i));		for (int j = 0; j < a.size(); j++) {		    v.addElement(a.elementAt(j));		}	    }	}	return v;    }    /**     * Post order traverse of all tree nodes, begging with root.     * CAUTION: If the tree is not memory resident, all nodes will be loaded into main memory.     *     * @return An Enumeration containing all tree nodes in the correct order.     */    public Enumeration traversePostOrder() {	class PostOrderEnum implements Enumeration {	    private boolean hasNext = true;	    private Vector nodes;	    private int index = 0;	    public PostOrderEnum() {		AbstractNode root = file.readNode(0);		nodes = traversePostOrder(root);	    }	    public boolean hasMoreElements() {		return hasNext;	    }	    public Object nextElement() {		if (! hasNext) {		    throw new NoSuchElementException("traversePostOrder");		}		Object n = nodes.elementAt(index);		index++;		if (index == nodes.size()) {		    hasNext = false;		}		return n;	    }	};	return new PostOrderEnum();    }    /**     * Pre order traverse of tree nodes.     * CAUTION: If the tree is not memory resident, all nodes will be loaded into main memory.     *     * @param root The node where the traversing should begin.     * @return A Vector containing all tree nodes in the correct order.     */    public Vector traversePreOrder(AbstractNode root) {	if (root == null) {	    throw new IllegalArgumentException("Node cannot be null.");	}	Vector v = new Vector();	if (root.isLeaf()) {	    v.addElement(root);	} else {	    for (int i = 0; i < root.usedSpace; i++) {		Vector a = traversePreOrder(((Index) root).getChild(i));		for (int j = 0; j < a.size(); j++) {		    v.addElement(a.elementAt(j));		}	    }	    v.addElement(root);	}	return v;    }    /**     * Pre order traverse of all tree nodes, begging with root.     * CAUTION: If the tree is not memory resident, all nodes will be loaded into main memory.     *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -