CMS 3D CMS Logo

json_batchallocator.h
Go to the documentation of this file.
1 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
2 #define JSONCPP_BATCHALLOCATOR_H_INCLUDED
3 
4 #include <cassert>
5 #include <cstdlib>
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, const unsigned int objectPerAllocation>
25  public:
26  typedef AllocatedType Type;
27 
28  BatchAllocator(unsigned int objectsPerPage = 255) : freeHead_(0), objectsPerPage_(objectsPerPage) {
29  // printf( "Size: %d => %s\n", sizeof(AllocatedType), typeid(AllocatedType).name() );
30  assert(sizeof(AllocatedType) * objectPerAllocation >=
31  sizeof(AllocatedType *)); // We must be able to store a slist in the object free space.
32  assert(objectsPerPage >= 16);
33  batches_ = allocateBatch(0); // allocated a dummy page
35  }
36 
38  for (BatchInfo *batch = batches_; batch;) {
39  BatchInfo *nextBatch = batch->next_;
40  free(batch);
41  batch = nextBatch;
42  }
43  }
44 
47  AllocatedType *allocate() {
48  if (freeHead_) // returns node from free list.
49  {
50  AllocatedType *object = freeHead_;
51  freeHead_ = *(AllocatedType **)object;
52  return object;
53  }
58 
59  if (!currentBatch_) // no free batch found, allocate a new one
60  {
62  currentBatch_->next_ = batches_; // insert at the head of the list
64  }
65  }
66  AllocatedType *allocated = currentBatch_->used_;
67  currentBatch_->used_ += objectPerAllocation;
68  return allocated;
69  }
70 
73  void release(AllocatedType *object) {
74  assert(object != 0);
75  *(AllocatedType **)object = freeHead_;
76  freeHead_ = object;
77  }
78 
79  // disabled copy constructor and assignement operator.
80  BatchAllocator(const BatchAllocator &) = delete;
81  void operator=(const BatchAllocator &) = delete;
82 
83  private:
84  struct BatchInfo {
86  AllocatedType *used_;
87  AllocatedType *end_;
88  AllocatedType buffer_[objectPerAllocation];
89  };
90 
91  static BatchInfo *allocateBatch(unsigned int objectsPerPage) {
92  const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType) * objectPerAllocation +
93  sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
94  BatchInfo *batch = static_cast<BatchInfo *>(malloc(mallocSize));
95  batch->next_ = 0;
96  batch->used_ = batch->buffer_;
97  batch->end_ = batch->buffer_ + objectsPerPage;
98  return batch;
99  }
100 
104  AllocatedType *freeHead_;
105  unsigned int objectsPerPage_;
106  };
107 
108 } // namespace Json
109 
110 #endif // ifndef JSONCPP_DOC_INCLUDE_IMPLEMENTATION
111 
112 #endif // JSONCPP_BATCHALLOCATOR_H_INCLUDED
AllocatedType * allocate()
assert(be >=bs)
void free(void *ptr) noexcept
BatchAllocator(unsigned int objectsPerPage=255)
void operator=(const BatchAllocator &)=delete
static BatchInfo * allocateBatch(unsigned int objectsPerPage)
JSON (JavaScript Object Notation).
void * malloc(size_t size) noexcept
AllocatedType buffer_[objectPerAllocation]
void release(AllocatedType *object)
AllocatedType * freeHead_
Head of a single linked list within the allocated space of freeed object.