opennurbs_fsp.cpp
Go to the documentation of this file.
00001 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00002 
00003 ON_FixedSizePool::ON_FixedSizePool()
00004 {
00005   memset(this,0,sizeof(*this));
00006 }
00007 
00008 ON_FixedSizePool::~ON_FixedSizePool()
00009 {
00010   Destroy();
00011 }
00012 
00013 size_t ON_FixedSizePool::SizeofElement() const
00014 {
00015   return m_sizeof_element;
00016 }
00017 
00018 
00019 bool ON_FixedSizePool::Create( 
00020         size_t sizeof_element, 
00021         size_t element_count_estimate,
00022         size_t block_element_capacity
00023         )
00024 {
00025   if ( sizeof_element <= 0 )
00026   {
00027     ON_ERROR( "ON_FixedSizePool::Create - sizeof_element <= 0" );
00028     return false;
00029   }
00030 
00031   if ( m_sizeof_element != 0 || 0 != m_first_block )
00032   {
00033     ON_ERROR( "ON_FixedSizePool::Create - called on a pool that is in use." );
00034     return false;
00035   }
00036 
00037   memset(this,0,sizeof(*this));
00038 
00039   m_sizeof_element = sizeof_element;
00040 
00041   if ( block_element_capacity <= 0 )
00042   {
00043     size_t page_size = ON_MemoryPageSize();
00044     if ( page_size < 512 )
00045       page_size = 512;
00046 
00047     // The "overhead" is for the 2*sizeof(void*) ON_FixedSizePool uses at
00048     // the start of each block + 32 bytes extra for the heap manager
00049     // to keep the total allocation not exceeding multiple of page_size.
00050     const size_t overhead = 2*sizeof(void*) + 32;
00051 
00052     size_t page_count = 1;
00053     block_element_capacity = (page_count*page_size - overhead)/m_sizeof_element;
00054     while ( block_element_capacity < 1000 )
00055     {
00056       page_count *= 2;
00057       block_element_capacity = (page_count*page_size - overhead)/m_sizeof_element;
00058       if (page_count > 8 && block_element_capacity > 64)
00059       {
00060         // for pools with large elements
00061         break;
00062       }
00063     }
00064   }
00065 
00066   // capacity for the the 2nd and subsequent blocks
00067   m_block_element_count = block_element_capacity;
00068 
00069   // Set m_al_count = capacity of the first block.
00070 
00071   // If the estimated number of elements is not too big, 
00072   // then make the first block that size.
00073   if ( element_count_estimate > 0 )
00074   {
00075     // this is the first block and it has a custom size
00076     if ( 8*m_block_element_count >= element_count_estimate )
00077       m_al_count = element_count_estimate;
00078     else 
00079       m_al_count = 8*m_block_element_count; // first block will be large
00080   }
00081   else
00082   {
00083     m_al_count = m_block_element_count;
00084   }
00085 
00086   return true;
00087 }
00088 
00089 void ON_FixedSizePool::ReturnAll()
00090 {
00091   if ( 0 != m_first_block )
00092   {
00093     // initialize
00094     m_al_element_stack = 0;
00095     m_qwerty_it_block = 0;
00096     m_qwerty_it_element = 0;
00097     m_al_block = m_first_block;
00098     m_al_element_array = (void*)(((char*)m_al_block) + 2*sizeof(void*));
00099     m_al_count = BlockElementCapacity(m_first_block); 
00100     m_active_element_count = 0;
00101     m_total_element_count = 0;
00102   }
00103 }
00104 
00105 void ON_FixedSizePool::Destroy()
00106 {
00107   void* p;
00108   void* next;
00109   next = m_first_block;
00110   memset(this,0,sizeof(*this));
00111   for ( p = next; 0 != p; p = next )
00112   {
00113     next = *((void**)p);
00114     onfree(p);
00115   }
00116 }
00117 
00118 void ON_FixedSizePool::EmergencyDestroy()
00119 {
00120   memset(this,0,sizeof(*this));
00121 }
00122 
00123 void ON_FixedSizePool::SetHeap( ON_MEMORY_POOL* heap )
00124 {
00125   m_heap = heap;
00126 }
00127 
00128 ON_MEMORY_POOL* ON_FixedSizePool::Heap()
00129 {
00130   return m_heap;
00131 }
00132 
00133 size_t ON_FixedSizePool::ActiveElementCount() const
00134 {
00135   return m_active_element_count;
00136 }
00137 
00138 size_t ON_FixedSizePool::TotalElementCount() const
00139 {
00140   return m_total_element_count;
00141 }
00142 
00143 void* ON_FixedSizePool::AllocateElement()
00144 {
00145   void* p;
00146 
00147   if ( 0 != m_al_element_stack )
00148   {
00149     // use item on the returned stack first.
00150     p = m_al_element_stack;
00151     m_al_element_stack = *((void**)m_al_element_stack);
00152   }
00153   else
00154   {
00155     if ( 0 == m_al_block || 0 == m_al_count )
00156     {
00157       // No more memory left in m_al_block.
00158       void* next_block = (0 != m_al_block)
00159                        ? *((void**)m_al_block)
00160                        : 0;
00161       if ( 0 == next_block )
00162       {
00163         // This if clause is used when we need to allocate a new block from the heap
00164         if ( 0 == m_sizeof_element )
00165         {
00166           ON_ERROR("ON_FixedSizePool::AllocateElement - you must call ON_FixedSizePool::Create with a valid element size before using ON_FixedSizePool");
00167           return 0;
00168         }
00169         // allocate a new block
00170         if ( 0 == m_al_count )
00171           m_al_count = m_block_element_count;
00172 
00173         if ( m_al_count <= 0 )
00174         {
00175           ON_ERROR("ON_FixedSizePool::AllocateElement - you must call ON_FixedSizePool::Create with a valid element size before using ON_FixedSizePool");
00176           return 0;
00177         }
00178 
00179         p = onmalloc_from_pool( m_heap, 2*sizeof(void*) + m_al_count*m_sizeof_element ); // get some heap
00180 
00181         // set "next" pointer to zero
00182         *((void**)p) = 0;
00183 
00184         // set "end" pointer to address after last byte in the block
00185         *((void**)(((char*)p) + sizeof(void*))) = ((char*)p) + (2*sizeof(void*) + m_al_count*m_sizeof_element);
00186         if ( 0 == m_first_block )
00187         {
00188           m_first_block = p;
00189           // If the call to Create() specified a positive element_count_estimate,
00190           // then m_sizeof_block needs to be reset for any future block allocations.
00191           
00192         }
00193         else
00194         {
00195           // If m_first_block != 0, then m_al_block is nonzero (or memory for this class has been trashed)
00196           *((void**)m_al_block) = p;
00197         }
00198         m_al_block = p;
00199       }
00200       else
00201       {
00202         // If we get here, ReturnAll() was used at some point in
00203         // the past, m_al_block != 0, m_al_count = zero, and we are
00204         // reusing blocks that were allocated early.
00205         m_al_block = next_block;
00206         m_al_count = BlockElementCapacity(m_al_block);
00207       }
00208 
00209       m_al_element_array = (void*)(((char*)m_al_block)+2*sizeof(void*));
00210     }
00211     m_al_count--;
00212     p = m_al_element_array;
00213     m_al_element_array = (void*)(((char*)m_al_element_array) + m_sizeof_element);
00214     m_total_element_count++;
00215   }
00216 
00217   memset(p,0,m_sizeof_element);
00218   m_active_element_count++;
00219 
00220   return p;
00221 }
00222 
00223 void ON_FixedSizePool::ReturnElement(void* p)
00224 {
00225   if ( p )
00226   {
00227     if ( m_active_element_count <= 0 )
00228     {
00229       // If you get this error, something is seriously wrong.
00230       // You may be returning the same element multiple times or 
00231       // you may be returning pointers that are not from this pool.
00232       // In any case, you're probably going to be crashing sometime soon.
00233       ON_ERROR("ON_FixedSizePool::ReturnElement - no active elements exist.");
00234     }
00235     else
00236     {
00237       m_active_element_count--;
00238       *((void**)p) = m_al_element_stack;
00239       m_al_element_stack = p;
00240     }
00241   }
00242 }
00243 
00244 
00245 ON_FixedSizePoolIterator::ON_FixedSizePoolIterator( const ON_FixedSizePool& fsp )
00246 : m_fsp(fsp)
00247 , m_it_block(0)
00248 , m_it_element(0)
00249 {}
00250 
00251 void* ON_FixedSizePool::FirstElement()
00252 {
00253   if ( m_first_block && m_total_element_count > 0 )
00254   {
00255     m_qwerty_it_block = m_first_block;
00256     m_qwerty_it_element = (void*)(((char*)m_qwerty_it_block)+2*sizeof(void*)); // m_qwerty_it_element points to first element in m_first_block
00257   }
00258   else
00259   {
00260     m_qwerty_it_block = 0;
00261     m_qwerty_it_element = 0;
00262   }
00263   return m_qwerty_it_element;
00264 }
00265 
00266 void* ON_FixedSizePoolIterator::FirstElement()
00267 {
00268   if ( m_fsp.m_first_block && m_fsp.m_total_element_count > 0 )
00269   {
00270     m_it_block = m_fsp.m_first_block;
00271     m_it_element = (void*)(((char*)m_it_block)+2*sizeof(void*)); // m_it_element points to first element in m_first_block
00272   }
00273   else
00274   {
00275     m_it_block = 0;
00276     m_it_element = 0;
00277   }
00278   return m_it_element;
00279 }
00280 
00281 void* ON_FixedSizePool::NextElement()
00282 {
00283   if ( m_qwerty_it_element )
00284   {
00285     m_qwerty_it_element = (void*)(((char*)m_qwerty_it_element) + m_sizeof_element);
00286     if ( m_qwerty_it_element == m_al_element_array )
00287     {
00288       m_qwerty_it_block = 0;
00289       m_qwerty_it_element = 0;
00290     }
00291     else if ( m_qwerty_it_element == *((void**)(((char*)m_qwerty_it_block) + sizeof(void*))) )
00292     {
00293       // m_qwerty_it_element  = "end" pointer which means we are at the end of m_qwerty_it_block
00294       m_qwerty_it_block = *((void**)m_qwerty_it_block); // m_qwerty_it_block = "next" block
00295       m_qwerty_it_element = (0 != m_qwerty_it_block)    // m_qwerty_it_element points to first element in m_qwerty_it_block
00296                    ? (void*)(((char*)m_qwerty_it_block)+2*sizeof(void*))
00297                    : 0;
00298       if ( m_qwerty_it_element == m_al_element_array )
00299       {
00300         m_qwerty_it_block = 0;
00301         m_qwerty_it_element = 0;
00302       }
00303     }
00304   }
00305   return m_qwerty_it_element;
00306 }
00307 
00308 void* ON_FixedSizePoolIterator::NextElement()
00309 {
00310   if ( m_it_element )
00311   {
00312     m_it_element = (void*)(((char*)m_it_element) + m_fsp.m_sizeof_element);
00313     if ( m_it_element == m_fsp.m_al_element_array )
00314     {
00315       m_it_block = 0;
00316       m_it_element = 0;
00317     }
00318     else if ( m_it_element == *((void**)(((char*)m_it_block) + sizeof(void*))) )
00319     {
00320       // m_it_element  = "end" pointer which means we are at the end of m_it_block
00321       m_it_block = *((void**)m_it_block); // m_it_block = "next" block
00322       m_it_element = (0 != m_it_block)    // m_it_element points to first element in m_it_block
00323                    ? (void*)(((char*)m_it_block)+2*sizeof(void*))
00324                    : 0;
00325       if ( m_it_element == m_fsp.m_al_element_array )
00326       {
00327         m_it_block = 0;
00328         m_it_element = 0;
00329       }
00330     }
00331   }
00332   return m_it_element;
00333 }
00334 
00335 void* ON_FixedSizePool::FirstElement(size_t element_index)
00336 {
00337   const char* block;
00338   const char* block_end;
00339   const char* next_block;
00340   size_t block_count;
00341 
00342   m_qwerty_it_block = 0;
00343   m_qwerty_it_element = 0;
00344   if ( element_index < m_total_element_count )
00345   {
00346     for ( block = (const char*)m_first_block; 0 != block; block = next_block )
00347     {
00348       if ( block == m_al_block )
00349       {
00350         next_block = 0;
00351         block_end = (const char*)m_al_element_array;
00352       }
00353       else
00354       {
00355         next_block = *((const char**)block);
00356         block_end =  *((const char**)(block + sizeof(void*)));
00357       }
00358       block_count = (block_end - block)/m_sizeof_element;
00359       if ( element_index < block_count )
00360       {
00361         m_qwerty_it_block = (void*)block;
00362         m_qwerty_it_element = ((void*)(block + (2*sizeof(void*) + element_index*m_sizeof_element)));
00363         break;
00364       }
00365       element_index -= block_count;
00366     }
00367   }
00368   return m_qwerty_it_element;
00369 }
00370 
00371 void* ON_FixedSizePoolIterator::FirstElement(size_t element_index)
00372 {
00373   const char* block;
00374   const char* block_end;
00375   const char* next_block;
00376   size_t block_count;
00377 
00378   m_it_block = 0;
00379   m_it_element = 0;
00380   if ( element_index < m_fsp.m_total_element_count )
00381   {
00382     for ( block = (const char*)m_fsp.m_first_block; 0 != block; block = next_block )
00383     {
00384       if ( block == m_fsp.m_al_block )
00385       {
00386         next_block = 0;
00387         block_end = (const char*)m_fsp.m_al_element_array;
00388       }
00389       else
00390       {
00391         next_block = *((const char**)block);
00392         block_end =  *((const char**)(block + sizeof(void*)));
00393       }
00394       block_count = (block_end - block)/m_fsp.m_sizeof_element;
00395       if ( element_index < block_count )
00396       {
00397         m_it_block = (void*)block;
00398         m_it_element = ((void*)(block + (2*sizeof(void*) + element_index*m_fsp.m_sizeof_element)));
00399         break;
00400       }
00401       element_index -= block_count;
00402     }
00403   }
00404   return m_it_element;
00405 }
00406 
00407 size_t ON_FixedSizePool::BlockElementCapacity( const void* block ) const
00408 {
00409   // returns number of items that can be allocated from block
00410   if ( 0 == block || m_sizeof_element <= 0 )
00411     return 0;
00412   char* block_end = *((char**)(((char*)block)+sizeof(void*)));
00413   return (block_end - ((char*)block))/m_sizeof_element;
00414 }
00415 
00416 size_t ON_FixedSizePool::BlockElementCount( const void* block ) const
00417 {
00418   // returns number of items allocated from block
00419   if ( 0 == block || m_sizeof_element <= 0 )
00420     return 0;
00421   char* block_end = (block == m_al_block && m_al_count > 0)
00422       ? ((char*)m_al_element_array)
00423       : *((char**)(((char*)block)+sizeof(void*)));
00424   return (block_end - ((char*)block))/m_sizeof_element;
00425 }
00426 
00427 void* ON_FixedSizePool::FirstBlock( size_t* block_element_count )
00428 {
00429   if ( m_first_block && m_total_element_count > 0 )
00430   {
00431     m_qwerty_it_block = m_first_block;
00432     m_qwerty_it_element = (void*)(((char*)m_qwerty_it_block)+2*sizeof(void*)); // m_qwerty_it_element points to first element in m_first_block
00433     if ( 0 != block_element_count )
00434       *block_element_count = BlockElementCount(m_qwerty_it_block);
00435   }
00436   else
00437   {
00438     m_qwerty_it_block = 0;
00439     m_qwerty_it_element = 0;
00440     if ( 0 != block_element_count )
00441       *block_element_count = 0;
00442   }
00443   return m_qwerty_it_element;
00444 }
00445 
00446 void* ON_FixedSizePoolIterator::FirstBlock( size_t* block_element_count )
00447 {
00448   if ( m_fsp.m_first_block && m_fsp.m_total_element_count > 0 )
00449   {
00450     m_it_block = m_fsp.m_first_block;
00451     m_it_element = (void*)(((char*)m_it_block)+2*sizeof(void*)); // m_it_element points to first element in m_first_block
00452     if ( 0 != block_element_count )
00453       *block_element_count = m_fsp.BlockElementCount(m_it_block);
00454   }
00455   else
00456   {
00457     m_it_block = 0;
00458     m_it_element = 0;
00459     if ( 0 != block_element_count )
00460       *block_element_count = 0;
00461   }
00462   return m_it_element;
00463 }
00464 
00465 void* ON_FixedSizePool::NextBlock( size_t* block_element_count )
00466 {
00467   if ( 0 != m_qwerty_it_block 
00468        && m_qwerty_it_block != m_al_block
00469        && m_qwerty_it_element == (void*)(((char*)m_qwerty_it_block)+2*sizeof(void*)) )
00470   {
00471     m_qwerty_it_block = *((void**)m_qwerty_it_block);
00472     if ( m_qwerty_it_block == m_al_element_array )
00473     {
00474       m_qwerty_it_block = 0;
00475       m_qwerty_it_element = 0;
00476       if ( 0 != block_element_count )
00477         *block_element_count = 0;
00478     }
00479     else
00480     {
00481       m_qwerty_it_element = (void*)(((char*)m_qwerty_it_block)+2*sizeof(void*)); // m_qwerty_it_element points to first element in m_first_block
00482       if ( 0 != block_element_count )
00483         *block_element_count = BlockElementCount(m_qwerty_it_block);
00484     }
00485   }
00486   else
00487   {
00488     m_qwerty_it_block = 0;
00489     m_qwerty_it_element = 0;
00490     if ( 0 != block_element_count )
00491       *block_element_count = 0;
00492   }
00493   return m_qwerty_it_element;
00494 }
00495 
00496 void* ON_FixedSizePoolIterator::NextBlock( size_t* block_element_count )
00497 {
00498   if ( 0 != m_it_block 
00499        && m_it_block != m_fsp.m_al_block
00500        && m_it_element == (void*)(((char*)m_it_block)+2*sizeof(void*)) )
00501   {
00502     m_it_block = *((void**)m_it_block);
00503     if ( m_it_block == m_fsp.m_al_element_array )
00504     {
00505       m_it_block = 0;
00506       m_it_element = 0;
00507       if ( 0 != block_element_count )
00508         *block_element_count = 0;
00509     }
00510     else
00511     {
00512       m_it_element = (void*)(((char*)m_it_block)+2*sizeof(void*)); // m_it_element points to first element in m_first_block
00513       if ( 0 != block_element_count )
00514         *block_element_count = m_fsp.BlockElementCount(m_it_block);
00515     }
00516   }
00517   else
00518   {
00519     m_it_block = 0;
00520     m_it_element = 0;
00521     if ( 0 != block_element_count )
00522       *block_element_count = 0;
00523   }
00524   return m_it_element;
00525 }
00526 
00527 void* ON_FixedSizePool::Element(size_t element_index) const
00528 {
00529   const char* block;
00530   const char* block_end;
00531   const char* next_block;
00532   size_t block_count;
00533 
00534   for ( block = (const char*)m_first_block; 0 != block; block = next_block )
00535   {
00536     if ( block == m_al_block )
00537     {
00538       next_block = 0;
00539       block_end = (const char*)m_al_element_array;
00540     }
00541     else
00542     {
00543       next_block = *((const char**)block);
00544       block_end =  *((const char**)(block + sizeof(void*)));
00545     }
00546     block_count = (block_end - block)/m_sizeof_element;
00547     if ( element_index < block_count )
00548       return ((void*)(block + (2*sizeof(void*) + element_index*m_sizeof_element)));
00549     element_index -= block_count;
00550   }
00551 
00552   return 0;
00553 }


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:01