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 }
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 }
00247 #endif // _PG_HEAP_HPP_