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 |
|
2241.4.14
by Stewart Smith
remove some includes from my_sys.h and instead only include where needed. This helps reduce the number of files that have to be rebuilt when you change some of the more widely included header files (such as the drizzled::identifier ones) |
23 |
#include <drizzled/definitions.h> |
24 |
#include <drizzled/memory/root.h> |
|
2173.2.1
by Monty Taylor
Fixes incorrect usage of include |
25 |
#include <drizzled/internal/my_sys.h> |
26 |
#include <drizzled/internal/m_string.h> |
|
2318.6.29
by Olaf van der Spek
Refactor |
27 |
#include <drizzled/sql_string.h> |
1
by brian
clean slate |
28 |
|
1067.4.10
by Nathan Williams
Converted all cmin/cmax usages in the mysys directory to std::min/max. |
29 |
#include <algorithm> |
30 |
||
31 |
using namespace std; |
|
1253.1.3
by Monty Taylor
MEM_ROOT == memory::Root |
32 |
|
2318.6.21
by Olaf van der Spek
Refactor |
33 |
namespace drizzled { |
2318.6.29
by Olaf van der Spek
Refactor |
34 |
namespace memory { |
1
by brian
clean slate |
35 |
|
1253.1.2
by Monty Taylor
We have init_sql_alloc and init_alloc_root - and I can't tell the difference. |
36 |
static const unsigned int MAX_BLOCK_TO_DROP= 4096; |
37 |
static const unsigned int MAX_BLOCK_USAGE_BEFORE_DROP= 10; |
|
38 |
||
1441.2.1
by Tim Martin
Reformatting some memory/root.h comments for doxygen |
39 |
/**
|
40 |
* @brief
|
|
41 |
* Initialize memory root
|
|
42 |
*
|
|
43 |
* @details
|
|
44 |
* This function prepares memory root for further use, sets initial size of
|
|
45 |
* chunk for memory allocation and pre-allocates first block if specified.
|
|
46 |
* Altough error can happen during execution of this function if
|
|
47 |
* pre_alloc_size is non-0 it won't be reported. Instead it will be
|
|
2318.6.41
by Olaf van der Spek
Refactor |
48 |
* reported as error in first alloc() on this memory root.
|
1441.2.1
by Tim Martin
Reformatting some memory/root.h comments for doxygen |
49 |
*
|
50 |
* @param mem_root memory root to initialize
|
|
51 |
* @param block_size size of chunks (blocks) used for memory allocation
|
|
52 |
* (It is external size of chunk i.e. it should include
|
|
53 |
* memory required for internal structures, thus it
|
|
2318.6.29
by Olaf van der Spek
Refactor |
54 |
* should be no less than ROOT_MIN_BLOCK_SIZE)
|
1441.2.1
by Tim Martin
Reformatting some memory/root.h comments for doxygen |
55 |
*
|
56 |
*/
|
|
2318.6.29
by Olaf van der Spek
Refactor |
57 |
void Root::init(size_t block_size_arg) |
1
by brian
clean slate |
58 |
{
|
1487
by Brian Aker
More updates for memory::Root |
59 |
free= used= pre_alloc= 0; |
60 |
min_malloc= 32; |
|
2318.6.29
by Olaf van der Spek
Refactor |
61 |
block_size= block_size_arg - ROOT_MIN_BLOCK_SIZE; |
1487
by Brian Aker
More updates for memory::Root |
62 |
block_num= 4; /* We shift this with >>2 */ |
63 |
first_block_usage= 0; |
|
1
by brian
clean slate |
64 |
}
|
65 |
||
1441.2.1
by Tim Martin
Reformatting some memory/root.h comments for doxygen |
66 |
/**
|
67 |
* @details
|
|
68 |
* Function aligns and assigns new value to block size; then it tries to
|
|
69 |
* reuse one of existing blocks as prealloc block, or malloc new one of
|
|
70 |
* requested size. If no blocks can be reused, all unused blocks are freed
|
|
71 |
* before allocation.
|
|
72 |
*
|
|
73 |
* @param mem_root memory root to change defaults of
|
|
74 |
* @param block_size new value of block size. Must be greater or equal
|
|
75 |
* than ALLOC_ROOT_MIN_BLOCK_SIZE (this value is about
|
|
76 |
* 68 bytes and depends on platform and compilation flags)
|
|
77 |
* @param pre_alloc_size new size of preallocated block. If not zero,
|
|
78 |
* must be equal to or greater than block size,
|
|
79 |
* otherwise means 'no prealloc'.
|
|
80 |
*/
|
|
2318.6.29
by Olaf van der Spek
Refactor |
81 |
void Root::reset_defaults(size_t block_size_arg, size_t pre_alloc_size) |
1
by brian
clean slate |
82 |
{
|
2318.6.29
by Olaf van der Spek
Refactor |
83 |
block_size= block_size_arg - ROOT_MIN_BLOCK_SIZE; |
1
by brian
clean slate |
84 |
if (pre_alloc_size) |
85 |
{
|
|
2318.6.29
by Olaf van der Spek
Refactor |
86 |
size_t size= pre_alloc_size + ALIGN_SIZE(sizeof(internal::UsedMemory)); |
1485
by Brian Aker
Updates to confine memroot |
87 |
if (not pre_alloc || pre_alloc->size != size) |
1
by brian
clean slate |
88 |
{
|
2318.6.29
by Olaf van der Spek
Refactor |
89 |
internal::UsedMemory *mem, **prev= &this->free; |
1
by brian
clean slate |
90 |
/*
|
91 |
Free unused blocks, so that consequent calls
|
|
92 |
to reset_root_defaults won't eat away memory.
|
|
93 |
*/
|
|
94 |
while (*prev) |
|
95 |
{
|
|
96 |
mem= *prev; |
|
97 |
if (mem->size == size) |
|
98 |
{
|
|
99 |
/* We found a suitable block, no need to do anything else */
|
|
1485
by Brian Aker
Updates to confine memroot |
100 |
pre_alloc= mem; |
1
by brian
clean slate |
101 |
return; |
102 |
}
|
|
2318.6.29
by Olaf van der Spek
Refactor |
103 |
if (mem->left + ALIGN_SIZE(sizeof(internal::UsedMemory)) == mem->size) |
1
by brian
clean slate |
104 |
{
|
105 |
/* remove block from the list and free it */
|
|
106 |
*prev= mem->next; |
|
1485
by Brian Aker
Updates to confine memroot |
107 |
std::free(mem); |
1
by brian
clean slate |
108 |
}
|
109 |
else
|
|
110 |
prev= &mem->next; |
|
111 |
}
|
|
112 |
/* Allocate new prealloc block and add it to the end of free list */
|
|
2318.6.29
by Olaf van der Spek
Refactor |
113 |
mem= static_cast<internal::UsedMemory *>(malloc(size)); |
2318.4.11
by Olaf van der Spek
New doesn't return NULL. |
114 |
mem->size= size; |
115 |
mem->left= pre_alloc_size; |
|
116 |
mem->next= *prev; |
|
117 |
*prev= pre_alloc= mem; |
|
1
by brian
clean slate |
118 |
}
|
119 |
}
|
|
120 |
else
|
|
779.1.27
by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files. |
121 |
{
|
1485
by Brian Aker
Updates to confine memroot |
122 |
pre_alloc= 0; |
779.1.27
by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files. |
123 |
}
|
1
by brian
clean slate |
124 |
}
|
125 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
126 |
/**
|
127 |
* @brief
|
|
128 |
* Allocate a chunk of memory from the Root structure provided,
|
|
129 |
* obtaining more memory from the heap if necessary
|
|
130 |
*
|
|
131 |
* @pre
|
|
2318.6.23
by Olaf van der Spek
Refactor |
132 |
* mem_root must have been initialised via init()
|
1441.2.5
by Tim Martin
More doxygen commenting |
133 |
*
|
134 |
* @param mem_root The memory Root to allocate from
|
|
135 |
* @param length The size of the block to allocate
|
|
136 |
*
|
|
137 |
* @todo Would this be more suitable as a member function on the
|
|
138 |
* Root class?
|
|
139 |
*/
|
|
2318.6.41
by Olaf van der Spek
Refactor |
140 |
unsigned char* Root::alloc(size_t length) |
1485
by Brian Aker
Updates to confine memroot |
141 |
{
|
2318.6.29
by Olaf van der Spek
Refactor |
142 |
internal::UsedMemory *next= NULL; |
1487
by Brian Aker
More updates for memory::Root |
143 |
assert(alloc_root_inited()); |
1
by brian
clean slate |
144 |
|
145 |
length= ALIGN_SIZE(length); |
|
2318.6.30
by Olaf van der Spek
Refactor |
146 |
internal::UsedMemory **prev= &this->free; |
147 |
if (*prev) |
|
1
by brian
clean slate |
148 |
{
|
149 |
if ((*prev)->left < length && |
|
1486
by Brian Aker
More encapsulation. |
150 |
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. |
151 |
(*prev)->left < MAX_BLOCK_TO_DROP) |
1
by brian
clean slate |
152 |
{
|
153 |
next= *prev; |
|
154 |
*prev= next->next; /* Remove block from list */ |
|
1486
by Brian Aker
More encapsulation. |
155 |
next->next= this->used; |
156 |
this->used= next; |
|
157 |
this->first_block_usage= 0; |
|
1
by brian
clean slate |
158 |
}
|
2318.6.30
by Olaf van der Spek
Refactor |
159 |
for (next= *prev; next && next->left < length; next= next->next) |
1
by brian
clean slate |
160 |
prev= &next->next; |
161 |
}
|
|
162 |
if (! next) |
|
163 |
{ /* Time to alloc new block */ |
|
2318.6.30
by Olaf van der Spek
Refactor |
164 |
size_t tmp_block_size= this->block_size * (this->block_num >> 2); |
165 |
size_t get_size= length+ALIGN_SIZE(sizeof(internal::UsedMemory)); |
|
1486
by Brian Aker
More encapsulation. |
166 |
get_size= max(get_size, tmp_block_size); |
1
by brian
clean slate |
167 |
|
2318.6.29
by Olaf van der Spek
Refactor |
168 |
next = static_cast<internal::UsedMemory *>(malloc(get_size)); |
1486
by Brian Aker
More encapsulation. |
169 |
this->block_num++; |
1
by brian
clean slate |
170 |
next->next= *prev; |
171 |
next->size= get_size; |
|
2318.6.29
by Olaf van der Spek
Refactor |
172 |
next->left= get_size-ALIGN_SIZE(sizeof(internal::UsedMemory)); |
1
by brian
clean slate |
173 |
*prev=next; |
174 |
}
|
|
175 |
||
2318.6.21
by Olaf van der Spek
Refactor |
176 |
unsigned char* point= (unsigned char*) ((char*) next+ (next->size-next->left)); |
1486
by Brian Aker
More encapsulation. |
177 |
/** @todo next part may be unneeded due to this->first_block_usage counter*/
|
178 |
if ((next->left-= length) < this->min_malloc) |
|
1
by brian
clean slate |
179 |
{ /* Full block */ |
180 |
*prev= next->next; /* Remove block from list */ |
|
1486
by Brian Aker
More encapsulation. |
181 |
next->next= this->used; |
182 |
this->used= next; |
|
183 |
this->first_block_usage= 0; |
|
1
by brian
clean slate |
184 |
}
|
1441.2.5
by Tim Martin
More doxygen commenting |
185 |
|
186 |
return point; |
|
1
by brian
clean slate |
187 |
}
|
188 |
||
189 |
||
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
190 |
/**
|
191 |
* @brief
|
|
192 |
* Allocate many pointers at the same time.
|
|
193 |
*
|
|
194 |
* @details
|
|
195 |
* The variable arguments are a list of alternating pointers and lengths,
|
|
196 |
* terminated by a null pointer:
|
|
2318.6.29
by Olaf van der Spek
Refactor |
197 |
* @li <tt>char* * pointer1</tt>
|
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
198 |
* @li <tt>uint length1</tt>
|
2318.6.29
by Olaf van der Spek
Refactor |
199 |
* @li <tt>char* * pointer2</tt>
|
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
200 |
* @li <tt>uint length2</tt>
|
201 |
* @li <tt>...</tt>
|
|
202 |
* @li <tt>NULL</tt>
|
|
203 |
*
|
|
204 |
* @c pointer1, @c pointer2 etc. all point into big allocated memory area
|
|
205 |
*
|
|
206 |
* @param root Memory root
|
|
207 |
*
|
|
208 |
* @return
|
|
209 |
* A pointer to the beginning of the allocated memory block in case of
|
|
210 |
* success or NULL if out of memory
|
|
211 |
*/
|
|
2318.6.41
by Olaf van der Spek
Refactor |
212 |
void* Root::multi_alloc(int unused, ...) |
1
by brian
clean slate |
213 |
{
|
214 |
va_list args; |
|
2318.6.29
by Olaf van der Spek
Refactor |
215 |
char* *ptr, *start, *res; |
1
by brian
clean slate |
216 |
size_t tot_length, length; |
217 |
||
1532.1.9
by Brian Aker
Fix for Solaris build issue. |
218 |
(void)unused; // For some reason Sun Studio registers unused as not used. |
1532.1.7
by Brian Aker
Fix for non-portable vastart usage. |
219 |
va_start(args, unused); |
1
by brian
clean slate |
220 |
tot_length= 0; |
2318.6.29
by Olaf van der Spek
Refactor |
221 |
while ((ptr= va_arg(args, char* *))) |
1
by brian
clean slate |
222 |
{
|
223 |
length= va_arg(args, uint); |
|
224 |
tot_length+= ALIGN_SIZE(length); |
|
225 |
}
|
|
226 |
va_end(args); |
|
227 |
||
2318.6.41
by Olaf van der Spek
Refactor |
228 |
start= (char*) this->alloc(tot_length); |
1
by brian
clean slate |
229 |
|
1532.1.7
by Brian Aker
Fix for non-portable vastart usage. |
230 |
va_start(args, unused); |
1
by brian
clean slate |
231 |
res= start; |
2318.6.29
by Olaf van der Spek
Refactor |
232 |
while ((ptr= va_arg(args, char* *))) |
1
by brian
clean slate |
233 |
{
|
234 |
*ptr= res; |
|
235 |
length= va_arg(args, uint); |
|
236 |
res+= ALIGN_SIZE(length); |
|
237 |
}
|
|
238 |
va_end(args); |
|
51.3.20
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
239 |
return((void*) start); |
1
by brian
clean slate |
240 |
}
|
241 |
||
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
242 |
/**
|
243 |
* @brief
|
|
244 |
* Mark all data in blocks free for reusage
|
|
1441.2.5
by Tim Martin
More doxygen commenting |
245 |
*/
|
2318.6.29
by Olaf van der Spek
Refactor |
246 |
void Root::mark_blocks_free() |
1
by brian
clean slate |
247 |
{
|
2318.6.29
by Olaf van der Spek
Refactor |
248 |
internal::UsedMemory *next; |
249 |
internal::UsedMemory **last; |
|
1
by brian
clean slate |
250 |
|
251 |
/* iterate through (partially) free blocks, mark them free */
|
|
1485
by Brian Aker
Updates to confine memroot |
252 |
last= &free; |
253 |
for (next= free; next; next= *(last= &next->next)) |
|
1
by brian
clean slate |
254 |
{
|
2318.6.29
by Olaf van der Spek
Refactor |
255 |
next->left= next->size - ALIGN_SIZE(sizeof(internal::UsedMemory)); |
1
by brian
clean slate |
256 |
}
|
257 |
||
258 |
/* Combine the free and the used list */
|
|
1485
by Brian Aker
Updates to confine memroot |
259 |
*last= next= used; |
1
by brian
clean slate |
260 |
|
261 |
/* now go through the used blocks and mark them free */
|
|
262 |
for (; next; next= next->next) |
|
263 |
{
|
|
2318.6.29
by Olaf van der Spek
Refactor |
264 |
next->left= next->size - ALIGN_SIZE(sizeof(internal::UsedMemory)); |
1
by brian
clean slate |
265 |
}
|
266 |
||
267 |
/* Now everything is set; Indicate that nothing is used anymore */
|
|
1485
by Brian Aker
Updates to confine memroot |
268 |
used= 0; |
269 |
first_block_usage= 0; |
|
1
by brian
clean slate |
270 |
}
|
271 |
||
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
272 |
/**
|
273 |
* @brief
|
|
2318.6.29
by Olaf van der Spek
Refactor |
274 |
* Deallocate everything used by alloc_root or just move
|
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
275 |
* used blocks to free list if called with MY_USED_TO_FREE
|
276 |
*
|
|
277 |
* @note
|
|
278 |
* One can call this function either with root block initialised with
|
|
2318.6.23
by Olaf van der Spek
Refactor |
279 |
* init() or with a zero:ed block.
|
1441.2.3
by Tim Martin
Updating existing comments to doxygen format |
280 |
* It's also safe to call this multiple times with the same mem_root.
|
281 |
*
|
|
282 |
* @param root Memory root
|
|
283 |
* @param MyFlags Flags for what should be freed:
|
|
284 |
* @li MARK_BLOCKS_FREED Don't free blocks, just mark them free
|
|
285 |
* @li KEEP_PREALLOC If this is not set, then free also the
|
|
286 |
* preallocated block
|
|
287 |
*/
|
|
2318.6.29
by Olaf van der Spek
Refactor |
288 |
void Root::free_root(myf MyFlags) |
1
by brian
clean slate |
289 |
{
|
2318.6.29
by Olaf van der Spek
Refactor |
290 |
if (MyFlags & MARK_BLOCKS_FREE) |
1
by brian
clean slate |
291 |
{
|
1487
by Brian Aker
More updates for memory::Root |
292 |
this->mark_blocks_free(); |
51.3.20
by Jay Pipes
Phase 6 - Remove DBUG from mysys |
293 |
return; |
1
by brian
clean slate |
294 |
}
|
2318.6.29
by Olaf van der Spek
Refactor |
295 |
if (!(MyFlags & KEEP_PREALLOC)) |
1487
by Brian Aker
More updates for memory::Root |
296 |
this->pre_alloc=0; |
1
by brian
clean slate |
297 |
|
2318.6.30
by Olaf van der Spek
Refactor |
298 |
for (internal::UsedMemory* next= this->used; next;) |
1
by brian
clean slate |
299 |
{
|
2318.6.30
by Olaf van der Spek
Refactor |
300 |
internal::UsedMemory* old =next; |
301 |
next= next->next; |
|
1487
by Brian Aker
More updates for memory::Root |
302 |
if (old != this->pre_alloc) |
303 |
std::free(old); |
|
1
by brian
clean slate |
304 |
}
|
2318.6.30
by Olaf van der Spek
Refactor |
305 |
for (internal::UsedMemory* next=this->free; next;) |
1
by brian
clean slate |
306 |
{
|
2318.6.30
by Olaf van der Spek
Refactor |
307 |
internal::UsedMemory* old= next; |
308 |
next= next->next; |
|
1487
by Brian Aker
More updates for memory::Root |
309 |
if (old != this->pre_alloc) |
310 |
std::free(old); |
|
1
by brian
clean slate |
311 |
}
|
1487
by Brian Aker
More updates for memory::Root |
312 |
this->used=this->free=0; |
313 |
if (this->pre_alloc) |
|
1
by brian
clean slate |
314 |
{
|
1487
by Brian Aker
More updates for memory::Root |
315 |
this->free=this->pre_alloc; |
2318.6.29
by Olaf van der Spek
Refactor |
316 |
this->free->left=this->pre_alloc->size-ALIGN_SIZE(sizeof(internal::UsedMemory)); |
1487
by Brian Aker
More updates for memory::Root |
317 |
this->free->next=0; |
1
by brian
clean slate |
318 |
}
|
1487
by Brian Aker
More updates for memory::Root |
319 |
this->block_num= 4; |
320 |
this->first_block_usage= 0; |
|
1
by brian
clean slate |
321 |
}
|
322 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
323 |
/**
|
324 |
* @brief
|
|
325 |
* Duplicate a null-terminated string into memory allocated from within the
|
|
326 |
* specified Root
|
|
327 |
*/
|
|
2318.6.29
by Olaf van der Spek
Refactor |
328 |
char* Root::strdup(const char* str) |
1
by brian
clean slate |
329 |
{
|
2318.9.10
by Olaf van der Spek
Rename strmake to strdup (standard name) |
330 |
return strdup(str, strlen(str)); |
1
by brian
clean slate |
331 |
}
|
332 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
333 |
/**
|
334 |
* @brief
|
|
335 |
* Copy the (not necessarily null-terminated) string into memory allocated
|
|
336 |
* from within the specified Root
|
|
337 |
*
|
|
338 |
* @details
|
|
339 |
* Note that the string is copied according to the length specified, so
|
|
340 |
* null-termination is ignored. The duplicated string will be null-terminated,
|
|
341 |
* even if the original string wasn't (one additional byte is allocated for
|
|
342 |
* this purpose).
|
|
343 |
*/
|
|
2318.9.10
by Olaf van der Spek
Rename strmake to strdup (standard name) |
344 |
char* Root::strdup(const char* str, size_t len) |
1
by brian
clean slate |
345 |
{
|
2318.6.40
by Olaf van der Spek
Refactor |
346 |
char* pos= (char*)alloc(len + 1); |
2318.6.21
by Olaf van der Spek
Refactor |
347 |
memcpy(pos, str, len); |
348 |
pos[len]= 0; |
|
1
by brian
clean slate |
349 |
return pos; |
350 |
}
|
|
351 |
||
2318.9.10
by Olaf van der Spek
Rename strmake to strdup (standard name) |
352 |
char* Root::strdup(str_ref v) |
353 |
{
|
|
354 |
return strdup(v.data(), v.size()); |
|
2318.6.29
by Olaf van der Spek
Refactor |
355 |
}
|
356 |
||
1441.2.5
by Tim Martin
More doxygen commenting |
357 |
/**
|
358 |
* @brief
|
|
359 |
* Duplicate the provided block into memory allocated from within the specified
|
|
360 |
* Root
|
|
361 |
*
|
|
362 |
* @return
|
|
363 |
* non-NULL pointer to a copy of the data if memory could be allocated, otherwise
|
|
364 |
* NULL
|
|
365 |
*/
|
|
2318.6.29
by Olaf van der Spek
Refactor |
366 |
void* Root::memdup(const void* str, size_t len) |
1
by brian
clean slate |
367 |
{
|
2318.6.40
by Olaf van der Spek
Refactor |
368 |
void* pos= alloc(len); |
2318.6.21
by Olaf van der Spek
Refactor |
369 |
memcpy(pos, str, len); |
1
by brian
clean slate |
370 |
return pos; |
371 |
}
|
|
1253.1.3
by Monty Taylor
MEM_ROOT == memory::Root |
372 |
|
2318.6.29
by Olaf van der Spek
Refactor |
373 |
}
|
1253.1.3
by Monty Taylor
MEM_ROOT == memory::Root |
374 |
} /* namespace drizzled */ |