diff options
Diffstat (limited to 'src/H5Adense.c')
-rw-r--r-- | src/H5Adense.c | 140 |
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() */ |