summaryrefslogtreecommitdiffstats
path: root/src/H5Oattribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Oattribute.c')
-rw-r--r--src/H5Oattribute.c114
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