Main Page   Class Hierarchy   Compound List   File List   Compound Members  

PG_heap.hpp

00001 #ifndef _PG_HEAP_HPP_
00002 #define _PG_HEAP_HPP_
00003 
00004 #include <vector>
00005 
00006 namespace ParGraph
00007 {
00008 
00009 namespace heap
00010 {
00011 const size_t rowsize = 256;
00012 
00013 template< class TYPE >
00014 class row
00015 {
00016     TYPE * data;
00017     size_t first_empty_entry;
00018     size_t empty_entries_count;
00019 public:
00020     row() : data(0), empty_entries_count(rowsize) {}
00021     size_t insert( const TYPE & element );
00022     size_t insert();
00023     bool erase( size_t );
00024     TYPE & operator[] ( size_t pos ) { return data[ pos ]; }
00025     const TYPE & operator[] ( size_t pos ) const { return data[ pos ]; }
00026     bool is_full() const { return empty_entries_count == 0; }
00027     void delete_row() 
00028         {
00029             assert( empty_entries_count == rowsize );
00030             free( data ); data = 0;
00031         }
00032     void destrukt();
00033 };
00034 
00035 template< class TYPE >
00036 size_t
00037 row<TYPE>::insert( const TYPE & element )
00038 {
00039   if( data == 0 )
00040   {
00041     data = (TYPE*) malloc( rowsize * sizeof(TYPE) * 2 );
00042     assert( data != 0 );
00043     for( size_t i = 0 ; i < rowsize ; i++ )
00044     {
00045       size_t * p = reinterpret_cast<size_t *>( & data[ i ] );
00046       *p = i + 1;
00047     }
00048     first_empty_entry = 0;
00049   }
00050   assert( first_empty_entry < rowsize && empty_entries_count > 0 );
00051 
00052   size_t tmp = first_empty_entry;
00053   size_t * p = reinterpret_cast<size_t *>( & data[ first_empty_entry ] );
00054   first_empty_entry = *p;
00055   new( static_cast< void* >( & data[ tmp ] ) ) TYPE( element );
00056   empty_entries_count--;
00057   return tmp;
00058 }
00059 
00060 template< class TYPE >
00061 size_t
00062 row<TYPE>::insert()
00063 {
00064   if( data == 0 )
00065   {
00066     data = (TYPE*) malloc( rowsize * sizeof(TYPE) * 2 );
00067     assert( data != 0 );
00068     for( size_t i = 0 ; i < rowsize ; i++ )
00069     {
00070       size_t * p = reinterpret_cast<size_t *>( & data[ i ] );
00071       *p = i + 1;
00072     }
00073     first_empty_entry = 0;
00074   }
00075   assert( first_empty_entry < rowsize && empty_entries_count > 0 );
00076 
00077   size_t tmp = first_empty_entry;
00078   size_t * p = reinterpret_cast<size_t *>( & data[ first_empty_entry ] );
00079   first_empty_entry = *p;
00080   new( static_cast< void* >( & data[ tmp ] ) ) TYPE();
00081   empty_entries_count--;
00082   return tmp;
00083 }
00084 
00085 template< class TYPE >
00086 bool
00087 row<TYPE>::erase( size_t pos )
00088 {
00089   data[ pos ].~TYPE();
00090   size_t * p = reinterpret_cast<size_t *>( & data[ pos ] );
00091   *p = first_empty_entry;
00092   first_empty_entry = pos;
00093   empty_entries_count++;
00094   return empty_entries_count == rowsize;
00095 }
00096 
00097 template< class TYPE >
00098 void
00099 row<TYPE>::destrukt()
00100 {
00101   if( data == 0 ) return;
00102   std::vector<bool> tmp( rowsize, true );
00103   size_t i = first_empty_entry;
00104   while( i != rowsize )
00105   {
00106     tmp[i] = false;
00107     size_t * p = reinterpret_cast<size_t *>( & data[ i ] );
00108     i = *p;
00109   }
00110   for( i = 0 ; i < rowsize ; i++ )
00111   {
00112     if( tmp[i] )  data[ i ].~TYPE();
00113   }
00114   free( data );
00115 }
00116 
00117 } // namespace heap
00118 
00119 
00120 template< class TYPE >
00121 class PG_heap
00122 {
00123     std::vector< heap::row<TYPE> > datarows;
00124 
00125     size_t first_non_full_row;
00126     bool one_non_deleted_row_exists;
00127     size_t non_deleted_row;
00128     size_t _size;
00129 public:
00130     PG_heap();
00131     ~PG_heap();
00132 
00133     size_t insert( const TYPE & );
00134     size_t insert();
00135     void erase( size_t );
00136     TYPE & operator[] ( size_t );
00137     const TYPE & operator[] ( size_t ) const;
00138     size_t size() const { return _size; }
00139 };
00140 
00141 template< class TYPE >
00142 PG_heap<TYPE>::PG_heap() : datarows(), first_non_full_row(0), 
00143                            one_non_deleted_row_exists(false),
00144                            non_deleted_row(0), _size(0)
00145 { }
00146 
00147 template< class TYPE >
00148 PG_heap<TYPE>::~PG_heap()
00149 {
00150   typename std::vector< heap::row<TYPE> >::iterator it = datarows.begin();
00151   for(; it != datarows.end() ; it++ )
00152   {
00153     (*it).destrukt();
00154   }
00155 }
00156 
00157 template< class TYPE >
00158 size_t
00159 PG_heap<TYPE>::insert( const TYPE & element )
00160 {
00161   _size++;
00162   if( first_non_full_row == datarows.size() )
00163   {
00164     datarows.push_back( heap::row<TYPE>() );
00165   }
00166 
00167   size_t pos = datarows[ first_non_full_row ].insert( element );
00168   pos += first_non_full_row * heap::rowsize;
00169 
00170   if( one_non_deleted_row_exists && non_deleted_row == pos )
00171       one_non_deleted_row_exists = false;
00172 
00173   while( first_non_full_row < datarows.size() && datarows[ first_non_full_row ].is_full() )
00174   {
00175     first_non_full_row++;
00176   }
00177   return pos;
00178 }
00179 
00180 template< class TYPE >
00181 size_t
00182 PG_heap<TYPE>::insert()
00183 {
00184   _size++;
00185   if( first_non_full_row == datarows.size() )
00186   {
00187     datarows.push_back( heap::row<TYPE>() );
00188   }
00189 
00190   size_t pos = datarows[ first_non_full_row ].insert();
00191   pos += first_non_full_row * heap::rowsize;
00192 
00193   if( one_non_deleted_row_exists && non_deleted_row == pos )
00194       one_non_deleted_row_exists = false;
00195 
00196   while( first_non_full_row < datarows.size() && datarows[ first_non_full_row ].is_full() )
00197   {
00198     first_non_full_row++;
00199   }
00200   return pos;
00201 }
00202 
00203 template< class TYPE >
00204 void
00205 PG_heap<TYPE>::erase( size_t pos )
00206 {
00207   _size--;
00208   if( datarows[ pos / heap::rowsize ].erase( pos % heap::rowsize ) )
00209   {
00210     if( one_non_deleted_row_exists )
00211     {
00212       if( pos / heap::rowsize < non_deleted_row )
00213       {
00214         datarows[ non_deleted_row ].delete_row();
00215         non_deleted_row = pos / heap::rowsize;
00216       }
00217       else
00218       {
00219         datarows[ pos / heap::rowsize ].delete_row();
00220       }
00221     }
00222     else
00223     {
00224       one_non_deleted_row_exists = true;
00225       non_deleted_row = pos / heap::rowsize;
00226     }
00227   }
00228   if( pos / heap::rowsize < first_non_full_row )
00229   first_non_full_row = pos / heap::rowsize;
00230 }
00231 
00232 template< class TYPE >
00233 TYPE &
00234 PG_heap<TYPE>::operator[] ( size_t pos )
00235 {
00236   return datarows[ pos / heap::rowsize ][ pos % heap::rowsize ];
00237 }
00238 
00239 template< class TYPE >
00240 const TYPE &
00241 PG_heap<TYPE>::operator[] ( size_t pos ) const
00242 {
00243   return datarows[ pos / heap::rowsize ][ pos % heap::rowsize ];
00244 }
00245 
00246 } // namespace ParGraph
00247 #endif // _PG_HEAP_HPP_

Generated on Sun Feb 29 05:14:24 2004 for ParGraph by doxygen1.3-rc3