Added linked lists to handle lists of column pointers in views (not

tested)
This commit is contained in:
Celine Mercier
2017-03-06 16:06:17 +01:00
parent 3319ede837
commit 778acc48cd
5 changed files with 473 additions and 53 deletions

View File

@ -32,6 +32,7 @@
#include "obidebug.h"
#include "obilittlebigman.h"
#include "hashtable.h"
#include "linked_list.h"
#include "utils.h"
#include "obiblob.h"
@ -169,10 +170,13 @@ static int create_obiview_file(OBIDMS_p dms, const char* view_name);
*
* @param view A pointer on the view.
*
* @retval 0 if the operation was successfully completed.
* @retval -1 if an error occurred.
*
* @since June 2016
* @author Celine Mercier (celine.mercier@metabarcoding.org)
*/
static void update_column_refs(Obiview_p view);
static int update_column_refs(Obiview_p view);
/**
@ -763,21 +767,32 @@ static int create_obiview_file(OBIDMS_p dms, const char* view_name)
}
static void update_column_refs(Obiview_p view)
static int update_column_refs(Obiview_p view)
{
int i;
OBIDMS_column_p column;
for (i=0; i < (view->infos)->column_count; i++)
{
strcpy(((((view->infos)->column_references)[i]).column_refs).column_name, (((view->columns)[i])->header)->name);
((((view->infos)->column_references)[i]).column_refs).version = (((view->columns)[i])->header)->version;
column = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column from the linked list of column pointers of a view");
return -1;
}
strcpy(((((view->infos)->column_references)[i]).column_refs).column_name, (column->header)->name);
((((view->infos)->column_references)[i]).column_refs).version = (column->header)->version;
}
return 0;
}
static int create_column_dict(Obiview_p view)
{
int i;
OBIDMS_column_p* column_pp;
view->column_dict = ht_create(MAX_NB_OPENED_COLUMNS);
if (view->column_dict == NULL)
@ -798,7 +813,15 @@ static int create_column_dict(Obiview_p view)
return -1;
}
if (ht_set(view->column_dict, (((view->infos)->column_references)[i]).alias, (view->columns)+i) < 0)
column_pp = (OBIDMS_column_p*) ll_get(view->columns, i);
if (column_pp == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column from the linked list of column pointers of a view when creating a column dictionary");
return -1;
}
if (ht_set(view->column_dict, (((view->infos)->column_references)[i]).alias, column_pp) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError adding a column in a column dictionary");
@ -824,14 +847,16 @@ static int update_column_dict(Obiview_p view)
static int update_column_refs_and_dict(Obiview_p view)
{
update_column_refs(view);
if (update_column_refs(view) < 0)
return -1;
return update_column_dict(view);
}
static int update_lines(Obiview_p view, index_t line_count)
{
int i;
int i;
OBIDMS_column_p column;
// Check that the view is not read-only
if (view->read_only)
@ -843,8 +868,16 @@ static int update_lines(Obiview_p view, index_t line_count)
for (i=0; i<((view->infos)->column_count); i++)
{
column = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column from the linked list of column pointers of a view when updating view lines");
return -1;
}
// Clone the column first if needed
if (!(((view->columns)[i])->writable))
if (!(column->writable))
{
if (clone_column_in_view(view, (((view->infos)->column_references)[i]).alias) < 0)
{
@ -853,13 +886,13 @@ static int update_lines(Obiview_p view, index_t line_count)
}
}
// Enlarge the column if needed
while (line_count > (((view->columns)[i])->header)->line_count)
while (line_count > (column->header)->line_count)
{
if (obi_enlarge_column(((view->columns)[i])) < 0)
if (obi_enlarge_column(column) < 0)
return -1;
}
// Set the number of lines used to the new view line count
(((view->columns)[i])->header)->lines_used = line_count;
(column->header)->lines_used = line_count;
}
(view->infos)->line_count = line_count;
@ -872,6 +905,7 @@ static OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_n
{
int i;
OBIDMS_column_p column = NULL;
OBIDMS_column_p new_column = NULL;
OBIDMS_column_p column_buffer;
bool found;
@ -890,24 +924,37 @@ static OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_n
{ // Clone with the right line selection and replace (for all columns if there is a line selection)
// Save pointer to close column after cloning
column_buffer = (view->columns)[i];
column_buffer = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column_buffer == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column to clone from the linked list of column pointers of a view");
return NULL;
}
// Clone and replace the column in the view
(view->columns)[i] = obi_clone_column(view->dms, view->line_selection, (((view->columns)[i])->header)->name, (((view->columns)[i])->header)->version, 1);
if ((view->columns)[i] == NULL)
column = obi_clone_column(view->dms, view->line_selection, (column_buffer->header)->name, (column_buffer->header)->version, true);
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError cloning a column to replace in a view");
return NULL;
}
// Change the pointer in the linked list of column pointers
if (ll_set(view->columns, i, column) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError changing the column pointer of a cloned column in the linked list of column pointers of a view");
return NULL;
}
// Close old cloned column
obi_close_column(column_buffer);
if (!strcmp((((view->infos)->column_references)[i]).alias, column_name))
{ // Found the column to return
column = (view->columns)[i];
}
// Found the column to return
new_column = column;
}
}
@ -922,9 +969,13 @@ static OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_n
}
// Update column refs and dict
update_column_refs_and_dict(view);
if (update_column_refs_and_dict(view) < 0)
{
obidebug(1, "\nError updating columns references and dictionary after cloning a column in a view");
return NULL;
}
return column;
return new_column;
}
@ -952,7 +1003,11 @@ static int save_view(Obiview_p view)
(view->infos)->all_lines = true;
}
update_column_refs(view);
if (update_column_refs(view) < 0)
{
obidebug(1, "\nError updating column references when saving a view");
return -1;
}
return 0;
}
@ -1044,12 +1099,20 @@ static int close_view(Obiview_p view)
{
int i;
int ret_value;
OBIDMS_column_p column;
ret_value = 0;
for (i=0; i < ((view->infos)->column_count); i++)
{
if (obi_close_column((view->columns)[i]) < 0)
column = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column to close from the linked list of column pointers of a view");
return -1;
}
if (obi_close_column(column) < 0)
{
obidebug(1, "\nError closing a column while closing a view");
ret_value = -1;
@ -1066,6 +1129,9 @@ static int close_view(Obiview_p view)
}
}
// Free the linked list of column pointers
ll_free(view->columns);
// Free the column dictionary
ht_free(view->column_dict);
@ -1251,6 +1317,7 @@ static char* view_check_qual_match_seqs(Obiview_p view)
int qual_len;
const uint8_t* qual;
char* seq;
OBIDMS_column_p column;
OBIDMS_column_p qual_column;
OBIDMS_column_p seq_column;
char* predicate;
@ -1260,12 +1327,20 @@ static char* view_check_qual_match_seqs(Obiview_p view)
at_least_one_qual_col = false;
for (i=0; i < ((view->infos)->column_count); i++)
{
column = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column to clone from the linked list of column pointers of a view");
return NULL;
}
// Check if it's a quality column
if ((((view->columns)[i])->header)->returned_data_type == OBI_QUAL)
if ((column->header)->returned_data_type == OBI_QUAL)
{
at_least_one_qual_col = true;
// Check that the quality arrays match the sequences of the associated column
qual_column = (view->columns)[i];
qual_column = column;
seq_column = obi_open_column(view->dms, ((qual_column->header)->associated_column).column_name, ((qual_column->header)->associated_column).version);
if (seq_column == NULL)
{
@ -1281,7 +1356,7 @@ static char* view_check_qual_match_seqs(Obiview_p view)
return NULL;
}
// Check each sequence and its sequence
// Check each sequence and its quality
for (j=0; j < (view->infos)->line_count; j++)
{
for (k=0; k < nb_elements_per_line; k++)
@ -1434,6 +1509,7 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
int i;
index_t line_nb;
char* clone_comment;
OBIDMS_column_p column;
// Check that the DMS is a valid pointer
if (dms == NULL)
@ -1600,10 +1676,10 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
(view->infos)->column_count = 0;
(view->infos)->line_count = 0;
(view->infos)->all_lines = true;
view->line_selection = NULL;
((view->infos)->created_from)[0] = '\0';
((view->infos)->view_type)[0] = '\0';
//view->columns = NULL; // TODO
view->line_selection = NULL;
view->columns = NULL;
}
// Fill last informations
@ -1641,6 +1717,9 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
((view->infos)->line_selection).version = ((view->line_selection)->header)->version;
}
// Initialize linked list of column pointers
view->columns = NULL;
// Create the column dictionary (hash table) associating column names (or aliases) to column pointers
if (create_column_dict(view) < 0)
{
@ -1654,9 +1733,16 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl
(view->infos)->column_count = 0;
for (i=0; i<((view_to_clone->infos)->column_count); i++)
{
column = *((OBIDMS_column_p*)ll_get(view_to_clone->columns, i));
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column from the linked list of column pointers of a view");
return NULL;
}
if (obi_view_add_column(view,
(((view_to_clone->columns)[i])->header)->name,
(((view_to_clone->columns)[i])->header)->version,
(column->header)->name,
(column->header)->version,
(((view_to_clone->infos)->column_references)[i]).alias,
0,
0,
@ -1964,6 +2050,13 @@ Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
return NULL;
}
// Initialize view informations
view->dms = dms;
view->read_only = true;
view->nb_predicates = 0;
view->predicate_functions = NULL;
view->columns = NULL;
// Map view file
view->infos = obi_view_map_file(dms, view_name, true);
if ((view->infos) == NULL)
@ -2000,15 +2093,15 @@ Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name)
close_view(view);
return NULL;
}
(view->columns)[i] = column_pointer;
view->columns = ll_add(view->columns, column_pointer);
if (view->columns == NULL)
{
obidebug(1, "\nError adding a column in the column linked list of a view: column %d: %s, version %d", i, column_name, column_version);
close_view(view);
return NULL;
}
}
view->dms = dms;
view->read_only = true;
view->nb_predicates = 0;
view->predicate_functions = NULL;
// Create the column dictionary associating each column alias with its pointer
if (create_column_dict(view) < 0)
{
@ -2054,16 +2147,31 @@ int obi_view_add_column(Obiview_p view,
{
{ // Clone with the right line selection and replace for all columns
// Save pointer to close column after cloning
column_buffer = (view->columns)[i];
column_buffer = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column_buffer == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column to clone from the linked list of column pointers of a view");
return -1;
}
// Clone and replace the column in the view
(view->columns)[i] = obi_clone_column(view->dms, view->line_selection, (((view->columns)[i])->header)->name, (((view->columns)[i])->header)->version, 1);
if ((view->columns)[i] == NULL)
column = obi_clone_column(view->dms, view->line_selection, (column_buffer->header)->name, (column_buffer->header)->version, 1);
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError cloning a column to replace in a view");
return -1;
}
// Change the pointer in the linked list of column pointers
if (ll_set(view->columns, i, column) < 0)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError changing the column pointer of a cloned column in the linked list of column pointers of a view");
return -1;
}
// Close old cloned column
obi_close_column(column_buffer);
}
@ -2120,7 +2228,14 @@ int obi_view_add_column(Obiview_p view,
}
// Store column pointer in the view structure
(view->columns)[(view->infos)->column_count] = column;
view->columns = ll_add(view->columns, column);
if (view->columns == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError adding a column in the linked list of column pointers of a view: column %s, version %d", column_name, version_number);
return -1;
}
// If an alias is not defined, it's the original name of the column. // TODO discuss
if (alias == NULL)
@ -2133,7 +2248,11 @@ int obi_view_add_column(Obiview_p view,
(view->infos)->column_count++;
// Update column references and dictionary
update_column_refs_and_dict(view);
if (update_column_refs_and_dict(view) < 0)
{
obidebug(1, "\nError updating column references and dictionary after adding a column to a view");
return -1;
}
// // Print dict
// for (i=0; i<((view->infos)->column_count); i++)
@ -2150,6 +2269,7 @@ int obi_view_delete_column(Obiview_p view, const char* column_name)
{
int i;
bool found;
OBIDMS_column_p column;
// Check that the view is not read-only
if (view->read_only)
@ -2162,22 +2282,40 @@ int obi_view_delete_column(Obiview_p view, const char* column_name)
found = false;
for (i=0; i<((view->infos)->column_count); i++)
{
column = *((OBIDMS_column_p*)ll_get(view->columns, i));
if (column == NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError getting a column from the linked list of column pointers of a view when deleting a column from a view");
return -1;
}
if ((!found) && (!strcmp((((view->infos)->column_references)[i]).alias, column_name)))
{
obi_close_column((view->columns)[i]);
obi_close_column(column);
view->columns = ll_delete(view->columns, i);
if (view->columns != NULL)
{
obi_set_errno(OBIVIEW_ERROR);
obidebug(1, "\nError trying to delete a column: column not found in linked list of column pointers");
return -1;
}
found = true;
}
if (found)
{
if (i != (((view->infos)->column_count) - 1)) // not the last one
{ // Shift the pointer and the references
(view->columns)[i] = (view->columns)[i+1];
{ // Shift the references
strcpy((((view->infos)->column_references)[i]).alias, (((view->infos)->column_references)[i+1]).alias);
strcpy(((((view->infos)->column_references)[i]).column_refs).column_name, ((((view->infos)->column_references)[i+1]).column_refs).column_name);
((((view->infos)->column_references)[i]).column_refs).version = ((((view->infos)->column_references)[i+1]).column_refs).version;
}
else // Last column
(view->columns)[i] = NULL;
{
strcpy((((view->infos)->column_references)[i]).alias, "");
strcpy(((((view->infos)->column_references)[i]).column_refs).column_name, "");
((((view->infos)->column_references)[i]).column_refs).version = -1;
}
}
}