summaryrefslogtreecommitdiffstats
path: root/src/H5Adense.c
diff options
context:
space:
mode:
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() */