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 */
182
Allocate or reallocate a chunkset in the dataspace
184
Attempts to allocate a new chunkset or change the size of an existing chunkset
186
@param info the hosting dataspace
187
@param chunk_count the number of chunks that we expect as the result
188
@param existing_set non-null value asks function to resize existing chunkset,
189
return value would point to this set
191
@return Pointer to the first chunk in the new or updated chunkset, or NULL if unsuccessful
194
static unsigned char *hp_allocate_variable_chunkset(HP_DATASPACE *info,
195
uint32_t chunk_count, unsigned char* existing_set)
197
int alloc_count= chunk_count, i;
198
unsigned char *first_chunk= 0, *curr_chunk= 0, *prev_chunk= 0, *last_existing_chunk= 0;
204
first_chunk= existing_set;
206
curr_chunk= existing_set;
207
while (curr_chunk && alloc_count)
209
prev_chunk= curr_chunk;
210
curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));
218
/* We came through all chunks and there is more left, let's truncate the list */
219
*((unsigned char**)(prev_chunk + info->offset_link)) = NULL;
220
hp_free_chunks(info, curr_chunk);
226
last_existing_chunk = prev_chunk;
229
/* We can reach this point only if we're allocating new chunkset or more chunks in existing set */
231
for (i=0; i<alloc_count; i++)
233
curr_chunk= hp_allocate_one_chunk(info);
236
/* no space in the current block */
238
if (last_existing_chunk)
240
/* Truncate whatever was added at the end of the existing chunkset */
241
prev_chunk= last_existing_chunk;
242
curr_chunk= *((unsigned char**)(prev_chunk + info->offset_link));
243
*((unsigned char**)(prev_chunk + info->offset_link)) = NULL;
244
hp_free_chunks(info, curr_chunk);
246
else if (first_chunk)
248
/* free any chunks previously allocated */
249
hp_free_chunks(info, first_chunk);
255
/* mark as if this chunk is last in the chunkset */
256
*((unsigned char**) (curr_chunk + info->offset_link))= 0;
260
/* tie them into a linked list */
261
*((unsigned char**) (prev_chunk + info->offset_link))= curr_chunk;
262
curr_chunk[info->offset_status]= CHUNK_STATUS_LINKED; /* Record linked from active */
266
curr_chunk[info->offset_status]= CHUNK_STATUS_ACTIVE; /* Record active */
271
first_chunk= curr_chunk;
274
prev_chunk= curr_chunk;
182
282
Allocate a new chunkset in the dataspace
184
284
Attempts to allocate a new chunkset
189
289
@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 )
292
unsigned char *hp_allocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count)
194
294
unsigned char* result;
196
result= hp_allocate_one_chunk(info);
199
result[info->offset_status]= CHUNK_STATUS_ACTIVE;
297
if (info->is_variable_size)
299
result = hp_allocate_variable_chunkset(info, chunk_count, NULL);
303
result= hp_allocate_one_chunk(info);
306
result[info->offset_status]= CHUNK_STATUS_ACTIVE;
317
Reallocate an existing chunkset in the dataspace
319
Attempts to change the size of an existing chunkset
321
@param info the hosting dataspace
322
@param chunk_count the number of chunks that we expect as the result
323
@param pos pointer to the existing chunkset
325
@return Error code or zero if successful
328
int hp_reallocate_chunkset(HP_DATASPACE *info, uint32_t chunk_count, unsigned char* pos)
331
if (!info->is_variable_size)
333
/* Update should never change chunk_count in fixed-size mode */
334
errno=HA_ERR_WRONG_COMMAND;
338
/* Reallocate never moves the first chunk */
339
if (!hp_allocate_variable_chunkset(info, chunk_count, pos))
207
347
Allocate a single chunk in the dataspace
209
349
Attempts to allocate a new chunk or reuse one from deleted list
263
403
unsigned char* curr_chunk= pos;
267
406
info->del_chunk_count++;
268
407
*((unsigned char**) curr_chunk)= info->del_link;
269
408
info->del_link= curr_chunk;
271
410
curr_chunk[info->offset_status]= CHUNK_STATUS_DELETED;
413
if (!info->is_variable_size)
418
/* Delete next chunk in this chunkset */
419
curr_chunk= *((unsigned char**)(curr_chunk + info->offset_link));