diff --git a/src/obiavl.c b/src/obiavl.c index e331a33..dc1b58d 100644 --- a/src/obiavl.c +++ b/src/obiavl.c @@ -41,23 +41,6 @@ **************************************************************************/ -/** - * @brief Internal function building the complete AVL name for an AVL with an associated index (for AVL groups). - * - * @warning The returned pointer has to be freed by the caller. - * - * @param avl_name The base name of the AVL tree. - * @param avl_idx The index associated with that AVL. - * - * @returns A pointer to the complete name of the AVL. - * @retval NULL if an error occurred. - * - * @since April 2016 - * @author Celine Mercier (celine.mercier@metabarcoding.org) - */ -static char* build_avl_name_with_idx(const char* avl_name, int avl_idx); - - /** * @brief Internal function building the full path of an AVL directory containing an AVL or an AVL group. * @@ -107,42 +90,6 @@ static char* build_avl_file_name(const char* avl_name); static char* build_avl_data_file_name(const char* avl_name); -/** - * @brief Internal function building the full path of an AVL tree file. - * - * @warning The returned pointer has to be freed by the caller. - * - * @param dms A pointer to the OBIDMS to which the AVL tree belongs. - * @param avl_name The name of the AVL tree. - * @param avl_idx The index of the AVL if it's part of an AVL group, or -1 if not. - * - * @returns A pointer to the full path of the file where the AVL tree is stored. - * @retval NULL if an error occurred. - * - * @since May 2016 - * @author Celine Mercier (celine.mercier@metabarcoding.org) - */ -static char* get_full_path_of_avl_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx); - - -/** - * @brief Internal function building the file name for an AVL data file. - * - * @warning The returned pointer has to be freed by the caller. - * - * @param dms A pointer to the OBIDMS to which the AVL tree belongs. - * @param avl_name The name of the AVL tree. - * @param avl_idx The index of the AVL if it's part of an AVL group, or -1 if not. - * - * @returns A pointer to the full path of the file where the data referred to by the AVL tree is stored. - * @retval NULL if an error occurred. - * - * @since May 2016 - * @author Celine Mercier (celine.mercier@metabarcoding.org) - */ -static char* get_full_path_of_avl_data_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx); - - /** * @brief Internal function returning the size of an AVL tree header on this platform, * including the size of the bloom filter associated with the AVL tree. @@ -501,36 +448,6 @@ void avl_print(OBIDMS_avl_p avl); * ************************************************************************/ -static char* build_avl_name_with_idx(const char* avl_name, int avl_idx) -{ - char* avl_name_with_idx; - int avl_idx_length; - - if (avl_idx < 0) - { - obi_set_errno(OBI_AVL_ERROR); - obidebug(1, "\nError building an AVL tree name with index: index < 0"); - return NULL; - } - - avl_idx_length = avl_idx == 0 ? 1 : (int)(log10(avl_idx)+1); - avl_name_with_idx = malloc((strlen(avl_name) + avl_idx_length + 2)*sizeof(char)); - if (avl_name_with_idx == NULL) - { - obi_set_errno(OBI_MALLOC_ERROR); - obidebug(1, "\nError allocating memory for an AVL name"); - return NULL; - } - if (sprintf(avl_name_with_idx, "%s_%u", avl_name, avl_idx) < 0) - { - obi_set_errno(OBI_AVL_ERROR); - obidebug(1, "\nError building an AVL tree name with index"); - return NULL; - } - - return avl_name_with_idx; -} - char* get_full_path_of_avl_dir(OBIDMS_p dms, const char* avl_name) { @@ -604,102 +521,6 @@ static char* build_avl_data_file_name(const char* avl_name) } -static char* get_full_path_of_avl_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx) -{ - char* complete_avl_name; - char* full_path; - char* avl_file_name; - - if (avl_idx >= 0) - { - complete_avl_name = build_avl_name_with_idx(avl_name, avl_idx); - if (complete_avl_name == NULL) - return NULL; - } - else - { - complete_avl_name = (char*) malloc((strlen(avl_name)+1)*sizeof(char)); - if (complete_avl_name == NULL) - { - obi_set_errno(OBI_MALLOC_ERROR); - obidebug(1, "\nError allocating memory for an AVL name"); - return NULL; - } - strcpy(complete_avl_name, avl_name); - } - - avl_file_name = build_avl_file_name(complete_avl_name); - if (avl_file_name == NULL) - { - free(complete_avl_name); - return NULL; - } - - full_path = get_full_path_of_avl_dir(dms, avl_name); - if (full_path == NULL) - { - free(complete_avl_name); - free(avl_file_name); - return NULL; - } - - strcat(full_path, "/"); - strcat(full_path, avl_file_name); - - free(complete_avl_name); - - return full_path; -} - - -static char* get_full_path_of_avl_data_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx) -{ - char* complete_avl_name; - char* full_path; - char* avl_data_file_name; - - if (avl_idx >= 0) - { - complete_avl_name = build_avl_name_with_idx(avl_name, avl_idx); - if (complete_avl_name == NULL) - return NULL; - } - else - { - complete_avl_name = (char*) malloc((strlen(avl_name)+1)*sizeof(char)); - if (complete_avl_name == NULL) - { - obi_set_errno(OBI_MALLOC_ERROR); - obidebug(1, "\nError allocating memory for an AVL name"); - return NULL; - } - strcpy(complete_avl_name, avl_name); - } - - avl_data_file_name = build_avl_data_file_name(complete_avl_name); - if (avl_data_file_name == NULL) - { - free(complete_avl_name); - return NULL; - } - - full_path = get_full_path_of_avl_dir(dms, avl_name); - if (full_path == NULL) - { - free(complete_avl_name); - free(avl_data_file_name); - return NULL; - } - - strcat(full_path, "/"); - strcat(full_path, avl_data_file_name); - - free(complete_avl_name); - - return full_path; -} - - size_t get_avl_header_size() { size_t header_size; @@ -1103,13 +924,13 @@ int add_new_avl_in_group(OBIDMS_avl_group_p avl_group) 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(obi_get_full_path_of_avl_file_name(avl_group_source->dms, avl_group_source->name, avl_idx), obi_get_full_path_of_avl_file_name(avl_group_dest->dms, avl_group_dest->name, avl_idx)) < 0) { obi_set_errno(OBI_AVL_ERROR); obidebug(1, "\nError creating a hard link to an existing AVL tree file"); return -1; } - if (link(get_full_path_of_avl_data_file_name(avl_group_source->dms, avl_group_source->name, avl_idx), get_full_path_of_avl_data_file_name(avl_group_dest->dms, avl_group_dest->name, avl_idx)) < 0) + if (link(obi_get_full_path_of_avl_data_file_name(avl_group_source->dms, avl_group_source->name, avl_idx), obi_get_full_path_of_avl_data_file_name(avl_group_dest->dms, avl_group_dest->name, avl_idx)) < 0) { obi_set_errno(OBI_AVL_ERROR); obidebug(1, "\nError creating a hard link to an existing AVL data file"); @@ -1400,6 +1221,134 @@ void avl_print(OBIDMS_avl_p avl) * **********************************************************************/ + +char* obi_build_avl_name_with_idx(const char* avl_name, int avl_idx) +{ + char* avl_name_with_idx; + int avl_idx_length; + + if (avl_idx < 0) + { + obi_set_errno(OBI_AVL_ERROR); + obidebug(1, "\nError building an AVL tree name with index: index < 0"); + return NULL; + } + + avl_idx_length = avl_idx == 0 ? 1 : (int)(log10(avl_idx)+1); + avl_name_with_idx = malloc((strlen(avl_name) + avl_idx_length + 2)*sizeof(char)); + if (avl_name_with_idx == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for an AVL name"); + return NULL; + } + if (sprintf(avl_name_with_idx, "%s_%u", avl_name, avl_idx) < 0) + { + obi_set_errno(OBI_AVL_ERROR); + obidebug(1, "\nError building an AVL tree name with index"); + return NULL; + } + + return avl_name_with_idx; +} + + +char* obi_get_full_path_of_avl_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx) +{ + char* complete_avl_name; + char* full_path; + char* avl_file_name; + + if (avl_idx >= 0) + { + complete_avl_name = obi_build_avl_name_with_idx(avl_name, avl_idx); + if (complete_avl_name == NULL) + return NULL; + } + else + { + complete_avl_name = (char*) malloc((strlen(avl_name)+1)*sizeof(char)); + if (complete_avl_name == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for an AVL name"); + return NULL; + } + strcpy(complete_avl_name, avl_name); + } + + avl_file_name = build_avl_file_name(complete_avl_name); + if (avl_file_name == NULL) + { + free(complete_avl_name); + return NULL; + } + + full_path = get_full_path_of_avl_dir(dms, avl_name); + if (full_path == NULL) + { + free(complete_avl_name); + free(avl_file_name); + return NULL; + } + + strcat(full_path, "/"); + strcat(full_path, avl_file_name); + + free(complete_avl_name); + + return full_path; +} + + +char* obi_get_full_path_of_avl_data_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx) +{ + char* complete_avl_name; + char* full_path; + char* avl_data_file_name; + + if (avl_idx >= 0) + { + complete_avl_name = obi_build_avl_name_with_idx(avl_name, avl_idx); + if (complete_avl_name == NULL) + return NULL; + } + else + { + complete_avl_name = (char*) malloc((strlen(avl_name)+1)*sizeof(char)); + if (complete_avl_name == NULL) + { + obi_set_errno(OBI_MALLOC_ERROR); + obidebug(1, "\nError allocating memory for an AVL name"); + return NULL; + } + strcpy(complete_avl_name, avl_name); + } + + avl_data_file_name = build_avl_data_file_name(complete_avl_name); + if (avl_data_file_name == NULL) + { + free(complete_avl_name); + return NULL; + } + + full_path = get_full_path_of_avl_dir(dms, avl_name); + if (full_path == NULL) + { + free(complete_avl_name); + free(avl_data_file_name); + return NULL; + } + + strcat(full_path, "/"); + strcat(full_path, avl_data_file_name); + + free(complete_avl_name); + + return full_path; +} + + int obi_avl_exists(OBIDMS_p dms, const char* avl_name) { struct stat buffer; @@ -1443,7 +1392,7 @@ OBIDMS_avl_p obi_create_avl(OBIDMS_p dms, const char* avl_name, int avl_idx) // Get complete name of AVL if index if (avl_idx >= 0) { - complete_avl_name = build_avl_name_with_idx(avl_name, avl_idx); + complete_avl_name = obi_build_avl_name_with_idx(avl_name, avl_idx); if (complete_avl_name == NULL) return NULL; } @@ -1740,7 +1689,7 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx) // Get complete name of AVL if index if (avl_idx >= 0) { - complete_avl_name = build_avl_name_with_idx(avl_name, avl_idx); + complete_avl_name = obi_build_avl_name_with_idx(avl_name, avl_idx); if (complete_avl_name == NULL) return NULL; } @@ -1794,7 +1743,7 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx) return NULL; // Open file - avl_data_file_descriptor = openat(avl_dir_file_descriptor, avl_data_file_name, O_RDONLY, 0777); + avl_data_file_descriptor = openat(avl_dir_file_descriptor, avl_data_file_name, O_RDWR, 0777); if (avl_data_file_descriptor < 0) { obi_set_errno(OBI_AVL_ERROR); @@ -1832,7 +1781,7 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx) // Fill the avl data structure avl_data->header = mmap(NULL, header_size, - PROT_READ, + PROT_READ | PROT_WRITE, MAP_SHARED, avl_data_file_descriptor, 0 @@ -1881,7 +1830,7 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx) } // Open file - avl_file_descriptor = openat(avl_dir_file_descriptor, avl_file_name, O_RDONLY, 0777); + avl_file_descriptor = openat(avl_dir_file_descriptor, avl_file_name, O_RDWR, 0777); if (avl_file_descriptor < 0) { obi_set_errno(OBI_AVL_ERROR); @@ -1921,7 +1870,7 @@ OBIDMS_avl_p obi_open_avl(OBIDMS_p dms, const char* avl_name, int avl_idx) // Fill the avl structure avl->header = mmap(NULL, header_size, - PROT_READ, + PROT_READ | PROT_WRITE, MAP_SHARED, avl_file_descriptor, 0 diff --git a/src/obiavl.h b/src/obiavl.h index d64e314..93fed50 100644 --- a/src/obiavl.h +++ b/src/obiavl.h @@ -169,11 +169,65 @@ typedef struct OBIDMS_avl_group { } OBIDMS_avl_group_t, *OBIDMS_avl_group_p; + +/** + * @brief Function building the complete AVL name for an AVL with an associated index (for AVL groups). + * + * @warning The returned pointer has to be freed by the caller. + * + * @param avl_name The base name of the AVL tree. + * @param avl_idx The index associated with that AVL. + * + * @returns A pointer to the complete name of the AVL. + * @retval NULL if an error occurred. + * + * @since April 2016 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +char* obi_build_avl_name_with_idx(const char* avl_name, int avl_idx); + + +/** + * @brief Function building the full path of an AVL tree file. + * + * @warning The returned pointer has to be freed by the caller. + * + * @param dms A pointer to the OBIDMS to which the AVL tree belongs. + * @param avl_name The name of the AVL tree. + * @param avl_idx The index of the AVL if it's part of an AVL group, or -1 if not. + * + * @returns A pointer to the full path of the file where the AVL tree is stored. + * @retval NULL if an error occurred. + * + * @since May 2016 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +char* obi_get_full_path_of_avl_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx); + + +/** + * @brief Function building the file name for an AVL data file. + * + * @warning The returned pointer has to be freed by the caller. + * + * @param dms A pointer to the OBIDMS to which the AVL tree belongs. + * @param avl_name The name of the AVL tree. + * @param avl_idx The index of the AVL if it's part of an AVL group, or -1 if not. + * + * @returns A pointer to the full path of the file where the data referred to by the AVL tree is stored. + * @retval NULL if an error occurred. + * + * @since May 2016 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +char* obi_get_full_path_of_avl_data_file_name(OBIDMS_p dms, const char* avl_name, int avl_idx); + + /** * @brief Checks if an AVL tree or AVL tree group already exists or not. * * @param dms The OBIDMS to which the AVL tree or AVL tree group belongs. - * @param avl_name The name of the AVL treeor the base name of the AVL tree group. + * @param avl_name The name of the AVL tree or the base name of the AVL tree group. * * @returns A value indicating whether the AVL tree or AVL tree group exists or not. * @retval 1 if the AVL tree or AVL tree group exists.