/****************************************************************************
 *   rtnode.h : 
 *   		header file for Rtree Node class.
 *
 *   Change Log :
 *		  09-17-1997 Initial version,  Liujian Qian
 *
 *   $Id: rtnode.h,v 1.5 1998/12/02 04:03:45 qian Exp $
 ***************************************************************************/
#ifndef _RTNODE_H_
#define _RTNODE_H_

#ifdef __GNUG__
#pragma interface
#endif

#include "rtentry.h"
#include "glist.h"

class RNodePool;

/**
 * @short      Class for RTree node.
 *
 *    A node in the RTree is a page consists of numerous RTree entries.
 *    There are three types of nodes, namely root node, leaf nodes and
 *    non-leaf nodes. 
 *      
 *    RNode is the in-memory representation of a RTree node; it owns
 *    an arrary of RTEntry. When a node is stored to disk, it is packed
 *    into a page of size RTPAGE_SIZE. Vice versa.
 *
 */
class RNode 
{
    friend	class  RNodePool;
    friend	class  RTree;
    
public:
    struct NodeHdr 
    {
	RPtr		parent;	//not used
	RPtr		sibling;
	int		n_entries;
	int		level;
    };
    
    RPtrStk		_path;	//the inclusive path from root to this node

    static    int	nodes_newed;
    static    int	nodes_deled;
    
private:

    NodeHdr		hdr;
    RPtr		_ptr;
    REntry*		entries[MAX_ETS + 1];  //+1 for temporary overflow

    RNode*		next;	//used only by the node allocation pool
    
public:
    
    ///
    NOP			RNode ();
    ///
    NOP			RNode (const RNode& node);
    ///
    virtual NOP		~RNode();
    ///
    RNode&		operator=(const RNode& node);
    ///
    //REntry*		operator[](int i) const;
    ///
    void * 		operator new(size_t);
    ///
    void  		operator delete(void* node, size_t);
    
    //====================================================
    //====
    // GROUP:  Rtree node house-keeping methods
    //====
    //====================================================

    ///
    virtual int		numEntries () const {return hdr.n_entries; };
    ///
    virtual void	setNumEntries (int n) { hdr.n_entries = n; };
    ///
    virtual RPtr	sibling	()  const{ return hdr.sibling; };
    ///
    virtual void	setSibling (const RPtr& p ) { hdr.sibling = p; };
    ///
    virtual RPtr	parent() const 	{ return hdr.parent; }
    ///
    virtual void	setParent(const RPtr& p) { hdr.parent = p; }
    ///
    virtual RPtr	pointer () const  {return _ptr; }
    ///
    virtual void	setPointer(const RPtr& p) {_ptr = p; };    
    ///
    virtual RPtrStk&	path ()   {return _path; };
    ///
    virtual void	setPath(RPtrStk& p) {_path = p; };
    ///
    virtual bool	isLeaf () const	{ return hdr.level ==0; }
    ///
    virtual bool	isRoot () const	{ return _ptr.id() == RT_ROOT_PAGE; };
    ///
    virtual int		level () const	{ return hdr.level; }
    ///
    virtual void	setLevel(int l) { hdr.level = l; } ;
    ///
    virtual bool	isOverFull ()  const;
    ///
    virtual bool	isUnderFull () const;

    ///
    virtual int		getPSize  () const;
    ///
    virtual Result	pack (DataPipe& p);
    ///
    virtual Result	unpack(DataPipe& p);
    ///
    friend ostream&	operator<<(ostream& os, const RNode& n);
    
    //====================================================
    //====
    // GROUP:  RTree node hard-core methods
    //====
    //====================================================

    ///
    virtual REntry*	getEntry(int i) const;
    ///
    virtual GList<REntry*>* search(const RPred& query) const;
    
    ///
    virtual REntry*	searchPtr (const RPtr& ptr, int& pos) const;
    ///
    virtual RPtr	searchMinPenalty (const REntry& e) const;
    ///
    virtual PageID	searchNeighbors (PageID ptr) const;
    
    ///
    virtual Result	insert(const REntry& e);
    ///
    virtual Result	insertBefore(const REntry& e, int idx);
    ///
    virtual Result	remove(int i);
    ///
    virtual Result	bulkRemove (int vec[], int num);
    
    ///
    virtual REntry*	unionIt () const;
    ///
    virtual RNode*	split	();

    
};

/**
 * @internal
 * a hack for speeding up the de/allocation of nodes
 */
class RNodePool
{
    enum {POOL_DELTA = 10};
    
    static int 	  	n_total;
    static int	  	n_free;
    static RNode*   	pool;
    
public:

    ///
    // allocate an Node record from the pool
    static RNode* 	allocNode();
    ///
    // free an Node record and put it back to the pool
    static void		freeNode(RNode* ep);
    ///
    // extend the capacity of the pool w/ 'incr' of new episodes
    static Result	extendPool(int incr=POOL_DELTA);
    ///
    // free all Node; vacate the pool
    static void		freeAll();
    
    static void		stats (){
	                          cout<<"total rtree nodes allocated: "
				  <<n_total<<", free rtree nodes: "
				  <<n_free<<endl; 
                        }
};

#endif

Documentation generated by lqian@lqian-sun on Wed Jul 14 09:36:10 EDT 1999