Drizzled Public API Documentation

json_batchallocator.h
1 /* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
2  *
3  * JSON Library, originally from http://jsoncpp.sourceforge.net/
4  *
5  * Copyright (C) 2011 Stewart Smith
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions are
10  * met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * * Redistributions in binary form must reproduce the above
16  * copyright notice, this list of conditions and the following disclaimer
17  * in the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * * The names of its contributors may not be used to endorse or
21  * promote products derived from this software without specific prior
22  * written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  */
37 
38 #pragma once
39 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
40 # define JSONCPP_BATCHALLOCATOR_H_INCLUDED
41 
42 # include <stdlib.h>
43 # include <assert.h>
44 
45 # ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
46 
47 namespace Json {
48 
49 /* Fast memory allocator.
50  *
51  * This memory allocator allocates memory for a batch of object (specified by
52  * the page size, the number of object in each page).
53  *
54  * It does not allow the destruction of a single object. All the allocated objects
55  * can be destroyed at once. The memory can be either released or reused for future
56  * allocation.
57  *
58  * The in-place new operator must be used to construct the object using the pointer
59  * returned by allocate.
60  */
61 template<typename AllocatedType
62  ,const unsigned int objectPerAllocation>
64 {
65 public:
66  typedef AllocatedType Type;
67 
68  BatchAllocator( unsigned int objectsPerPage = 255 )
69  : freeHead_( 0 )
70  , objectsPerPage_( objectsPerPage )
71  {
72 // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
73  assert( sizeof(AllocatedType) * objectPerAllocation >= sizeof(AllocatedType *) ); // We must be able to store a slist in the object free space.
74  assert( objectsPerPage >= 16 );
75  batches_ = allocateBatch( 0 ); // allocated a dummy page
76  currentBatch_ = batches_;
77  }
78 
80  {
81  for ( BatchInfo *batch = batches_; batch; )
82  {
83  BatchInfo *nextBatch = batch->next_;
84  free( batch );
85  batch = nextBatch;
86  }
87  }
88 
91  AllocatedType *allocate()
92  {
93  if ( freeHead_ ) // returns node from free list.
94  {
95  AllocatedType *object = freeHead_;
96  freeHead_ = *(AllocatedType **)object;
97  return object;
98  }
99  if ( currentBatch_->used_ == currentBatch_->end_ )
100  {
101  currentBatch_ = currentBatch_->next_;
102  while ( currentBatch_ && currentBatch_->used_ == currentBatch_->end_ )
103  currentBatch_ = currentBatch_->next_;
104 
105  if ( !currentBatch_ ) // no free batch found, allocate a new one
106  {
107  currentBatch_ = allocateBatch( objectsPerPage_ );
108  currentBatch_->next_ = batches_; // insert at the head of the list
109  batches_ = currentBatch_;
110  }
111  }
112  AllocatedType *allocated = currentBatch_->used_;
113  currentBatch_->used_ += objectPerAllocation;
114  return allocated;
115  }
116 
119  void release( AllocatedType *object )
120  {
121  assert( object != 0 );
122  *(AllocatedType **)object = freeHead_;
123  freeHead_ = object;
124  }
125 
126 private:
127  struct BatchInfo
128  {
129  BatchInfo *next_;
130  AllocatedType *used_;
131  AllocatedType *end_;
132  AllocatedType buffer_[objectPerAllocation];
133  };
134 
135  // disabled copy constructor and assignement operator.
136  BatchAllocator( const BatchAllocator & );
137  void operator =( const BatchAllocator &);
138 
139  static BatchInfo *allocateBatch( unsigned int objectsPerPage )
140  {
141  const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType)* objectPerAllocation
142  + sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
143  BatchInfo *batch = static_cast<BatchInfo*>( malloc( mallocSize ) );
144  batch->next_ = 0;
145  batch->used_ = batch->buffer_;
146  batch->end_ = batch->buffer_ + objectsPerPage;
147  return batch;
148  }
149 
150  BatchInfo *batches_;
151  BatchInfo *currentBatch_;
153  AllocatedType *freeHead_;
154  unsigned int objectsPerPage_;
155 };
156 
157 
158 } // namespace Json
159 
160 # endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
161 
162 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
163 
AllocatedType * allocate()
void release(AllocatedType *object)
AllocatedType * freeHead_
Head of a single linked list within the allocated space of freeed object.