Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
allocators.h
Go to the documentation of this file.
1// Tencent is pleased to support the open source community by making RapidJSON available.
2//
3// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
4//
5// Licensed under the MIT License (the "License"); you may not use this file except
6// in compliance with the License. You may obtain a copy of the License at
7//
8// http://opensource.org/licenses/MIT
9//
10// Unless required by applicable law or agreed to in writing, software distributed
11// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12// CONDITIONS OF ANY KIND, either express or implied. See the License for the
13// specific language governing permissions and limitations under the License.
14
15#ifndef RAPIDJSON_ALLOCATORS_H_
16#define RAPIDJSON_ALLOCATORS_H_
17
18#include "rapidjson.h"
19
21
23// Allocator
24
63#ifndef RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
64#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY (64 * 1024)
65#endif
66
67
69// CrtAllocator
70
72
76public:
77 static const bool kNeedFree = true;
78 void* Malloc(size_t size) {
79 if (size) // behavior of malloc(0) is implementation defined.
80 return std::malloc(size);
81 else
82 return NULL; // standardize to returning NULL.
83 }
84 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
85 (void)originalSize;
86 if (newSize == 0) {
87 std::free(originalPtr);
88 return NULL;
89 }
90 return std::realloc(originalPtr, newSize);
91 }
92 static void Free(void *ptr) { std::free(ptr); }
93};
94
96// MemoryPoolAllocator
97
99
114template <typename BaseAllocator = CrtAllocator>
116public:
117 static const bool kNeedFree = false;
118
120
123 MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
124 chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
125 {
126 }
127
129
138 MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
139 chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
140 {
141 RAPIDJSON_ASSERT(buffer != 0);
142 RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
143 chunkHead_ = reinterpret_cast<ChunkHeader*>(buffer);
144 chunkHead_->capacity = size - sizeof(ChunkHeader);
145 chunkHead_->size = 0;
146 chunkHead_->next = 0;
147 }
148
150
153 Clear();
154 RAPIDJSON_DELETE(ownBaseAllocator_);
155 }
156
158 void Clear() {
159 while (chunkHead_ && chunkHead_ != userBuffer_) {
160 ChunkHeader* next = chunkHead_->next;
161 baseAllocator_->Free(chunkHead_);
162 chunkHead_ = next;
163 }
164 if (chunkHead_ && chunkHead_ == userBuffer_)
165 chunkHead_->size = 0; // Clear user buffer
166 }
167
169
171 size_t Capacity() const {
172 size_t capacity = 0;
173 for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
174 capacity += c->capacity;
175 return capacity;
176 }
177
179
181 size_t Size() const {
182 size_t size = 0;
183 for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
184 size += c->size;
185 return size;
186 }
187
189 void* Malloc(size_t size) {
190 if (!size)
191 return NULL;
192
193 size = RAPIDJSON_ALIGN(size);
194 if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
195 if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
196 return NULL;
197
198 void *buffer = reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
199 chunkHead_->size += size;
200 return buffer;
201 }
202
204 void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
205 if (originalPtr == 0)
206 return Malloc(newSize);
207
208 if (newSize == 0)
209 return NULL;
210
211 originalSize = RAPIDJSON_ALIGN(originalSize);
212 newSize = RAPIDJSON_ALIGN(newSize);
213
214 // Do not shrink if new size is smaller than original
215 if (originalSize >= newSize)
216 return originalPtr;
217
218 // Simply expand it if it is the last allocation and there is sufficient space
219 if (originalPtr == reinterpret_cast<char *>(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
220 size_t increment = static_cast<size_t>(newSize - originalSize);
221 if (chunkHead_->size + increment <= chunkHead_->capacity) {
222 chunkHead_->size += increment;
223 return originalPtr;
224 }
225 }
226
227 // Realloc process: allocate and copy memory, do not free original buffer.
228 if (void* newBuffer = Malloc(newSize)) {
229 if (originalSize)
230 std::memcpy(newBuffer, originalPtr, originalSize);
231 return newBuffer;
232 }
233 else
234 return NULL;
235 }
236
238 static void Free(void *ptr) { (void)ptr; } // Do nothing
239
240private:
242 MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
244 MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
245
247
250 bool AddChunk(size_t capacity) {
251 if (!baseAllocator_)
252 ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator)();
253 if (ChunkHeader* chunk = reinterpret_cast<ChunkHeader*>(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
254 chunk->capacity = capacity;
255 chunk->size = 0;
256 chunk->next = chunkHead_;
257 chunkHead_ = chunk;
258 return true;
259 }
260 else
261 return false;
262 }
263
264 static const int kDefaultChunkCapacity = RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY;
265
267
269 struct ChunkHeader {
270 size_t capacity;
271 size_t size;
272 ChunkHeader *next;
273 };
274
275 ChunkHeader *chunkHead_;
276 size_t chunk_capacity_;
277 void *userBuffer_;
278 BaseAllocator* baseAllocator_;
279 BaseAllocator* ownBaseAllocator_;
280};
281
283
284#endif // RAPIDJSON_ENCODINGS_H_
C-runtime library allocator.
Definition allocators.h:75
static void Free(void *ptr)
Definition allocators.h:92
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Definition allocators.h:84
static const bool kNeedFree
Definition allocators.h:77
void * Malloc(size_t size)
Definition allocators.h:78
Default memory allocator used by the parser and DOM.
Definition allocators.h:115
MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with user-supplied buffer.
Definition allocators.h:138
size_t Capacity() const
Computes the total capacity of allocated memory chunks.
Definition allocators.h:171
void Clear()
Deallocates all memory chunks, excluding the user-supplied buffer.
Definition allocators.h:158
static void Free(void *ptr)
Frees a memory block (concept Allocator)
Definition allocators.h:238
void * Realloc(void *originalPtr, size_t originalSize, size_t newSize)
Resizes a memory block (concept Allocator)
Definition allocators.h:204
void * Malloc(size_t size)
Allocates a memory block. (concept Allocator)
Definition allocators.h:189
static const bool kNeedFree
Tell users that no need to call Free() with this allocator. (concept Allocator)
Definition allocators.h:117
~MemoryPoolAllocator()
Destructor.
Definition allocators.h:152
size_t Size() const
Computes the memory blocks allocated.
Definition allocators.h:181
MemoryPoolAllocator(size_t chunkSize=kDefaultChunkCapacity, BaseAllocator *baseAllocator=0)
Constructor with chunkSize.
Definition allocators.h:123
#define RAPIDJSON_ALIGN(x)
Data alignment of the machine.
Definition rapidjson.h:276
#define RAPIDJSON_ALLOCATOR_DEFAULT_CHUNK_CAPACITY
User-defined kDefaultChunkCapacity definition.
Definition allocators.h:64
#define RAPIDJSON_ASSERT(x)
Assertion.
Definition rapidjson.h:406
#define RAPIDJSON_NAMESPACE_BEGIN
provide custom rapidjson namespace (opening expression)
Definition rapidjson.h:121
#define RAPIDJSON_NAMESPACE_END
provide custom rapidjson namespace (closing expression)
Definition rapidjson.h:124
common definitions and configuration
#define RAPIDJSON_DELETE(x)
! customization point for global delete
Definition rapidjson.h:631
#define RAPIDJSON_NEW(TypeName)
! customization point for global new
Definition rapidjson.h:627