@ -11,6 +11,7 @@
# define POOL_FUNC_HPP
# include "alloc_func.hpp"
# include "bitmath_func.hpp"
# include "mem_func.hpp"
# include "pool_type.hpp"
# include "../error_func.h"
@ -60,6 +61,16 @@ DEFINE_POOL_METHOD(inline void)::ResizeFor(size_t index)
this - > data = ReallocT ( this - > data , new_size ) ;
MemSetT ( this - > data + this - > size , 0 , new_size - this - > size ) ;
this - > used_bitmap . resize ( Align ( new_size , BITMAP_SIZE ) / BITMAP_SIZE ) ;
if ( this - > size % BITMAP_SIZE ! = 0 ) {
/* Already-allocated bits above old size are now unused. */
this - > used_bitmap [ this - > size / BITMAP_SIZE ] & = ~ ( ( ~ static_cast < BitmapStorage > ( 0 ) ) < < ( this - > size % BITMAP_SIZE ) ) ;
}
if ( new_size % BITMAP_SIZE ! = 0 ) {
/* Bits above new size are considered used. */
this - > used_bitmap [ new_size / BITMAP_SIZE ] | = ( ~ static_cast < BitmapStorage > ( 0 ) ) < < ( new_size % BITMAP_SIZE ) ;
}
this - > size = new_size ;
}
@ -69,25 +80,20 @@ DEFINE_POOL_METHOD(inline void)::ResizeFor(size_t index)
*/
DEFINE_POOL_METHOD ( inline size_t ) : : FindFirstFree ( )
{
size_t index = this - > first_free ;
for ( ; index < this - > first_unused ; index + + ) {
if ( this - > data [ index ] = = nullptr ) return index ;
for ( auto it = std : : next ( std : : begin ( this - > used_bitmap ) , this - > first_free / BITMAP_SIZE ) ; it ! = std : : end ( this - > used_bitmap ) ; + + it ) {
BitmapStorage available = ~ ( * it ) ;
if ( available = = 0 ) continue ;
return std : : distance ( std : : begin ( this - > used_bitmap ) , it ) * BITMAP_SIZE + FindFirstBit ( available ) ;
}
if ( index < this - > size ) {
return index ;
}
assert ( index = = this - > size ) ;
assert ( this - > first_unused = = this - > size ) ;
if ( index < Tmax_size ) {
this - > ResizeFor ( index ) ;
return index ;
if ( this - > first_unused < Tmax_size ) {
this - > ResizeFor ( this - > first_unused ) ;
return this - > first_unused ;
}
assert ( this - > items = = Tmax_size ) ;
assert ( this - > first_unused = = Tmax_size ) ;
return NO_FREE_ITEM ;
}
@ -122,6 +128,7 @@ DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index)
item = ( Titem * ) MallocT < byte > ( size ) ;
}
this - > data [ index ] = item ;
SetBit ( this - > used_bitmap [ index / BITMAP_SIZE ] , index % BITMAP_SIZE ) ;
item - > index = ( Tindex ) ( uint ) index ;
return item ;
}
@ -190,7 +197,10 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index)
this - > data [ index ] = nullptr ;
this - > first_free = std : : min ( this - > first_free , index ) ;
this - > items - - ;
if ( ! this - > cleaning ) Titem : : PostDestructor ( index ) ;
if ( ! this - > cleaning ) {
ClrBit ( this - > used_bitmap [ index / BITMAP_SIZE ] , index % BITMAP_SIZE ) ;
Titem : : PostDestructor ( index ) ;
}
}
/** Destroys all items in the pool and resets all member variables. */
@ -202,6 +212,8 @@ DEFINE_POOL_METHOD(void)::CleanPool()
}
assert ( this - > items = = 0 ) ;
free ( this - > data ) ;
this - > used_bitmap . clear ( ) ;
this - > used_bitmap . shrink_to_fit ( ) ;
this - > first_unused = this - > first_free = this - > size = 0 ;
this - > data = nullptr ;
this - > cleaning = false ;