diff --git a/src/obidmscolumn.c b/src/obidmscolumn.c index bdfc4fb..dfedaaf 100644 --- a/src/obidmscolumn.c +++ b/src/obidmscolumn.c @@ -23,6 +23,7 @@ #include #include "obidmscolumn.h" +#include "obidmscolumn_idx.h" #include "obidmscolumndir.h" #include "obidms.h" #include "obitypes.h" @@ -826,8 +827,8 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, } -OBIDMS_column_p obi_open_column(OBIDMS_p dms, - const char* column_name, +OBIDMS_column_p obi_open_column(OBIDMS_p dms, + const char* column_name, obiversion_t version_number) { OBIDMS_column_p column; @@ -863,6 +864,12 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms, if (column != NULL) { (column->counter)++; + if (obi_close_column_directory(column_directory) < 0) + { + obi_set_errno(OBICOL_UNKNOWN_ERROR); + obidebug(1, "\nError closing a column directory"); + return NULL; + } return column; } @@ -985,7 +992,7 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms, { OBIDMS_column_p column_to_clone; OBIDMS_column_p new_column; - index_t nb_lines; + index_t nb_lines = 0; index_t nb_elements_per_line; OBIType_t data_type; size_t line_size; @@ -1003,10 +1010,10 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms, nb_elements_per_line = (column_to_clone->header)->nb_elements_per_line; - if (clone_data) + if (clone_data && (line_selection == NULL)) nb_lines = (column_to_clone->header)->line_count; - else - nb_lines = get_line_count_per_page(data_type, nb_elements_per_line); // minimum line count corresponding to one memory page + else if (clone_data && (line_selection != NULL)) + nb_lines = (line_selection->header)->line_count; new_column = obi_create_column(dms, column_name, @@ -1035,15 +1042,26 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms, if (clone_data && (line_selection == NULL)) { + if ((new_column->header)->data_size != (column_to_clone->header)->data_size) + { + obi_set_errno(OBICOL_UNKNOWN_ERROR); + obidebug(1, "\nError cloning a column: the sizes of the data source and destination are not equal: source %zu bytes, destination %zu bytes.", + (column_to_clone->header)->data_size, (new_column->header)->data_size); + return NULL; + } + // Copy all the data to the new column memcpy(new_column->data, column_to_clone->data, (column_to_clone->header)->data_size); (new_column->header)->lines_used = (column_to_clone->header)->lines_used; } else if (clone_data && (line_selection != NULL)) { line_size = obi_sizeof((new_column->header)->stored_data_type) * (new_column->header)->nb_elements_per_line; - for (i=0; i<((line_selection->header)->lines_used); i++) + // Copy each line at the right index to the new column + for (i=0; idata)) + i); + // Get the index in the line selection column + index = obi_column_get_index(line_selection, i); + // Copy the line at the index in the column to clone to the new column memcpy((new_column->data)+(i*line_size), (column_to_clone->data)+(index*line_size), line_size); } (new_column->header)->lines_used = (line_selection->header)->lines_used; @@ -1121,16 +1139,22 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap multiple = ceil((double) (ONE_IF_ZERO((column->header)->lines_used) * (column->header)->nb_elements_per_line * obi_sizeof((column->header)->stored_data_type)) / (double) getpagesize()); new_line_count = floor((((int) multiple) * getpagesize()) / ((column->header)->nb_elements_per_line * obi_sizeof((column->header)->stored_data_type))); - // Check that it is actually greater than the current number of lines allocated in the file, otherwise no need to truncate - if ((column->header)->line_count == new_line_count) + data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line); + + // Check that it is actually greater than the current data size, otherwise no need to truncate + if ((column->header)->data_size == data_size) return 0; + else if ((column->header)->data_size < data_size) + { + obi_set_errno(OBICOL_UNKNOWN_ERROR); + obidebug(1, "\nError truncating a column: The current data size seems smaller than needed."); + return -1; + } // Get the column file name column_file_name = build_column_file_name((column->header)->name, (column->header)->version); if (column_file_name == NULL) - { return -1; - } // Open the column file column_file_descriptor = openat((column->column_directory)->dir_fd, column_file_name, O_RDWR); @@ -1154,7 +1178,6 @@ int obi_truncate_column(OBIDMS_column_p column) // TODO is it necessary to unmap } // Truncate the column file - data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line); file_size = (column->header)->header_size + data_size; if (ftruncate(column_file_descriptor, file_size) < 0) { @@ -1246,7 +1269,7 @@ int obi_enlarge_column(OBIDMS_column_p column) return -1; } old_data_size = (column->header)->data_size; - new_data_size = old_data_size * COLUMN_GROWTH_FACTOR; + new_data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line); header_size = (column->header)->header_size; file_size = header_size + new_data_size;