13
13
You should have received a copy of the GNU General Public License
14
14
along with this program; if not, write to the Free Software
15
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
17
/* Implements various base dataspace-related functions - allocate, free, clear */
19
#include "heap_priv.h"
180
Allocate or reallocate a chunkset in the dataspace
182
Attempts to allocate a new chunkset or change the size of an existing chunkset
184
@param info the hosting dataspace
185
@param chunk_count the number of chunks that we expect as the result
186
@param existing_set non-null value asks function to resize existing chunkset,
187
return value would point to this set
189
@return Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
192
static unsigned char *hp_allocate_variable_chunkset(HP_DATASPACE *info,
193
uint32_t chunk_count, unsigned char* existing_set)
195
int alloc_count= chunk_count, i;
196
unsigned char *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
202
first_chunk= existing_set;
204
curr_chunk= existing_set;
205
while (curr_chunk && alloc_count)
207
prev_chunk= curr_chunk;
208
curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));
216
/* We came through all chunks and there is more left, let's truncate the list */
217
*((unsigned char**)(prev_chunk + info->offset_link)) = NULL;
218
hp_free_chunks(info, curr_chunk);
224
last_existing_chunk = prev_chunk;
227
/* We can reach this point only if we're allocating new chunkset or more chunks in existing set */
229
for (i=0; i<alloc_count; i++)
231
curr_chunk= hp_allocate_one_chunk(info);
234
/* no space in the current block */
236
if (last_existing_chunk)
238
/* Truncate whatever was added at the end of the existing chunkset */
239
prev_chunk= last_existing_chunk;
240
curr_chunk= *((unsigned char**)(prev_chunk + info->offset_link));
241
*((unsigned char**)(prev_chunk + info->offset_link)) = NULL;
242
hp_free_chunks(info, curr_chunk);
244
else if (first_chunk)
246
/* free any chunks previously allocated */
247
hp_free_chunks(info, first_chunk);
253
/* mark as if this chunk is last in the chunkset */
254
*((unsigned char**) (curr_chunk + info->offset_link))= 0;
258
/* tie them into a linked list */
259
*((unsigned char**) (prev_chunk + info->offset_link))= curr_chunk;
260
curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED; /* Record linked from active */
264
curr_chunk[info->offset_status]= CHUNK_STATUS_ACTIVE; /* Record active */
269
first_chunk= curr_chunk;
272
prev_chunk= curr_chunk;
182
280
Allocate a new chunkset in the dataspace
184
282
Attempts to allocate a new chunkset
189
287
@return Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
192
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t )
290
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count)
194
292
unsigned char* result;
196
result= hp_allocate_one_chunk(info);
199
result[info->offset_status]= CHUNK_STATUS_ACTIVE;
295
if (info->is_variable_size)
297
result = hp_allocate_variable_chunkset(info, chunk_count, NULL);
301
result= hp_allocate_one_chunk(info);
304
result[info->offset_status]= CHUNK_STATUS_ACTIVE;
315
Reallocate an existing chunkset in the dataspace
317
Attempts to change the size of an existing chunkset
319
@param info the hosting dataspace
320
@param chunk_count the number of chunks that we expect as the result
321
@param pos pointer to the existing chunkset
323
@return Error code or zero if successful
326
int hp_reallocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count, unsigned char* pos)
329
if (!info->is_variable_size)
331
/* Update should never change chunk_count in fixed-size mode */
332
my_errno=HA_ERR_WRONG_COMMAND;
336
/* Reallocate never moves the first chunk */
337
if (!hp_allocate_variable_chunkset(info, chunk_count, pos))
207
345
Allocate a single chunk in the dataspace
209
347
Attempts to allocate a new chunk or reuse one from deleted list
263
401
unsigned char* curr_chunk= pos;
267
404
info->del_chunk_count++;
268
405
*((unsigned char**) curr_chunk)= info->del_link;
269
406
info->del_link= curr_chunk;
271
408
curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;
411
if (!info->is_variable_size)
416
/* Delete next chunk in this chunkset */
417
curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));