Fixed bug where columns would not get truncated to the right size, and

fixed bug where column directories would be open and not closed in some
instances
This commit is contained in:
Celine Mercier
2016-09-21 17:28:52 +02:00
parent 802bae110b
commit a0da984003

View File

@ -23,6 +23,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "obidmscolumn.h" #include "obidmscolumn.h"
#include "obidmscolumn_idx.h"
#include "obidmscolumndir.h" #include "obidmscolumndir.h"
#include "obidms.h" #include "obidms.h"
#include "obitypes.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, OBIDMS_column_p obi_open_column(OBIDMS_p dms,
const char* column_name, const char* column_name,
obiversion_t version_number) obiversion_t version_number)
{ {
OBIDMS_column_p column; OBIDMS_column_p column;
@ -863,6 +864,12 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms,
if (column != NULL) if (column != NULL)
{ {
(column->counter)++; (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; return column;
} }
@ -985,7 +992,7 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
{ {
OBIDMS_column_p column_to_clone; OBIDMS_column_p column_to_clone;
OBIDMS_column_p new_column; OBIDMS_column_p new_column;
index_t nb_lines; index_t nb_lines = 0;
index_t nb_elements_per_line; index_t nb_elements_per_line;
OBIType_t data_type; OBIType_t data_type;
size_t line_size; 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; 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; nb_lines = (column_to_clone->header)->line_count;
else else if (clone_data && (line_selection != NULL))
nb_lines = get_line_count_per_page(data_type, nb_elements_per_line); // minimum line count corresponding to one memory page nb_lines = (line_selection->header)->line_count;
new_column = obi_create_column(dms, new_column = obi_create_column(dms,
column_name, column_name,
@ -1035,15 +1042,26 @@ OBIDMS_column_p obi_clone_column(OBIDMS_p dms,
if (clone_data && (line_selection == NULL)) 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); 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; (new_column->header)->lines_used = (column_to_clone->header)->lines_used;
} }
else if (clone_data && (line_selection != NULL)) else if (clone_data && (line_selection != NULL))
{ {
line_size = obi_sizeof((new_column->header)->stored_data_type) * (new_column->header)->nb_elements_per_line; 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; i<nb_lines; i++)
{ {
index = *(((index_t*) (line_selection->data)) + 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); 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; (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()); 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))); 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 data_size = obi_array_sizeof((column->header)->stored_data_type, new_line_count, (column->header)->nb_elements_per_line);
if ((column->header)->line_count == new_line_count)
// 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; 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 // Get the column file name
column_file_name = build_column_file_name((column->header)->name, (column->header)->version); column_file_name = build_column_file_name((column->header)->name, (column->header)->version);
if (column_file_name == NULL) if (column_file_name == NULL)
{
return -1; return -1;
}
// Open the column file // Open the column file
column_file_descriptor = openat((column->column_directory)->dir_fd, column_file_name, O_RDWR); 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 // 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; file_size = (column->header)->header_size + data_size;
if (ftruncate(column_file_descriptor, file_size) < 0) if (ftruncate(column_file_descriptor, file_size) < 0)
{ {
@ -1246,7 +1269,7 @@ int obi_enlarge_column(OBIDMS_column_p column)
return -1; return -1;
} }
old_data_size = (column->header)->data_size; 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; header_size = (column->header)->header_size;
file_size = header_size + new_data_size; file_size = header_size + new_data_size;