annotate third_party/json/json_batchallocator.h @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
rev   line source
ian@0 1 // Copyright 2007-2010 Baptiste Lepilleur
ian@0 2 // Distributed under MIT license, or public domain if desired and
ian@0 3 // recognized in your jurisdiction.
ian@0 4 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
ian@0 5
ian@0 6 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
ian@0 7 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
ian@0 8
ian@0 9 # include <stdlib.h>
ian@0 10 # include <assert.h>
ian@0 11
ian@0 12 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
ian@0 13
ian@0 14 namespace Json {
ian@0 15
ian@0 16 /* Fast memory allocator.
ian@0 17 *
ian@0 18 * This memory allocator allocates memory for a batch of object (specified by
ian@0 19 * the page size, the number of object in each page).
ian@0 20 *
ian@0 21 * It does not allow the destruction of a single object. All the allocated objects
ian@0 22 * can be destroyed at once. The memory can be either released or reused for future
ian@0 23 * allocation.
ian@0 24 *
ian@0 25 * The in-place new operator must be used to construct the object using the pointer
ian@0 26 * returned by allocate.
ian@0 27 */
ian@0 28 template<typename AllocatedType
ian@0 29 ,const unsigned int objectPerAllocation>
ian@0 30 class BatchAllocator
ian@0 31 {
ian@0 32 public:
ian@0 33 BatchAllocator( unsigned int objectsPerPage = 255 )
ian@0 34 : freeHead_( 0 )
ian@0 35 , objectsPerPage_( objectsPerPage )
ian@0 36 {
ian@0 37 // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
ian@0 38 assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
ian@0 39 assert( objectsPerPage >= 16 );
ian@0 40 batches_ = allocateBatch( 0 ); // allocated a dummy page
ian@0 41 currentBatch_ = batches_;
ian@0 42 }
ian@0 43
ian@0 44 ~BatchAllocator()
ian@0 45 {
ian@0 46 for ( BatchInfo *batch = batches_; batch; )
ian@0 47 {
ian@0 48 BatchInfo *nextBatch = batch->next_;
ian@0 49 free( batch );
ian@0 50 batch = nextBatch;
ian@0 51 }
ian@0 52 }
ian@0 53
ian@0 54 /// allocate space for an array of objectPerAllocation object.
ian@0 55 /// @warning it is the responsability of the caller to call objects constructors.
ian@0 56 AllocatedType *allocate()
ian@0 57 {
ian@0 58 if ( freeHead_ ) // returns node from free list.
ian@0 59 {
ian@0 60 AllocatedType *object = freeHead_;
ian@0 61 freeHead_ = *(AllocatedType **)object;
ian@0 62 return object;
ian@0 63 }
ian@0 64 if ( currentBatch_->used_ == currentBatch_->end_ )
ian@0 65 {
ian@0 66 currentBatch_ = currentBatch_->next_;
ian@0 67 while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
ian@0 68 currentBatch_ = currentBatch_->next_;
ian@0 69
ian@0 70 if ( !currentBatch_ ) // no free batch found, allocate a new one
ian@0 71 {
ian@0 72 currentBatch_ = allocateBatch( objectsPerPage_ );
ian@0 73 currentBatch_->next_ = batches_; // insert at the head of the list
ian@0 74 batches_ = currentBatch_;
ian@0 75 }
ian@0 76 }
ian@0 77 AllocatedType *allocated = currentBatch_->used_;
ian@0 78 currentBatch_->used_ += objectPerAllocation;
ian@0 79 return allocated;
ian@0 80 }
ian@0 81
ian@0 82 /// Release the object.
ian@0 83 /// @warning it is the responsability of the caller to actually destruct the object.
ian@0 84 void release( AllocatedType *object )
ian@0 85 {
ian@0 86 assert( object != 0 );
ian@0 87 *(AllocatedType **)object = freeHead_;
ian@0 88 freeHead_ = object;
ian@0 89 }
ian@0 90
ian@0 91 private:
ian@0 92 struct BatchInfo
ian@0 93 {
ian@0 94 BatchInfo *next_;
ian@0 95 AllocatedType *used_;
ian@0 96 AllocatedType *end_;
ian@0 97 AllocatedType buffer_[objectPerAllocation];
ian@0 98 };
ian@0 99
ian@0 100 // disabled copy constructor and assignement operator.
ian@0 101 BatchAllocator( const BatchAllocator & );
ian@0 102 void operator =( const BatchAllocator &);
ian@0 103
ian@0 104 static BatchInfo *allocateBatch( unsigned int objectsPerPage )
ian@0 105 {
ian@0 106 const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
ian@0 107 + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
ian@0 108 BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
ian@0 109 batch->next_ = 0;
ian@0 110 batch->used_ = batch->buffer_;
ian@0 111 batch->end_ = batch->buffer_ + objectsPerPage;
ian@0 112 return batch;
ian@0 113 }
ian@0 114
ian@0 115 BatchInfo *batches_;
ian@0 116 BatchInfo *currentBatch_;
ian@0 117 /// Head of a single linked list within the allocated space of freeed object
ian@0 118 AllocatedType *freeHead_;
ian@0 119 unsigned int objectsPerPage_;
ian@0 120 };
ian@0 121
ian@0 122
ian@0 123 } // namespace Json
ian@0 124
ian@0 125 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
ian@0 126
ian@0 127 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED