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