summaryrefslogtreecommitdiffstats
path: root/src/H5Oattribute.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Oattribute.c')
-rw-r--r--src/H5Oattribute.c242
1 files changed, 181 insertions, 61 deletions
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index 2f8a1ea..7aea0df 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -997,7 +997,7 @@ H5O_attr_iterate(hid_t loc_id, const H5O_loc_t *loc, hid_t dxpl_id,
else {
/* Build table of attributes for compact storage */
if(H5A_compact_build_table(loc->file, dxpl_id, oh, idx_type, order, &atable, &oh_flags) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "error building attribute table")
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
/* Release the object header */
if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
@@ -1025,6 +1025,108 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_attr_remove_update
+ *
+ * Purpose: Check for reverting from dense to compact attribute storage
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, February 14, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_attr_remove_update(const H5O_loc_t *loc, H5O_t *oh, unsigned *oh_flags,
+ hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_remove_update)
+
+ /* Check arguments */
+ HDassert(loc);
+ HDassert(oh);
+ HDassert(oh_flags);
+
+ /* Reset the creation order min/max if there's no more attributes on the object */
+ if(oh->nattrs == 0)
+ oh->max_attr_crt_idx = 0;
+
+ /* Check for shifting from dense storage back to compact storage */
+ if(H5F_addr_defined(oh->attr_fheap_addr)) {
+ /* Check if there's no more attributes */
+ if(oh->nattrs == 0) {
+ /* Delete 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")
+ } /* end if */
+ else if(oh->nattrs < oh->min_dense) {
+ H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
+ hbool_t can_convert = TRUE; /* Whether converting to attribute messages is possible */
+ size_t u; /* Local index */
+
+ /* Build the table of attributes for this object */
+ if(H5A_dense_build_table(loc->file, dxpl_id, oh->attr_fheap_addr, oh->name_bt2_addr, H5_INDEX_NAME, H5_ITER_NATIVE, &atable) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
+
+ /* Inspect attributes in table for ones that can't be converted back
+ * into attribute message form (currently only attributes which
+ * can't fit into an object header message)
+ */
+ for(u = 0; u < oh->nattrs; u++)
+ if(H5O_msg_mesg_size(loc->file, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
+ can_convert = FALSE;
+ break;
+ } /* end if */
+
+ /* If ok, insert attributes as object header messages */
+ 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? */
+
+ /* Check if attribute is shared */
+ if((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, &(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 {
+ /* Reset 'shared' status, so attributes will be shared again */
+ atable.attrs[u].sh_loc.flags = 0;
+ } /* end else */
+
+ /* Insert attribute message into object header */
+ /* (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 */
+ if(H5A_attr_release_table(&atable) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table")
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_attr_remove_update() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_attr_remove_cb
*
* Purpose: Object header iterator callback routine to remove an
@@ -1083,7 +1185,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5O_attr_remove
*
- * Purpose: Delete an attributes on an object.
+ * Purpose: Delete an attribute on an object.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1138,80 +1240,98 @@ H5O_attr_remove(const H5O_loc_t *loc, const char *name, hid_t dxpl_id)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute")
} /* end else */
- /* Check for shifting from dense storage back to compact storage */
- if(H5F_addr_defined(oh->attr_fheap_addr) && (oh->nattrs == 0 || oh->nattrs < oh->min_dense)) {
- /* Check if there's no more attributes */
- if(oh->nattrs == 0) {
- /* Delete 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")
- } /* end if */
- else {
- H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
- hbool_t can_convert = TRUE; /* Whether converting to attribute messages is possible */
- size_t u; /* Local index */
+ /* Update the object header information after removing an attribute */
+ if(H5O_attr_remove_update(loc, oh, &oh_flags, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info")
- /* Build the table of attributes for this object */
- if(H5A_dense_build_table(loc->file, dxpl_id, oh->attr_fheap_addr, oh->name_bt2_addr, H5_INDEX_NAME, H5_ITER_NATIVE, &atable) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "error building attribute table")
+done:
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_PROTECT, FAIL, "unable to release object header")
- /* Inspect attributes in table for ones that can't be converted back
- * into attribute message form (currently only attributes which
- * can't fit into an object header message)
- */
- for(u = 0; u < oh->nattrs; u++)
- if(H5O_msg_mesg_size(loc->file, H5O_ATTR_ID, &(atable.attrs[u]), (size_t)0) >= H5O_MESG_MAX_SIZE) {
- can_convert = FALSE;
- break;
- } /* end if */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_attr_remove() */
- /* If ok, insert attributes as object header messages */
- 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? */
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_attr_remove_by_idx
+ *
+ * Purpose: Delete an attribute on an object, according to an order within
+ * an index.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, February 14, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_attr_remove_by_idx(const H5O_loc_t *loc, H5_index_t idx_type,
+ H5_iter_order_t order, hsize_t n, hid_t dxpl_id)
+{
+ H5O_t *oh = NULL; /* Pointer to actual object header */
+ H5A_attr_table_t atable = {0, NULL}; /* Table of attributes */
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for object header */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Check if attribute is shared */
- if((shared_mesg = H5O_msg_is_shared(H5O_ATTR_ID, &(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 {
- /* Reset 'shared' status, so attributes will be shared again */
- atable.attrs[u].sh_loc.flags = 0;
- } /* end else */
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_remove_by_idx)
- /* Insert attribute message into object header */
- /* (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 */
+ /* Check arguments */
+ HDassert(loc);
- /* 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")
+ /* 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")
- /* 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 */
+ /* Check for attributes stored densely */
+ if(H5F_addr_defined(oh->attr_fheap_addr)) {
+ /* Delete attribute from dense storage */
+ if(H5A_dense_remove_by_idx(loc->file, dxpl_id, oh, idx_type, order, n) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute in dense storage")
- /* Free attribute table information */
- if(H5A_attr_release_table(&atable) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table")
- } /* end else */
+ /* Decrement # of attributes on object */
+ oh->nattrs--;
} /* end if */
+ else {
+ H5O_iter_rm_t udata; /* User data for callback */
+ H5O_mesg_operator_t op; /* Wrapper for operator */
+
+ /* Build table of attributes for compact storage */
+ if(H5A_compact_build_table(loc->file, dxpl_id, oh, idx_type, order, &atable, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "error building attribute table")
+
+ /* Check for skipping too many attributes */
+ if(n >= atable.nattrs)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
+
+ /* Set up user data for callback, to remove the attribute by name */
+ udata.f = loc->file;
+ udata.dxpl_id = dxpl_id;
+ udata.name = atable.attrs[n].name;
+ udata.found = FALSE;
+
+ /* Iterate over attributes, to locate correct one to delete */
+ op.lib_op = H5O_attr_remove_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_CANTDELETE, FAIL, "error deleting attribute")
+
+ /* Check that we found the attribute */
+ if(!udata.found)
+ HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "can't locate attribute")
+ } /* end else */
+
+ /* Update the object header information after removing an attribute */
+ if(H5O_attr_remove_update(loc, oh, &oh_flags, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute info")
done:
if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
HDONE_ERROR(H5E_ATTR, H5E_PROTECT, FAIL, "unable to release object header")
+ if(atable.attrs && H5A_attr_release_table(&atable) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to release attribute table")
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_attr_remove */
+} /* end H5O_attr_remove_by_idx() */
/*-------------------------------------------------------------------------