summaryrefslogtreecommitdiffstats
path: root/src/H5Adense.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-01-06 20:54:19 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-01-06 20:54:19 (GMT)
commit327ea3a76678ed2f92b0eb72df36c1d02651c2be (patch)
tree14b77bf71608596fc45fea60445e7d4c1559a247 /src/H5Adense.c
parentd6c27d4b4d82d794e860770f5903e84511596d19 (diff)
downloadhdf5-327ea3a76678ed2f92b0eb72df36c1d02651c2be.zip
hdf5-327ea3a76678ed2f92b0eb72df36c1d02651c2be.tar.gz
hdf5-327ea3a76678ed2f92b0eb72df36c1d02651c2be.tar.bz2
[svn-r13116] Description:
Add support for deleting all the attributes on an object, when they are dense and possibly shared. Also, add some testing routines, for better error detection. Should fix daily test failures also... Tested on: FreeBSD/32 6.1 (duty)
Diffstat (limited to 'src/H5Adense.c')
-rw-r--r--src/H5Adense.c140
1 files changed, 119 insertions, 21 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 9d9746a..6c0a907 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -38,6 +38,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Apkg.h" /* Attributes */
#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared object header messages */
@@ -123,16 +124,6 @@ typedef struct {
H5A_t *attr; /* Copy of attribute */
} H5A_fh_ud_cp_t;
-/*
- * Data exchange structure to pass through the fractal heap layer for the
- * H5HF_op function when removing an attribute from densely stored attributes.
- */
-typedef struct {
- /* downward */
- H5F_t *f; /* Pointer to file that fractal heap is in */
- hid_t dxpl_id; /* DXPL for operation */
-} H5A_fh_ud_rm_t;
-
/********************/
/* Package Typedefs */
@@ -1055,14 +1046,8 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_bt2_udata)
/* Check for inserting shared attribute */
if(record->flags & H5O_MSG_FLAG_SHARED) {
- H5O_shared_t sh_mesg; /* Shared object header message */
-
- /* Get the shared information for the attribute */
- if(NULL == H5O_attr_get_share(*(H5A_t **)bt2_udata->found_op_data, &sh_mesg))
- HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared message")
-
/* Decrement the reference count on the shared attribute message */
- if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &sh_mesg) < 0)
+ if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &((*(H5A_t **)bt2_udata->found_op_data)->sh_loc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute")
} /* end if */
else {
@@ -1159,7 +1144,6 @@ done:
if(attr_copy)
H5O_msg_free_real(H5O_MSG_ATTR, attr_copy);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_remove() */
@@ -1249,6 +1233,70 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5A_dense_delete_bt2_cb
+ *
+ * Purpose: v2 B-tree callback for dense attribute storage deletion
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 3 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5A_dense_delete_bt2_cb(const void *_record, void *_bt2_udata)
+{
+ const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
+ H5A_bt2_ud_common_t *bt2_udata = (H5A_bt2_ud_common_t *)_bt2_udata; /* User data for callback */
+ H5HF_t *fheap; /* Fractal heap handle for attribute storage */
+ H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_delete_bt2_cb)
+
+ /* Check for shared attribute */
+ if(record->flags & H5O_MSG_FLAG_SHARED)
+ fheap = bt2_udata->shared_fheap;
+ else
+ fheap = bt2_udata->fheap;
+
+ /* Prepare user data for callback */
+ /* down */
+ fh_udata.f = bt2_udata->f;
+ fh_udata.dxpl_id = bt2_udata->dxpl_id;
+ fh_udata.record = record;
+ /* up */
+ fh_udata.attr = NULL;
+
+ /* Call fractal heap 'op' routine, to copy the attribute information */
+ if(H5HF_op(fheap, bt2_udata->dxpl_id, record->id, H5A_dense_copy_fh_cb, &fh_udata) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "heap op callback failed")
+
+ /* Check for shared attribute */
+ if(record->flags & H5O_MSG_FLAG_SHARED) {
+ /* Decrement the reference count on the shared attribute message */
+ if(H5SM_try_delete(bt2_udata->f, bt2_udata->dxpl_id, H5O_ATTR_ID, &(fh_udata.attr->sh_loc)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute")
+ } /* end if */
+ else {
+ /* Perform the deletion action on the attribute */
+ /* (takes care of shared & committed datatype/dataspace components) */
+ if(H5O_attr_delete(bt2_udata->f, bt2_udata->dxpl_id, fh_udata.attr, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
+ } /* end else */
+
+done:
+ /* Release resources */
+ if(fh_udata.attr)
+ H5O_msg_free_real(H5O_MSG_ATTR, fh_udata.attr);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_delete_bt2_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5A_dense_delete
*
* Purpose: Delete all dense storage structures for attributes on an object
@@ -1264,6 +1312,10 @@ done:
herr_t
H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
{
+ H5A_bt2_ud_common_t udata; /* v2 B-tree user data for deleting attributes */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
+ H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_dense_delete, FAIL)
@@ -1274,20 +1326,66 @@ H5A_dense_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
HDassert(f);
HDassert(oh);
-/* XXX: iterate through name index v2 B-tree and delete shared attributes */
-/* XXX: we need to delete shared & unshared attributes that use shared & committed components also */
+ /* Open the fractal heap */
+ if(NULL == (fheap = H5HF_open(f, dxpl_id, oh->attr_fheap_addr)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
+
+ /* Check if attributes are shared in this file */
+ if((attr_sharable = H5SM_type_shared(f, H5O_ATTR_ID, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't determine if attributes are shared")
+
+ /* Get handle for shared object heap, if attributes are sharable */
+ if(attr_sharable) {
+ haddr_t shared_fheap_addr; /* Address of fractal heap to use */
+
+ /* Retrieve the address of the shared object's fractal heap */
+ if(HADDR_UNDEF == (shared_fheap_addr = H5SM_get_fheap_addr(f, H5O_ATTR_ID, dxpl_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get shared object heap address")
+
+ /* 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 */
+
+ /* Create the "udata" information for v2 B-tree 'delete' */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.fheap = fheap;
+ udata.shared_fheap = shared_fheap;
+ udata.name = NULL;
+ udata.name_hash = 0;
+ udata.flags = 0;
+ udata.corder = -1; /* XXX: None yet */
+ udata.found_op = NULL; /* v2 B-tree comparison callback */
+ udata.found_op_data = NULL;
/* Delete name index v2 B-tree */
- if(H5B2_delete(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, NULL, NULL) < 0)
+ if(H5B2_delete(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, H5A_dense_delete_bt2_cb, &udata) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree for name index")
oh->name_bt2_addr = HADDR_UNDEF;
+ /* Release resources */
+ if(shared_fheap) {
+ if(H5HF_close(shared_fheap, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ shared_fheap = NULL;
+ } /* end if */
+ if(H5HF_close(fheap, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ fheap = NULL;
+
/* Delete fractal heap */
if(H5HF_delete(f, dxpl_id, oh->attr_fheap_addr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete fractal heap")
oh->attr_fheap_addr = HADDR_UNDEF;
done:
+ /* Release resources */
+ if(shared_fheap && H5HF_close(shared_fheap, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+ if(fheap && H5HF_close(fheap, dxpl_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_delete() */