87
87
The allocation and contents of the actual chunks varies between
88
88
fixed and variable-size modes. Total chunk length is always
89
aligned to the next sizeof(unsigned char*). Here is the format of
89
aligned to the next sizeof(uchar*). Here is the format of
91
unsigned char[] - sizeof=chunk_dataspace_length, but at least
92
sizeof(unsigned char*) bytes. Keeps actual data or pointer
91
uchar[] - sizeof=chunk_dataspace_length, but at least
92
sizeof(uchar*) bytes. Keeps actual data or pointer
93
93
to the next deleted chunk.
94
94
chunk_dataspace_length equals to full record length
95
unsigned char - status field (1 means "in use", 0 means "deleted")
95
uchar - status field (1 means "in use", 0 means "deleted")
96
96
Variable-size uses different format:
97
unsigned char[] - sizeof=chunk_dataspace_length, but at least
98
sizeof(unsigned char*) bytes. Keeps actual data or pointer
97
uchar[] - sizeof=chunk_dataspace_length, but at least
98
sizeof(uchar*) bytes. Keeps actual data or pointer
99
99
to the next deleted chunk.
100
100
chunk_dataspace_length is set according to table
101
101
setup (block_size)
102
unsigned char* - pointer to the next chunk in this chunkset,
102
uchar* - pointer to the next chunk in this chunkset,
103
103
or NULL for the last chunk
104
unsigned char - status field (1 means "first", 0 means "deleted",
104
uchar - status field (1 means "first", 0 means "deleted",
105
105
2 means "linked")
107
107
When allocating a new chunkset of N chunks, Heap Engine will try
112
112
Freeing chunks will place them at the front of free list
113
113
referenced by del_link in HP_DATASPACE. The newly freed chunk
114
114
will contain reference to the previously freed chunk in its first
115
sizeof(unsigned char*) of the payload space.
115
sizeof(uchar*) of the payload space.
117
117
Here is open issues:
118
118
1. It is not very nice to require people to keep key columns
144
144
5. In variable-size format status should be moved to lower
145
145
bits of the "next" pointer. Pointer is always aligned
146
to sizeof(unsigned char*), which is at least 4, leaving 2 lower
146
to sizeof(uchar*), which is at least 4, leaving 2 lower
147
147
bits free. This will save 8 bytes per chunk
148
148
on 64-bit platform.
149
149
6. As we do not want to modify FRM format, BLOCK_SIZE option
167
167
if (info->block.levels)
169
hp_free_level(&info->block,info->block.levels,info->block.root,
169
VOID(hp_free_level(&info->block,info->block.levels,info->block.root,
172
172
info->block.levels=0;
173
173
info->del_chunk_count= info->chunk_count= 0;
189
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)
192
static uchar *hp_allocate_variable_chunkset(HP_DATASPACE *info,
193
uint chunk_count, uchar* existing_set)
195
195
int alloc_count= chunk_count, i;
196
unsigned char *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
196
uchar *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
198
198
assert(alloc_count);
216
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;
217
*((uchar**)(prev_chunk + info->offset_link)) = NULL;
218
218
hp_free_chunks(info, curr_chunk);
238
238
/* Truncate whatever was added at the end of the existing chunkset */
239
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;
240
curr_chunk= *((uchar**)(prev_chunk + info->offset_link));
241
*((uchar**)(prev_chunk + info->offset_link)) = NULL;
242
242
hp_free_chunks(info, curr_chunk);
244
244
else if (first_chunk)
253
253
/* mark as if this chunk is last in the chunkset */
254
*((unsigned char**) (curr_chunk + info->offset_link))= 0;
254
*((uchar**) (curr_chunk + info->offset_link))= 0;
258
258
/* tie them into a linked list */
259
*((unsigned char**) (prev_chunk + info->offset_link))= curr_chunk;
259
*((uchar**) (prev_chunk + info->offset_link))= curr_chunk;
260
260
curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED; /* Record linked from active */
287
287
@return Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
290
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count)
290
uchar *hp_allocate_chunkset(HP_DATASPACE *info, uint chunk_count)
292
unsigned char* result;
295
295
if (info->is_variable_size)
323
323
@return Error code or zero if successful
326
int hp_reallocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count, unsigned char* pos)
326
int hp_reallocate_chunkset(HP_DATASPACE *info, uint chunk_count, uchar* pos)
329
329
if (!info->is_variable_size)
351
351
@return Pointer to the chunk, or NULL if unsuccessful
354
static unsigned char *hp_allocate_one_chunk(HP_DATASPACE *info)
354
static uchar *hp_allocate_one_chunk(HP_DATASPACE *info)
356
unsigned char* curr_chunk;
357
357
size_t length, block_pos;
359
359
if (info->del_link)
361
361
curr_chunk=info->del_link;
362
info->del_link= *((unsigned char**) curr_chunk);
362
info->del_link= *((uchar**) curr_chunk);
363
363
info->del_chunk_count--;
365
365
return curr_chunk;
396
396
@param pos pointer to the head of the chunkset
399
void hp_free_chunks(HP_DATASPACE *info, unsigned char *pos)
399
void hp_free_chunks(HP_DATASPACE *info, uchar *pos)
401
unsigned char* curr_chunk= pos;
401
uchar* curr_chunk= pos;
403
403
while (curr_chunk) {
404
404
info->del_chunk_count++;
405
*((unsigned char**) curr_chunk)= info->del_link;
405
*((uchar**) curr_chunk)= info->del_link;
406
406
info->del_link= curr_chunk;
408
408
curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;