FPB.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2007  A.N. Yzelman
00003  *  Released under LGPL, see license.txt
00004  *
00005  *  Last modified at 31th of May, 2007, by A.N. Yzelman
00006  *
00007  *  FPB.h: Definition of a Fast Packed Bulk-loaded R-tree.
00008  */
00009 
00010 #ifndef _H_FPB
00011 #define _H_FPB
00012  
00013 #include "Hilbert_R-Tree.h"
00014 #include <limits>
00015 
00016 //#define _DEBUG
00017 
00019 template< typename base_tree >
00020 class FPB_tree : public base_tree {
00021 
00022    private:
00023    
00029         virtual bool checkReady() const { return loaded; }
00030         
00032         bool loaded;
00033         
00037         vector< BB_container > cache;
00038 
00046         vector< base_tree* > bulkLoad( vector< BB_container* > *input );
00047         
00048    protected:
00049    
00054         virtual Ordering< BB_container >* useOrdering() const;
00055         
00056         
00057    public:
00058    
00063    FPB_tree() : base_tree() { loaded = false; this->deleteLeaves = false; }
00064    
00071    FPB_tree( R_tree_props *props ) : base_tree( props ) { loaded = false; this->deleteLeaves = false; }
00072         
00076     virtual ~FPB_tree() { }
00077    
00083         virtual void ensureReady();
00084    
00086         void bulkLoad();
00087         
00097          virtual base_tree *insert( BB_container *element );
00098 
00107         virtual base_tree *remove( BB_container *element );
00108 
00116         virtual base_tree *search( BB_container *element );
00117 
00119         virtual vector< int > containedIn( BB_type box ) const;
00120 
00122         virtual vector< int > intersects( const vector< double > begin, const vector< double > end ) const;
00123 
00125         virtual vector< int > intersects( Point point ) const;
00126 
00128         virtual vector< int > intersects( vector<double> a, double b ) const;
00129 
00131         virtual vector< int > neighboursOf( BB_container *item ) const;
00132 
00133 };
00134 
00135 
00136 /***************************************************
00137  *                       PRIVATE                   *
00138  ***************************************************/
00139 
00140 template< typename base_tree >
00141 void FPB_tree< base_tree >::ensureReady() {
00142         if ( !loaded ) {
00143                 bulkLoad();
00144         }
00145 }
00146 
00147 template< typename base_tree >
00148 Ordering< BB_container >* FPB_tree< base_tree >::useOrdering() const {
00149         //basic FPB algorithm assumes the existance of an Hilbert ordering
00150         return &BB_container::HILC_ORDERING;
00151 }
00152 
00153 template< typename base_tree >
00154 void FPB_tree< base_tree >::bulkLoad() {
00155         if ( loaded ) {
00156                 cerr << "FPB_tree::bulkLoad() called while already bulkloaded!" << endl;
00157                 exit( 1 );
00158         }
00159 
00160         if ( cache.size() == 0 ) {
00161                 cerr << "Error; tried to bulk load an empty set. Aborting..." << endl;
00162                 return;
00163         }
00164         
00165         vector< BB_container* > p_cache;
00166         vector< BB_container >::iterator it = cache.begin();
00167         for( ; it!=cache.end(); it++ )
00168                 p_cache.push_back( &( *it ) );
00169 
00170 #ifdef _DEBUG
00171         cout << "Entering sort... " << endl; fflush( stdout );
00172 #endif
00173 
00174                 useOrdering()->sort( &p_cache );
00175 
00176 #ifdef _DEBUG
00177         cout << "Exitting sort... " << endl; fflush( stdout );
00178 #endif
00179         
00180         vector< base_tree* > new_children = bulkLoad( &p_cache );
00181         
00182         /*BB_type children_mbr;
00183         
00184         vector< base_tree* >::iterator it = new_children.begin();
00185         for( ; it!=new_children.end(); it++ )
00186                 children_mbr = (*it)->mbr.unite( children_mbr );
00187         
00188         //check for degenerate root
00189         if ( new_children.size() == 1 ) {
00190                 base_tree* walk = new_children[0];
00191                 elements = walk->elements;
00192                 children = walk->children;
00193                 properties = walk->properties; //actually kind of useless
00194                 //mbr = children_mbr;
00195                 updateMBRLocal();
00196         } else {*/
00197                 //simply set new children
00198                 this->setChildren( new_children, 0 );
00199                 /* weird c++ protected rules prevent the below
00200                 this->children = new_children;
00201                 typename vector< base_tree* >::iterator childIt = new_children.begin();
00202                 for( ; childIt!=new_children.end(); childIt++ )
00203                         (*childIt)->parent = this;*/
00204                 //mbr = children_mbr;
00205                 this->updateMBRLocal();
00206         //}
00207         
00208         //whilst MBRs were updated constantly, things like LHV were not (in the hilbert r-tree case).
00209         //we do this now;
00210         this->postBulkLoad();
00211         
00212         loaded = true;
00213 }
00214 
00215 template< typename base_tree >
00216 vector< base_tree* > FPB_tree< base_tree >::bulkLoad( vector< BB_container* > *input ) {
00217                 
00218         //initialise lowest tree level
00219         vector< base_tree* > singleTreeLevel;
00220 
00221         //add all elements and build the lowest level
00222         vector< BB_container* >::iterator it = input->begin();
00223         unsigned int added = 0;
00224         BB_type curBB;
00225         vector< BB_container* > nodeElems;
00226         for( ; it!=input->end(); it++ ) {
00227                 if ( added == this->properties->maximum ) {
00228                         singleTreeLevel.push_back( this->buildNode( nodeElems, new BB_type( curBB ) ) );
00229                         nodeElems.clear();
00230                         added = 0;
00231                 }
00232                 curBB = curBB && ( *(*it) );
00233                 nodeElems.push_back( *it );
00234                 added++;
00235         }
00236         
00237         //could be that nodeElems is not empty;
00238         if ( added > 0 )
00239                         singleTreeLevel.push_back( this->buildNode( nodeElems, new BB_type( curBB ) ) );
00240         
00241         added = 0;
00242         nodeElems.clear();
00243         curBB.clear();
00244         
00245         //lowest level done, now we recurse until singleTreeLevel < max
00246         while ( singleTreeLevel.size() > this->properties->maximum ) {
00247                 vector< base_tree* > newLevel;
00248                 typename vector< base_tree* >::iterator it;
00249                 vector< base_tree* > nodeElems;
00250                 it = singleTreeLevel.begin();
00251                 for( ; it!=singleTreeLevel.end(); it++ ) {
00252                         if ( added == this->properties->maximum ) {
00253                                 newLevel.push_back( buildNode( nodeElems, new BB_type( curBB ) ) );
00254                                 nodeElems.clear();
00255                                 added = 0;
00256                         }
00257                         curBB.unite( (*it)->getMBR() );
00258                         //curBB = (*it)->getMBR()->unite( curBB );
00259                         nodeElems.push_back( *it );
00260                         added++;
00261                 }
00262                 if ( added > 0 )
00263                         newLevel.push_back( buildNode( nodeElems, new BB_type( curBB ) ) );
00264                 added = 0;
00265                 nodeElems.clear();
00266                 curBB.clear();
00267                 //prepare next recursion
00268                 singleTreeLevel.assign( newLevel.begin(), newLevel.end() );
00269                 newLevel.clear();
00270         }
00271         
00272         //return the highest level of children
00273         return singleTreeLevel;
00274         
00275 }
00276 
00277 template< typename base_tree >
00278 base_tree* FPB_tree< base_tree >::insert( BB_container *element ) {
00279         if ( loaded ) {
00280                 return base_tree::insert( element );
00281         } else {
00282                 cache.push_back( BB_container( element ) );
00283                 delete element;
00284                 return this;
00285         }
00286 }
00287 
00288 template< typename base_tree >
00289 base_tree* FPB_tree< base_tree >::remove( BB_container *element ) {
00290         if ( loaded ) {
00291                 return base_tree::remove( element );
00292         } else {
00293                 vector< BB_container >:: iterator it = cache.begin();
00294                 for( ; it!=cache.end(); it++ )
00295                         if ( &(*it) == element || (*it).getID() == element->getID() )
00296                                 cache.erase( it );
00297                 return this;
00298         }
00299 }
00300 
00301 template< typename base_tree >
00302 base_tree* FPB_tree< base_tree >::search( BB_container *element ) {
00303         if ( loaded ) {
00304                 return base_tree::search( element );
00305         } else {
00306                 vector< BB_container >:: iterator it = cache.begin();
00307                 for( ; it!=cache.end(); it++ )
00308                         if ( &(*it) == element || (*it).getID() == element->getID() )
00309                                 return this;
00310                 return 0;
00311         }
00312 }
00313 
00314 template< typename base_tree >
00315 vector< int > FPB_tree< base_tree >::containedIn( BB_type box ) const {
00316         if ( !checkReady() ) {
00317                 cerr << "Trying to query while datastructure was not ready for access!" << endl;
00318                 exit( 1 );
00319         }
00320         return base_tree::containedIn( box );
00321 }
00322 
00323 template< typename base_tree >
00324 vector< int > FPB_tree< base_tree >::intersects( const vector< double > begin, const vector< double > end ) const {
00325         if ( !checkReady() ) {
00326                 cerr << "Trying to query while datastructure was not ready for access!" << endl;
00327                 exit( 1 );
00328         }
00329         return base_tree::intersects( begin, end );
00330 }
00331 
00332 template< typename base_tree >
00333 vector< int > FPB_tree< base_tree >::intersects( Point point ) const {
00334         if ( !checkReady() ) {
00335                 cerr << "Trying to query while datastructure was not ready for access!" << endl;
00336                 exit( 1 );
00337         }
00338         return base_tree::intersects( point );
00339 }
00340 
00341 template< typename base_tree >
00342 vector< int > FPB_tree< base_tree >::intersects( vector<double> a, double b ) const {
00343         if ( !checkReady() ) {
00344                 cerr << "Trying to query while datastructure was not ready for access!" << endl;
00345                 exit( 1 );
00346         }
00347         return base_tree::intersects( a, b );
00348 }
00349 
00350 template< typename base_tree >
00351 vector< int > FPB_tree< base_tree >::neighboursOf( BB_container *item ) const {
00352         if ( !checkReady() ) {
00353                 cerr << "Trying to query while datastructure was not ready for access!" << endl;
00354                 exit( 1 );
00355         }
00356         return base_tree::neighboursOf( item );
00357 }
00358 
00359 #endif

Generated on Sat Oct 13 17:34:42 2007 for R-Tree by  doxygen 1.5.2