json_batchallocator.h
Go to the documentation of this file.00001
00002
00003
00004
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
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
00040 assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) );
00041 assert( objectsPerPage >= 16 );
00042 batches_ = allocateBatch( 0 );
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_ )
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_ )
00073 {
00074 currentBatch_ = allocateBatch( objectsPerPage_ );
00075 currentBatch_->next_ = batches_;
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
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 }
00126
00127 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
00128
00129 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
00130