00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 #ifndef _H_HILBERTinsert_TGS
00012 #define _H_HILBERTinsert_TGS
00013  
00014 #include "TGS.h"
00015 #include <limits>
00016 #include <vector>
00017 
00026 template< typename base_tree >
00027 class Hilbert_TGSinsert_tree : public TGS_tree< base_tree > {
00028 
00029   private:
00035         inline void insertionSort( BB_container* element );
00036         
00046         unsigned int lowestGeqThan( const double currentVal, const unsigned int left, const unsigned int right ) const;
00047         
00049         vector< double > hilbertCache;
00050 
00051   protected:
00052   
00054         virtual vector< Ordering< BB_container > * > useOrderings() const;
00055 
00056   public:
00057   
00059         Hilbert_TGSinsert_tree() : TGS_tree< base_tree >() {}
00060         
00062         Hilbert_TGSinsert_tree( R_tree_props* props ) : TGS_tree< base_tree >( props ) {}
00063         
00065         virtual base_tree* insert( BB_container *element );
00066 
00067 };
00068 
00069 template< typename base_tree >
00070 unsigned int Hilbert_TGSinsert_tree< base_tree >::lowestGeqThan( const double currentVal, const unsigned int left, const unsigned int right ) const {
00071         if ( hilbertCache[ left ] >= currentVal )
00072                 return left;
00073         if ( left == right )
00074                 return left + 1;
00075         
00076         const unsigned int mid = ( left + right ) / 2;
00077         
00078         if ( hilbertCache[ mid ] >= currentVal )
00079                 return lowestGeqThan( currentVal, left + 1, mid );
00080         else
00081                 return lowestGeqThan( currentVal, mid + 1, right );
00082 }
00083 
00084 template< typename base_tree >
00085 void Hilbert_TGSinsert_tree< base_tree >::insertionSort( BB_container* element ) {
00086         const unsigned int size = this->cache.size();
00087         vector< double > centre;
00088         element->getCenterCoordinate( ¢re );
00089         const double currentVal = HilbertCoordinateMapper::toHilbert3D( ¢re );
00090         if ( size == 0 ) {
00091                 hilbertCache.push_back( currentVal );
00092                 this->cache.push_back( BB_container( element ) );
00093                 return;
00094         }
00095         const unsigned int insertAt = lowestGeqThan( currentVal, 0, size-1 );
00096         hilbertCache.insert( hilbertCache.begin() + insertAt, currentVal );
00097         this->cache.insert( this->cache.begin() + insertAt, BB_container( element ) );
00098 }
00099 
00100 template< typename base_tree >
00101 base_tree* Hilbert_TGSinsert_tree< base_tree >::insert( BB_container *element ) {
00102         if ( this->loaded ) {
00103                 return base_tree::insert( element );
00104         } else {
00105                 insertionSort( element );
00106                 delete element;
00107                 return this;
00108         }
00109 }
00110 
00111 template< typename base_tree >
00112 vector< Ordering< BB_container > * > Hilbert_TGSinsert_tree< base_tree >::useOrderings() const {
00113         vector< Ordering< BB_container > * > ret;
00114         
00115         ret.push_back( &BB_container::NO_ORDERING );
00116         
00117         return ret;
00118 }
00119 
00120 #endif
00121