/*------------------------------------------------------------------------*/ /* */ /* BTREE.H */ /* */ /* Copyright Borland International 1991 */ /* All Rights Reserved */ /* */ /*------------------------------------------------------------------------*/ #if !defined( __BTREE_H ) #define __BTREE_H #if !defined( __CHECKS_H ) #include #endif // __CHECKS_H #if !defined( __SORTABLE_H ) #include #endif // __SORTABLE_H #if !defined( __COLLECT_H ) #include #endif // __COLLECT_H _CLASSDEF(Node) _CLASSDEF(Item) _CLASSDEF(Btree) _CLASSDEF(InnerNode) _CLASSDEF(LeafNode) _CLASSDEF(BtreeIterator) class _CLASSTYPE Node { public: /*dbg*/int debugKey; // !*!*!*! not for distribution! Node( int b, InnerNode _FAR * P, Btree _FAR * T = 0 ); virtual ~Node(); virtual void add( Sortable _FAR *, int ) = 0; virtual void remove( int ) = 0; virtual Object _FAR & operator[]( long i ) const = 0; virtual Object _FAR & found( Sortable _FAR *, Node _FAR * _FAR *, int _FAR * ) = 0; virtual long findRank( Sortable _FAR * ) const = 0; virtual long nofKeys() const = 0; // # keys in or below this node virtual LeafNode _FAR * firstLeafNode() = 0; virtual LeafNode _FAR * lastLeafNode() = 0; virtual void split() = 0; virtual void printOn(ostream _FAR &) const = 0; friend ostream _FAR & operator <<( ostream _FAR &, const Node _FAR & ); int last; // for inner node 1 <= last <= InnerMaxIndex // for leaf node 1 <= last <= LeafMaxIndex // (last==0 only temporarily while the tree is being // updated) InnerNode _FAR *parent; // a parent is always an inner node (or 0 for the root) Btree _FAR *tree; // the tree of which this node is a part int isLeaf; // run-time type flag }; class _CLASSTYPE Item { public: Item(); Item(Node _FAR * n, Sortable _FAR * o); Item(Sortable _FAR * o, Node _FAR * n); ~Item(); // data long nofKeysInTree; // tree can have more than 32K elements Sortable _FAR *key; Node _FAR *tree; }; class _CLASSTYPE InnerNode : public Node { public: InnerNode( InnerNode _FAR *, Btree _FAR * = 0 ); InnerNode( InnerNode _FAR *, Btree _FAR *, Node _FAR * ); ~InnerNode(); void add( Sortable _FAR *, int ); void add( Item _FAR &, int ); void add( int, Sortable _FAR *, Node _FAR * ); void addElt( Item _FAR &, int ); void addElt( int, Sortable _FAR *, Node _FAR * ); void remove( int ); void removeItem( int ); Object _FAR & operator[]( long i ) const; Object _FAR & found( Sortable _FAR *, Node _FAR * _FAR *, int _FAR * ); long nofKeys( int i ) const; void setTree( int i, Node _FAR * node ); void setKey( int i, Sortable _FAR * obj ); void setItem( int i, Item _FAR & itm ); void setItem( int i, Sortable _FAR * obj, Node _FAR * node ); long getNofKeys( int i ) const; void setNofKeys( int i, long r ); long incNofKeys( int i, long N=1 ); long decNofKeys( int i, long N=1 ); long findRank( Sortable _FAR * ) const; long findRank_bu( const Node _FAR * ) const; Node _FAR *getTree( int i ) const; Sortable _FAR *getKey( int i ) const; Item _FAR & getItem( int i ) const; int indexOf( const Node _FAR * ) const; void incrNofKeys( Node _FAR * np ); void decrNofKeys( Node _FAR * np ); long nofKeys() const; LeafNode _FAR *firstLeafNode(); LeafNode _FAR *lastLeafNode(); void informParent(); void split(); void splitWith( InnerNode _FAR *, int ); void mergeWithRight( InnerNode _FAR *, int ); void balanceWithLeft( InnerNode _FAR *, int ); void balanceWithRight( InnerNode _FAR *, int ); void balanceWith( InnerNode _FAR *, int ); void pushLeft( int cnt, InnerNode _FAR * leftsib, int parentIdx ); void pushRight( int cnt, InnerNode _FAR * rightsib, int parentIdx ); void appendFrom( InnerNode _FAR *, int, int ); void append( Sortable _FAR *, Node _FAR * ); void append( Item _FAR & ); void shiftLeft( int ); int Psize() const; int Vsize() const; int maxIndex() const; int maxPsize() const; void printOn(ostream&) const; int isFull() const; void isFull( Node _FAR * ); int isAlmostFull() const; int isLow() const; void isLow( Node _FAR * ); private: Item _FAR *item; // actually items[maxIndex()+1] is desired }; class _CLASSTYPE LeafNode : public Node { public: LeafNode(InnerNode _FAR * P, Sortable _FAR * obj = 0, Btree _FAR * T = 0 ); ~LeafNode(); void add( Sortable _FAR * , int ); void remove( int i ); void removeItem( int i); Object _FAR & operator[]( long i ) const; Object _FAR & found( Sortable _FAR *, Node _FAR * _FAR *, int _FAR * ); long nofKeys( int i ) const; long nofKeys() const; long findRank( Sortable _FAR * ) const; Sortable _FAR *getKey( int idx ) { return item[idx]; } void setKey( int idx, Sortable _FAR * obj ) { item[idx] = obj; } int indexOf( const Sortable _FAR * ) const; LeafNode _FAR *firstLeafNode(); LeafNode _FAR *lastLeafNode(); void split(); void splitWith( LeafNode _FAR *, int ); void mergeWithRight( LeafNode _FAR *, int ); void balanceWithLeft( LeafNode _FAR *, int ); void balanceWithRight( LeafNode _FAR *, int ); void balanceWith( LeafNode _FAR *, int ); void pushLeft( int cnt, LeafNode _FAR *, int parentIndex ); void pushRight( int cnt, LeafNode _FAR *, int parentIndex ); void appendFrom( LeafNode _FAR *, int, int ); void append( Sortable _FAR * ); void shiftLeft ( int ); int Psize() const; int Vsize() const; int maxIndex() const; int maxPsize() const; void printOn(ostream _FAR &) const; int isFull() const; int isAlmostFull() const; int isLow() const; Sortable _FAR * _FAR *item; // actually Sortable* item[maxIndex()+1] is desired }; class _CLASSTYPE Btree : public Collection { public: Btree( int ordern = 3 );//-create a Btree of order n ~Btree(); void add( Object _FAR & ); void detach( Object _FAR &, DeleteType = NoDelete ); void flush( DeleteType = DefDelete ); virtual int hasMember( Object _FAR & ) const; virtual Object _FAR & findMember( Object _FAR & ) const; virtual int isEmpty() const { return itemsInContainer == 0; } virtual countType getItemsInContainer() const { return itemsInContainer; } virtual classType isA() const { return btreeClass; } virtual char _FAR *nameOf() const { return "Btree"; } virtual int isEqual( const Object _FAR & ) const; virtual void printOn( ostream _FAR & ) const; virtual ContainerIterator _FAR & initIterator() const; int order(); Object _FAR & operator[]( long i ) const; long rank( const Object _FAR & ) const; protected: void incrNofKeys() { itemsInContainer++; } void decrNofKeys() { itemsInContainer--; } long i_add( const Object _FAR & ); //-add the object to the tree; return the index // in the tree at which the object was inserted // (C++ doesn't allow signatures // to differ in only the return value). // NOTE: other insertions and deletions may // change this object's index. private: int Order; //-the order of the tree (should be > 2) int Order2; //-always == order*2+1 (assumes a memory access // is cheaper than a multiply and increment by one int Inner_LowWaterMark; int Leaf_LowWaterMark; int Inner_MaxIndex; int Leaf_MaxIndex; Node _FAR *root; void finishInit(int); void rootIsFull(); // called when the root node is full void rootIsEmpty(); // called when root is empty unsigned itemsInContainer; friend Node; friend InnerNode; friend LeafNode; }; inline Node _FAR *InnerNode::getTree( int i ) const { return item[i].tree; } inline Sortable _FAR * InnerNode::getKey( int i ) const { return item[i].key; } inline Item _FAR & InnerNode::getItem( int i ) const { return item[i]; } inline void InnerNode::setTree( int i, Node _FAR * node ) { item[i].tree = node; node->parent = this; } inline void InnerNode::setKey( int i, Sortable _FAR * obj ) { item[i].key = obj; } inline void InnerNode::setItem( int i, Item _FAR & itm ) { item[i] = itm; itm.tree->parent = this; } inline void InnerNode::setItem( int i, Sortable _FAR * obj, Node _FAR * node ) { setTree(i, node); setKey(i, obj); } inline long InnerNode::getNofKeys( int i ) const { PRECONDITION( i >= 0 && i <= last ); return item[i].nofKeysInTree; } inline void InnerNode::setNofKeys( int i, long r ) { item[i].nofKeysInTree = r; } inline long InnerNode::incNofKeys( int i, long N ) { return ( item[i].nofKeysInTree += N ); } inline long InnerNode::decNofKeys( int i, long N ) { return ( item[i].nofKeysInTree -= N ); } inline long InnerNode::nofKeys( int i ) const { return getNofKeys(i); } inline int InnerNode::Psize() const { return last; } inline int InnerNode::Vsize() const { PRECONDITION( parent != 0 && parent->getTree(0) != (Node _FAR *)this ); return Psize()+1; } inline int InnerNode::maxIndex() const { return tree->Inner_MaxIndex; } inline int InnerNode::maxPsize() const { return tree->Inner_MaxIndex; } inline int InnerNode::isFull() const { return last == maxIndex(); } inline int InnerNode::isAlmostFull() const { return last >= maxIndex() - 1; } inline int InnerNode::isLow() const { return last < tree->Inner_LowWaterMark; } inline void LeafNode::removeItem( int i) { remove(i); } inline Object _FAR & LeafNode::operator[]( long i ) const { PRECONDITION( i >=0 && i <= last ); return *((Object _FAR *)item[(int)i]); // CHECK - cast to int OK? } inline int LeafNode::Psize() const { return last+1; } inline int LeafNode::Vsize() const { PRECONDITION( parent != 0 && parent->getTree(0) != (Node _FAR *)this ); return Psize()+1; } inline int LeafNode::maxIndex() const { return tree->Leaf_MaxIndex; } inline int LeafNode::maxPsize() const { return tree->Leaf_MaxIndex + 1; } inline int LeafNode::isFull() const { return last == maxIndex(); } inline int LeafNode::isAlmostFull() const { return last >= maxIndex() - 1; } inline int LeafNode::isLow() const { return last < tree->Leaf_LowWaterMark; } inline int Btree::order() { return Order; } inline ostream _FAR & operator <<( ostream& outputStream, const Node _FAR & aNode) { aNode.printOn( outputStream ); return outputStream; } class _CLASSTYPE BtreeIterator : public ContainerIterator { public: BtreeIterator( const Btree _FAR & ); virtual ~BtreeIterator(); virtual operator int(); virtual Object _FAR & current(); virtual Object _FAR & operator ++(); virtual Object _FAR & operator ++( int ); virtual void restart(); private: const Btree _FAR & beingIterated; long index; }; inline BtreeIterator::BtreeIterator( const Btree _FAR & toIterate ) : beingIterated( toIterate ), index( 0 ) { } inline Object _FAR & Btree::operator[]( long i ) const { return (*root)[i]; } #endif