1 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
2 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
7 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
11 /* Fast memory allocator.
13 * This memory allocator allocates memory for a batch of object (specified by
14 * the page size, the number of object in each page).
16 * It does not allow the destruction of a single object. All the allocated objects
17 * can be destroyed at once. The memory can be either released or reused for future
20 * The in-place new operator must be used to construct the object using the pointer
21 * returned by allocate.
23 template<typename AllocatedType
24 ,const unsigned int objectPerAllocation
>
28 typedef AllocatedType Type
;
30 BatchAllocator( unsigned int objectsPerPage
= 255 )
32 , objectsPerPage_( objectsPerPage
)
34 // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
35 assert( sizeof(AllocatedType
) * objectPerAllocation
>= sizeof(AllocatedType
*) ); // We must be able to store a slist in the object free space.
36 assert( objectsPerPage
>= 16 );
37 batches_
= allocateBatch( 0 ); // allocated a dummy page
38 currentBatch_
= batches_
;
43 for ( BatchInfo
*batch
= batches_
; batch
; )
45 BatchInfo
*nextBatch
= batch
->next_
;
51 /// allocate space for an array of objectPerAllocation object.
52 /// @warning it is the responsability of the caller to call objects constructors.
53 AllocatedType
*allocate()
55 if ( freeHead_
) // returns node from free list.
57 AllocatedType
*object
= freeHead_
;
58 freeHead_
= *(AllocatedType
**)object
;
61 if ( currentBatch_
->used_
== currentBatch_
->end_
)
63 currentBatch_
= currentBatch_
->next_
;
64 while ( currentBatch_
&& currentBatch_
->used_
== currentBatch_
->end_
)
65 currentBatch_
= currentBatch_
->next_
;
67 if ( !currentBatch_
) // no free batch found, allocate a new one
69 currentBatch_
= allocateBatch( objectsPerPage_
);
70 currentBatch_
->next_
= batches_
; // insert at the head of the list
71 batches_
= currentBatch_
;
74 AllocatedType
*allocated
= currentBatch_
->used_
;
75 currentBatch_
->used_
+= objectPerAllocation
;
79 /// Release the object.
80 /// @warning it is the responsability of the caller to actually destruct the object.
81 void release( AllocatedType
*object
)
83 assert( object
!= 0 );
84 *(AllocatedType
**)object
= freeHead_
;
94 AllocatedType buffer_
[objectPerAllocation
];
97 // disabled copy constructor and assignement operator.
98 BatchAllocator( const BatchAllocator
& );
99 void operator =( const BatchAllocator
&);
101 static BatchInfo
*allocateBatch( unsigned int objectsPerPage
)
103 const unsigned int mallocSize
= sizeof(BatchInfo
) - sizeof(AllocatedType
)* objectPerAllocation
104 + sizeof(AllocatedType
) * objectPerAllocation
* objectsPerPage
;
105 BatchInfo
*batch
= static_cast<BatchInfo
*>( malloc( mallocSize
) );
107 batch
->used_
= batch
->buffer_
;
108 batch
->end_
= batch
->buffer_
+ objectsPerPage
;
113 BatchInfo
*currentBatch_
;
114 /// Head of a single linked list within the allocated space of freeed object
115 AllocatedType
*freeHead_
;
116 unsigned int objectsPerPage_
;
122 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
124 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED