diff options
Diffstat (limited to 'src/H5Oattribute.c')
-rw-r--r-- | src/H5Oattribute.c | 114 |
1 files changed, 63 insertions, 51 deletions
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 249437b..701dd05 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -40,6 +40,8 @@ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ #include "H5SMprivate.h" /* Shared Object Header Messages */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Fprivate.h" /* File */ /****************/ @@ -474,6 +476,8 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ H5A_t *ret_value; /* Return value */ + H5A_t *exist_attr = NULL; /* Opened attribute object */ + htri_t found_open_attr = FALSE; /* Whether opened object is found */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_open_by_name) @@ -491,43 +495,40 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) /* Clear error stack from not finding attribute info */ H5E_clear_stack(NULL); - /* Check for opening attribute with dense storage */ - if(H5F_addr_defined(ainfo.fheap_addr)) { - H5A_t *exist_attr = NULL; - htri_t found_open_attr = FALSE; - - /* If found the attribute is already opened, make a copy of it to share the - object information. If not, open attribute in dense storage */ - if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, name)) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") - else if(found_open_attr == TRUE) { - if(NULL == (ret_value = H5A_copy(NULL, exist_attr))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute") - } else if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute") - } /* end if */ - else { - H5O_iter_opn_t udata; /* User data for callback */ - H5O_mesg_operator_t op; /* Wrapper for operator */ - - /* Set up user data for callback */ - udata.name = name; - udata.attr = NULL; - - /* Iterate over attributes, to locate correct one to open */ - op.op_type = H5O_MESG_OP_LIB; - op.u.lib_op = H5O_attr_open_cb; - if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, &op, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "error updating attribute") - - /* Check that we found the attribute */ - if(!udata.attr) - HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute") - - /* Get attribute opened from object header */ - HDassert(udata.attr); - ret_value = udata.attr; - } /* end else */ + /* If found the attribute is already opened, make a copy of it to share the + object information. If not, open attribute as a new object */ + if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, name)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") + else if(found_open_attr == TRUE) { + if(NULL == (ret_value = H5A_copy(NULL, exist_attr))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute") + } else { + if(H5F_addr_defined(ainfo.fheap_addr)) { /* Open attribute with dense storage */ + if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute") + } else { /* Open attribute in compact storage */ + H5O_iter_opn_t udata; /* User data for callback */ + H5O_mesg_operator_t op; /* Wrapper for operator */ + + /* Set up user data for callback */ + udata.name = name; + udata.attr = NULL; + + /* Iterate over attributes, to locate correct one to open */ + op.op_type = H5O_MESG_OP_LIB; + op.u.lib_op = H5O_attr_open_cb; + if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, &op, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "error updating attribute") + + /* Check that we found the attribute */ + if(!udata.attr) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, NULL, "can't locate attribute") + + /* Get attribute opened from object header */ + HDassert(udata.attr); + ret_value = udata.attr; + } /* end else */ + } done: if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0) @@ -595,8 +596,8 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, H5_iter_order_t order, hsize_t n, hid_t dxpl_id) { H5A_attr_iter_op_t attr_op; /* Attribute operator */ - H5A_t *exist_attr = NULL; - htri_t found_open_attr = FALSE; + H5A_t *exist_attr = NULL; /* Opened attribute object */ + htri_t found_open_attr = FALSE; /* Whether opened object is found */ H5A_t *ret_value = NULL; /* Return value */ H5O_t *oh = NULL; /* Object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ @@ -625,10 +626,9 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, /* Clear error stack from not finding attribute info */ H5E_clear_stack(NULL); - /* If the opened attribute is in dense storage, find out whether it has already been - * opened. If it has, close the object and make a copy of the already opened object - * to share the object info. */ - if(H5F_addr_defined(ainfo.fheap_addr) && ret_value) { + /* Find out whether it has already been opened. If it has, close the object + * and make a copy of the already opened object to share the object info. */ + if(ret_value) { if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, ret_value->shared->name)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") @@ -673,14 +673,18 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* { htri_t ret_value = FALSE; int num_open_attr = 0; - ssize_t name_len = 0; hid_t *attr_id_list = NULL; + unsigned long loc_fnum, attr_fnum; int i; FUNC_ENTER_NOAPI_NOINIT(H5O_attr_find_opened_attr) + /* Get file serial number for the location of attribute */ + if(H5F_get_fileno(loc->file, &loc_fnum) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number") + /* Count all opened attributes */ - if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR)) < 0) + if((num_open_attr = H5F_get_obj_count(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "can't get number of opened attributes") /* Find out whether the attribute has been opened */ @@ -688,16 +692,23 @@ htri_t H5O_attr_find_opened_attr(const H5O_loc_t *loc, H5A_t **attr, const char* attr_id_list = (hid_t*)H5MM_malloc(num_open_attr*sizeof(hid_t)); /* Retrieve the IDs of all opened attributes */ - if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR, num_open_attr, attr_id_list) < 0) + if(H5F_get_obj_ids(loc->file, H5F_OBJ_ATTR | H5F_OBJ_LOCAL, num_open_attr, attr_id_list) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't IDs of opened attributes") for(i=0; i<num_open_attr; i++) { - if(NULL == (*attr = (H5A_t *)H5I_object_verify(attr_id_list[i], H5I_ATTR))) + if(NULL == (*attr = (H5A_t *)H5I_object(attr_id_list[i]))) HGOTO_ERROR(H5E_ATTR, H5E_BADTYPE, FAIL, "not an attribute") - /* Verify whether it's the right object */ - if(!strcmp(name_to_open, (*attr)->shared->name) && loc->addr == - (*attr)->shared->oloc.addr) { + /* Get file serial number for attribute */ + if(H5F_get_fileno((*attr)->shared->oloc.file, &attr_fnum) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "can't get file serial number") + + /* Verify whether it's the right object. The attribute name, object address + * to which the attribute is attached, and file serial number should all + * match. */ + if(!strcmp(name_to_open, (*attr)->shared->name) && + loc->addr == (*attr)->shared->oloc.addr && + loc_fnum == attr_fnum) { ret_value = TRUE; break; } @@ -1304,7 +1315,8 @@ done: * the attribute is already opened, use the opened message * to insert. If not, still use the message in the attribute * table. This will guarantee that the attribute message is - * shared. + * shared between the object in metadata cache and the opened + * object. *------------------------------------------------------------------------- */ static herr_t |