From 9ad31fddff144a48da96f290654476b90201bb17 Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Wed, 26 Aug 2015 10:29:07 +0200 Subject: [PATCH] Added the possibility to clone a column, with or without its data --- .../obidms/obidmscolumn/capidmscolumn.pxd | 3 +- .../obidms/obidmscolumn/capidmscolumn.pyx | 66 ++++++++++--------- src/obidmscolumn.c | 55 +++++++++++++++- src/obidmscolumn.h | 21 +++++- 4 files changed, 110 insertions(+), 35 deletions(-) diff --git a/python/obitools3/obidms/obidmscolumn/capidmscolumn.pxd b/python/obitools3/obidms/obidmscolumn/capidmscolumn.pxd index d9d8fac..93d39f1 100644 --- a/python/obitools3/obidms/obidmscolumn/capidmscolumn.pxd +++ b/python/obitools3/obidms/obidmscolumn/capidmscolumn.pxd @@ -35,7 +35,8 @@ cdef extern from "obidmscolumn.h" nogil: OBIType_t obi_column_get_type(OBIDMS_column_p column) int obi_close_column(OBIDMS_column_p column) OBIType_t obi_column_get_data_type_from_name(OBIDMS_p dms, const char* column_name) - + OBIDMS_column_p obi_clone_column(OBIDMS_p dms, const char* column_name, obiversion_t version_number, bint clone_data) + cdef class OBIDMS_column: cdef OBIDMS_column_p pointer diff --git a/python/obitools3/obidms/obidmscolumn/capidmscolumn.pyx b/python/obitools3/obidms/obidmscolumn/capidmscolumn.pyx index 737a0ce..fc2e13e 100644 --- a/python/obitools3/obidms/obidmscolumn/capidmscolumn.pyx +++ b/python/obitools3/obidms/obidmscolumn/capidmscolumn.pyx @@ -12,9 +12,10 @@ cdef class OBIDMS_column: #Should only be initialized through a subclass (or open()) def __init__(self, dms_name, column_name, - create, version_number, - type, nb_elements, - nb_elements_per_line, elements_names): + create, clone, clone_data, + version_number, type, + nb_elements, nb_elements_per_line, + elements_names): column_name_b = column_name.encode(encoding='UTF-8') dms_name_b = dms_name.encode(encoding='UTF-8') self.dms_name = dms_name @@ -31,13 +32,10 @@ cdef class OBIDMS_column: else : dms = obi_open_dms(dms_name_b) self.dms = dms - self.pointer = obi_open_column(self.dms, column_name_b, version_number) - - def create(self, dms_name, column_name, type, nb_elements, nb_elements_per_line=1, elements_names=None): - if elements_names == None : - elements_names = column_name - self.dms = obi_dms(dms_name) - self.pointer = obi_create_column(self.dms, column_name, type, nb_elements, nb_elements_per_line, elements_names) + if clone : + self.pointer = obi_clone_column(self.dms, column_name_b, version_number, clone_data) + else : + self.pointer = obi_open_column(self.dms, column_name_b, version_number) def __iter__(self): elements_names = self.get_elements_names() @@ -78,9 +76,10 @@ cdef class OBIDMS_column: @staticmethod def open(dms_name, column_name, - create=False, version_number=-1, - type=None, nb_elements=None, - nb_elements_per_line=1, elements_names=None): + create=False, clone=False, clone_data=True, + version_number=-1, type=None, + nb_elements=None, nb_elements_per_line=1, + elements_names=None): column_name_b = column_name.encode(encoding='UTF-8') dms_name_b = dms_name.encode(encoding='UTF-8') @@ -94,39 +93,44 @@ cdef class OBIDMS_column: if type == 1 : column = OBIDMS_column_int(dms_name, column_name, - create, version_number, - type, nb_elements, - nb_elements_per_line, elements_names) + create, clone, clone_data, + version_number, type, + nb_elements, nb_elements_per_line, + elements_names) elif type == 2 : column = OBIDMS_column_float(dms_name, column_name, - create, version_number, - type, nb_elements, - nb_elements_per_line, elements_names) + create, clone, clone_data, + version_number, type, + nb_elements, nb_elements_per_line, + elements_names) elif type == 3 : column = OBIDMS_column_bool(dms_name, column_name, - create, version_number, - type, nb_elements, - nb_elements_per_line, elements_names) + create, clone, clone_data, + version_number, type, + nb_elements, nb_elements_per_line, + elements_names) -# elif type == 4 : -# column = OBIDMS_column_char(dms_name, column_name, -# create, version_number, -# type, nb_elements, -# nb_elements_per_line, elements_names) +# elif type == 4 : +# column = OBIDMS_column_char(dms_name, column_name, +# create, clone, clone_data, +# version_number, type, +# nb_elements, nb_elements_per_line, +# elements_names) elif type == 5 : column = OBIDMS_column_idx(dms_name, column_name, - create, version_number, - type, nb_elements, - nb_elements_per_line, elements_names) + create, clone, clone_data, + version_number, type, + nb_elements, nb_elements_per_line, + elements_names) else : "Problem with the data type" return column - + \ No newline at end of file diff --git a/src/obidmscolumn.c b/src/obidmscolumn.c index 4b0900c..0077ff2 100644 --- a/src/obidmscolumn.c +++ b/src/obidmscolumn.c @@ -723,6 +723,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, header->data_type = type; header->creation_date = time(NULL); header->version = version_number; + header->cloned_from = -1; header->comments[0] = 0x0; obi_column_set_elements_names(new_column, elements_names); @@ -813,7 +814,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms, const char* column_name, obiversio column->header = mmap(NULL, header_size, PROT_READ, - MAP_SHARED, + MAP_PRIVATE, column_file_descriptor, 0 ); @@ -836,7 +837,7 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms, const char* column_name, obiversio column->data = mmap(NULL, data_size, PROT_READ, - MAP_SHARED, + MAP_PRIVATE, column_file_descriptor, header_size ); @@ -861,9 +862,59 @@ OBIDMS_column_p obi_open_column(OBIDMS_p dms, const char* column_name, obiversio } +OBIDMS_column_p obi_clone_column(OBIDMS_p dms, const char* column_name, obiversion_t version_number, bool clone_data) +{ + OBIDMS_column_p column_to_clone; + OBIDMS_column_p new_column; + size_t nb_lines; + size_t nb_elements_per_line; + OBIType_t data_type; + + column_to_clone = obi_open_column(dms, column_name, version_number); + if (column_to_clone == NULL) + { + obi_set_errno(OBICOL_UNKNOWN_ERROR); + obidebug(1, "\nError opening the column to clone"); + return NULL; + } + + if (clone_data) + nb_lines = (column_to_clone->header)->line_count; + else + nb_lines = INITIAL_LINE_COUNT; + + nb_elements_per_line = (column_to_clone->header)->nb_elements_per_line; + data_type = (column_to_clone->header)->data_type; + + new_column = obi_create_column(dms, + column_name, + data_type, + nb_lines, + nb_elements_per_line, + (column_to_clone->header)->elements_names); + + if (new_column == NULL) + { + obi_set_errno(OBICOL_UNKNOWN_ERROR); + obidebug(1, "\nError creating the new column when cloning a column"); + // TODO the new file should be deleted + return NULL; + } + + (new_column->header)->cloned_from = version_number; + // TODO copy header->comments? + + if (clone_data) + memcpy(new_column->data, column_to_clone->data, nb_lines*nb_elements_per_line*sizeof(data_type)); + + return new_column; +} + + int obi_close_column(OBIDMS_column_p column) { //munmap? TODO + //truncate to lines used TODO free(column); return 0; } diff --git a/src/obidmscolumn.h b/src/obidmscolumn.h index f5c5d75..8439ea7 100644 --- a/src/obidmscolumn.h +++ b/src/obidmscolumn.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "obidms.h" #include "obitypes.h" @@ -25,6 +26,7 @@ #include "obidmscolumndir.h" #define ELEMENTS_NAMES_MAX (2048) +#define INITIAL_LINE_COUNT (1000) typedef int32_t obiversion_t; /**< Used to store the column version number @@ -49,6 +51,7 @@ typedef struct OBIDMS_column_header { OBIType_t data_type; /**< type of the data */ time_t creation_date; /**< date of creation of the file */ obiversion_t version; /**< version of the OBIColumn */ + obiversion_t cloned_from; /**< version of the OBIColumn from which the column was cloned from (-1 if it does not come from cloning).*/ char name[OBIDMS_MAX_COLNAME+1]; /**< The column name as a NULL * terminated string. */ @@ -148,7 +151,7 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, * * @param dms a pointer on an OBIDMS * @param column_name the name of the column - * @param version_number the version of the column that should be opened + * @param version_number the version of the column that should be opened (if -1, the latest version number is retrieved) * * @return a pointer to the opened column * @@ -158,6 +161,22 @@ OBIDMS_column_p obi_create_column(OBIDMS_p dms, OBIDMS_column_p obi_open_column(OBIDMS_p dms, const char* column_name, obiversion_t version_number); +/** + * @brief Clones a column, and returns a pointer to the writable new column. + * + * @param dms a pointer on an OBIDMS + * @param column_name the name of the column to clone + * @param version_number the version of the column that should be cloned (if -1, the latest version number is retrieved) + * @param clone_data whether the data should be copied or not + * + * @return a pointer to the created column + * + * @since August 2015 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +OBIDMS_column_p obi_clone_column(OBIDMS_p dms, const char* column_name, obiversion_t version_number, bool clone_data); + + /** * @brief Closes a column. *