JsonCpp project page JsonCpp home page

json_batchallocator.h

Go to the documentation of this file.
00001 // Copyright 2007-2010 Baptiste Lepilleur
00002 // Distributed under MIT license, or public domain if desired and
00003 // recognized in your jurisdiction.
00004 // See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE
00005 
00006 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
00007 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
00008 
00009 # include <stdlib.h>
00010 # include <assert.h>
00011 
00012 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
00013 
00014 namespace Json {
00015 
00016 /* Fast memory allocator.
00017  *
00018  * This memory allocator allocates memory for a batch of object (specified by
00019  * the page size, the number of object in each page).
00020  *
00021  * It does not allow the destruction of a single object. All the allocated objects
00022  * can be destroyed at once. The memory can be either released or reused for future
00023  * allocation.
00024  * 
00025  * The in-place new operator must be used to construct the object using the pointer
00026  * returned by allocate.
00027  */
00028 template<typename AllocatedType
00029         ,const unsigned int objectPerAllocation>
00030 class BatchAllocator
00031 {
00032 public:
00033    typedef AllocatedType Type;
00034 
00035    BatchAllocator( unsigned int objectsPerPage = 255 )
00036       : freeHead_( 0 )
00037       , objectsPerPage_( objectsPerPage )
00038    {
00039 //      printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
00040       assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
00041       assert( objectsPerPage >= 16 );
00042       batches_ = allocateBatch( 0 );   // allocated a dummy page
00043       currentBatch_ = batches_;
00044    }
00045 
00046    ~BatchAllocator()
00047    {
00048       for ( BatchInfo *batch = batches_; batch;  )
00049       {
00050          BatchInfo *nextBatch = batch->next_;
00051          free( batch );
00052          batch = nextBatch;
00053       }
00054    }
00055 
00058    AllocatedType *allocate()
00059    {
00060       if ( freeHead_ ) // returns node from free list.
00061       {
00062          AllocatedType *object = freeHead_;
00063          freeHead_ = *(AllocatedType **)object;
00064          return object;
00065       }
00066       if ( currentBatch_->used_ == currentBatch_->end_ )
00067       {
00068          currentBatch_ = currentBatch_->next_;
00069          while ( currentBatch_  &&  currentBatch_->used_ == currentBatch_->end_ )
00070             currentBatch_ = currentBatch_->next_;
00071 
00072          if ( !currentBatch_  ) // no free batch found, allocate a new one
00073          { 
00074             currentBatch_ = allocateBatch( objectsPerPage_ );
00075             currentBatch_->next_ = batches_; // insert at the head of the list
00076             batches_ = currentBatch_;
00077          }
00078       }
00079       AllocatedType *allocated = currentBatch_->used_;
00080       currentBatch_->used_ += objectPerAllocation;
00081       return allocated;
00082    }
00083 
00086    void release( AllocatedType *object )
00087    {
00088       assert( object != 0 );
00089       *(AllocatedType **)object = freeHead_;
00090       freeHead_ = object;
00091    }
00092 
00093 private:
00094    struct BatchInfo
00095    {
00096       BatchInfo *next_;
00097       AllocatedType *used_;
00098       AllocatedType *end_;
00099       AllocatedType buffer_[objectPerAllocation];
00100    };
00101 
00102    // disabled copy constructor and assignement operator.
00103    BatchAllocator( const BatchAllocator & );
00104    void operator =( const BatchAllocator &);
00105 
00106    static BatchInfo *allocateBatch( unsigned int objectsPerPage )
00107    {
00108       const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
00109                                 + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
00110       BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
00111       batch->next_ = 0;
00112       batch->used_ = batch->buffer_;
00113       batch->end_ = batch->buffer_ + objectsPerPage;
00114       return batch;
00115    }
00116 
00117    BatchInfo *batches_;
00118    BatchInfo *currentBatch_;
00120    AllocatedType *freeHead_;
00121    unsigned int objectsPerPage_;
00122 };
00123 
00124 
00125 } // namespace Json
00126 
00127 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
00128 
00129 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
00130 

SourceForge Logo hosts this site. Send comments to:
Json-cpp Developers