From 0869b9ba3fa9a5fcd61b1f9ec2bbf29ceee0166d Mon Sep 17 00:00:00 2001 From: Celine Mercier Date: Thu, 30 Jun 2016 11:41:30 +0200 Subject: [PATCH] Closes issue #47 by storing each view in a separate file named with the view's name and created upon view creation. --- python/obitools3/obidms/_obidms.pxd | 2 +- python/obitools3/obidms/_obidms.pyx | 137 ++-- python/obitools3/obidms/capi/obiview.pxd | 44 +- src/obidms.c | 43 +- src/obidms.h | 8 + src/obiview.c | 843 +++++++++-------------- src/obiview.h | 98 +-- 7 files changed, 526 insertions(+), 649 deletions(-) diff --git a/python/obitools3/obidms/_obidms.pxd b/python/obitools3/obidms/_obidms.pxd index 0b5480b..908c9e3 100644 --- a/python/obitools3/obidms/_obidms.pxd +++ b/python/obitools3/obidms/_obidms.pxd @@ -91,5 +91,5 @@ cdef class OBIDMS: cpdef OBIView open_view(self, str view_name) cpdef OBIView new_view(self, str view_name, object view_to_clone=*, list line_selection=*, str view_type=*, str comments=*) cpdef dict read_view_infos(self, str view_name) - cpdef dict read_views(self) +# cpdef dict read_views(self) TODO diff --git a/python/obitools3/obidms/_obidms.pyx b/python/obitools3/obidms/_obidms.pyx index f0bf455..2b516e7 100644 --- a/python/obitools3/obidms/_obidms.pyx +++ b/python/obitools3/obidms/_obidms.pyx @@ -54,16 +54,15 @@ from ._obidmscolumn_seq cimport OBIDMS_column_seq, \ OBIDMS_column_multi_elts_seq from .capi.obiview cimport Obiview_p, \ - Obiviews_infos_all_p, \ Obiview_infos_p, \ Column_reference_p, \ obi_new_view_nuc_seqs, \ obi_new_view, \ obi_new_view_cloned_from_name, \ obi_new_view_nuc_seqs_cloned_from_name, \ + obi_view_map_file, \ + obi_view_unmap_file, \ obi_open_view, \ - obi_read_view_infos, \ - obi_close_view_infos, \ obi_view_delete_column, \ obi_view_add_column, \ obi_view_get_column, \ @@ -291,11 +290,11 @@ cdef class OBIView : raise Exception("Error creating/opening a view") self.pointer = view - self.name = bytes2str(view.name) + self.name = bytes2str(view.infos.name) # Go through columns to build list of corresponding python instances self.columns = {} - for i in range(view.column_count) : + for i in range(view.infos.column_count) : column_p = (view.columns)[i] header = (column_p).header col_name = bytes2str(header.name) @@ -305,7 +304,7 @@ cdef class OBIView : def __repr__(self) : cdef str s - s = str(self.name) + ", " + str(self.comments) + ", " + str(self.pointer.line_count) + " lines\n" + s = str(self.name) + ", " + str(self.comments) + ", " + str(self.pointer.infos.line_count) + " lines\n" for column_name in self.columns : s = s + self.columns[column_name].__repr__() + '\n' return s @@ -402,7 +401,7 @@ cdef class OBIView : cdef OBIView_line line # TODO Check that this works for NUC SEQ views # Yield each line - lines_used = (self.pointer).line_count + lines_used = self.pointer.infos.line_count for line_nb in range(lines_used) : line = self[line_nb] @@ -486,12 +485,12 @@ cdef class OBIView_NUC_SEQS(OBIView): raise Exception("Error creating/opening view") self.pointer = view - self.name = bytes2str(view.name) - self.comments = bytes2str(view.comments) + self.name = bytes2str(view.infos.name) + self.comments = bytes2str(view.infos.comments) # Go through columns to build list of corresponding python instances self.columns = {} - for i in range(view.column_count) : + for i in range(view.infos.column_count) : column_p = (view.columns)[i] header = (column_p).header col_name = bytes2str(header.name) @@ -603,7 +602,7 @@ cdef class OBIDMS : view_class = OBIView_NUC_SEQS else : view_class = OBIView - + return view_class(self, view_name) @@ -621,54 +620,84 @@ cdef class OBIDMS : cpdef dict read_view_infos(self, str view_name) : - all_views = self.read_views() - return all_views[view_name] - - - cpdef dict read_views(self) : # TODO function that prints the dic nicely and function that prints 1 view nicely. Add column type in col ref - cdef Obiviews_infos_all_p all_views_p - cdef Obiview_infos_p view_p + cdef Obiview_infos_p view_infos_p + cdef dict view_infos_d cdef Column_reference_p column_refs - cdef int nb_views cdef int i, j - cdef str view_name cdef str column_name - cdef dict views - cdef bytes name_b + + view_infos_p = obi_view_map_file(self.pointer, str2bytes(view_name)) + view_infos_d = {} + view_infos_d["name"] = bytes2str(view_infos_p.name) + view_infos_d["comments"] = bytes2str(view_infos_p.comments) + view_infos_d["view_type"] = bytes2str(view_infos_p.view_type) + view_infos_d["column_count"] = view_infos_p.column_count + view_infos_d["line_count"] = view_infos_p.line_count + view_infos_d["created_from"] = bytes2str(view_infos_p.created_from) + view_infos_d["creation_date"] = bytes2str(obi_format_date(view_infos_p.creation_date)) + if (view_infos_p.all_lines) : + view_infos_d["line_selection"] = None + else : + view_infos_d["line_selection"] = {} + view_infos_d["line_selection"]["column_name"] = bytes2str((view_infos_p.line_selection).column_name) + view_infos_d["line_selection"]["version"] = (view_infos_p.line_selection).version + view_infos_d["column_references"] = {} + column_refs = view_infos_p.column_references + for j in range(view_infos_d["column_count"]) : + column_name = bytes2str((column_refs[j]).column_name) + view_infos_d["column_references"][column_name] = {} + view_infos_d["column_references"][column_name]["version"] = column_refs[j].version - views = {} - all_views_p = obi_read_view_infos(self.pointer) - if all_views_p == NULL : - raise Exception("No views to read") - nb_views = (all_views_p.header).view_count - for i in range(nb_views) : - view_p = ( (all_views_p.view_infos)) + i - view_name = bytes2str(view_p.name) - views[view_name] = {} - views[view_name]["comments"] = bytes2str(view_p.comments) - views[view_name]["view_type"] = bytes2str(view_p.view_type) - views[view_name]["column_count"] = view_p.column_count - views[view_name]["line_count"] = view_p.line_count - views[view_name]["view_number"] = view_p.view_number - views[view_name]["created_from"] = bytes2str(view_p.created_from) - views[view_name]["creation_date"] = bytes2str(obi_format_date(view_p.creation_date)) - if (view_p.all_lines) : - views[view_name]["line_selection"] = None - else : - views[view_name]["line_selection"] = {} - views[view_name]["line_selection"]["column_name"] = bytes2str((view_p.line_selection).column_name) - views[view_name]["line_selection"]["version"] = (view_p.line_selection).version - views[view_name]["column_references"] = {} - column_refs = view_p.column_references - for j in range(views[view_name]["column_count"]) : - column_name = bytes2str((column_refs[j]).column_name) - views[view_name]["column_references"][column_name] = {} - views[view_name]["column_references"][column_name]["version"] = column_refs[j].version - - obi_close_view_infos(all_views_p); - - return views + obi_view_unmap_file(self.pointer, view_infos_p) + + return view_infos_d + + +# cpdef dict read_views(self) : # TODO function that prints the dic nicely and function that prints 1 view nicely. Add column type in col ref +# +# cdef Obiviews_infos_all_p all_views_p +# cdef Obiview_infos_p view_p +# cdef Column_reference_p column_refs +# cdef int nb_views +# cdef int i, j +# cdef str view_name +# cdef str column_name +# cdef dict views +# cdef bytes name_b +# +# views = {} +# all_views_p = obi_read_view_infos(self.pointer) +# if all_views_p == NULL : +# raise Exception("No views to read") +# nb_views = (all_views_p.header).view_count +# for i in range(nb_views) : +# view_p = ( (all_views_p.view_infos)) + i +# view_name = bytes2str(view_p.name) +# views[view_name] = {} +# views[view_name]["comments"] = bytes2str(view_p.comments) +# views[view_name]["view_type"] = bytes2str(view_p.view_type) +# views[view_name]["column_count"] = view_p.column_count +# views[view_name]["line_count"] = view_p.line_count +# views[view_name]["view_number"] = view_p.view_number +# views[view_name]["created_from"] = bytes2str(view_p.created_from) +# views[view_name]["creation_date"] = bytes2str(obi_format_date(view_p.creation_date)) +# if (view_p.all_lines) : +# views[view_name]["line_selection"] = None +# else : +# views[view_name]["line_selection"] = {} +# views[view_name]["line_selection"]["column_name"] = bytes2str((view_p.line_selection).column_name) +# views[view_name]["line_selection"]["version"] = (view_p.line_selection).version +# views[view_name]["column_references"] = {} +# column_refs = view_p.column_references +# for j in range(views[view_name]["column_count"]) : +# column_name = bytes2str((column_refs[j]).column_name) +# views[view_name]["column_references"][column_name] = {} +# views[view_name]["column_references"][column_name]["version"] = column_refs[j].version +# +# obi_close_view_infos(all_views_p); +# +# return views diff --git a/python/obitools3/obidms/capi/obiview.pxd b/python/obitools3/obidms/capi/obiview.pxd index 6c48de6..50cc56a 100644 --- a/python/obitools3/obidms/capi/obiview.pxd +++ b/python/obitools3/obidms/capi/obiview.pxd @@ -23,21 +23,6 @@ cdef extern from "obiview.h" nogil: extern const_char_p DEFINITION_COLUMN extern const_char_p QUALITY_COLUMN - struct Obiview_t : - OBIDMS_p dms - const_char_p name - const_char_p created_from - const_char_p view_type - bint read_only - OBIDMS_column_p line_selection - OBIDMS_column_p new_line_selection - index_t line_count - int column_count - OBIDMS_column_p columns - const_char_p comments - - ctypedef Obiview_t* Obiview_p - struct Column_reference_t : const_char_p column_name @@ -47,7 +32,6 @@ cdef extern from "obiview.h" nogil: struct Obiview_infos_t : - int view_number time_t creation_date const_char_p name const_char_p created_from @@ -62,19 +46,15 @@ cdef extern from "obiview.h" nogil: ctypedef Obiview_infos_t* Obiview_infos_p - struct Obiviews_header_t : - size_t header_size - size_t views_size - int view_count - - ctypedef Obiviews_header_t* Obiviews_header_p + struct Obiview_t : + Obiview_infos_p infos + OBIDMS_p dms + bint read_only + OBIDMS_column_p line_selection + OBIDMS_column_p new_line_selection + OBIDMS_column_p columns - - struct Obiviews_infos_all_t : - Obiviews_header_p header - Obiview_infos_p view_infos - - ctypedef Obiviews_infos_all_t* Obiviews_infos_all_p + ctypedef Obiview_t* Obiview_p Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const_char_p view_name, Obiview_p view_to_clone, index_t* line_selection, const_char_p comments) @@ -85,6 +65,10 @@ cdef extern from "obiview.h" nogil: Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const_char_p view_name, const_char_p view_to_clone_name, index_t* line_selection, const_char_p comments) + Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name) + + int obi_view_unmap_file(OBIDMS_p dms, Obiview_infos_p view_infos) + Obiview_p obi_open_view(OBIDMS_p dms, const_char_p view_name) int obi_view_add_column(Obiview_p view, @@ -113,10 +97,6 @@ cdef extern from "obiview.h" nogil: int obi_close_view(Obiview_p view) int obi_save_and_close_view(Obiview_p view) - - Obiviews_infos_all_p obi_read_view_infos(OBIDMS_p dms) - - int obi_close_view_infos(Obiviews_infos_all_p views) int obi_column_set_obiint_with_elt_name_in_view(Obiview_p view, OBIDMS_column_p column, diff --git a/src/obidms.c b/src/obidms.c index 2ab190f..6f7eb23 100644 --- a/src/obidms.c +++ b/src/obidms.c @@ -252,7 +252,7 @@ OBIDMS_p obi_create_dms(const char* dms_path) return NULL; } - // Get file descriptor of DMS directory to create the indexer directory + // Get file descriptor of DMS directory to create other directories dms_dir = opendir(directory_name); if (dms_dir == NULL) { @@ -280,6 +280,14 @@ OBIDMS_p obi_create_dms(const char* dms_path) return NULL; } + // Create the view directory + if (mkdirat(dms_file_descriptor, VIEW_DIR_NAME, 00777) < 0) + { + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nProblem creating a view directory"); + return NULL; + } + // Isolate the dms name j = 0; for (i=0; iview_directory = opendir_in_dms(dms, VIEW_DIR_NAME); + if (dms->view_directory == NULL) + { + obi_set_errno(OBIDMS_UNKNOWN_ERROR); + obidebug(1, "\nError opening the view directory"); + closedir(dms->indexer_directory); + closedir(dms->directory); + free(dms); + return NULL; + } + + // Store the view directory's file descriptor + dms->view_dir_fd = dirfd(dms->view_directory); + if (dms->view_dir_fd < 0) + { + obi_set_errno(OBIDMS_UNKNOWN_ERROR); + obidebug(1, "\nError getting the file descriptor of the view directory"); + closedir(dms->view_directory); + closedir(dms->directory); + free(dms); + return NULL; + } + // Initialize the list of opened columns dms->opened_columns = (Opened_columns_list_p) malloc(sizeof(Opened_columns_list_t)); (dms->opened_columns)->nb_opened_columns = 0; @@ -486,7 +518,7 @@ int obi_close_dms(OBIDMS_p dms) while ((dms->opened_columns)->nb_opened_columns > 0) obi_close_column(*((dms->opened_columns)->columns)); - // Close dms and indexer directories + // Close dms, and view and indexer directories if (closedir(dms->directory) < 0) { obi_set_errno(OBIDMS_MEMORY_ERROR); @@ -501,6 +533,13 @@ int obi_close_dms(OBIDMS_p dms) free(dms); return -1; } + if (closedir(dms->view_directory) < 0) + { + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nError closing a view directory"); + free(dms); + return -1; + } free(dms); } diff --git a/src/obidms.h b/src/obidms.h index b44071b..494e851 100644 --- a/src/obidms.h +++ b/src/obidms.h @@ -30,6 +30,8 @@ */ #define INDEXER_DIR_NAME "OBIBLOB_INDEXERS" /**< The name of the Obiblob indexer directory. */ +#define VIEW_DIR_NAME "VIEWS" /**< The name of the view directory. + */ #define TAXONOMY_DIR_NAME "TAXONOMY" /**< The name of the taxonomy directory. */ #define MAX_NB_OPENED_COLUMNS (100) /**< The maximum number of columns open at the same time. @@ -98,6 +100,12 @@ typedef struct OBIDMS { int indexer_dir_fd; /**< The file descriptor of the directory entry * usable to refer and scan the indexer directory. */ + DIR* view_directory; /**< A directory entry usable to + * refer and scan the view directory. + */ + int view_dir_fd; /**< The file descriptor of the directory entry + * usable to refer and scan the view directory. + */ bool little_endian; /**< Endianness of the database. */ Opened_columns_list_p opened_columns; /**< List of opened columns. diff --git a/src/obiview.c b/src/obiview.c index 1b4cf31..da23357 100644 --- a/src/obiview.c +++ b/src/obiview.c @@ -44,39 +44,50 @@ /** - * Internal function building the file name where obiviews are stored. + * Internal function building the file name where the informations about an obiview are stored. * * @warning The returned pointer has to be freed by the caller. * * @returns A pointer to the file name. * @retval NULL if an error occurred. * - * @param dms_name The name of the OBIDMS. + * @param view_name The name of the view. * - * @since December 2015 + * @since June 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -static char* build_obiview_file_name(); +static char* build_obiview_file_name(const char* view_name); // TODO delete after discussion -/** TODO public? - * Internal function creating the file containing basic informations on the OBIDMS. +/** + * @brief Internal function creating a file containing all the informations on a view. * - * This file contains: - * - The endianness of the platform + * The file is named with the name of the view. * - * @warning The returned pointer has to be freed by the caller. - * - * @param dms_file_descriptor The file descriptor for the OBIDMS directory. - * @param dms_name The name of the OBIDMS. + * @param dms The DMS to which the view belongs. + * @param view_name The name of the view. * * @retval 0 if the operation was successfully completed. * @retval -1 if an error occurred. * - * @since November 2015 + * @since June 2016 * @author Celine Mercier (celine.mercier@metabarcoding.org) */ -int create_obiview_file(int dms_file_descriptor); +int create_obiview_file(OBIDMS_p dms, const char* view_name); + + +/** + * @brief Internal function to update the column references of a view. + * + * The column references stored in the mapped view infos structures are updated + * to match the columns opened in the opened view structure. + * + * @param view A pointer on the view. + * + * @since June 2016 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +void update_column_refs(Obiview_p view); /** @@ -160,46 +171,31 @@ int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p); * ************************************************************************/ -static char* build_obiview_file_name() -{ - char* file_name; - - // Build file name - file_name = (char*) malloc((strlen(OBIVIEW_FILE_NAME) + 1)*sizeof(char)); - if (file_name == NULL) - { - obi_set_errno(OBI_MALLOC_ERROR); - obidebug(1, "\nError allocating memory for a view file name"); - return NULL; - } - if (sprintf(file_name, OBIVIEW_FILE_NAME) < 0) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nProblem building an obiview file name"); - return NULL; - } - - return file_name; -} +// TODO +//static char* build_obiview_file_name(const char* view_name) +//{ +// char* file_name; +// +// // Build file name +// file_name = (char*) malloc((strlen(view_name) + 1)*sizeof(char)); +// if (file_name == NULL) +// { +// obi_set_errno(OBI_MALLOC_ERROR); +// obidebug(1, "\nError allocating memory for a view file name"); +// return NULL; +// } +// if (sprintf(file_name, view_name) < 0) +// { +// obi_set_errno(OBIVIEW_ERROR); +// obidebug(1, "\nProblem building an obiview file name"); +// return NULL; +// } +// +// return file_name; +//} -size_t get_platform_header_size() -{ - size_t header_size; - size_t rounded_header_size; - double multiple; - - header_size = sizeof(Obiviews_header_t); - - multiple = ceil((double) header_size / (double) getpagesize()); - - rounded_header_size = multiple * getpagesize(); - - return rounded_header_size; -} - - -size_t get_platform_views_size(int nb_of_views) +size_t get_platform_view_file_size() { size_t obiview_size; size_t rounded_obiview_size; @@ -207,7 +203,7 @@ size_t get_platform_views_size(int nb_of_views) obiview_size = sizeof(Obiview_infos_t); - multiple = ceil((double) (obiview_size*nb_of_views) / (double) getpagesize()); + multiple = ceil((double) (obiview_size) / (double) getpagesize()); rounded_obiview_size = multiple * getpagesize(); @@ -215,34 +211,32 @@ size_t get_platform_views_size(int nb_of_views) } -int create_obiview_file(int dms_file_descriptor) +int create_obiview_file(OBIDMS_p dms, const char* view_name) { - char* file_name; +// char* file_name; int obiview_file_descriptor; - size_t header_size; size_t file_size; - Obiviews_header_p header; - // Create file name - file_name = build_obiview_file_name(); - if (file_name == NULL) - return -1; + // TODO +// // Create file name +// file_name = build_obiview_file_name(view_name); +// if (file_name == NULL) +// return -1; // Create file - obiview_file_descriptor = openat(dms_file_descriptor, file_name, O_RDWR | O_CREAT | O_EXCL, 0777); + obiview_file_descriptor = openat(dms->view_dir_fd, view_name, O_RDWR | O_CREAT | O_EXCL, 0777); if (obiview_file_descriptor < 0) { obi_set_errno(OBIVIEW_ERROR); obidebug(1, "\nError creating an obiview file"); - free(file_name); +// free(file_name); TODO return -1; } - free(file_name); + //free(file_name); TODO // Truncate file to the right size - header_size = get_platform_header_size(); - file_size = header_size; + file_size = get_platform_view_file_size(); if (ftruncate(obiview_file_descriptor, file_size) < 0) { @@ -252,47 +246,30 @@ int create_obiview_file(int dms_file_descriptor) return -1; } - // Map the header - header = mmap(NULL, - header_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - 0 - ); - if (header == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping an obiview file header"); - close(obiview_file_descriptor); - return -1; - } - - // Initialize the header - header->header_size = header_size; - header->views_size = 0; - header->view_count = 0; - - // Unmap the header - if (munmap(header, header_size) < 0) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError munmapping an obiview file header"); - close(obiview_file_descriptor); - return -1; - } - close(obiview_file_descriptor); return 0; } + +void update_column_refs(Obiview_p view) +{ + int i; + + for (i=0; i < (view->infos)->column_count; i++) + { + strcpy((((view->infos)->column_references)+i)->column_name, (((view->columns)[i])->header)->name); + (((view->infos)->column_references)+i)->version = (((view->columns)[i])->header)->version; + } +} + + int update_lines(Obiview_p view, index_t line_count) { int i; - for (i=0; i<(view->column_count); i++) + for (i=0; i<((view->infos)->column_count); i++) { while (line_count > (((view->columns)[i])->header)->line_count) { @@ -303,7 +280,7 @@ int update_lines(Obiview_p view, index_t line_count) } } - view->line_count = line_count; + (view->infos)->line_count = line_count; return 0; } @@ -329,7 +306,7 @@ OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name) else current_line_selection = view->line_selection; - for (i=0; i<(view->column_count); i++) + for (i=0; i<((view->infos)->column_count); i++) { if ((current_line_selection != NULL) || (!(strcmp((((view->columns)[i])->header)->name, column_name)))) { // Clone with the right line selection and replace (for all columns if there is a line selection) @@ -361,6 +338,9 @@ OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name) { obi_close_column(view->line_selection); view->line_selection = NULL; + // Update line selection reference + (((view->infos)->line_selection).column_name)[0] = '\0'; + ((view->infos)->line_selection).version = -1; } if (view->new_line_selection != NULL) { @@ -368,6 +348,9 @@ OBIDMS_column_p clone_column_in_view(Obiview_p view, const char* column_name) view->new_line_selection = NULL; } + // Update column references in view infos + update_column_refs(view); + return column; } @@ -410,7 +393,7 @@ int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, i free(column_name); } - if (((*line_nb_p)+1) > view->line_count) + if (((*line_nb_p)+1) > (view->infos)->line_count) { if (update_lines(view, ((*line_nb_p)+1)) < 0) return -1; @@ -422,7 +405,7 @@ int prepare_to_set_value_in_column(Obiview_p view, OBIDMS_column_p* column_pp, i int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p) { - if (((*line_nb_p)+1) > (view->line_count)) + if (((*line_nb_p)+1) > ((view->infos)->line_count)) { obi_set_errno(OBICOL_UNKNOWN_ERROR); obidebug(1, "\nError trying to get a value that is beyond the current line count of the view"); @@ -444,28 +427,25 @@ int prepare_to_get_value_from_column(Obiview_p view, index_t* line_nb_p) Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_clone, index_t* line_selection, const char* comments) { - Obiview_p view; - int i; - index_t line_nb; - Obiviews_infos_all_p views_infos; + Obiview_p view; + int i; + index_t line_nb; + struct dirent* dp; - // Check uniqueness of name TODO but problem if view not written yet has the same name. Save lists of open views in DMS ? - views_infos = obi_read_view_infos(dms); - if (views_infos != NULL) + // Check uniqueness of name + while ((dp = readdir(dms->view_directory)) != NULL) { - for (i=0; i<((views_infos->header)->view_count); i++) + if ((dp->d_name)[0] == '.') + continue; + if (strcmp(dp->d_name, view_name) == 0) // TODO change if view name building changes { - if (strcmp(((views_infos->view_infos)+i)->name, view_name) == 0) // TODO discuss what to do - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nView name already exists for a previous view"); - obi_close_view_infos(views_infos); - return NULL; - } + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nName of new view already exists"); + return NULL; } - obi_close_view_infos(views_infos); } + // Allocate memory for view structure view = (Obiview_p) malloc(sizeof(Obiview_t)); if (view == NULL) { @@ -474,6 +454,24 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl return NULL; } + view->dms = dms; + + // Create view file + if (create_obiview_file(dms, view_name) < 0) + { + free(view); + return NULL; + } + + // Map view file + view->infos = obi_view_map_file(dms, view_name); + if (view->infos == NULL) + { + obidebug(1, "\nError mapping the informations of a new view"); + free(view); + return NULL; + } + // Clone view to clone if there is one if (view_to_clone != NULL) { @@ -481,19 +479,22 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl { obi_set_errno(OBIVIEW_ERROR); obidebug(1, "\nA view can not be cloned if it is not read-only"); + obi_view_unmap_file(view->dms, view->infos); free(view); return NULL; } - view->dms = dms; - // If the view to clone has an associated line selection and there is no new line selection, open the associated line selection if ((view_to_clone->line_selection != NULL) && (line_selection == NULL)) { view->line_selection = obi_open_column(dms, ((view_to_clone->line_selection)->header)->name, ((view_to_clone->line_selection)->header)->version); if (view->line_selection == NULL) + { + obi_view_unmap_file(view->dms, view->infos); + free(view); return NULL; - view->line_count = view_to_clone->line_count; + } + (view->infos)->line_count = (view_to_clone->infos)->line_count; } // If there is a new line selection, build it by combining it with the one from the view to clone if there is one else if (line_selection != NULL) @@ -502,19 +503,23 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl if ((view->line_selection) == NULL) { obidebug(1, "\nError creating a column corresponding to a line selection"); + obi_view_unmap_file(view->dms, view->infos); + free(view); return NULL; } - view->line_count = 0; + (view->infos)->all_lines = false; + (view->infos)->line_count = 0; i = 0; for (i=0; line_selection[i] != -1; i++) { line_nb = line_selection[i]; - if (line_nb > view_to_clone->line_count) + if (line_nb > (view_to_clone->infos)->line_count) { obi_set_errno(OBIVIEW_ERROR); obidebug(1, "\nError trying to select a line for a new view that is beyond the line count of the view to clone"); obi_close_column(view->line_selection); + obi_view_unmap_file(view->dms, view->infos); free(view); return NULL; } @@ -525,54 +530,73 @@ Obiview_p obi_new_view(OBIDMS_p dms, const char* view_name, Obiview_p view_to_cl if (obi_column_set_index(view->line_selection, ((view->line_selection)->header)->lines_used, line_nb) < 0) { obi_close_column(view->line_selection); + obi_view_unmap_file(view->dms, view->infos); free(view); return NULL; } // Update view line count - (view->line_count)++; + ((view->infos)->line_count)++; } } else // If there is no line selection associated with the view to clone or the new view { view->line_selection = NULL; - view->line_count = view_to_clone->line_count; + (view->infos)->all_lines = true; + (view->infos)->line_count = (view_to_clone->infos)->line_count; } - for (i=0; i<(view_to_clone->column_count); i++) + for (i=0; i<((view_to_clone->infos)->column_count); i++) { (view->columns)[i] = obi_open_column(dms, (((view_to_clone->columns)[i])->header)->name, (((view_to_clone->columns)[i])->header)->version); if ((view->columns)[i] == NULL) { if (view->line_selection != NULL) obi_close_column(view->line_selection); + obi_view_unmap_file(view->dms, view->infos); free(view); return NULL; } } - view->column_count = view_to_clone->column_count; - strcpy(view->view_type, view_to_clone->view_type); - strcpy(view->created_from, view_to_clone->name); + (view->infos)->column_count = (view_to_clone->infos)->column_count; + strcpy((view->infos)->view_type, (view_to_clone->infos)->view_type); + strcpy((view->infos)->created_from, (view_to_clone->infos)->name); view->new_line_selection = NULL; } // Else, fill empty view structure else { - view->dms = dms; - view->column_count = 0; - view->line_count = 0; - view->line_selection = NULL; - view->new_line_selection = NULL; - (view->created_from)[0] = '\0'; - (view->view_type)[0] = '\0'; + (view->infos)->column_count = 0; + (view->infos)->line_count = 0; + (view->infos)->all_lines = true; + view->line_selection = NULL; + view->new_line_selection = NULL; + ((view->infos)->created_from)[0] = '\0'; + ((view->infos)->view_type)[0] = '\0'; //view->columns = NULL; // TODO } - strcpy(view->name, view_name); - strcpy(view->comments, comments); + strcpy((view->infos)->name, view_name); + strcpy((view->infos)->comments, comments); + (view->infos)->creation_date = time(NULL); view->read_only = 0; + // Store reference for line selection + if (view->line_selection == NULL) + { + (((view->infos)->line_selection).column_name)[0] = '\0'; + ((view->infos)->line_selection).version = -1; + } + else + { + strcpy(((view->infos)->line_selection).column_name, ((view->line_selection)->header)->name); + ((view->infos)->line_selection).version = ((view->line_selection)->header)->version; + } + + // Store references for columns + update_column_refs(view); + return view; } @@ -599,7 +623,7 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v if (view_to_clone != NULL) { // Check that the view to clone is already a NUC_SEQS view (TODO discuss possibility of transforming type of a view) - if (strcmp(view_to_clone->view_type, VIEW_TYPE_NUC_SEQS)) + if (strcmp((view_to_clone->infos)->view_type, VIEW_TYPE_NUC_SEQS)) { obi_set_errno(OBIVIEW_ERROR); obidebug(1, "Trying to clone a non-NUC SEQS view to create a NUC SEQS view"); @@ -608,10 +632,10 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v } view = obi_new_view(dms, view_name, view_to_clone, line_selection, comments); - if (view== NULL) + if (view == NULL) return NULL; - strcpy(view->view_type, VIEW_TYPE_NUC_SEQS); + strcpy((view->infos)->view_type, VIEW_TYPE_NUC_SEQS); if (view_to_clone == NULL) { @@ -661,160 +685,140 @@ Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const char* view_ } -Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name) +Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name) { - Obiview_p view; - char* view_file_name; +// char* file_name; + Obiview_infos_p view_infos; int obiview_file_descriptor; - size_t header_size; - Obiviews_header_p header; - Obiview_infos_p views; - Obiview_infos_p view_infos; - OBIDMS_column_p column; - int i; - int view_number; + size_t file_size; - view_file_name = build_obiview_file_name(); - if (view_file_name == NULL) - return NULL; + // TODO +// // Create file name +// file_name = build_obiview_file_name(view_name); +// if (file_name == NULL) +// return -1; - // Open view file, read header size and map header and views - obiview_file_descriptor = openat(dms->dir_fd, view_file_name, O_RDWR, 0777); + // Open view file + obiview_file_descriptor = openat(dms->view_dir_fd, view_name, O_RDWR, 0777); if (obiview_file_descriptor < 0) { obi_set_errno(OBIVIEW_ERROR); obidebug(1, "\nError opening an obiview file"); - free(view_file_name); +// free(file_name); TODO return NULL; } - free(view_file_name); + //free(file_name); TODO - // Read the header size - if (read(obiview_file_descriptor, &header_size, sizeof(size_t)) < ((ssize_t) sizeof(size_t))) + // Map the view infos structure + file_size = get_platform_view_file_size(); + view_infos = mmap(NULL, + file_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + obiview_file_descriptor, + 0 + ); + if (view_infos == NULL) { obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError reading the header size of an obiview file (trying to open a view when there are none?)"); - close(obiview_file_descriptor); + obidebug(1, "\nError mapping an obiview file"); return NULL; } - // Map the header - header = mmap(NULL, - header_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - 0 - ); - if (header == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping an obiview file header"); - close(obiview_file_descriptor); - return NULL; - } + close(obiview_file_descriptor); - // Map the views - views = mmap(NULL, - header->views_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - header_size - ); - if (views == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping the views from an obiview file"); - munmap(header, header_size); - close(obiview_file_descriptor); - return NULL; - } + return view_infos; +} - // Find and open the view that should be read with the line selection associated - view_number = -1; - if (view_name == NULL) // If view name is NULL, open the latest view TODO discuss - view_number = (header->view_count) - 1; - else - { - for (i=0; i<(header->view_count); i++) + +int obi_view_unmap_file(OBIDMS_p dms, Obiview_infos_p view_infos) +{ + // char* file_name; + int obiview_file_descriptor; + size_t file_size; + + // TODO + // // Get file name + // file_name = build_obiview_file_name(view_name); + // if (file_name == NULL) + // return -1; + + // Open view file + obiview_file_descriptor = openat(dms->view_dir_fd, view_infos->name, O_RDWR, 0777); + if (obiview_file_descriptor < 0) { - if (!strcmp((views+i)->name, view_name)) - { // Found the view to open - view_number = i; - } + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nError opening an obiview file"); + // free(file_name); TODO + return -1; + } + + //free(file_name); TODO + + // Unmap the view infos structure + file_size = get_platform_view_file_size(); + if (munmap(view_infos, file_size) < 0) + { + obi_set_errno(OBIVIEW_ERROR); + obidebug(1, "\nError unmapping an obiview file"); + close(obiview_file_descriptor); + return -1; } - } - if (view_number == -1) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError: the view '%s' to open was not found", view_name); - munmap(views, header->views_size); - munmap(header, header_size); close(obiview_file_descriptor); - return NULL; - } - view_infos = views + view_number; + return 0; +} + +Obiview_p obi_open_view(OBIDMS_p dms, const char* view_name) +{ + Obiview_p view; + int i; + + // Alllocate the memory for the view structure view = (Obiview_p) malloc(sizeof(Obiview_t)); if (view == NULL) { - obi_set_errno(OBIVIEW_ERROR); + obi_set_errno(OBI_MALLOC_ERROR); obidebug(1, "\nError allocating memory for a view"); - munmap(views, header->views_size); - munmap(header, header_size); - close(obiview_file_descriptor); return NULL; } - if (view_infos->all_lines) + // Map view file + view->infos = obi_view_map_file(dms, view_name); + + // Open the line selection associated with the view + if ((view->infos)->all_lines) view->line_selection = NULL; else { - view->line_selection = obi_open_column(dms, (view_infos->line_selection).column_name, (view_infos->line_selection).version); + view->line_selection = obi_open_column(dms, ((view->infos)->line_selection).column_name, ((view->infos)->line_selection).version); if (view->line_selection == NULL) { - munmap(views, header->views_size); - munmap(header, header_size); - close(obiview_file_descriptor); + obidebug(1, "\nError opening a line selection for a view"); + obi_view_unmap_file(view->dms, view->infos); + free(view); + return NULL; + } + } + + // Open the columns to read + for (i=0; i < ((view->infos)->column_count); i++) + { + (view->columns)[i] = obi_open_column(dms, (((view->infos)->column_references)+i)->column_name, (((view->infos)->column_references)+i)->version); + if ((view->columns)[i] == NULL) + { + obidebug(1, "\nError opening a column for a view: column %d: %s, version %d", i, (((view->infos)->column_references)+i)->column_name, (((view->infos)->column_references)+i)->version); + obi_close_view(view); return NULL; } } view->dms = dms; view->new_line_selection = NULL; - view->read_only = 1; - view->column_count = 0; - view->line_count = view_infos->line_count; - strcpy(view->created_from, view_infos->created_from); - strcpy(view->name, view_infos->name); - strcpy(view->view_type, view_infos->view_type); - strcpy(view->comments, view_infos->comments); - - // Open the columns to read - for (i=0; i<(view_infos->column_count); i++) - { - column = obi_open_column(dms, ((view_infos->column_references)+i)->column_name, ((view_infos->column_references)+i)->version); - if (column == NULL) - { - obidebug(1, "\nError opening a column for a view: column %d: %s, version %d", i, ((view_infos->column_references)+i)->column_name, ((view_infos->column_references)+i)->version); - munmap(views, header->views_size); - munmap(header, header_size); - close(obiview_file_descriptor); - return NULL; - } - // Store column in the view - (view->columns)[view->column_count] = column; - view->column_count++; - } - - // Munmap and close things - munmap(views, header->views_size); - munmap(header, header_size); - close(obiview_file_descriptor); + view->read_only = true; return view; } @@ -852,7 +856,7 @@ int obi_view_add_column(Obiview_p view, if (current_line_selection != NULL) { - for (i=0; i<(view->column_count); i++) + for (i=0; i<((view->infos)->column_count); i++) { { // Clone with the right line selection and replace for all columns // Save pointer to close column after cloning @@ -878,6 +882,9 @@ int obi_view_add_column(Obiview_p view, { obi_close_column(view->line_selection); view->line_selection = NULL; + // Update line selection reference + (((view->infos)->line_selection).column_name)[0] = '\0'; + ((view->infos)->line_selection).version = -1; } if (view->new_line_selection != NULL) { @@ -886,9 +893,9 @@ int obi_view_add_column(Obiview_p view, } // Update the line count - if (view->line_count > nb_lines) - nb_lines = view->line_count; - else if (nb_lines > view->line_count) + if ((view->infos)->line_count > nb_lines) + nb_lines = (view->infos)->line_count; + else if (nb_lines > (view->infos)->line_count) update_lines(view, nb_lines); // Open or create the column @@ -908,10 +915,13 @@ int obi_view_add_column(Obiview_p view, } // Store column in the view - (view->columns)[view->column_count] = column; - view->column_count++; - if (view->column_count == 1) // first column in the view - view->line_count = (column->header)->lines_used; + (view->columns)[(view->infos)->column_count] = column; + (view->infos)->column_count++; + if ((view->infos)->column_count == 1) // first column in the view + (view->infos)->line_count = (column->header)->lines_used; + + // Update reference in view infos + update_column_refs(view); return 0; } @@ -934,7 +944,7 @@ int obi_view_delete_column(Obiview_p view, const char* column_name) found = 0; - for (i=0; i<(view->column_count); i++) + for (i=0; i<((view->infos)->column_count); i++) { if (!strcmp((((view->columns)[i])->header)->name, column_name)) { @@ -943,7 +953,7 @@ int obi_view_delete_column(Obiview_p view, const char* column_name) } if (found) { - if (i != ((view->column_count) - 1)) // not the last one + if (i != (((view->infos)->column_count) - 1)) // not the last one (view->columns)[i] = (view->columns)[i+1]; else // Last column (view->columns)[i] = NULL; @@ -953,7 +963,10 @@ int obi_view_delete_column(Obiview_p view, const char* column_name) if (!found) return -1; - (view->column_count)--; + ((view->infos)->column_count)--; + + // Update reference in view infos + update_column_refs(view); return 0; } @@ -963,7 +976,7 @@ OBIDMS_column_p obi_view_get_column(Obiview_p view, const char* column_name) { int i; - for (i=0; i<(view->column_count); i++) + for (i=0; i<((view->infos)->column_count); i++) { if (!(strcmp((((view->columns)[i])->header)->name, column_name))) return (view->columns)[i]; @@ -976,7 +989,7 @@ OBIDMS_column_p* obi_view_get_pointer_on_column_in_view(Obiview_p view, const ch { int i; - for (i=0; i<(view->column_count); i++) + for (i=0; i<((view->infos)->column_count); i++) { if (!(strcmp((((view->columns)[i])->header)->name, column_name))) return ((view->columns)+i); @@ -1059,20 +1072,6 @@ int obi_select_lines(Obiview_p view, index_t* line_nbs) int obi_save_view(Obiview_p view) { - int i; - struct stat buffer; - char* view_file_name; - char* full_path; - int check_file; - int obiview_file_descriptor; - size_t header_size; - size_t views_size; - size_t file_size; - Obiviews_header_p header; - Obiview_infos_p views; - Obiview_infos_p view_infos; - OBIDMS_column_p current_line_selection; - // Check that the view is not read-only if (view->read_only) { @@ -1081,142 +1080,28 @@ int obi_save_view(Obiview_p view) return -1; } - view_file_name = build_obiview_file_name(); - if (view_file_name == NULL) - return -1; - - // Get the full path for the column directory - full_path = obi_dms_get_full_path(view->dms, view_file_name); - if (full_path == NULL) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError getting the full path of an obiview file"); - free(view_file_name); - return -1; - } - - check_file = stat(full_path, &buffer); - if (check_file < 0) - { // 1st view: create view file - if (create_obiview_file((view->dms)->dir_fd) < 0) - return -1; - } - - // Open view file, read header size and map header and views - obiview_file_descriptor = openat((view->dms)->dir_fd, view_file_name, O_RDWR, 0777); - if (obiview_file_descriptor < 0) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError opening an obiview file"); - free(view_file_name); - return -1; - } - - free(view_file_name); - - // Read the header size - if (read(obiview_file_descriptor, &header_size, sizeof(size_t)) < ((ssize_t) sizeof(size_t))) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError reading the header size of an obiview file"); - close(obiview_file_descriptor); - return -1; - } - - // Map the header - header = mmap(NULL, - header_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - 0 - ); - if (header == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping an obiview file header"); - close(obiview_file_descriptor); - return -1; - } - - // Truncate file to the right size to add a new view // TODO lock for multithreading - views_size = get_platform_views_size((header->view_count)+1); - file_size = header_size + views_size; - - if (ftruncate(obiview_file_descriptor, file_size) < 0) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError truncating an obiview file to the right size"); - munmap(header, header_size); - close(obiview_file_descriptor); - return -1; - } - - header->views_size = views_size; - - // Map the views - views = mmap(NULL, - header->views_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - header_size - ); - if (views == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping the views from an obiview file"); - munmap(header, header_size); - close(obiview_file_descriptor); - return -1; - } - - // Write view infos - view_infos = views + (header->view_count); - view_infos->view_number = (header->view_count); - view_infos->column_count = view->column_count; - view_infos->creation_date = time(NULL); - strcpy(view_infos->created_from, view->created_from); - strcpy(view_infos->name, view->name); - strcpy(view_infos->view_type, view->view_type); - strcpy(view_infos->comments, view->comments); - - // Store reference for the line selection associated with that view + // Store reference for the line selection associated with that view if there is one if (view->new_line_selection != NULL) { - view_infos->line_count = ((view->new_line_selection)->header)->lines_used; - current_line_selection = view->new_line_selection; + (view->infos)->line_count = ((view->new_line_selection)->header)->lines_used; + strcpy(((view->infos)->line_selection).column_name, ((view->new_line_selection)->header)->name); + ((view->infos)->line_selection).version = ((view->new_line_selection)->header)->version; + (view->infos)->all_lines = false; } - else + else if (view->line_selection != NULL) // Unnecessary in theory { - view_infos->line_count = view->line_count; - current_line_selection = view->line_selection; + strcpy(((view->infos)->line_selection).column_name, ((view->line_selection)->header)->name); + ((view->infos)->line_selection).version = ((view->line_selection)->header)->version; + (view->infos)->all_lines = false; } - if (current_line_selection != NULL) + else // Necessary because line selection could have been deleted if a column was cloned { - view_infos->all_lines = 0; - strcpy((view_infos->line_selection).column_name, (current_line_selection->header)->name); - (view_infos->line_selection).version = (current_line_selection->header)->version; - } - else - { - view_infos->all_lines = 1; - ((view_infos->line_selection).column_name)[0] = '\0'; - (view_infos->line_selection).version = -1; - } - for (i=0; icolumn_count; i++) - { - strcpy(((view_infos->column_references)+i)->column_name, (((view->columns)[i])->header)->name); - ((view_infos->column_references)+i)->version = (((view->columns)[i])->header)->version; + (((view->infos)->line_selection).column_name)[0] = '\0'; + ((view->infos)->line_selection).version = -1; + (view->infos)->all_lines = true; } - // Increment view count - (header->view_count)++; - - // Unmap and close file - munmap(views, header->views_size); - munmap(header, header_size); - close(obiview_file_descriptor); + update_column_refs(view); return 0; } @@ -1225,15 +1110,48 @@ int obi_save_view(Obiview_p view) int obi_close_view(Obiview_p view) { int i; + int ret_value; - for (i=0; i < (view->column_count); i++) + ret_value = 0; + + for (i=0; i < ((view->infos)->column_count); i++) { - obi_close_column((view->columns)[i]); + if (obi_close_column((view->columns)[i]) < 0) + { + obidebug(1, "\nError closing a column while closing a view"); + ret_value = -1; + } + } + + // Close line selections if they exist + if (view->line_selection != NULL) + { + if (obi_close_column(view->line_selection) < 0) + { + obidebug(1, "\nError closing a line selection while closing a view"); + ret_value = -1; + } + } + + if (view->new_line_selection != NULL) + { + if (obi_close_column(view->new_line_selection) < 0) + { + obidebug(1, "\nError closing a new line selection while closing a view"); + ret_value = -1; + } + } + + // Unmap view file + if (obi_view_unmap_file(view->dms, view->infos) < 0) + { + obidebug(1, "\nError unmaping a view file while closing a view"); + ret_value = -1; } free(view); - return 0; + return ret_value; } @@ -1250,113 +1168,6 @@ int obi_save_and_close_view(Obiview_p view) } -Obiviews_infos_all_p obi_read_view_infos(OBIDMS_p dms) -{ - char* view_file_name; - int obiview_file_descriptor; - size_t header_size; - Obiviews_header_p header; - Obiview_infos_p view_infos; - Obiviews_infos_all_p views; - - view_file_name = build_obiview_file_name(); - if (view_file_name == NULL) - return NULL; - - // Open view file, read header size and map header and views - obiview_file_descriptor = openat(dms->dir_fd, view_file_name, O_RDWR, 0777); - if (obiview_file_descriptor < 0) - { // No views yet - free(view_file_name); - return NULL; - } - - free(view_file_name); - - // Read the header size - if (read(obiview_file_descriptor, &header_size, sizeof(size_t)) < ((ssize_t) sizeof(size_t))) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError reading the header size of an obiview file (trying to open a view when there are none?)"); - close(obiview_file_descriptor); - return NULL; - } - - // Map the header - header = mmap(NULL, - header_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - 0 - ); - if (header == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping an obiview file header"); - close(obiview_file_descriptor); - return NULL; - } - - // Map the views - view_infos = mmap(NULL, - header->views_size, - PROT_READ | PROT_WRITE, - MAP_SHARED, - obiview_file_descriptor, - header_size - ); - if (view_infos == MAP_FAILED) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping the views from an obiview file"); - munmap(header, header_size); - close(obiview_file_descriptor); - return NULL; - } - - views = (Obiviews_infos_all_p) malloc(sizeof(Obiviews_infos_all_t)); - if (views == NULL) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError mmapping the views from an obiview file"); - munmap(view_infos, header->views_size); - munmap(header, header_size); - close(obiview_file_descriptor); - return NULL; - } - - views->header = header; - views->view_infos = view_infos; - - close(obiview_file_descriptor); - - return views; -} - - -int obi_close_view_infos(Obiviews_infos_all_p views) -{ - if (munmap(views->view_infos, (views->header)->views_size) < 0) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError unmapping the views of an obiview file"); - free(views); - return -1; - } - if (munmap(views->header, (views->header)->header_size) < 0) - { - obi_set_errno(OBIVIEW_ERROR); - obidebug(1, "\nError unmapping the header of an obiview file"); - free(views); - return -1; - - } - free(views); - return 0; -} - - /*********** FOR BOOL COLUMNS ***********/ int obi_column_set_obibool_with_elt_idx_in_view(Obiview_p view, OBIDMS_column_p column, index_t line_nb, index_t element_idx, obibool_t value) diff --git a/src/obiview.h b/src/obiview.h index 9da8185..1f018e3 100644 --- a/src/obiview.h +++ b/src/obiview.h @@ -34,8 +34,6 @@ */ #define VIEW_TYPE_MAX_LENGTH (1024) /**< The maximum length of the type name of a view. */ -#define OBIVIEW_FILE_NAME "obiviews" /**< The default name of a view file. - */ #define LINES_COLUMN_NAME "LINES" /**< The name of the column containing the line selections * in all views. */ @@ -56,45 +54,6 @@ */ -/** - * @brief Structure for an opened view. - */ -typedef struct Obiview { - - OBIDMS_p dms; /**< A pointer on the DMS to which the view belongs. - */ - char name[OBIVIEW_NAME_MAX_LENGTH+1]; /**< Name of the view. - */ - char created_from[OBIVIEW_NAME_MAX_LENGTH+1]; /**< Name of the view from which that view was cloned if the view was cloned. - */ - char view_type[VIEW_TYPE_MAX_LENGTH+1]; /**< Type of the view if there is one. - * Types existing: NUC_SEQS_VIEW. - */ - bool read_only; /**< Whether the view is read-only or can be modified. - */ - OBIDMS_column_p line_selection; /**< A pointer on the column containing the line selection - * associated with the view if there is one. - * This line selection is read-only, and when a line from the view is read, - * it is this line selection that is used. - */ - OBIDMS_column_p new_line_selection; /**< A pointer on the column containing the new line selection being built - * to associate with the view, if there is one. - * When a line is selected with obi_select_line() or obi_select_lines(), - * it is recorded in this line selection. - */ - index_t line_count; /**< The number of lines in the view. Refers to the number of lines in each - * column of the view if line_selection is NULL, or to the line count of - * line_selection if it is not NULL. - */ - int column_count; /**< The number of columns in the view. - */ - OBIDMS_column_p columns[MAX_NB_OPENED_COLUMNS]; /**< Array of pointers on all the columns of the view. - */ - char comments[OBIVIEW_COMMENTS_MAX_LENGTH+1]; /**< Comments, additional informations on the view. - */ -} Obiview_t, *Obiview_p; - - /** * @brief Structure referencing a column by its name and its version. */ @@ -112,8 +71,6 @@ typedef struct Column_reference { * Once a view has been written in the view file, it can not be modified and can only be read. */ typedef struct Obiview_infos { - int view_number; /**< Number of the view in the view file. - */ time_t creation_date; /**< Time at which the view was written in the view file. */ char name[OBIVIEW_NAME_MAX_LENGTH+1]; /**< Name of the view, used to identify it. @@ -138,7 +95,29 @@ typedef struct Obiview_infos { } Obiview_infos_t, *Obiview_infos_p; -// TODO : Combine the common elements of the Obiview_infos and Obiview structures in one structure used by both? +/** + * @brief Structure for an opened view. + */ +typedef struct Obiview { + Obiview_infos_p infos; /**< A pointer on the mapped view informations. + */ + OBIDMS_p dms; /**< A pointer on the DMS to which the view belongs. + */ + bool read_only; /**< Whether the view is read-only or can be modified. + */ + OBIDMS_column_p line_selection; /**< A pointer on the column containing the line selection + * associated with the view if there is one. + * This line selection is read-only, and when a line from the view is read, + * it is this line selection that is used. + */ + OBIDMS_column_p new_line_selection; /**< A pointer on the column containing the new line selection being built + * to associate with the view, if there is one. + * When a line is selected with obi_select_line() or obi_select_lines(), + * it is recorded in this line selection. + */ + OBIDMS_column_p columns[MAX_NB_OPENED_COLUMNS]; /**< Array of pointers on all the columns of the view. + */ +} Obiview_t, *Obiview_p; /** @@ -269,6 +248,37 @@ Obiview_p obi_new_view_nuc_seqs(OBIDMS_p dms, const char* view_name, Obiview_p v Obiview_p obi_new_view_nuc_seqs_cloned_from_name(OBIDMS_p dms, const char* view_name, const char* view_to_clone_name, index_t* line_selection, const char* comments); +/** + * @brief Maps a view file and returns the mapped structure stored in it. + * + * @param dms A pointer on the OBIDMS. + * @param view_name The unique name identifying the view. + * + * @returns A pointer on the mapped view infos structure. + * @retval NULL if an error occurred. + * + * @since June 2016 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +Obiview_infos_p obi_view_map_file(OBIDMS_p dms, const char* view_name); + + +/** + * @brief Unmaps a view file. + * + * @param dms A pointer on the OBIDMS. + * @param view_infos A pointer on the mapped view infos structure. + * + * @returns A value indicating the success of the operation. + * @retval 0 if the operation was successfully completed. + * @retval -1 if an error occurred. + * + * @since June 2016 + * @author Celine Mercier (celine.mercier@metabarcoding.org) + */ +int obi_view_unmap_file(OBIDMS_p dms, Obiview_infos_p view_infos); + + /** * @brief Opens a view identified by its name stored in the view file. *