Commit 6a8df069 authored by Celine Mercier's avatar Celine Mercier

Indexers are now cloned if needed to modify them after they've been

closed. Obligatory indexers' names now follow the same pattern as other
indexers (columnname_version). Closes #46 and #49.
parent 8ae76449
......@@ -923,7 +923,7 @@ int remap_an_avl(OBIDMS_avl_p avl)
int add_new_avl_in_group(OBIDMS_avl_group_p avl_group)
{
// Check that maximum number of AVLs in a group was not reached
if (avl_group->current_avl_idx == (MAX_NB_OF_AVLS_IN_GROUP-1))
if (avl_group->last_avl_idx == (MAX_NB_OF_AVLS_IN_GROUP - 1))
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nError: Trying to add new AVL in AVL group but maximum number of AVLs in a group reached");
......@@ -931,15 +931,15 @@ int add_new_avl_in_group(OBIDMS_avl_group_p avl_group)
}
// Unmap the previous AVL
if (unmap_an_avl((avl_group->sub_avls)[avl_group->current_avl_idx]) < 0)
if (unmap_an_avl((avl_group->sub_avls)[avl_group->last_avl_idx]) < 0)
return -1;
// Increment current AVL index
(avl_group->current_avl_idx)++;
(avl_group->last_avl_idx)++;
// Create the new AVL
(avl_group->sub_avls)[avl_group->current_avl_idx] = obi_create_avl(avl_group->dms, avl_group->name, avl_group->current_avl_idx);
if ((avl_group->sub_avls)[avl_group->current_avl_idx] == NULL)
(avl_group->sub_avls)[avl_group->last_avl_idx] = obi_create_avl(avl_group->dms, avl_group->name, avl_group->last_avl_idx);
if ((avl_group->sub_avls)[avl_group->last_avl_idx] == NULL)
{
obidebug(1, "\nError creating a new AVL tree in a group");
return -1;
......@@ -1823,7 +1823,7 @@ OBIDMS_avl_group_p obi_create_avl_group(OBIDMS_p dms, const char* avl_name)
return NULL;
}
avl_group->current_avl_idx = 0;
avl_group->last_avl_idx = 0;
strcpy(avl_group->name, avl_name);
avl_group->dms = dms;
......@@ -1845,7 +1845,7 @@ OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name)
{
OBIDMS_avl_group_p avl_group;
char* avl_dir_name;
int avl_count;
int last_avl_idx;
int i;
// Check if the group isn't already open
......@@ -1869,21 +1869,21 @@ OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name)
avl_dir_name = get_full_path_of_avl_dir(dms, avl_name);
if (avl_dir_name == NULL)
return NULL;
avl_count = count_dir(avl_dir_name) / 2;
if (avl_count < 0)
last_avl_idx = count_dir(avl_dir_name) / 2;
if (last_avl_idx < 0)
{
obidebug(1, "\nError counting the AVLs in an AVL directory: %s", avl_name);
return NULL;
}
// Open the AVLs
for (i=0; i<avl_count; i++)
for (i=0; i<last_avl_idx; i++)
{
(avl_group->sub_avls)[i] = obi_open_avl(dms, avl_name, i);
if ((avl_group->sub_avls)[i] == NULL)
return NULL;
}
avl_group->current_avl_idx = avl_count-1; // TODO latest. discuss
avl_group->last_avl_idx = last_avl_idx-1; // TODO latest. discuss
strcpy(avl_group->name, avl_name);
avl_group->dms = dms;
......@@ -1901,6 +1901,56 @@ 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)
{
// Clone AVL tree
memcpy(new_avl->tree, avl->tree, (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)->root_idx = (avl->header)->root_idx;
(new_avl->header)->bloom_filter = (avl->header)->bloom_filter;
// Clone AVL data
memcpy((new_avl->data)->data, (avl->data)->data, ((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)->nb_items = ((avl->data)->header)->nb_items;
}
OBIDMS_avl_group_p obi_clone_avl_group(OBIDMS_avl_group_p avl_group, const char* new_avl_name)
{
OBIDMS_avl_group_p new_avl_group;
int i;
// Create the new AVL group
new_avl_group = obi_create_avl_group(avl_group->dms, new_avl_name);
// Copy the data from each old AVL to the new ones
for (i=0; i<=(avl_group->last_avl_idx); i++)
{
if (i > 0) // Don't need to create the 1st AVL
{
if (add_new_avl_in_group(new_avl_group) < 0)
{
obi_close_avl_group(new_avl_group);
return NULL;
}
}
obi_clone_avl((avl_group->sub_avls)[i], (new_avl_group->sub_avls)[i]);
}
// Close old AVL group
if (obi_close_avl_group(avl_group) < 0)
{
obi_close_avl_group(new_avl_group);
return NULL;
}
return new_avl_group;
}
int obi_close_avl(OBIDMS_avl_p avl)
{
int ret_val = 0;
......@@ -1946,7 +1996,7 @@ int obi_close_avl_group(OBIDMS_avl_group_p avl_group)
ret_val = obi_dms_unlist_indexer(avl_group->dms, avl_group);
// Close each AVL of the group
for (i=0; i < (avl_group->current_avl_idx); i++)
for (i=0; i < (avl_group->last_avl_idx); i++)
if (obi_close_avl((avl_group->sub_avls)[i]) < 0)
ret_val = -1;
......@@ -2157,18 +2207,18 @@ index_t obi_avl_group_add(OBIDMS_avl_group_p avl_group, Obi_blob_p value)
index_t index_with_avl;
int i;
if (maybe_in_avl((avl_group->sub_avls)[avl_group->current_avl_idx], value))
if (maybe_in_avl((avl_group->sub_avls)[avl_group->last_avl_idx], value))
{
index_in_avl = (int32_t) obi_avl_find((avl_group->sub_avls)[avl_group->current_avl_idx], value);
index_in_avl = (int32_t) obi_avl_find((avl_group->sub_avls)[avl_group->last_avl_idx], value);
if (index_in_avl >= 0)
{
index_with_avl = avl_group->current_avl_idx;
index_with_avl = avl_group->last_avl_idx;
index_with_avl = index_with_avl << 32;
index_with_avl = index_with_avl + index_in_avl;
return index_with_avl;
}
}
for (i=0; i < (avl_group->current_avl_idx); i++)
for (i=0; i < (avl_group->last_avl_idx); i++)
{
if (maybe_in_avl((avl_group->sub_avls)[i], value))
{
......@@ -2192,24 +2242,23 @@ index_t obi_avl_group_add(OBIDMS_avl_group_p avl_group, Obi_blob_p value)
// Check if the AVL group is writable
if (!(avl_group->writable))
{
obi_set_errno(OBI_AVL_ERROR);
obidebug(1, "\nTrying to add a value in an AVL group that is read-only.");
obi_set_errno(OBI_READ_ONLY_INDEXER_ERROR);
return -1;
}
// Check if need to make new AVL
if (((((avl_group->sub_avls)[avl_group->current_avl_idx])->header)->nb_items == MAX_NODE_COUNT_PER_AVL) || (((((avl_group->sub_avls)[avl_group->current_avl_idx])->data)->header)->data_size_used >= MAX_DATA_SIZE_PER_AVL))
if (((((avl_group->sub_avls)[avl_group->last_avl_idx])->header)->nb_items == MAX_NODE_COUNT_PER_AVL) || (((((avl_group->sub_avls)[avl_group->last_avl_idx])->data)->header)->data_size_used >= MAX_DATA_SIZE_PER_AVL))
{
if (add_new_avl_in_group(avl_group) < 0)
return -1;
}
// Add in the current AVL
bloom_add(&((((avl_group->sub_avls)[avl_group->current_avl_idx])->header)->bloom_filter), value, obi_blob_sizeof(value));
index_in_avl = (int32_t) obi_avl_add((avl_group->sub_avls)[avl_group->current_avl_idx], value);
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);
// Build the index containing the AVL index
index_with_avl = avl_group->current_avl_idx;
index_with_avl = avl_group->last_avl_idx;
index_with_avl = index_with_avl << 32;
index_with_avl = index_with_avl + index_in_avl;
......
......@@ -160,7 +160,7 @@ typedef struct OBIDMS_avl {
typedef struct OBIDMS_avl_group {
OBIDMS_avl_p sub_avls[MAX_NB_OF_AVLS_IN_GROUP]; /**< Array containing the pointers to the AVL trees of the group.
*/
int current_avl_idx; /**< Index in the sub_avls array of the AVL tree currently being filled.
int last_avl_idx; /**< Index in the sub_avls array of the AVL tree currently being filled.
*/
char name[AVL_MAX_NAME+1]; /**< Base name of the AVL group. The AVL trees in it have names of the form basename_idx.
*/
......@@ -290,6 +290,37 @@ OBIDMS_avl_group_p obi_create_avl_group(OBIDMS_p dms, const char* avl_name);
OBIDMS_avl_group_p obi_open_avl_group(OBIDMS_p dms, const char* avl_name);
/**
* @brief Clones an AVL.
*
* The tree and the data are both cloned into the new AVL.
*
* @param avl A pointer on the AVL to clone.
* @param new_avl A pointer on the new AVL to fill.
*
* @since May 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
void obi_clone_avl(OBIDMS_avl_p avl, OBIDMS_avl_p new_avl);
/**
* @brief Clones an AVL group.
*
* @warning The AVL group that has be cloned is closed by the function.
*
* @param avl_group A pointer on the AVL group to clone.
* @param new_avl_name The name of the new AVL group.
*
* @returns A pointer on the new AVL group structure.
* @retval NULL if an error occurred.
*
* @since May 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
OBIDMS_avl_group_p obi_clone_avl_group(OBIDMS_avl_group_p avl_group, const char* new_avl_name);
/**
* @brief Closes an AVL tree.
*
......
......@@ -30,6 +30,8 @@ inline Obi_indexer_p obi_create_indexer(OBIDMS_p dms, const char* name);
inline Obi_indexer_p obi_open_indexer(OBIDMS_p dms, const char* name);
inline Obi_indexer_p obi_clone_indexer(Obi_indexer_p indexer, const char* name);
inline int obi_close_indexer(Obi_indexer_p indexer);
inline index_t obi_indexer_add(Obi_indexer_p indexer, Obi_blob_p value);
......
......@@ -107,6 +107,24 @@ inline Obi_indexer_p obi_open_indexer(OBIDMS_p dms, const char* name)
}
/**
* @brief Clones an indexer.
*
* @param indexer The indexer to clone.
* @param name The name of the new indexer.
*
* @returns A pointer on the new indexer structure.
* @retval NULL if an error occurred.
*
* @since May 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
inline Obi_indexer_p obi_clone_indexer(Obi_indexer_p indexer, const char* name)
{
return obi_clone_avl_group(indexer, name);
}
/**
* @brief Closes an indexer.
*
......
......@@ -27,15 +27,30 @@
int obi_column_set_obiseq_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, const char* value)
{
index_t idx;
char* new_indexer_name;
if (obi_column_prepare_to_set_value(column, line_nb) < 0)
return -1;
// Add the value in the indexer
idx = obi_index_dna_seq(column->indexer, value);
if (idx == -1)
return -1;
if (idx == -1) // An error occurred
{
if (obi_errno == OBI_READ_ONLY_INDEXER_ERROR)
{
// If the error is that the indexer is read-only, clone it
new_indexer_name = obi_build_indexer_name((column->header)->name, (column->header)->version);
if (new_indexer_name == NULL)
return -1;
column->indexer = obi_clone_indexer(column->indexer, new_indexer_name); // TODO Need to lock this somehow?
// Add the value in the new indexer
idx = obi_index_dna_seq(column->indexer, value);
if (idx == -1)
return -1;
}
else
return -1;
}
// Add the value's index in the column
*(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = idx;
......
......@@ -27,6 +27,7 @@
int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb, index_t element_idx, const char* value)
{
index_t idx;
char* new_indexer_name;
// TODO
// size_t i;
......@@ -44,8 +45,23 @@ int obi_column_set_obistr_with_elt_idx(OBIDMS_column_p column, index_t line_nb,
// Add the value in the indexer
idx = obi_index_char_str(column->indexer, value);
if (idx == -1)
return -1;
if (idx == -1) // An error occurred
{
if (obi_errno == OBI_READ_ONLY_INDEXER_ERROR)
{
// If the error is that the indexer is read-only, clone it
new_indexer_name = obi_build_indexer_name((column->header)->name, (column->header)->version);
if (new_indexer_name == NULL)
return -1;
column->indexer = obi_clone_indexer(column->indexer, new_indexer_name); // TODO Need to lock this somehow?
// Add the value in the new indexer
idx = obi_index_char_str(column->indexer, value);
if (idx == -1)
return -1;
}
else
return -1;
}
// Add the value's index in the column
*(((index_t*) (column->data)) + (line_nb * ((column->header)->nb_elements_per_line)) + element_idx) = idx;
......
......@@ -114,7 +114,9 @@ extern int obi_errno;
*/
#define OBI_INDEXER_ERROR (27) /** Error handling a blob indexer
*/
#define OBI_ALIGN_ERROR (28) /** Error while aligning sequences
#define OBI_READ_ONLY_INDEXER_ERROR (28) /** Error trying to modify a read-only a blob indexer
*/
#define OBI_ALIGN_ERROR (29) /** Error while aligning sequences
*/
/**@}*/
......
......@@ -603,19 +603,19 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v
// TODO Add quality column?
// Adding sequence column
if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, OBI_SEQ, 0, 1, NUC_SEQUENCE_COLUMN, NUC_SEQUENCE_INDEXER, "Nucleotide sequences", true) < 0)
if (obi_view_add_column(view, NUC_SEQUENCE_COLUMN, -1, OBI_SEQ, 0, 1, NUC_SEQUENCE_COLUMN, "", "Nucleotide sequences", true) < 0)
{
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL;
}
// Adding id column
if (obi_view_add_column(view, ID_COLUMN, -1, OBI_STR, 0, 1, ID_COLUMN, ID_INDEXER, "Ids", true) < 0)
if (obi_view_add_column(view, ID_COLUMN, -1, OBI_STR, 0, 1, ID_COLUMN, "", "Ids", true) < 0)
{
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL;
}
// Adding definition column
if (obi_view_add_column(view, DEFINITION_COLUMN, -1, OBI_STR, 0, 1, DEFINITION_COLUMN, DEFINITION_INDEXER, "Definitions", true) < 0)
if (obi_view_add_column(view, DEFINITION_COLUMN, -1, OBI_STR, 0, 1, DEFINITION_COLUMN, "", "Definitions", true) < 0)
{
obidebug(1, "Error adding an obligatory column in a nucleotide sequences view");
return NULL;
......
......@@ -44,21 +44,12 @@
#define NUC_SEQUENCE_COLUMN "NUC_SEQ" /**< The name of the column containing the nucleotide sequences
* in NUC_SEQS_VIEW views.
*/
#define NUC_SEQUENCE_INDEXER "NUC_SEQ_INDEXER" /**< The name of the indexer containing the nucleotide sequences
* in NUC_SEQS_VIEW views.
*/
#define ID_COLUMN "ID" /**< The name of the column containing the sequence identifiers
* in NUC_SEQS_VIEW views.
*/
#define ID_INDEXER "ID_INDEXER" /**< The name of the indexer containing the sequence identifiers
* in NUC_SEQS_VIEW views.
*/
#define DEFINITION_COLUMN "DEFINITION" /**< The name of the column containing the sequence definitions
* in NUC_SEQS_VIEW views.
*/
#define DEFINITION_INDEXER "DEFINITION_INDEXER" /**< The name of the indexer containing the sequence definitions
* in NUC_SEQS_VIEW views.
*/
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment