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 // Set new data size and new max node count
(avl->header)->avl_size = new_data_size; (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; return 0;
} }
@ -905,12 +905,12 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
return -1; 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 // Set the new avl size
(avl->header)->avl_size = new_data_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; return 0;
} }
@ -1012,7 +1012,7 @@ int unmap_an_avl(OBIDMS_avl_p avl)
obidebug(1, "\nError unmapping the data of an AVL tree"); obidebug(1, "\nError unmapping the data of an AVL tree");
return -1; 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); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError unmapping the tree of an AVL tree"); 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->tree = mmap(NULL,
((avl->header)->nb_items_max) * sizeof(AVL_node_t), (avl->header)->avl_size,
PROT_READ, PROT_READ,
MAP_SHARED, MAP_SHARED,
avl->avl_fd, 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)->header_size = header_size;
(avl->header)->avl_size = data_size; (avl->header)->avl_size = data_size;
(avl->header)->nb_items = 0; (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)->root_idx = -1;
(avl->header)->creation_date = time(NULL); (avl->header)->creation_date = time(NULL);
strcpy((avl->header)->avl_name, complete_avl_name); 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->tree = mmap(NULL,
(((avl->header)->nb_items_max) * sizeof(AVL_node_t)), (avl->header)->avl_size,
PROT_READ, PROT_READ,
MAP_SHARED, MAP_SHARED,
avl_file_descriptor, 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 // Clone AVL tree
memcpy(new_avl->tree, avl->tree, (avl->header)->avl_size); memcpy(new_avl->tree, avl->tree, (avl->header)->avl_size);
(new_avl->header)->avl_size = (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_used = ((avl->data)->header)->data_size_used;
((new_avl->data)->header)->data_size_max = ((avl->data)->header)->data_size_max; ((new_avl->data)->header)->data_size_max = ((avl->data)->header)->data_size_max;
((new_avl->data)->header)->nb_items = ((avl->data)->header)->nb_items; ((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 // Create the new AVL group
new_avl_group = obi_create_avl_group(avl_group->dms, new_avl_name); 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 // 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++) for (i=0; i<(avl_group->last_avl_idx); i++)
{ {
if (add_existing_avl_in_group(new_avl_group, avl_group, i) < 0) 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; return NULL;
}
} }
// Create the last AVL to copy data in it // Create the last AVL to copy data in it
if (add_new_avl_in_group(new_avl_group) < 0) 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); obi_close_avl_group(new_avl_group);
return NULL; return NULL;
} }
// Copy the data from the last AVL to a new one that can be modified // Copy the data from the last AVL to the 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]); 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 // Close old AVL group
if (obi_close_avl_group(avl_group) < 0) 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); obi_close_avl_group(new_avl_group);
return NULL; 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 avl A pointer on the AVL to clone.
* @param new_avl A pointer on the new AVL to fill. * @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 * @since May 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org) * @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);
/** /**