1
by brian
clean slate |
1 |
/* Copyright (C) 2000 MySQL AB
|
2 |
||
3 |
This program is free software; you can redistribute it and/or modify
|
|
4 |
it under the terms of the GNU General Public License as published by
|
|
5 |
the Free Software Foundation; version 2 of the License.
|
|
6 |
||
7 |
This program is distributed in the hope that it will be useful,
|
|
8 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
9 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
10 |
GNU General Public License for more details.
|
|
11 |
||
12 |
You should have received a copy of the GNU General Public License
|
|
13 |
along with this program; if not, write to the Free Software
|
|
1802.10.2
by Monty Taylor
Update all of the copyright headers to include the correct address. |
14 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
1
by brian
clean slate |
15 |
|
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
16 |
/**
|
17 |
* @file
|
|
18 |
* Routines to handle mallocing of results which will be freed the same time
|
|
19 |
*/
|
|
1
by brian
clean slate |
20 |
|
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
21 |
#include <config.h> |
1280.1.10
by Monty Taylor
Put everything in drizzled into drizzled namespace. |
22 |
|
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
23 |
#include <drizzled/internal/my_sys.h> |
24 |
#include <drizzled/internal/m_string.h> |
|
1
by brian
clean slate |
25 |
|
1067.4.10
by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max. |
26 |
#include <algorithm> |
27 |
||
28 |
using namespace std; |
|
1253.1.3
by Monty Taylor
MEM_ROOT == memory::Root |
29 |
|
30 |
namespace drizzled |
|
31 |
{
|
|
1
by brian
clean slate |
32 |
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
33 |
static const unsigned int MAX_BLOCK_TO_DROP= 4096; |
34 |
static const unsigned int MAX_BLOCK_USAGE_BEFORE_DROP= 10; |
|
35 |
||
1441.2.1
by Tim Martin
Reformatting some memory/root.h comments for doxygen |
36 |
/**
|
37 |
* @brief
|
|
38 |
* Initialize memory root
|
|
39 |
*
|
|
40 |
* @details
|
|
41 |
* This function prepares memory root for further use, sets initial size of
|
|
42 |
* chunk for memory allocation and pre-allocates first block if specified.
|
|
43 |
* Altough error can happen during execution of this function if
|
|
44 |
* pre_alloc_size is non-0 it won't be reported. Instead it will be
|
|
45 |
* reported as error in first alloc_root() on this memory root.
|
|
46 |
*
|
|
47 |
* @param mem_root memory root to initialize
|
|
48 |
* @param block_size size of chunks (blocks) used for memory allocation
|
|
49 |
* (It is external size of chunk i.e. it should include
|
|
50 |
* memory required for internal structures, thus it
|
|
51 |
* should be no less than memory::ROOT_MIN_BLOCK_SIZE)
|
|
52 |
*
|
|
53 |
*/
|
|
1487
by Brian Aker
More updates for memory::Root |
54 |
void memory::Root::init_alloc_root(size_t block_size_arg) |
1
by brian
clean slate |
55 |
{
|
1487
by Brian Aker
More updates for memory::Root |
56 |
free= used= pre_alloc= 0; |
57 |
min_malloc= 32; |
|
58 |
block_size= block_size_arg - memory::ROOT_MIN_BLOCK_SIZE; |
|
59 |
error_handler= 0; |
|
60 |
block_num= 4; /* We shift this with >>2 */ |
|
61 |
first_block_usage= 0; |
|
1
by brian
clean slate |
62 |
}
|
63 |
||
1869.1.7
by Brian Aker
Cleanup of caller to ha_open(). |
64 |
memory::Root::~Root() |
65 |
{
|
|
66 |
}
|
|
67 |
||
1
by brian
clean slate |
68 |
|
1441.2.1
by Tim Martin
Reformatting some memory/root.h comments for doxygen |
69 |
/**
|
70 |
* @details
|
|
71 |
* Function aligns and assigns new value to block size; then it tries to
|
|
72 |
* reuse one of existing blocks as prealloc block, or malloc new one of
|
|
73 |
* requested size. If no blocks can be reused, all unused blocks are freed
|
|
74 |
* before allocation.
|
|
75 |
*
|
|
76 |
* @param mem_root memory root to change defaults of
|
|
77 |
* @param block_size new value of block size. Must be greater or equal
|
|
78 |
* than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about
|
|
79 |
* 68 bytes and depends on platform and compilation flags)
|
|
80 |
* @param pre_alloc_size new size of preallocated block. If not zero,
|
|
81 |
* must be equal to or greater than block size,
|
|
82 |
* otherwise means 'no prealloc'.
|
|
83 |
*/
|
|
1485
by Brian Aker
Updates to confine memroot |
84 |
void memory::Root::reset_root_defaults(size_t block_size_arg, size_t pre_alloc_size) |
1
by brian
clean slate |
85 |
{
|
1485
by Brian Aker
Updates to confine memroot |
86 |
block_size= block_size_arg - memory::ROOT_MIN_BLOCK_SIZE; |
1
by brian
clean slate |
87 |
if (pre_alloc_size) |
88 |
{
|
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
89 |
size_t size= pre_alloc_size + ALIGN_SIZE(sizeof(memory::internal::UsedMemory)); |
1485
by Brian Aker
Updates to confine memroot |
90 |
if (not pre_alloc || pre_alloc->size != size) |
1
by brian
clean slate |
91 |
{
|
1485
by Brian Aker
Updates to confine memroot |
92 |
memory::internal::UsedMemory *mem, **prev= &this->free; |
1
by brian
clean slate |
93 |
/*
|
94 |
Free unused blocks, so that consequent calls
|
|
95 |
to reset_root_defaults won't eat away memory.
|
|
96 |
*/
|
|
97 |
while (*prev) |
|
98 |
{
|
|
99 |
mem= *prev; |
|
100 |
if (mem->size == size) |
|
101 |
{
|
|
102 |
/* We found a suitable block, no need to do anything else */
|
|
1485
by Brian Aker
Updates to confine memroot |
103 |
pre_alloc= mem; |
1
by brian
clean slate |
104 |
return; |
105 |
}
|
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
106 |
if (mem->left + ALIGN_SIZE(sizeof(memory::internal::UsedMemory)) == mem->size) |
1
by brian
clean slate |
107 |
{
|
108 |
/* remove block from the list and free it */
|
|
109 |
*prev= mem->next; |
|
1485
by Brian Aker
Updates to confine memroot |
110 |
std::free(mem); |
1
by brian
clean slate |
111 |
}
|
112 |
else
|
|
113 |
prev= &mem->next; |
|
114 |
}
|
|
115 |
/* Allocate new prealloc block and add it to the end of free list */
|
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
116 |
if ((mem= static_cast<memory::internal::UsedMemory *>(malloc(size)))) |
1
by brian
clean slate |
117 |
{
|
660.1.3
by Eric Herman
removed trailing whitespace with simple script: |
118 |
mem->size= size; |
1
by brian
clean slate |
119 |
mem->left= pre_alloc_size; |
120 |
mem->next= *prev; |
|
1485
by Brian Aker
Updates to confine memroot |
121 |
*prev= pre_alloc= mem; |
1
by brian
clean slate |
122 |
}
|
123 |
else
|
|
124 |
{
|
|
1485
by Brian Aker
Updates to confine memroot |
125 |
pre_alloc= 0; |
1
by brian
clean slate |
126 |
}
|
127 |
}
|
|
128 |
}
|
|
129 |
else
|
|
779.1.27
by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files. |
130 |
{
|
1485
by Brian Aker
Updates to confine memroot |
131 |
pre_alloc= 0; |
779.1.27
by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files. |
132 |
}
|
1
by brian
clean slate |
133 |
}
|
134 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
135 |
/**
|
136 |
* @brief
|
|
137 |
* Allocate a chunk of memory from the Root structure provided,
|
|
138 |
* obtaining more memory from the heap if necessary
|
|
139 |
*
|
|
140 |
* @pre
|
|
141 |
* mem_root must have been initialised via init_alloc_root()
|
|
142 |
*
|
|
143 |
* @param mem_root The memory Root to allocate from
|
|
144 |
* @param length The size of the block to allocate
|
|
145 |
*
|
|
146 |
* @todo Would this be more suitable as a member function on the
|
|
147 |
* Root class?
|
|
148 |
*/
|
|
1485
by Brian Aker
Updates to confine memroot |
149 |
void *memory::Root::alloc_root(size_t length) |
150 |
{
|
|
481
by Brian Aker
Remove all of uchar. |
151 |
unsigned char* point; |
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
152 |
memory::internal::UsedMemory *next= NULL; |
153 |
memory::internal::UsedMemory **prev; |
|
1487
by Brian Aker
More updates for memory::Root |
154 |
assert(alloc_root_inited()); |
1
by brian
clean slate |
155 |
|
156 |
length= ALIGN_SIZE(length); |
|
1486
by Brian Aker
More encapsulation. |
157 |
if ((*(prev= &this->free)) != NULL) |
1
by brian
clean slate |
158 |
{
|
159 |
if ((*prev)->left < length && |
|
1486
by Brian Aker
More encapsulation. |
160 |
this->first_block_usage++ >= MAX_BLOCK_USAGE_BEFORE_DROP && |
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
161 |
(*prev)->left < MAX_BLOCK_TO_DROP) |
1
by brian
clean slate |
162 |
{
|
163 |
next= *prev; |
|
164 |
*prev= next->next; /* Remove block from list */ |
|
1486
by Brian Aker
More encapsulation. |
165 |
next->next= this->used; |
166 |
this->used= next; |
|
167 |
this->first_block_usage= 0; |
|
1
by brian
clean slate |
168 |
}
|
169 |
for (next= *prev ; next && next->left < length ; next= next->next) |
|
170 |
prev= &next->next; |
|
171 |
}
|
|
172 |
if (! next) |
|
173 |
{ /* Time to alloc new block */ |
|
1486
by Brian Aker
More encapsulation. |
174 |
size_t get_size, tmp_block_size; |
175 |
||
176 |
tmp_block_size= this->block_size * (this->block_num >> 2); |
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
177 |
get_size= length+ALIGN_SIZE(sizeof(memory::internal::UsedMemory)); |
1486
by Brian Aker
More encapsulation. |
178 |
get_size= max(get_size, tmp_block_size); |
1
by brian
clean slate |
179 |
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
180 |
if (!(next = static_cast<memory::internal::UsedMemory *>(malloc(get_size)))) |
1
by brian
clean slate |
181 |
{
|
1486
by Brian Aker
More encapsulation. |
182 |
if (this->error_handler) |
183 |
(*this->error_handler)(); |
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
184 |
return NULL; |
1
by brian
clean slate |
185 |
}
|
1486
by Brian Aker
More encapsulation. |
186 |
this->block_num++; |
1
by brian
clean slate |
187 |
next->next= *prev; |
188 |
next->size= get_size; |
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
189 |
next->left= get_size-ALIGN_SIZE(sizeof(memory::internal::UsedMemory)); |
1
by brian
clean slate |
190 |
*prev=next; |
191 |
}
|
|
192 |
||
481
by Brian Aker
Remove all of uchar. |
193 |
point= (unsigned char*) ((char*) next+ (next->size-next->left)); |
1486
by Brian Aker
More encapsulation. |
194 |
/** @todo next part may be unneeded due to this->first_block_usage counter*/
|
195 |
if ((next->left-= length) < this->min_malloc) |
|
1
by brian
clean slate |
196 |
{ /* Full block */ |
197 |
*prev= next->next; /* Remove block from list */ |
|
1486
by Brian Aker
More encapsulation. |
198 |
next->next= this->used; |
199 |
this->used= next; |
|
200 |
this->first_block_usage= 0; |
|
1
by brian
clean slate |
201 |
}
|
1441.2.5
by Tim Martin
More doxygen commenting |
202 |
|
203 |
return point; |
|
1
by brian
clean slate |
204 |
}
|
205 |
||
206 |
||
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
207 |
/**
|
208 |
* @brief
|
|
209 |
* Allocate many pointers at the same time.
|
|
210 |
*
|
|
211 |
* @details
|
|
212 |
* The variable arguments are a list of alternating pointers and lengths,
|
|
213 |
* terminated by a null pointer:
|
|
214 |
* @li <tt>char ** pointer1</tt>
|
|
215 |
* @li <tt>uint length1</tt>
|
|
216 |
* @li <tt>char ** pointer2</tt>
|
|
217 |
* @li <tt>uint length2</tt>
|
|
218 |
* @li <tt>...</tt>
|
|
219 |
* @li <tt>NULL</tt>
|
|
220 |
*
|
|
221 |
* @c pointer1, @c pointer2 etc. all point into big allocated memory area
|
|
222 |
*
|
|
223 |
* @param root Memory root
|
|
224 |
*
|
|
225 |
* @return
|
|
226 |
* A pointer to the beginning of the allocated memory block in case of
|
|
227 |
* success or NULL if out of memory
|
|
228 |
*/
|
|
1532.1.7
by Brian Aker
Fix for non-portable vastart usage. |
229 |
void *memory::Root::multi_alloc_root(int unused, ...) |
1
by brian
clean slate |
230 |
{
|
231 |
va_list args; |
|
232 |
char **ptr, *start, *res; |
|
233 |
size_t tot_length, length; |
|
234 |
||
1532.1.9
by Brian Aker
Fix for Solaris build issue. |
235 |
(void)unused; // For some reason Sun Studio registers unused as not used. |
1532.1.7
by Brian Aker
Fix for non-portable vastart usage. |
236 |
va_start(args, unused); |
1
by brian
clean slate |
237 |
tot_length= 0; |
238 |
while ((ptr= va_arg(args, char **))) |
|
239 |
{
|
|
240 |
length= va_arg(args, uint); |
|
241 |
tot_length+= ALIGN_SIZE(length); |
|
242 |
}
|
|
243 |
va_end(args); |
|
244 |
||
1532.1.5
by Brian Aker
Shift the varargs so that they are a part of memory::Root |
245 |
if (!(start= (char*) this->alloc_root(tot_length))) |
971.6.11
by Eric Day
Removed purecov messages. |
246 |
return(0); |
1
by brian
clean slate |
247 |
|
1532.1.7
by Brian Aker
Fix for non-portable vastart usage. |
248 |
va_start(args, unused); |
1
by brian
clean slate |
249 |
res= start; |
250 |
while ((ptr= va_arg(args, char **))) |
|
251 |
{
|
|
252 |
*ptr= res; |
|
253 |
length= va_arg(args, uint); |
|
254 |
res+= ALIGN_SIZE(length); |
|
255 |
}
|
|
256 |
va_end(args); |
|
51.3.20
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
257 |
return((void*) start); |
1
by brian
clean slate |
258 |
}
|
259 |
||
2151.2.5
by Olaf van der Spek
Replace TRASH_MEM macro by function |
260 |
static void trash_mem(memory::internal::UsedMemory *) |
261 |
{
|
|
262 |
TRASH(((char*)(x) + (x->size - x->left)), x->left); |
|
263 |
}
|
|
1
by brian
clean slate |
264 |
|
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
265 |
/**
|
266 |
* @brief
|
|
267 |
* Mark all data in blocks free for reusage
|
|
1441.2.5
by Tim Martin
More doxygen commenting |
268 |
*/
|
1485
by Brian Aker
Updates to confine memroot |
269 |
void memory::Root::mark_blocks_free() |
1
by brian
clean slate |
270 |
{
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
271 |
memory::internal::UsedMemory *next; |
272 |
memory::internal::UsedMemory **last; |
|
1
by brian
clean slate |
273 |
|
274 |
/* iterate through (partially) free blocks, mark them free */
|
|
1485
by Brian Aker
Updates to confine memroot |
275 |
last= &free; |
276 |
for (next= free; next; next= *(last= &next->next)) |
|
1
by brian
clean slate |
277 |
{
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
278 |
next->left= next->size - ALIGN_SIZE(sizeof(memory::internal::UsedMemory)); |
2151.2.5
by Olaf van der Spek
Replace TRASH_MEM macro by function |
279 |
trash_mem(next); |
1
by brian
clean slate |
280 |
}
|
281 |
||
282 |
/* Combine the free and the used list */
|
|
1485
by Brian Aker
Updates to confine memroot |
283 |
*last= next= used; |
1
by brian
clean slate |
284 |
|
285 |
/* now go through the used blocks and mark them free */
|
|
286 |
for (; next; next= next->next) |
|
287 |
{
|
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
288 |
next->left= next->size - ALIGN_SIZE(sizeof(memory::internal::UsedMemory)); |
2151.2.5
by Olaf van der Spek
Replace TRASH_MEM macro by function |
289 |
trash_mem(next); |
1
by brian
clean slate |
290 |
}
|
291 |
||
292 |
/* Now everything is set; Indicate that nothing is used anymore */
|
|
1485
by Brian Aker
Updates to confine memroot |
293 |
used= 0; |
294 |
first_block_usage= 0; |
|
1
by brian
clean slate |
295 |
}
|
296 |
||
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
297 |
/**
|
298 |
* @brief
|
|
299 |
* Deallocate everything used by memory::alloc_root or just move
|
|
300 |
* used blocks to free list if called with MY_USED_TO_FREE
|
|
301 |
*
|
|
302 |
* @note
|
|
303 |
* One can call this function either with root block initialised with
|
|
304 |
* init_alloc_root() or with a zero:ed block.
|
|
305 |
* It's also safe to call this multiple times with the same mem_root.
|
|
306 |
*
|
|
307 |
* @param root Memory root
|
|
308 |
* @param MyFlags Flags for what should be freed:
|
|
309 |
* @li MARK_BLOCKS_FREED Don't free blocks, just mark them free
|
|
310 |
* @li KEEP_PREALLOC If this is not set, then free also the
|
|
311 |
* preallocated block
|
|
312 |
*/
|
|
1487
by Brian Aker
More updates for memory::Root |
313 |
void memory::Root::free_root(myf MyFlags) |
1
by brian
clean slate |
314 |
{
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
315 |
memory::internal::UsedMemory *next,*old; |
1
by brian
clean slate |
316 |
|
1253.1.1
by Monty Taylor
First bits of namespacing. Ugh. Why do I do this to myself. |
317 |
if (MyFlags & memory::MARK_BLOCKS_FREE) |
1
by brian
clean slate |
318 |
{
|
1487
by Brian Aker
More updates for memory::Root |
319 |
this->mark_blocks_free(); |
51.3.20
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
320 |
return; |
1
by brian
clean slate |
321 |
}
|
1253.1.1
by Monty Taylor
First bits of namespacing. Ugh. Why do I do this to myself. |
322 |
if (!(MyFlags & memory::KEEP_PREALLOC)) |
1487
by Brian Aker
More updates for memory::Root |
323 |
this->pre_alloc=0; |
1
by brian
clean slate |
324 |
|
1487
by Brian Aker
More updates for memory::Root |
325 |
for (next=this->used; next ;) |
1
by brian
clean slate |
326 |
{
|
327 |
old=next; next= next->next ; |
|
1487
by Brian Aker
More updates for memory::Root |
328 |
if (old != this->pre_alloc) |
329 |
std::free(old); |
|
1
by brian
clean slate |
330 |
}
|
1487
by Brian Aker
More updates for memory::Root |
331 |
for (next=this->free ; next ;) |
1
by brian
clean slate |
332 |
{
|
333 |
old=next; next= next->next; |
|
1487
by Brian Aker
More updates for memory::Root |
334 |
if (old != this->pre_alloc) |
335 |
std::free(old); |
|
1
by brian
clean slate |
336 |
}
|
1487
by Brian Aker
More updates for memory::Root |
337 |
this->used=this->free=0; |
338 |
if (this->pre_alloc) |
|
1
by brian
clean slate |
339 |
{
|
1487
by Brian Aker
More updates for memory::Root |
340 |
this->free=this->pre_alloc; |
341 |
this->free->left=this->pre_alloc->size-ALIGN_SIZE(sizeof(memory::internal::UsedMemory)); |
|
2151.2.5
by Olaf van der Spek
Replace TRASH_MEM macro by function |
342 |
trash_mem(this->pre_alloc); |
1487
by Brian Aker
More updates for memory::Root |
343 |
this->free->next=0; |
1
by brian
clean slate |
344 |
}
|
1487
by Brian Aker
More updates for memory::Root |
345 |
this->block_num= 4; |
346 |
this->first_block_usage= 0; |
|
1
by brian
clean slate |
347 |
}
|
348 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
349 |
/**
|
350 |
* @brief
|
|
351 |
* Duplicate a null-terminated string into memory allocated from within the
|
|
352 |
* specified Root
|
|
353 |
*/
|
|
1487
by Brian Aker
More updates for memory::Root |
354 |
char *memory::Root::strdup_root(const char *str) |
1
by brian
clean slate |
355 |
{
|
1487
by Brian Aker
More updates for memory::Root |
356 |
return strmake_root(str, strlen(str)); |
1
by brian
clean slate |
357 |
}
|
358 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
359 |
/**
|
360 |
* @brief
|
|
361 |
* Copy the (not necessarily null-terminated) string into memory allocated
|
|
362 |
* from within the specified Root
|
|
363 |
*
|
|
364 |
* @details
|
|
365 |
* Note that the string is copied according to the length specified, so
|
|
366 |
* null-termination is ignored. The duplicated string will be null-terminated,
|
|
367 |
* even if the original string wasn't (one additional byte is allocated for
|
|
368 |
* this purpose).
|
|
369 |
*/
|
|
1487
by Brian Aker
More updates for memory::Root |
370 |
char *memory::Root::strmake_root(const char *str, size_t len) |
1
by brian
clean slate |
371 |
{
|
372 |
char *pos; |
|
1487
by Brian Aker
More updates for memory::Root |
373 |
if ((pos= (char *)alloc_root(len+1))) |
1
by brian
clean slate |
374 |
{
|
375 |
memcpy(pos,str,len); |
|
376 |
pos[len]=0; |
|
377 |
}
|
|
378 |
return pos; |
|
379 |
}
|
|
380 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
381 |
/**
|
382 |
* @brief
|
|
383 |
* Duplicate the provided block into memory allocated from within the specified
|
|
384 |
* Root
|
|
385 |
*
|
|
386 |
* @return
|
|
387 |
* non-NULL pointer to a copy of the data if memory could be allocated, otherwise
|
|
388 |
* NULL
|
|
389 |
*/
|
|
1487
by Brian Aker
More updates for memory::Root |
390 |
void *memory::Root::memdup_root(const void *str, size_t len) |
1
by brian
clean slate |
391 |
{
|
575.3.1
by Monty Taylor
Made mysys and mystrings c++. Fixed the resulting bugs the compiler found. |
392 |
void *pos; |
1487
by Brian Aker
More updates for memory::Root |
393 |
|
394 |
if ((pos= this->alloc_root(len))) |
|
1
by brian
clean slate |
395 |
memcpy(pos,str,len); |
1487
by Brian Aker
More updates for memory::Root |
396 |
|
1
by brian
clean slate |
397 |
return pos; |
398 |
}
|
|
1253.1.3
by Monty Taylor
MEM_ROOT == memory::Root |
399 |
|
400 |
} /* namespace drizzled */ |