diff options
-rw-r--r-- | src/H5A.c | 14 | ||||
-rw-r--r-- | src/H5Adense.c | 98 | ||||
-rw-r--r-- | src/H5Aint.c | 17 | ||||
-rw-r--r-- | src/H5Apkg.h | 5 | ||||
-rw-r--r-- | src/H5Aprivate.h | 3 | ||||
-rw-r--r-- | src/H5Oattr.c | 12 | ||||
-rw-r--r-- | src/H5Oattribute.c | 446 | ||||
-rw-r--r-- | src/H5Omessage.c | 6 | ||||
-rw-r--r-- | src/H5Opkg.h | 2 |
9 files changed, 224 insertions, 379 deletions
@@ -359,12 +359,10 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy path") /* Check if any of the pieces should be (or are already) shared in the - * SOHM table */ - /* Data type */ + * SOHM table + */ if(H5SM_try_share(attr->oloc.file, dxpl_id, H5O_DTYPE_ID, attr->dt) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share datatype failed") - - /* Data space */ if(H5SM_try_share(attr->oloc.file, dxpl_id, H5O_SDSPACE_ID, attr->ds) < 0) HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "trying to share dataspace failed") @@ -1302,9 +1300,11 @@ H5Arename(hid_t loc_id, const char *old_name, const char *new_name) if(H5G_loc(loc_id, & loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - /* Call attribute rename routine */ - if(H5O_attr_rename(loc.oloc, H5AC_dxpl_id, old_name, new_name) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") + /* Avoid thrashing things if the names are the same */ + if(HDstrcmp(old_name, new_name)) + /* Call attribute rename routine */ + if(H5O_attr_rename(loc.oloc, H5AC_dxpl_id, old_name, new_name) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute") done: FUNC_LEAVE_API(ret_value) diff --git a/src/H5Adense.c b/src/H5Adense.c index 7091856..30229f4 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -334,11 +334,12 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Create the "udata" information for v2 B-tree record modify */ @@ -382,8 +383,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags, - const H5A_t *attr) +H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr) { H5A_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */ H5HF_t *fheap = NULL; /* Fractal heap handle for attributes */ @@ -391,6 +391,7 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags, H5O_shared_t sh_mesg; /* Shared object header message */ uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */ void *attr_ptr = NULL; /* Pointer to serialized message */ + unsigned mesg_flags = 0; /* Flags for storing message */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -410,16 +411,33 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, unsigned mesg_flags, /* Get handle for shared message heap, if attributes are sharable */ if(attr_sharable) { haddr_t shared_fheap_addr; /* Address of fractal heap to use */ + htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ + + /* Check if message is already shared */ + if((shared_mesg = H5O_attr_is_shared(attr)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error determining if message is shared") + else if(shared_mesg > 0) + /* Mark the message as shared */ + mesg_flags |= H5O_MSG_FLAG_SHARED; + else { + /* Should this attribute be written as a SOHM? */ + if((shared_mesg = H5SM_try_share(f, dxpl_id, H5O_ATTR_ID, attr)) > 0) + /* Mark the message as shared */ + mesg_flags |= H5O_MSG_FLAG_SHARED; + else if(shared_mesg < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") + } /* end else */ /* Retrieve the address of the shared message's fractal heap */ if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Open the fractal heap */ @@ -525,20 +543,10 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed) /* Check for modifying shared attribute */ if(record->flags & H5O_MSG_FLAG_SHARED) { - H5O_shared_t sh_mesg; /* Shared object header message */ - - /* Extract shared message info from current attribute */ - if(NULL == H5O_attr_get_share(op_data->attr, &sh_mesg)) - HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared info") - /* Update the shared attribute in the SOHM info */ - if(H5O_attr_update_shared(op_data->f, op_data->dxpl_id, op_data->attr, &sh_mesg) < 0) + if(H5O_attr_update_shared(op_data->f, op_data->dxpl_id, op_data->attr, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute in shared storage") - /* Extract new shared message info from updated attribute */ - if(NULL == H5O_attr_get_share(op_data->attr, &sh_mesg)) - HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared info") - /* Update record's heap ID */ record->id = op_data->attr->sh_loc.u.heap_id; @@ -575,7 +583,7 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed) } #endif /* NDEBUG */ /* Update existing attribute in heap */ - /* (would be more efficient as fractal heap 'op' callback, but leave that for later -QAK) */ + /* (might be more efficient as fractal heap 'op' callback, but leave that for later -QAK) */ if(H5HF_write(op_data->fheap, op_data->dxpl_id, &record->id, changed, attr_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute in heap") } /* end else */ @@ -633,11 +641,12 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr) if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Open the fractal heap */ @@ -741,7 +750,6 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_name, H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */ H5A_t *attr_copy = NULL; /* Copy of attribute to rename */ htri_t attr_sharable; /* Flag indicating attributes are sharable */ - unsigned mesg_flags = 0; /* Flags for storing message */ htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ herr_t ret_value = SUCCEED; /* Return value */ @@ -767,11 +775,12 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_name, if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Open the fractal heap */ @@ -795,17 +804,27 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_name, HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to find record in v2 B-tree") HDassert(attr_copy); + /* Check if message is already shared */ + if((shared_mesg = H5O_attr_is_shared(attr_copy)) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error determining if message is shared") + else if(shared_mesg > 0) { + /* Reset shared status of copy */ + /* (so it will get shared again if necessary) */ + attr_copy->sh_loc.flags = 0; + } /* end if */ + /* Change name of attribute */ H5MM_xfree(attr_copy->name); attr_copy->name = H5MM_xstrdup(new_name); - /* Should this attribute be written as a SOHM? */ - /* (allows for attributes that change "shared" status) */ - if((shared_mesg = H5SM_try_share(f, dxpl_id, H5O_ATTR_ID, attr_copy)) > 0) { - hsize_t attr_rc; /* Attribute's ref count in shared message storage */ + /* Insert renamed attribute back into dense storage */ + /* (Possibly making it shared) */ + if(H5A_dense_insert(f, dxpl_id, oh, attr_copy) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to add to dense storage") - /* Mark the message as shared */ - mesg_flags |= H5O_MSG_FLAG_SHARED; + /* Was this attribute shared? */ + if((shared_mesg = H5O_attr_is_shared(attr_copy)) > 0) { + hsize_t attr_rc; /* Attribute's ref count in shared message storage */ /* Retrieve ref count for shared attribute */ if(H5SM_get_refcount(f, dxpl_id, H5O_ATTR_ID, &attr_copy->sh_loc, &attr_rc) < 0) @@ -833,10 +852,6 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_name, else if(shared_mesg < 0) HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") - /* Insert renamed attribute back into dense storage */ - if(H5A_dense_insert(f, dxpl_id, oh, mesg_flags, attr_copy) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to add to dense storage") - /* Delete old attribute from dense storage */ if(H5A_dense_remove(f, dxpl_id, oh, old_name) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute in dense storage") @@ -851,7 +866,7 @@ done: H5O_msg_free(H5O_ATTR_ID, attr_copy); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5A_dense_write() */ +} /* end H5A_dense_rename() */ /*------------------------------------------------------------------------- @@ -997,11 +1012,12 @@ H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id, haddr_t attr_fheap_addr if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Construct the user data for v2 B-tree iterator callback */ @@ -1141,11 +1157,12 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Set up the user data for the v2 B-tree 'record remove' callback */ @@ -1225,11 +1242,12 @@ H5A_dense_exists(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name) if(H5SM_get_fheap_addr(f, dxpl_id, H5O_ATTR_ID, &shared_fheap_addr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared message heap address") - /* Open the fractal heap for shared header messages */ + /* Check if there are any shared messages currently */ if(H5F_addr_defined(shared_fheap_addr)) { + /* Open the fractal heap for shared header messages */ if(NULL == (shared_fheap = H5HF_open(f, dxpl_id, shared_fheap_addr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - } + } /* end if */ } /* end if */ /* Create the "udata" information for v2 B-tree record 'find' */ diff --git a/src/H5Aint.c b/src/H5Aint.c index 456717b..3bfb494 100644 --- a/src/H5Aint.c +++ b/src/H5Aint.c @@ -135,20 +135,9 @@ H5A_compact_build_table_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/, udata->atable->nattrs = n; } /* end if */ - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &udata->atable->attrs[udata->curr_attr])) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to read shared attribute") - } /* end if */ - else { - if(NULL == H5A_copy(&udata->atable->attrs[udata->curr_attr], (const H5A_t *)mesg->native)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute") - } /* end else */ + /* Copy attribute into table */ + if(NULL == H5A_copy(&udata->atable->attrs[udata->curr_attr], (const H5A_t *)mesg->native)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "can't copy attribute") /* Increment current attribute */ udata->curr_attr++; diff --git a/src/H5Apkg.h b/src/H5Apkg.h index 6fa92e8..3194494 100644 --- a/src/H5Apkg.h +++ b/src/H5Apkg.h @@ -161,8 +161,11 @@ H5_DLL herr_t H5A_free(H5A_t *attr); H5_DLL herr_t H5A_close(H5A_t *attr); /* Attribute "dense" storage routines */ +H5_DLL herr_t H5A_dense_create(H5F_t *f, hid_t dxpl_id, H5O_t *oh); H5_DLL H5A_t *H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name); +H5_DLL herr_t H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, + H5A_t *attr); H5_DLL herr_t H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr); H5_DLL herr_t H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, @@ -197,7 +200,7 @@ H5_DLL htri_t H5O_attr_is_shared(const void *_mesg); /* Attribute operations */ H5_DLL herr_t H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, - const H5O_shared_t *sh_mesg); + H5O_shared_t *sh_mesg); /* Testing functions */ #ifdef H5A_TESTING diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h index ca14ebc..88b7f32 100644 --- a/src/H5Aprivate.h +++ b/src/H5Aprivate.h @@ -54,9 +54,6 @@ H5_DLL struct H5O_loc_t *H5A_oloc(H5A_t *attr); H5_DLL H5G_name_t *H5A_nameof(H5A_t *attr); /* Attribute "dense" storage routines */ -H5_DLL herr_t H5A_dense_create(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh); -H5_DLL herr_t H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const struct H5O_t *oh, - unsigned mesg_flags, const H5A_t *attr); H5_DLL herr_t H5A_dense_delete(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh); #endif /* _H5Aprivate_H */ diff --git a/src/H5Oattr.c b/src/H5Oattr.c index b2d2712..2997705 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -65,20 +65,20 @@ const H5O_msg_class_t H5O_MSG_ATTR[1] = {{ H5O_ATTR_ID, /* message id number */ "attribute", /* message name for debugging */ sizeof(H5A_t), /* native message size */ - H5O_attr_decode, /* decode message */ - H5O_attr_encode, /* encode message */ + H5O_attr_shared_decode, /* decode message */ + H5O_attr_shared_encode, /* encode message */ H5O_attr_copy, /* copy the native value */ - H5O_attr_size, /* size of raw message */ + H5O_attr_shared_size, /* size of raw message */ H5O_attr_reset, /* reset method */ H5O_attr_free, /* free method */ - H5O_attr_delete, /* file delete method */ - NULL /* H5O_attr_link */, /* link method */ + H5O_attr_shared_delete, /* file delete method */ + H5O_attr_shared_link, /* link method */ H5O_attr_get_share, /* get share method */ H5O_attr_set_share, /* set share method */ NULL, /*can share method */ H5O_attr_is_shared, /*is shared method */ H5O_attr_pre_copy_file, /* pre copy native value to file */ - H5O_attr_copy_file, /* copy native value to file */ + H5O_attr_shared_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ NULL /* H5O_attr_get_crt_index */, /* get creation index */ NULL /* H5O_attr_set_crt_index */, /* set creation index */ diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index 62e86e0..5d6d1aa 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -161,9 +161,8 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, unsigned UNUSED sequence, unsigned *oh_flags_ptr, void *_udata/*in,out*/) { H5O_iter_cvt_t *udata = (H5O_iter_cvt_t *)_udata; /* Operator user data */ - H5A_t shared_attr; /* Copy of shared attribute */ - H5A_t *attr = NULL; /* Pointer to attribute to insert */ - herr_t ret_value = H5_ITER_CONT; /* Return value */ + H5A_t *attr = (H5A_t *)mesg->native; /* Pointer to attribute to insert */ + herr_t ret_value = H5_ITER_CONT; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_to_dense_cb) @@ -171,20 +170,8 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, HDassert(oh); HDassert(mesg); - /* Check for shared attribute */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - /* Read the shared attribute in */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") - - /* Point attribute to insert at shared attribute read in */ - attr = &shared_attr; - } /* end if */ - else - attr = (H5A_t *)mesg->native; - /* Insert attribute into dense storage */ - if(H5A_dense_insert(udata->f, udata->dxpl_id, oh, mesg->flags, attr) < 0) + if(H5A_dense_insert(udata->f, udata->dxpl_id, oh, attr) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to add to dense storage") /* Convert message into a null message in the header */ @@ -196,10 +183,6 @@ H5O_attr_to_dense_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, *oh_flags_ptr |= H5AC__DIRTIED_FLAG; done: - /* Release copy of shared attribute */ - if(attr == &shared_attr) - H5O_attr_reset(&shared_attr); - FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_to_dense_cb() */ @@ -221,7 +204,6 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) { H5O_t *oh = NULL; /* Pointer to actual object header */ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */ - unsigned mesg_flags = 0; /* Flags for storing message */ htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ herr_t ret_value = SUCCEED; /* Return value */ @@ -231,48 +213,6 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) HDassert(loc); HDassert(attr); - /* Should this message be written as a SOHM? */ - if((shared_mesg = H5SM_try_share(loc->file, dxpl_id, H5O_ATTR_ID, attr)) > 0) { - hsize_t attr_rc; /* Attribute's ref count in shared message storage */ - - /* Mark the message as shared */ - mesg_flags |= H5O_MSG_FLAG_SHARED; - - /* Retrieve ref count for shared attribute */ - if(H5SM_get_refcount(loc->file, dxpl_id, H5O_ATTR_ID, &attr->sh_loc, &attr_rc) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") - - /* If this is not the first copy of the attribute in the shared message - * storage, decrement the reference count on any shared components - * of the attribute. This is done because the shared message - * storage's "try delete" call doesn't call the message class's - * "delete" callback until the reference count drops to zero. - * However, attributes have already increased the reference - * count on shared components before passing the attribute - * to the shared message code to manage, causing an asymmetry - * in the reference counting for any shared components. - * - * The alternate solution is to have the shared message's "try - * delete" code always call the message class's "delete" callback, - * even when the reference count is positive. This can be done - * without an appreciable performance hit (by using H5HF_op() in - * the shared message comparison v2 B-tree callback), but it has - * the undesirable side-effect of leaving the reference count on - * the attribute's shared components artificially (and possibly - * misleadingly) high, because there's only one shared attribute - * referencing the shared components, not <refcount for the - * shared attribute> objects referencing the shared components. - * - * *ick* -QAK, 2007/01/08 - */ - if(attr_rc > 1) { - if(H5O_attr_delete(loc->file, dxpl_id, attr, TRUE) < 0) - HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") - } /* end if */ - } /* end if */ - else if(shared_mesg < 0) - HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") - /* Protect the object header to iterate over */ if(NULL == (oh = (H5O_t *)H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE))) HGOTO_ERROR(H5E_ATTR, H5E_CANTLOAD, FAIL, "unable to load object header") @@ -313,15 +253,54 @@ H5O_attr_create(const H5O_loc_t *loc, hid_t dxpl_id, H5A_t *attr) /* Check for storing attribute with dense storage */ if(H5F_addr_defined(oh->attr_fheap_addr)) { /* Insert attribute into dense storage */ - if(H5A_dense_insert(loc->file, dxpl_id, oh, mesg_flags, attr) < 0) + if(H5A_dense_insert(loc->file, dxpl_id, oh, attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to add to dense storage") } /* end if */ else { /* Append new message to object header */ - if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, mesg_flags, 0, attr, &oh_flags) < 0) + if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, attr, &oh_flags) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to create new attribute in header") } /* end else */ + /* Was new attribugte shared? */ + if((shared_mesg = H5O_attr_is_shared(attr)) > 0) { + hsize_t attr_rc; /* Attribute's ref count in shared message storage */ + + /* Retrieve ref count for shared attribute */ + if(H5SM_get_refcount(loc->file, dxpl_id, H5O_ATTR_ID, &attr->sh_loc, &attr_rc) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") + + /* If this is not the first copy of the attribute in the shared message + * storage, decrement the reference count on any shared components + * of the attribute. This is done because the shared message + * storage's "try delete" call doesn't call the message class's + * "delete" callback until the reference count drops to zero. + * However, attributes have already increased the reference + * count on shared components before passing the attribute + * to the shared message code to manage, causing an asymmetry + * in the reference counting for any shared components. + * + * The alternate solution is to have the shared message's "try + * delete" code always call the message class's "delete" callback, + * even when the reference count is positive. This can be done + * without an appreciable performance hit (by using H5HF_op() in + * the shared message comparison v2 B-tree callback), but it has + * the undesirable side-effect of leaving the reference count on + * the attribute's shared components artificially (and possibly + * misleadingly) high, because there's only one shared attribute + * referencing the shared components, not <refcount for the + * shared attribute> objects referencing the shared components. + * + * *ick* -QAK, 2007/01/08 + */ + if(attr_rc > 1) { + if(H5O_attr_delete(loc->file, dxpl_id, attr, TRUE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } /* end if */ + } /* end if */ + else if(shared_mesg < 0) + HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") + /* Update the modification time, if any */ if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE, &oh_flags) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") @@ -362,39 +341,12 @@ H5O_attr_open_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/, HDassert(mesg); HDassert(!udata->attr); - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - H5A_t shared_attr; /* Copy of shared attribute */ - - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") - - /* Check for correct attribute message to modify */ - if(HDstrcmp(shared_attr.name, udata->name) == 0) { - /* Make a copy of the attribute to return */ - if(NULL == (udata->attr = H5A_copy(NULL, &shared_attr))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy attribute") - } /* end if */ - - /* Release copy of shared attribute */ - H5O_attr_reset(&shared_attr); - } /* end if */ - else { - /* Check for correct attribute message to modify */ - if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) { - /* Make a copy of the attribute to return */ - if(NULL == (udata->attr = H5A_copy(NULL, (H5A_t *)mesg->native))) - HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy attribute") - } /* end if */ - } /* end else */ + /* Check for correct attribute message to modify */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) { + /* Make a copy of the attribute to return */ + if(NULL == (udata->attr = H5A_copy(NULL, (H5A_t *)mesg->native))) + HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, H5_ITER_ERROR, "unable to copy attribute") - /* Set common info, if we found the correct attribute */ - if(udata->attr) { /* Stop iterating */ ret_value = H5_ITER_STOP; } /* end if */ @@ -557,9 +509,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, - const H5O_shared_t *sh_mesg) +H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, + H5O_shared_t *update_sh_mesg) { + H5O_shared_t sh_mesg; /* Shared object header message */ hsize_t attr_rc; /* Attribute's ref count in shared message storage */ htri_t shared_mesg; /* Whether the message should be shared */ herr_t ret_value = SUCCEED; /* Return value */ @@ -569,7 +522,10 @@ H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, /* check args */ HDassert(f); HDassert(attr); - HDassert(sh_mesg); + + /* Extract shared message info from current attribute (for later use) */ + if(NULL == H5O_attr_get_share(attr, &sh_mesg)) + HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared info") /* Store new version of message as a SOHM */ /* (should always work, since we're not changing the size of the attribute) */ @@ -596,9 +552,14 @@ H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, } /* end if */ /* Remove the old attribute from the SOHM storage */ - if(H5SM_try_delete(f, dxpl_id, H5O_ATTR_ID, sh_mesg) < 0) + if(H5SM_try_delete(f, dxpl_id, H5O_ATTR_ID, &sh_mesg) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute in shared storage") + /* Extract updated shared message info from modified attribute, if requested */ + if(update_sh_mesg) + if(NULL == H5O_attr_get_share(attr, update_sh_mesg)) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared info") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_update_shared() */ @@ -632,61 +593,33 @@ H5O_attr_write_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/, HDassert(mesg); HDassert(!udata->found); - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - H5A_t shared_attr; /* Copy of shared attribute */ - - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") - - /* Check for correct attribute message to modify */ - if(HDstrcmp(shared_attr.name, udata->attr->name) == 0) { - /* Update the shared attribute in the SOHM storage */ - if(H5O_attr_update_shared(udata->f, udata->dxpl_id, udata->attr, (const H5O_shared_t *)mesg->native) < 0) + /* Check for correct attribute message to modify */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->attr->name) == 0) { + /* Update the shared attribute in the SOHM storage */ + if(mesg->flags & H5O_MSG_FLAG_SHARED) { + if(H5O_attr_update_shared(udata->f, udata->dxpl_id, udata->attr, (H5O_shared_t *)mesg->native) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, H5_ITER_ERROR, "unable to update attribute in shared storage") - - /* Extract updated shared message info from modified attribute */ - if(NULL == H5O_attr_get_share(udata->attr, (H5O_shared_t *)mesg->native)) - HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, H5_ITER_ERROR, "can't get shared info") - - /* Indicate that we found the correct attribute */ - udata->found = TRUE; } /* end if */ - /* Release copy of shared attribute */ - H5O_attr_reset(&shared_attr); - } /* end if */ - else { - /* Check for correct attribute message to modify */ - if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->attr->name) == 0) { - /* Allocate storage for the message's data, if necessary */ - if(((H5A_t *)mesg->native)->data == NULL) - if(NULL == (((H5A_t *)mesg->native)->data = H5FL_BLK_MALLOC(attr_buf, udata->attr->data_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") - - /* Copy the data */ - HDmemcpy(((H5A_t *)mesg->native)->data, udata->attr->data, udata->attr->data_size); - - /* Indicate that we found the correct attribute */ - udata->found = TRUE; - } /* end if */ - } /* end else */ + /* Allocate storage for the message's data, if necessary */ + if(((H5A_t *)mesg->native)->data == NULL) + if(NULL == (((H5A_t *)mesg->native)->data = H5FL_BLK_MALLOC(attr_buf, udata->attr->data_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed") + + /* Copy the data into the header message */ + HDmemcpy(((H5A_t *)mesg->native)->data, udata->attr->data, udata->attr->data_size); - /* Set common info, if we found the correct attribute */ - if(udata->found) { /* Mark message as dirty */ mesg->dirty = TRUE; - /* Stop iterating */ - ret_value = H5_ITER_STOP; - /* Indicate that the object header was modified */ *oh_flags_ptr |= H5AC__DIRTIED_FLAG; + + /* Indicate that the attribute was found */ + udata->found = TRUE; + + /* Stop iterating */ + ret_value = H5_ITER_STOP; } /* end if */ done: @@ -782,49 +715,22 @@ H5O_attr_rename_chk_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/, H5O_iter_ren_t *udata = (H5O_iter_ren_t *)_udata; /* Operator user data */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_attr_rename_chk_cb) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_rename_chk_cb) /* check args */ HDassert(oh); HDassert(mesg); HDassert(!udata->found); - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - H5A_t shared_attr; /* Copy of shared attribute */ - - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") - - /* Check for existing attribute with new name */ - if(HDstrcmp(shared_attr.name, udata->new_name) == 0) { - /* Indicate that we found an existing attribute with the new name*/ - udata->found = TRUE; - - /* Stop iterating */ - ret_value = H5_ITER_STOP; - } /* end if */ + /* Check for existing attribute with new name */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->new_name) == 0) { + /* Indicate that we found an existing attribute with the new name*/ + udata->found = TRUE; - /* Release copy of shared attribute */ - H5O_attr_reset(&shared_attr); + /* Stop iterating */ + ret_value = H5_ITER_STOP; } /* end if */ - else { - /* Check for existing attribute with new name */ - if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->new_name) == 0) { - /* Indicate that we found an existing attribute with the new name*/ - udata->found = TRUE; - /* Stop iterating */ - ret_value = H5_ITER_STOP; - } /* end if */ - } /* end else */ - -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_rename_chk_cb() */ @@ -862,51 +768,24 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, HDassert(mesg); HDassert(!udata->found); - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - H5A_t shared_attr; /* Copy of shared attribute */ - - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") + /* Find correct attribute message to rename */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->old_name) == 0) { + /* Change the name for the attribute */ + H5MM_xfree(((H5A_t *)mesg->native)->name); + ((H5A_t *)mesg->native)->name = H5MM_xstrdup(udata->new_name); - /* Check for correct attribute message to modify */ - if(HDstrcmp(shared_attr.name, udata->old_name) == 0) { - /* Change the name for the attribute */ - H5MM_xfree(shared_attr.name); - shared_attr.name = H5MM_xstrdup(udata->new_name); - - /* Mark message as dirty */ - mesg->dirty = TRUE; + /* Mark message as dirty */ + mesg->dirty = TRUE; + /* Check for shared message */ + if(mesg->flags & H5O_MSG_FLAG_SHARED) { /* Update the shared attribute in the SOHM storage */ - if(H5O_attr_update_shared(udata->f, udata->dxpl_id, &shared_attr, (const H5O_shared_t *)mesg->native) < 0) + if(H5O_attr_update_shared(udata->f, udata->dxpl_id, mesg->native, NULL) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, H5_ITER_ERROR, "unable to update attribute in shared storage") - - /* Extract updated shared message info from modified attribute */ - if(NULL == H5O_attr_get_share(&shared_attr, (H5O_shared_t *)mesg->native)) - HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, H5_ITER_ERROR, "can't get shared info") - - /* Indicate that we found the correct attribute */ - udata->found = TRUE; } /* end if */ - - /* Release copy of shared attribute */ - H5O_attr_reset(&shared_attr); - } /* end if */ - else { - /* Find correct attribute message to rename */ - if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->old_name) == 0) { - /* Change the name for the attribute */ - H5MM_xfree(((H5A_t *)mesg->native)->name); - ((H5A_t *)mesg->native)->name = H5MM_xstrdup(udata->new_name); - - /* Mark message as dirty */ - mesg->dirty = TRUE; + else { + /* Sanity check */ + HDassert(H5O_attr_is_shared((H5A_t *)mesg->native) == FALSE); /* Check for attribute message changing size */ if(HDstrlen(udata->new_name) != HDstrlen(udata->old_name)) { @@ -947,27 +826,26 @@ H5O_attr_rename_mod_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, oh->nattrs++; /* Append renamed attribute to object header */ - /* (doesn't increment the link count on shared components because - * attributes no longer have a 'link' callback) */ - if(H5O_msg_append_real(udata->f, udata->dxpl_id, oh, H5O_MSG_ATTR, 0, 0, attr, oh_flags_ptr) < 0) + /* (Don't let it become shared) */ + if(H5O_msg_append_real(udata->f, udata->dxpl_id, oh, H5O_MSG_ATTR, (mesg->flags | H5O_MSG_FLAG_DONTSHARE), 0, attr, oh_flags_ptr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, H5_ITER_ERROR, "unable to relocate renamed attribute in header") + /* Sanity check */ + HDassert(H5O_attr_is_shared(attr) == FALSE); + /* Release the local copy of the attribute */ H5O_msg_free_real(H5O_MSG_ATTR, attr); } /* end if */ + } /* end else */ - /* Indicate that we found an existing attribute with the old name */ - udata->found = TRUE; - } /* end if */ - } /* end else */ + /* Indicate that the object header was modified */ + *oh_flags_ptr |= H5AC__DIRTIED_FLAG; + + /* Indicate that we found an existing attribute with the old name */ + udata->found = TRUE; - /* Set common info, if we found the correct attribute */ - if(udata->found) { /* Stop iterating */ ret_value = H5_ITER_STOP; - - /* Indicate that the object header was modified */ - *oh_flags_ptr |= H5AC__DIRTIED_FLAG; } /* end if */ done: @@ -1036,6 +914,10 @@ H5O_attr_rename(const H5O_loc_t *loc, hid_t dxpl_id, const char *old_name, op.lib_op = H5O_attr_rename_mod_cb; if(H5O_msg_iterate_real(loc->file, oh, H5O_MSG_ATTR, TRUE, op, &udata, dxpl_id, &oh_flags) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "error updating attribute") + + /* Check that we found the attribute to rename */ + if(!udata.found) + HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute with old name") } /* end else */ /* Update the modification time, if any */ @@ -1162,35 +1044,8 @@ H5O_attr_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, HDassert(mesg); HDassert(!udata->found); - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - H5A_t shared_attr; /* Copy of shared attribute */ - - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") - - /* Check for correct attribute message to modify */ - if(HDstrcmp(shared_attr.name, udata->name) == 0) - /* Indicate that this message is the attribute to be deleted */ - udata->found = TRUE; - - /* Release copy of shared attribute */ - H5O_attr_reset(&shared_attr); - } /* end if */ - else { - /* Check for correct attribute message to modify */ - if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) - /* Indicate that this message is the attribute to be deleted */ - udata->found = TRUE; - } /* end else */ - - /* Check for finding correct message to delete */ - if(udata->found) { + /* Check for correct attribute message to modify */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) { /* If the later version of the object header format, decrement attribute */ /* (must be decremented before call to H5O_release_mesg(), in order for * sanity checks to pass - QAK) @@ -1202,11 +1057,14 @@ H5O_attr_remove_cb(H5O_t *oh, H5O_mesg_t *mesg/*in,out*/, if(H5O_release_mesg(udata->f, udata->dxpl_id, oh, mesg, TRUE, TRUE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5_ITER_ERROR, "unable to convert into null message") - /* Stop iterating */ - ret_value = H5_ITER_STOP; - /* Indicate that the object header was modified */ *oh_flags_ptr |= H5AC__DIRTIED_FLAG; + + /* Indicate that this message is the attribute to be deleted */ + udata->found = TRUE; + + /* Stop iterating */ + ret_value = H5_ITER_STOP; } /* end if */ done: @@ -1303,30 +1161,35 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) if(can_convert) { /* Iterate over attributes, to put them into header */ for(u = 0; u < oh->nattrs; u++) { - htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ - unsigned mesg_flags = 0; /* Message flags for attribute */ + htri_t shared_mesg; /* Should this message be stored in the Shared Message table? */ - /* Should this message be written as a SOHM? */ - if((shared_mesg = H5SM_try_share(loc->file, dxpl_id, H5O_ATTR_ID, &(atable.attrs[u]))) > 0) - /* Mark the message as shared */ - mesg_flags |= H5O_MSG_FLAG_SHARED; + /* Check if attribute is shared */ + if((shared_mesg = H5O_attr_is_shared(&(atable.attrs[u]))) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "error determining if message is shared") else if(shared_mesg == 0) { /* Increment reference count on attribute components */ /* (so that they aren't deleted when the dense attribute storage is deleted) */ if(H5O_attr_link(loc->file, dxpl_id, &(atable.attrs[u])) < 0) HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count") } /* end if */ - else if(shared_mesg < 0) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") + else { + /* Reset 'shared' status, so attributes will be shared again */ + atable.attrs[u].sh_loc.flags = 0; + } /* end else */ /* Insert attribute message into object header */ - if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, mesg_flags, H5O_UPDATE_TIME, &(atable.attrs[u]), &oh_flags) < 0) + /* (Will increment reference count on shared attributes) */ + if(H5O_msg_append_real(loc->file, dxpl_id, oh, H5O_MSG_ATTR, 0, 0, &(atable.attrs[u]), &oh_flags) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't create message") } /* end for */ /* Remove the dense storage */ if(H5A_dense_delete(loc->file, dxpl_id, oh) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete dense attribute storage") + + /* Update the modification time, if any */ + if(H5O_touch_oh(loc->file, dxpl_id, oh, FALSE, &oh_flags) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update time on object") } /* end if */ /* Free attribute table information */ @@ -1411,46 +1274,21 @@ H5O_attr_exists_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/, H5O_iter_rm_t *udata = (H5O_iter_rm_t *)_udata; /* Operator user data */ herr_t ret_value = H5_ITER_CONT; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_attr_exists_cb) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_exists_cb) /* check args */ HDassert(mesg); HDassert(!udata->found); - /* Check for shared message */ - if(mesg->flags & H5O_MSG_FLAG_SHARED) { - H5A_t shared_attr; /* Copy of shared attribute */ - - /* - * If the message is shared then then the native pointer points to an - * H5O_MSG_SHARED message. We use that information to look up the real - * message in the global heap or some other object header. - */ - if(NULL == H5O_shared_read(udata->f, udata->dxpl_id, (const H5O_shared_t *)mesg->native, H5O_MSG_ATTR, &shared_attr)) - HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, H5_ITER_ERROR, "unable to read shared attribute") - - /* Check for correct attribute message */ - if(HDstrcmp(shared_attr.name, udata->name) == 0) - /* Indicate that this message is the attribute sought */ - udata->found = TRUE; - - /* Release copy of shared attribute */ - H5O_attr_reset(&shared_attr); - } /* end if */ - else { - /* Check for correct attribute message */ - if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) - /* Indicate that this message is the attribute sought */ - udata->found = TRUE; - } /* end else */ + /* Check for correct attribute message */ + if(HDstrcmp(((H5A_t *)mesg->native)->name, udata->name) == 0) { + /* Indicate that this message is the attribute sought */ + udata->found = TRUE; - /* Check for finding correct message to delete */ - if(udata->found) { /* Stop iterating */ ret_value = H5_ITER_STOP; } /* end if */ -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_exists_cb() */ diff --git a/src/H5Omessage.c b/src/H5Omessage.c index 6d4a15c..1c9235e 100644 --- a/src/H5Omessage.c +++ b/src/H5Omessage.c @@ -2086,7 +2086,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *mesg_flags, const H5O_msg_class_t *o /* Check if message is already shared */ if((shared_mesg = H5O_msg_is_shared((*new_type)->id, (*new_mesg))) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, UFAIL, "error determining if message is shared") + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, UFAIL, "error determining if message is shared") else if(shared_mesg > 0) { /* Increment message's reference count */ if((*new_type)->link && ((*new_type)->link)(f, dxpl_id, (*new_mesg)) < 0) @@ -2094,7 +2094,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *mesg_flags, const H5O_msg_class_t *o *mesg_flags |= H5O_MSG_FLAG_SHARED; } /* end if */ else { - /* Check for unsharable message */ + /* Avoid unsharable messages */ if(!(*mesg_flags & H5O_MSG_FLAG_DONTSHARE)) { /* Attempt to share message */ if((shared_mesg = H5SM_try_share(f, dxpl_id, (*new_type)->id, (*new_mesg))) > 0) @@ -2222,7 +2222,7 @@ H5O_msg_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const void *mesg) HDassert(type); /* delete */ - if((type->del) && (type->del)(f, dxpl_id, mesg, 1) < 0) + if((type->del) && (type->del)(f, dxpl_id, mesg, TRUE) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message") done: diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 83065d4..0a0310d 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -160,7 +160,7 @@ /* Temporary macro to define which message classes are using the "new" * shared message "interface" for their methods. */ -#define H5O_NEW_SHARED(T) ((T) == H5O_MSG_PLINE || (T) == H5O_MSG_FILL_NEW || (T) == H5O_MSG_FILL || (T) == H5O_MSG_SDSPACE || (T) == H5O_MSG_DTYPE) +#define H5O_NEW_SHARED(T) ((T) == H5O_MSG_PLINE || (T) == H5O_MSG_FILL_NEW || (T) == H5O_MSG_FILL || (T) == H5O_MSG_SDSPACE || (T) == H5O_MSG_DTYPE || (T) == H5O_MSG_ATTR) /* The "message class" type */ |