comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:add35537fdbb
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 BatchAllocator( unsigned int objectsPerPage = 255 )
34 : freeHead_( 0 )
35 , objectsPerPage_( objectsPerPage )
36 {
37 // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
38 assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
39 assert( objectsPerPage >= 16 );
40 batches_ = allocateBatch( 0 ); // allocated a dummy page
41 currentBatch_ = batches_;
42 }
43
44 ~BatchAllocator()
45 {
46 for ( BatchInfo *batch = batches_; batch; )
47 {
48 BatchInfo *nextBatch = batch->next_;
49 free( batch );
50 batch = nextBatch;
51 }
52 }
53
54 /// allocate space for an array of objectPerAllocation object.
55 /// @warning it is the responsability of the caller to call objects constructors.
56 AllocatedType *allocate()
57 {
58 if ( freeHead_ ) // returns node from free list.
59 {
60 AllocatedType *object = freeHead_;
61 freeHead_ = *(AllocatedType **)object;
62 return object;
63 }
64 if ( currentBatch_->used_ == currentBatch_->end_ )
65 {
66 currentBatch_ = currentBatch_->next_;
67 while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
68 currentBatch_ = currentBatch_->next_;
69
70 if ( !currentBatch_ ) // no free batch found, allocate a new one
71 {
72 currentBatch_ = allocateBatch( objectsPerPage_ );
73 currentBatch_->next_ = batches_; // insert at the head of the list
74 batches_ = currentBatch_;
75 }
76 }
77 AllocatedType *allocated = currentBatch_->used_;
78 currentBatch_->used_ += objectPerAllocation;
79 return allocated;
80 }
81
82 /// Release the object.
83 /// @warning it is the responsability of the caller to actually destruct the object.
84 void release( AllocatedType *object )
85 {
86 assert( object != 0 );
87 *(AllocatedType **)object = freeHead_;
88 freeHead_ = object;
89 }
90
91 private:
92 struct BatchInfo
93 {
94 BatchInfo *next_;
95 AllocatedType *used_;
96 AllocatedType *end_;
97 AllocatedType buffer_[objectPerAllocation];
98 };
99
100 // disabled copy constructor and assignement operator.
101 BatchAllocator( const BatchAllocator & );
102 void operator =( const BatchAllocator &);
103
104 static BatchInfo *allocateBatch( unsigned int objectsPerPage )
105 {
106 const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
107 + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
108 BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
109 batch->next_ = 0;
110 batch->used_ = batch->buffer_;
111 batch->end_ = batch->buffer_ + objectsPerPage;
112 return batch;
113 }
114
115 BatchInfo *batches_;
116 BatchInfo *currentBatch_;
117 /// Head of a single linked list within the allocated space of freeed object
118 AllocatedType *freeHead_;
119 unsigned int objectsPerPage_;
120 };
121
122
123 } // namespace Json
124
125 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
126
127 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED