]> git.donarmstrong.com Git - bamtools.git/blob - src/third_party/jsoncpp/json_batchallocator.h
Minor version bump - 2.3.0
[bamtools.git] / src / third_party / jsoncpp / json_batchallocator.h
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
5
6 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
7 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
8
9 # include <stdlib.h>
10 # include <assert.h>
11
12 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
13
14 namespace Json {
15
16 /* Fast memory allocator.
17  *
18  * This memory allocator allocates memory for a batch of object (specified by
19  * the page size, the number of object in each page).
20  *
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
23  * allocation.
24  * 
25  * The in-place new operator must be used to construct the object using the pointer
26  * returned by allocate.
27  */
28 template<typename AllocatedType
29         ,const unsigned int objectPerAllocation>
30 class BatchAllocator
31 {
32 public:
33    typedef AllocatedType Type;
34
35    BatchAllocator( unsigned int objectsPerPage = 255 )
36       : freeHead_( 0 )
37       , objectsPerPage_( objectsPerPage )
38    {
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_;
44    }
45
46    ~BatchAllocator()
47    {
48       for ( BatchInfo *batch = batches_; batch;  )
49       {
50          BatchInfo *nextBatch = batch->next_;
51          free( batch );
52          batch = nextBatch;
53       }
54    }
55
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()
59    {
60       if ( freeHead_ ) // returns node from free list.
61       {
62          AllocatedType *object = freeHead_;
63          freeHead_ = *(AllocatedType **)object;
64          return object;
65       }
66       if ( currentBatch_->used_ == currentBatch_->end_ )
67       {
68          currentBatch_ = currentBatch_->next_;
69          while ( currentBatch_  &&  currentBatch_->used_ == currentBatch_->end_ )
70             currentBatch_ = currentBatch_->next_;
71
72          if ( !currentBatch_  ) // no free batch found, allocate a new one
73          { 
74             currentBatch_ = allocateBatch( objectsPerPage_ );
75             currentBatch_->next_ = batches_; // insert at the head of the list
76             batches_ = currentBatch_;
77          }
78       }
79       AllocatedType *allocated = currentBatch_->used_;
80       currentBatch_->used_ += objectPerAllocation;
81       return allocated;
82    }
83
84    /// Release the object.
85    /// @warning it is the responsability of the caller to actually destruct the object.
86    void release( AllocatedType *object )
87    {
88       assert( object != 0 );
89       *(AllocatedType **)object = freeHead_;
90       freeHead_ = object;
91    }
92
93 private:
94    struct BatchInfo
95    {
96       BatchInfo *next_;
97       AllocatedType *used_;
98       AllocatedType *end_;
99       AllocatedType buffer_[objectPerAllocation];
100    };
101
102    // disabled copy constructor and assignement operator.
103    BatchAllocator( const BatchAllocator & );
104    void operator =( const BatchAllocator &);
105
106    static BatchInfo *allocateBatch( unsigned int objectsPerPage )
107    {
108       const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
109                                 + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
110       BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
111       batch->next_ = 0;
112       batch->used_ = batch->buffer_;
113       batch->end_ = batch->buffer_ + objectsPerPage;
114       return batch;
115    }
116
117    BatchInfo *batches_;
118    BatchInfo *currentBatch_;
119    /// Head of a single linked list within the allocated space of freeed object
120    AllocatedType *freeHead_;
121    unsigned int objectsPerPage_;
122 };
123
124
125 } // namespace Json
126
127 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
128
129 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
130