1 // Copyright 2007-2010 Baptiste Lepilleur
2 // Distributed under MIT license, or public domain if desired and
3 // recognized in your jurisdiction.
4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
6 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
7 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
12 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
16 /* Fast memory allocator.
18 * This memory allocator allocates memory for a batch of object (specified by
19 * the page size, the number of object in each page).
21 * It does not allow the destruction of a single object. All the allocated objects
22 * can be destroyed at once. The memory can be either released or reused for future
25 * The in-place new operator must be used to construct the object using the pointer
26 * returned by allocate.
28 template<typename AllocatedType
29 ,const unsigned int objectPerAllocation>
33 typedef AllocatedType Type;
35 BatchAllocator( unsigned int objectsPerPage = 255 )
37 , objectsPerPage_( objectsPerPage )
39 // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
40 assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
41 assert( objectsPerPage >= 16 );
42 batches_ = allocateBatch( 0 ); // allocated a dummy page
43 currentBatch_ = batches_;
48 for ( BatchInfo *batch = batches_; batch; )
50 BatchInfo *nextBatch = batch->next_;
56 /// allocate space for an array of objectPerAllocation object.
57 /// @warning it is the responsability of the caller to call objects constructors.
58 AllocatedType *allocate()
60 if ( freeHead_ ) // returns node from free list.
62 AllocatedType *object = freeHead_;
63 freeHead_ = *(AllocatedType **)object;
66 if ( currentBatch_->used_ == currentBatch_->end_ )
68 currentBatch_ = currentBatch_->next_;
69 while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
70 currentBatch_ = currentBatch_->next_;
72 if ( !currentBatch_ ) // no free batch found, allocate a new one
74 currentBatch_ = allocateBatch( objectsPerPage_ );
75 currentBatch_->next_ = batches_; // insert at the head of the list
76 batches_ = currentBatch_;
79 AllocatedType *allocated = currentBatch_->used_;
80 currentBatch_->used_ += objectPerAllocation;
84 /// Release the object.
85 /// @warning it is the responsability of the caller to actually destruct the object.
86 void release( AllocatedType *object )
88 assert( object != 0 );
89 *(AllocatedType **)object = freeHead_;
99 AllocatedType buffer_[objectPerAllocation];
102 // disabled copy constructor and assignement operator.
103 BatchAllocator( const BatchAllocator & );
104 void operator =( const BatchAllocator &);
106 static BatchInfo *allocateBatch( unsigned int objectsPerPage )
108 const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
109 + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
110 BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
112 batch->used_ = batch->buffer_;
113 batch->end_ = batch->buffer_ + objectsPerPage;
118 BatchInfo *currentBatch_;
119 /// Head of a single linked list within the allocated space of freeed object
120 AllocatedType *freeHead_;
121 unsigned int objectsPerPage_;
127 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
129 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED