Fixed major bug when cloning an AVL group (last AVL of new group was not

correctly enlarged before copying the data) + minor improvements
This commit is contained in:
Celine Mercier
2016-09-05 12:29:52 +02:00
parent eb82d088cb
commit c9dce03295
2 changed files with 45 additions and 12 deletions

View File

@ -790,7 +790,7 @@ int truncate_avl_to_size_used(OBIDMS_avl_p avl) // TODO is it necessary to unmap
// Set new data size and new max node count
(avl->header)->avl_size = new_data_size;
(avl->header)->nb_items_max = floor(new_data_size / sizeof(AVL_node_t));
(avl->header)->nb_items_max = (index_t) floor(((double) (avl->header)->avl_size) / ((double) sizeof(AVL_node_t)));
return 0;
}
@ -905,12 +905,12 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
return -1;
}
// Set new maximum number of items
(avl->header)->nb_items_max = floor(((double) new_data_size) / ((double) sizeof(AVL_node_t)));
// Set the new avl size
(avl->header)->avl_size = new_data_size;
// Set new maximum number of items
(avl->header)->nb_items_max = (index_t) floor(((double) (avl->header)->avl_size) / ((double) sizeof(AVL_node_t)));
return 0;
}
@ -1012,7 +1012,7 @@ int unmap_an_avl(OBIDMS_avl_p avl)
obidebug(1, "\nError unmapping the data of an AVL tree");
return -1;
}
if (munmap(avl->tree, (((avl->header)->nb_items_max) * sizeof(AVL_node_t))) < 0)
if (munmap(avl->tree, (avl->header)->avl_size) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError unmapping the tree of an AVL tree");
@ -1038,7 +1038,7 @@ int remap_an_avl(OBIDMS_avl_p avl)
}
avl->tree = mmap(NULL,
((avl->header)->nb_items_max) * sizeof(AVL_node_t),
(avl->header)->avl_size,
PROT_READ,
MAP_SHARED,
avl->avl_fd,
@ -1686,7 +1686,7 @@ OBIDMS_avl_p obi_create_avl(OBIDMS_p dms, const char* avl_name, int avl_idx)
(avl->header)->header_size = header_size;
(avl->header)->avl_size = data_size;
(avl->header)->nb_items = 0;
(avl->header)->nb_items_max = (index_t) floor(((double) get_initial_avl_size()) / ((double) sizeof(AVL_node_t)));
(avl->header)->nb_items_max = (index_t) floor(((double) (avl->header)->avl_size) / ((double) sizeof(AVL_node_t)));
(avl->header)->root_idx = -1;
(avl->header)->creation_date = time(NULL);
strcpy((avl->header)->avl_name, complete_avl_name);
@ -1916,7 +1916,7 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx)
}
avl->tree = mmap(NULL,
(((avl->header)->nb_items_max) * sizeof(AVL_node_t)),
(avl->header)->avl_size,
PROT_READ,
MAP_SHARED,
avl_file_descriptor,
@ -2069,8 +2069,20 @@ OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name)
}
void obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl)
int obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl)
{
// Grow the new AVL as needed before copying
while (((new_avl->header)->nb_items_max) < ((avl->header)->nb_items))
{
if (grow_avl(new_avl) < 0)
return -1;
}
while ((((new_avl->data)->header)->data_size_max) < (((avl->data)->header)->data_size_used))
{
if (grow_avl_data(new_avl->data) < 0)
return -1;
}
// Clone AVL tree
memcpy(new_avl->tree, avl->tree, (avl->header)->avl_size);
(new_avl->header)->avl_size = (avl->header)->avl_size;
@ -2083,6 +2095,9 @@ void obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl)
((new_avl->data)->header)->data_size_used = ((avl->data)->header)->data_size_used;
((new_avl->data)->header)->data_size_max = ((avl->data)->header)->data_size_max;
((new_avl->data)->header)->nb_items = ((avl->data)->header)->nb_items;
//avl_print(new_avl);
return 0;
}
@ -2093,27 +2108,42 @@ OBIDMS_avl_group_p obi_clone_avl_group(OBIDMS_avl_group_p avl_group, const char*
// Create the new AVL group
new_avl_group = obi_create_avl_group(avl_group->dms, new_avl_name);
if (new_avl_group == NULL)
return NULL;
// Create hard links to all the full AVLs that won't be modified: all but the last one
for (i=0; i<(avl_group->last_avl_idx); i++)
{
if (add_existing_avl_in_group(new_avl_group, avl_group, i) < 0)
{
obidebug(1, "\nError adding an existing AVL tree in a new group of AVL trees");
return NULL;
}
}
// Create the last AVL to copy data in it
if (add_new_avl_in_group(new_avl_group) < 0)
{
obidebug(1, "\nError creating a new AVL tree in a new group of AVL trees");
obi_close_avl_group(new_avl_group);
return NULL;
}
// Copy the data from the last AVL to a new one that can be modified
obi_clone_avl((avl_group->sub_avls)[avl_group->last_avl_idx], (new_avl_group->sub_avls)[new_avl_group->last_avl_idx]);
// Copy the data from the last AVL to the new one that can be modified
if ((((avl_group->sub_avls)[avl_group->last_avl_idx])->header)->nb_items > 0)
{
if (obi_clone_avl((avl_group->sub_avls)[avl_group->last_avl_idx], (new_avl_group->sub_avls)[new_avl_group->last_avl_idx]) < 0)
{
obidebug(1, "\nError copying an AVL tree in a new group of AVL trees");
obi_close_avl_group(new_avl_group);
return NULL;
}
}
// Close old AVL group
if (obi_close_avl_group(avl_group) < 0)
{
obidebug(1, "\nError closing a group of AVL trees after cloning it to make a new group");
obi_close_avl_group(new_avl_group);
return NULL;
}

View File

@ -298,10 +298,13 @@ OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name);
* @param avl A pointer on the AVL to clone.
* @param new_avl A pointer on the new AVL to fill.
*
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since May 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
void obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl);
int obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl);
/**