Fixed major bug when cloning an AVL where the bloom filter was not

copied properly (because the sutructure copy via assignation does not
work for structures with a variable size)
This commit is contained in:
Celine Mercier
2016-09-15 11:47:02 +02:00
parent 9a97f1f633
commit de189fd7e0
2 changed files with 73 additions and 25 deletions

View File

@ -294,7 +294,7 @@ int remap_an_avl(OBIDMS_avl_p avl);
* @warning The previous AVL in the list of the group is unmapped, * @warning The previous AVL in the list of the group is unmapped,
* if it's not the 1st AVL being added. * if it's not the 1st AVL being added.
* *
* @param avl A pointer on the AVL tree group structure. * @param avl_group A pointer on the AVL tree group structure.
* *
* @retval 0 if the operation was successfully completed. * @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred. * @retval -1 if an error occurred.
@ -305,6 +305,24 @@ int remap_an_avl(OBIDMS_avl_p avl);
int add_new_avl_in_group(OBIDMS_avl_group_p avl_group); int add_new_avl_in_group(OBIDMS_avl_group_p avl_group);
/**
* @brief Internal function adding an existing AVL in an AVL group.
*
* The AVL is hard-linked in the AVL group directory, and opened for that group.
*
* @param avl_group_dest A pointer on the destination AVL group to which the AVL should be added.
* @param avl_group_source A pointer on the source AVL group where the AVL already exists.
* @param avl_idx Index of the AVL in the source AVL group.
*
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since June 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
int add_existing_avl_in_group(OBIDMS_avl_group_p avl_group_dest, OBIDMS_avl_group_p avl_group_source, int avl_idx);
/** /**
* @brief Internal function testing if a value might already be stored in an AVL tree. * @brief Internal function testing if a value might already be stored in an AVL tree.
* *
@ -875,7 +893,6 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError enlarging an AVL tree file"); obidebug(1, "\nError enlarging an AVL tree file");
close(avl_file_descriptor);
return -1; return -1;
} }
@ -885,7 +902,6 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the tree of an AVL tree file before enlarging"); obidebug(1, "\nError munmapping the tree of an AVL tree file before enlarging");
close(avl_file_descriptor);
return -1; return -1;
} }
@ -901,7 +917,6 @@ int grow_avl(OBIDMS_avl_p avl) // TODO Lock when needed
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError re-mmapping the tree of an AVL tree file after enlarging the file"); obidebug(1, "\nError re-mmapping the tree of an AVL tree file after enlarging the file");
close(avl_file_descriptor);
return -1; return -1;
} }
@ -936,7 +951,6 @@ int grow_avl_data(OBIDMS_avl_data_p avl_data) // TODO Lock when needed
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError enlarging an AVL tree data file"); obidebug(1, "\nError enlarging an AVL tree data file");
close(avl_data_file_descriptor);
return -1; return -1;
} }
@ -946,7 +960,6 @@ int grow_avl_data(OBIDMS_avl_data_p avl_data) // TODO Lock when needed
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError munmapping the data of an AVL tree data file before enlarging"); obidebug(1, "\nError munmapping the data of an AVL tree data file before enlarging");
close(avl_data_file_descriptor);
return -1; return -1;
} }
@ -962,7 +975,6 @@ int grow_avl_data(OBIDMS_avl_data_p avl_data) // TODO Lock when needed
{ {
obi_set_errno(OBI_AVL_ERROR); obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError re-mmapping the data of an AVL tree data file after enlarging the file"); obidebug(1, "\nError re-mmapping the data of an AVL tree data file after enlarging the file");
close(avl_data_file_descriptor);
return -1; return -1;
} }
@ -996,7 +1008,12 @@ int close_avl_data(OBIDMS_avl_data_p avl_data)
ret_val = -1; ret_val = -1;
} }
close(avl_data->data_fd); if (close(avl_data->data_fd) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError closing an AVL tree data file");
ret_val = -1;
}
free(avl_data); free(avl_data);
@ -1084,7 +1101,6 @@ int add_new_avl_in_group(OBIDMS_avl_group_p avl_group)
} }
// TODO doc
int add_existing_avl_in_group(OBIDMS_avl_group_p avl_group_dest, OBIDMS_avl_group_p avl_group_source, int avl_idx) int add_existing_avl_in_group(OBIDMS_avl_group_p avl_group_dest, OBIDMS_avl_group_p avl_group_source, int avl_idx)
{ {
if (link(get_full_path_of_avl_file_name(avl_group_source->dms, avl_group_source->name, avl_idx), get_full_path_of_avl_file_name(avl_group_dest->dms, avl_group_dest->name, avl_idx)) < 0) if (link(get_full_path_of_avl_file_name(avl_group_source->dms, avl_group_source->name, avl_idx), get_full_path_of_avl_file_name(avl_group_dest->dms, avl_group_dest->name, avl_idx)) < 0)
@ -1103,7 +1119,7 @@ int add_existing_avl_in_group(OBIDMS_avl_group_p avl_group_dest, OBIDMS_avl_grou
// Increment current AVL index // Increment current AVL index
(avl_group_dest->last_avl_idx)++; (avl_group_dest->last_avl_idx)++;
// Open AVL for that group TODO ideally not needed, but needed for now // Open AVL for that group TODO ideally not needed because AVL open twice, but needed for now
avl_group_dest->sub_avls[avl_group_dest->last_avl_idx] = obi_open_avl(avl_group_source->dms, avl_group_source->name, avl_idx); avl_group_dest->sub_avls[avl_group_dest->last_avl_idx] = obi_open_avl(avl_group_source->dms, avl_group_source->name, avl_idx);
if ((avl_group_dest->sub_avls)[avl_group_dest->last_avl_idx] == NULL) if ((avl_group_dest->sub_avls)[avl_group_dest->last_avl_idx] == NULL)
{ {
@ -1114,6 +1130,7 @@ int add_existing_avl_in_group(OBIDMS_avl_group_p avl_group_dest, OBIDMS_avl_grou
return 0; return 0;
} }
int maybe_in_avl(OBIDMS_avl_p avl, Obi_blob_p value) int maybe_in_avl(OBIDMS_avl_p avl, Obi_blob_p value)
{ {
return (bloom_check(&((avl->header)->bloom_filter), value, obi_blob_sizeof(value))); return (bloom_check(&((avl->header)->bloom_filter), value, obi_blob_sizeof(value)));
@ -1361,7 +1378,8 @@ void avl_print_node(OBIDMS_avl_p avl, AVL_node_p node, index_t node_idx, int dep
putchar(' '); putchar(' ');
fprintf(stderr, "Node idx: %lld, Value idx: %lld, Left child: %lld, Right child: %lld, " fprintf(stderr, "Node idx: %lld, Value idx: %lld, Left child: %lld, Right child: %lld, "
"Balance factor: %d, CRC: %llu\n", node_idx, node->value, node->left_child, node->right_child, node->balance_factor, node->crc64); "Balance factor: %d, CRC: %llu\nValue:", node_idx, node->value, node->left_child, node->right_child, node->balance_factor, node->crc64);
print_bits(((avl->data)->data)+(node->value), obi_blob_sizeof((Obi_blob_p)(((avl->data)->data)+(node->value))));
if (node->right_child != -1) if (node->right_child != -1)
avl_print_node(avl, RIGHT_CHILD(node), node->right_child, depth+2); avl_print_node(avl, RIGHT_CHILD(node), node->right_child, depth+2);
@ -1679,8 +1697,6 @@ OBIDMS_avl_p obi_create_avl(OBIDMS_p dms, const char* avl_name, int avl_idx)
avl->dms = dms; avl->dms = dms;
avl->data = avl_data; avl->data = avl_data;
avl->directory = dms->indexer_directory;
avl->dir_fd = avl_dir_fd;
avl->avl_fd = avl_file_descriptor; avl->avl_fd = avl_file_descriptor;
(avl->header)->header_size = header_size; (avl->header)->header_size = header_size;
@ -1696,6 +1712,13 @@ OBIDMS_avl_p obi_create_avl(OBIDMS_p dms, const char* avl_name, int avl_idx)
free(complete_avl_name); free(complete_avl_name);
if (closedir(directory) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError closing an AVL directory");
return NULL;
}
return avl; return avl;
} }
@ -1937,12 +1960,17 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx)
avl->dms = dms; avl->dms = dms;
avl->data = avl_data; avl->data = avl_data;
avl->directory = dms->indexer_directory;
avl->dir_fd = avl_dir_file_descriptor;
avl->avl_fd = avl_file_descriptor; avl->avl_fd = avl_file_descriptor;
free(complete_avl_name); free(complete_avl_name);
if (closedir(directory) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError closing an AVL directory");
return NULL;
}
return avl; return avl;
} }
@ -1996,6 +2024,9 @@ OBIDMS_avl_group_p obi_create_avl_group(OBIDMS_p dms, const char* avl_name)
return NULL; return NULL;
} }
// Store pointer on directory
avl_group->directory = opendir(avl_dir_name);
// Add in the list of open indexers // Add in the list of open indexers
obi_dms_list_indexer(dms, avl_group); obi_dms_list_indexer(dms, avl_group);
@ -2005,6 +2036,8 @@ OBIDMS_avl_group_p obi_create_avl_group(OBIDMS_p dms, const char* avl_name)
// Set as writable // Set as writable
avl_group->writable = true; avl_group->writable = true;
free(avl_dir_name);
return avl_group; return avl_group;
} }
@ -2051,11 +2084,16 @@ OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name)
if ((avl_group->sub_avls)[i] == NULL) if ((avl_group->sub_avls)[i] == NULL)
return NULL; return NULL;
} }
avl_group->last_avl_idx = avl_count-1; // TODO latest. discuss
// Store the index of the last AVL (the one to be modified)
avl_group->last_avl_idx = avl_count-1;
strcpy(avl_group->name, avl_name); strcpy(avl_group->name, avl_name);
avl_group->dms = dms; avl_group->dms = dms;
// Store pointer on directory
avl_group->directory = opendir(avl_dir_name);
// Add in the list of open indexers // Add in the list of open indexers
obi_dms_list_indexer(dms, avl_group); obi_dms_list_indexer(dms, avl_group);
@ -2065,6 +2103,8 @@ OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name)
// Set as read-only // Set as read-only
avl_group->writable = false; avl_group->writable = false;
free(avl_dir_name);
return avl_group; return avl_group;
} }
@ -2085,10 +2125,10 @@ int obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl)
// 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);
memcpy(&((new_avl->header)->bloom_filter), &((avl->header)->bloom_filter), bloom_filter_size(MAX_NODE_COUNT_PER_AVL, BLOOM_FILTER_ERROR_RATE));
(new_avl->header)->avl_size = (avl->header)->avl_size; (new_avl->header)->avl_size = (avl->header)->avl_size;
(new_avl->header)->nb_items = (avl->header)->nb_items; (new_avl->header)->nb_items = (avl->header)->nb_items;
(new_avl->header)->root_idx = (avl->header)->root_idx; (new_avl->header)->root_idx = (avl->header)->root_idx;
(new_avl->header)->bloom_filter = (avl->header)->bloom_filter;
// Clone AVL data // Clone AVL data
memcpy((new_avl->data)->data, (avl->data)->data, ((avl->data)->header)->data_size_used); memcpy((new_avl->data)->data, (avl->data)->data, ((avl->data)->header)->data_size_used);
@ -2174,7 +2214,12 @@ int obi_close_avl(OBIDMS_avl_p avl)
ret_val = -1; ret_val = -1;
} }
close(avl->avl_fd); if (close(avl->avl_fd) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError closing an AVL tree file");
ret_val = -1;
}
free(avl); free(avl);
@ -2209,6 +2254,13 @@ int obi_close_avl_group(OBIDMS_avl_group_p avl_group)
ret_val = -1; ret_val = -1;
} }
if (closedir(avl_group->directory) < 0)
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError closing an AVL group directory");
ret_val = -1;
}
free(avl_group); free(avl_group);
} }
@ -2474,8 +2526,8 @@ index_t obi_avl_group_add(OBIDMS_avl_group_p avl_group, Obi_blob_p value)
} }
// Add in the current AVL // Add in the current AVL
bloom_add(&((((avl_group->sub_avls)[avl_group->last_avl_idx])->header)->bloom_filter), value, obi_blob_sizeof(value));
index_in_avl = (int32_t) obi_avl_add((avl_group->sub_avls)[avl_group->last_avl_idx], value); index_in_avl = (int32_t) obi_avl_add((avl_group->sub_avls)[avl_group->last_avl_idx], value);
bloom_add(&((((avl_group->sub_avls)[avl_group->last_avl_idx])->header)->bloom_filter), value, obi_blob_sizeof(value));
// Build the index containing the AVL index // Build the index containing the AVL index
index_with_avl = avl_group->last_avl_idx; index_with_avl = avl_group->last_avl_idx;

View File

@ -143,12 +143,6 @@ typedef struct OBIDMS_avl {
OBIDMS_avl_data_p data; /**< A pointer to the structure containing the data OBIDMS_avl_data_p data; /**< A pointer to the structure containing the data
* that the AVL tree references. * that the AVL tree references.
*/ */
DIR* directory; /**< A directory entry usable to
* refer and scan the AVL tree directory.
*/
int dir_fd; /**< The file descriptor of the directory entry
* usable to refer and scan the AVL tree directory.
*/
int avl_fd; /**< The file descriptor of the file containing the AVL tree. int avl_fd; /**< The file descriptor of the file containing the AVL tree.
*/ */
} OBIDMS_avl_t, *OBIDMS_avl_p; } OBIDMS_avl_t, *OBIDMS_avl_p;
@ -168,6 +162,8 @@ typedef struct OBIDMS_avl_group {
*/ */
bool writable; /**< Indicates whether the AVL group is read-only or not. bool writable; /**< Indicates whether the AVL group is read-only or not.
*/ */
DIR* directory; /**< A directory entry usable to refer and scan the AVL group directory.
*/
size_t counter; /**< Indicates by how many threads/programs (TODO) the AVL group is used. size_t counter; /**< Indicates by how many threads/programs (TODO) the AVL group is used.
*/ */
} OBIDMS_avl_group_t, *OBIDMS_avl_group_p; } OBIDMS_avl_group_t, *OBIDMS_avl_group_p;