Arcane  v3.14.10.0
Documentation développeur
Chargement...
Recherche...
Aucune correspondance
allocators.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2// Tencent is pleased to support the open source community by making RapidJSON available.
3//
4// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
5//
6// Licensed under the MIT License (the "License"); you may not use this file except
7// in compliance with the License. You may obtain a copy of the License at
8//
9// http://opensource.org/licenses/MIT
10//
11// Unless required by applicable law or agreed to in writing, software distributed
12// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
13// CONDITIONS OF ANY KIND, either express or implied. See the License for the
14// specific language governing permissions and limitations under the License.
15
16#ifndef RAPIDJSON_ALLOCATORS_H_
17#define RAPIDJSON_ALLOCATORS_H_
18
19#include "rapidjson.h"
20
22
24// Allocator
25
64#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
65#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
66#endif
67
68
70// CrtAllocator
71
73
77public:
78 static const bool kNeedFree = true;
79 void* Malloc(size_t size) {
80 if (size) // behavior of malloc(0) is implementation defined.
81 return std::malloc(size);
82 else
83 return NULL; // standardize to returning NULL.
84 }
85 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
86 (void)originalSize;
87 if (newSize == 0) {
88 std::free(originalPtr);
89 return NULL;
90 }
91 return std::realloc(originalPtr, newSize);
92 }
93 static void Free(void *ptr) { std::free(ptr); }
94};
95
97// MemoryPoolAllocator
98
100
115template <typename BaseAllocator = CrtAllocator>
117public:
118 static const bool kNeedFree = false;
119
121
124 MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
125 chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
126 {
127 }
128
130
139 MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
140 chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
141 {
142 RAPIDJSON_ASSERT(buffer != 0);
143 RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
144 chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
145 chunkHead_->capacity = size - sizeof(ChunkHeader);
146 chunkHead_->size = 0;
147 chunkHead_->next = 0;
148 }
149
151
157
159 void Clear() {
160 while (chunkHead_ && chunkHead_ != userBuffer_) {
161 ChunkHeader* next = chunkHead_->next;
163 chunkHead_ = next;
164 }
166 chunkHead_->size = 0; // Clear user buffer
167 }
168
170
172 size_t Capacity() const {
173 size_t capacity = 0;
174 for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
175 capacity += c->capacity;
176 return capacity;
177 }
178
180
182 size_t Size() const {
183 size_t size = 0;
184 for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
185 size += c->size;
186 return size;
187 }
188
190 void* Malloc(size_t size) {
191 if (!size)
192 return NULL;
193
194 size = RAPIDJSON_ALIGN(size);
195 if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
196 if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
197 return NULL;
198
199 void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
200 chunkHead_->size += size;
201 return buffer;
202 }
203
205 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
206 if (originalPtr == 0)
207 return Malloc(newSize);
208
209 if (newSize == 0)
210 return NULL;
211
212 originalSize = RAPIDJSON_ALIGN(originalSize);
213 newSize = RAPIDJSON_ALIGN(newSize);
214
215 // Do not shrink if new size is smaller than original
216 if (originalSize >= newSize)
217 return originalPtr;
218
219 // Simply expand it if it is the last allocation and there is sufficient space
220 if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
221 size_t increment = static_cast<size_t>(newSize - originalSize);
222 if (chunkHead_->size + increment <= chunkHead_->capacity) {
223 chunkHead_->size += increment;
224 return originalPtr;
225 }
226 }
227
228 // Realloc process: allocate and copy memory, do not free original buffer.
229 if (void* newBuffer = Malloc(newSize)) {
230 if (originalSize)
231 std::memcpy(newBuffer, originalPtr, originalSize);
232 return newBuffer;
233 }
234 else
235 return NULL;
236 }
237
239 static void Free(void *ptr) { (void)ptr; } // Do nothing
240
241private:
243 MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
246
248
251 bool AddChunk(size_t capacity) {
252 if (!baseAllocator_)
254 if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
255 chunk->capacity = capacity;
256 chunk->size = 0;
257 chunk->next = chunkHead_;
258 chunkHead_ = chunk;
259 return true;
260 }
261 else
262 return false;
263 }
264
266
268
270 struct ChunkHeader {
271 size_t capacity;
272 size_t size;
274 };
275
279 BaseAllocator* baseAllocator_;
280 BaseAllocator* ownBaseAllocator_;
281};
282
284
285#endif // RAPIDJSON_ENCODINGS_H_
C-runtime library allocator.
Definition allocators.h:76
Default memory allocator used by the parser and DOM.
Definition allocators.h:116
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition allocators.h:139
BaseAllocator * ownBaseAllocator_
base allocator created by this object.
Definition allocators.h:280
bool AddChunk(size_t capacity)
Creates a new chunk.
Definition allocators.h:251
size_t Capacity() const
Computes the total capacity of allocated memory chunks.
Definition allocators.h:172
ChunkHeader * chunkHead_
Head of the chunk linked-list. Only the head chunk serves allocation.
Definition allocators.h:276
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition allocators.h:159
BaseAllocator * baseAllocator_
base allocator for allocating memory chunks.
Definition allocators.h:279
size_t chunk_capacity_
The minimum capacity of chunk when they are allocated.
Definition allocators.h:277
static void Free(void *ptr)
Frees a memory block (concept Allocator)
Definition allocators.h:239
MemoryPoolAllocator(const MemoryPoolAllocator &rhs)
Copy constructor is not permitted.
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition allocators.h:205
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition allocators.h:190
void * userBuffer_
User supplied buffer.
Definition allocators.h:278
static const int kDefaultChunkCapacity
Default chunk capacity.
Definition allocators.h:265
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition allocators.h:118
~MemoryPoolAllocator()
Destructor.
Definition allocators.h:153
MemoryPoolAllocator & operator=(const MemoryPoolAllocator &rhs)
Copy assignment operator is not permitted.
size_t Size() const
Computes the memory blocks allocated.
Definition allocators.h:182
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition allocators.h:124
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition rapidjson.h:277
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
User-defined kDefaultChunkCapacity definition.
Definition allocators.h:65
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:407
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:122
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:125
common definitions and configuration
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:652
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:648
Chunk header for perpending to each chunk.
Definition allocators.h:270
ChunkHeader * next
Next chunk in the linked list.
Definition allocators.h:273
size_t size
Current size of allocated memory in bytes.
Definition allocators.h:272
size_t capacity
Capacity of the chunk in bytes (excluding the header itself).
Definition allocators.h:271