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
00048
00049
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
00061 break;
00062 }
00063 }
00064 }
00065
00066
00067 m_block_element_count = block_element_capacity;
00068
00069
00070
00071
00072
00073 if ( element_count_estimate > 0 )
00074 {
00075
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;
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
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
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
00158 void* next_block = (0 != m_al_block)
00159 ? *((void**)m_al_block)
00160 : 0;
00161 if ( 0 == next_block )
00162 {
00163
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
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 );
00180
00181
00182 *((void**)p) = 0;
00183
00184
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
00190
00191
00192 }
00193 else
00194 {
00195
00196 *((void**)m_al_block) = p;
00197 }
00198 m_al_block = p;
00199 }
00200 else
00201 {
00202
00203
00204
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
00230
00231
00232
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*));
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*));
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
00294 m_qwerty_it_block = *((void**)m_qwerty_it_block);
00295 m_qwerty_it_element = (0 != 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
00321 m_it_block = *((void**)m_it_block);
00322 m_it_element = (0 != 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
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
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*));
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*));
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*));
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*));
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 }