File indexing completed on 2024-05-20 22:39:44
0001 #ifndef JSONCPP_BATCHALLOCATOR_H_INCLUDED
0002 #define JSONCPP_BATCHALLOCATOR_H_INCLUDED
0003
0004 #include <cassert>
0005 #include <cstdlib>
0006
0007 #ifndef JSONCPP_DOC_EXCLUDE_IMPLEMENTATION
0008
0009 namespace jsoncollector {
0010 namespace Json {
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 template <typename AllocatedType, const unsigned int objectPerAllocation>
0025 class BatchAllocator {
0026 public:
0027 typedef AllocatedType Type;
0028
0029 BatchAllocator(unsigned int objectsPerPage = 255) : freeHead_(0), objectsPerPage_(objectsPerPage) {
0030
0031 assert(sizeof(AllocatedType) * objectPerAllocation >=
0032 sizeof(AllocatedType *));
0033 assert(objectsPerPage >= 16);
0034 batches_ = allocateBatch(0);
0035 currentBatch_ = batches_;
0036 }
0037
0038 ~BatchAllocator() {
0039 for (BatchInfo *batch = batches_; batch;) {
0040 BatchInfo *nextBatch = batch->next_;
0041 free(batch);
0042 batch = nextBatch;
0043 }
0044 }
0045
0046
0047
0048 AllocatedType *allocate() {
0049 if (freeHead_)
0050 {
0051 AllocatedType *object = freeHead_;
0052 freeHead_ = *(AllocatedType **)object;
0053 return object;
0054 }
0055 if (currentBatch_->used_ == currentBatch_->end_) {
0056 currentBatch_ = currentBatch_->next_;
0057 while (currentBatch_ && currentBatch_->used_ == currentBatch_->end_)
0058 currentBatch_ = currentBatch_->next_;
0059
0060 if (!currentBatch_)
0061 {
0062 currentBatch_ = allocateBatch(objectsPerPage_);
0063 currentBatch_->next_ = batches_;
0064 batches_ = currentBatch_;
0065 }
0066 }
0067 AllocatedType *allocated = currentBatch_->used_;
0068 currentBatch_->used_ += objectPerAllocation;
0069 return allocated;
0070 }
0071
0072
0073
0074 void release(AllocatedType *object) {
0075 assert(object != 0);
0076 *(AllocatedType **)object = freeHead_;
0077 freeHead_ = object;
0078 }
0079
0080
0081 BatchAllocator(const BatchAllocator &) = delete;
0082 void operator=(const BatchAllocator &) = delete;
0083
0084 private:
0085 struct BatchInfo {
0086 BatchInfo *next_;
0087 AllocatedType *used_;
0088 AllocatedType *end_;
0089 AllocatedType buffer_[objectPerAllocation];
0090 };
0091
0092 static BatchInfo *allocateBatch(unsigned int objectsPerPage) {
0093 const unsigned int mallocSize = sizeof(BatchInfo) - sizeof(AllocatedType) * objectPerAllocation +
0094 sizeof(AllocatedType) * objectPerAllocation * objectsPerPage;
0095 BatchInfo *batch = static_cast<BatchInfo *>(malloc(mallocSize));
0096 batch->next_ = 0;
0097 batch->used_ = batch->buffer_;
0098 batch->end_ = batch->buffer_ + objectsPerPage;
0099 return batch;
0100 }
0101
0102 BatchInfo *batches_;
0103 BatchInfo *currentBatch_;
0104
0105 AllocatedType *freeHead_;
0106 unsigned int objectsPerPage_;
0107 };
0108
0109 }
0110 }
0111
0112 #endif
0113
0114 #endif