ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/cf.schmorp.de/dclient/src/backend/json/json_batchallocator.h
Revision: 1.1
Committed: Sun Oct 17 08:15:06 2010 UTC (16 years ago) by sf-pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
initial import

File Contents

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