summaryrefslogtreecommitdiffstats
path: root/src/H5Adense.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-01-03 19:34:15 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-01-03 19:34:15 (GMT)
commita15089ee73ddf92468de1af48babd7f55d9e5b16 (patch)
tree6713410a91c677dcadc0bb1a5a474aa594baa36a /src/H5Adense.c
parent91fe7912391201929f2b267f2454357d10b97b0b (diff)
downloadhdf5-a15089ee73ddf92468de1af48babd7f55d9e5b16.zip
hdf5-a15089ee73ddf92468de1af48babd7f55d9e5b16.tar.gz
hdf5-a15089ee73ddf92468de1af48babd7f55d9e5b16.tar.bz2
[svn-r13104] Description:
Add support for renaming compact & dense/shared & non-shared attributes in all cases. Tested on: Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2)
Diffstat (limited to 'src/H5Adense.c')
-rw-r--r--src/H5Adense.c208
1 files changed, 131 insertions, 77 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c
index f47f9c0..9d9746a 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -75,7 +75,7 @@
/*
* Data exchange structure for dense attribute storage. This structure is
- * passed through the v2 B-tree layer when modifying attributes.
+ * passed through the v2 B-tree layer when modifying the attribute data value.
*/
typedef struct H5A_bt2_od_wrt_t {
/* downward */
@@ -117,6 +117,7 @@ typedef struct {
/* downward (internal) */
H5F_t *f; /* Pointer to file that fractal heap is in */
hid_t dxpl_id; /* DXPL for operation */
+ const H5A_dense_bt2_name_rec_t *record; /* v2 B-tree record for attribute */
/* upward */
H5A_t *attr; /* Copy of attribute */
@@ -264,7 +265,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5A_dense_open_cb
+ * Function: H5A_dense_fnd_cb
*
* Purpose: Callback when an attribute is located in an index
*
@@ -277,13 +278,13 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_open_cb(const void *_attr, void *_user_attr)
+H5A_dense_fnd_cb(const void *_attr, void *_user_attr)
{
const H5A_t *attr = (const H5A_t *)_attr; /* Record from B-tree */
H5A_t **user_attr = (H5A_t **)_user_attr; /* User data from v2 B-tree attribute lookup */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5A_dense_open_cb)
+ FUNC_ENTER_NOAPI_NOINIT(H5A_dense_fnd_cb)
/*
* Check arguments.
@@ -297,7 +298,7 @@ H5A_dense_open_cb(const void *_attr, void *_user_attr)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A_dense_open_cb() */
+} /* end H5A_dense_fnd_cb() */
/*-------------------------------------------------------------------------
@@ -361,7 +362,7 @@ H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
udata.flags = 0;
udata.corder = -1; /* XXX: None yet */
- udata.found_op = H5A_dense_open_cb; /* v2 B-tree comparison callback */
+ udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */
udata.found_op_data = &ret_value;
/* Find & copy the attribute in the 'name' index */
@@ -720,12 +721,123 @@ H5A_dense_copy_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
if(NULL == (udata->attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, FAIL, "can't decode attribute")
+ /* Check whether we should "reconstitute" the shared message info */
+ if(udata->record->flags & H5O_MSG_FLAG_SHARED)
+ H5SM_reconstitute(&(udata->attr->sh_loc), udata->record->id);
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_copy_fh_cb() */
/*-------------------------------------------------------------------------
+ * Function: H5A_dense_rename
+ *
+ * Purpose: Rename an attribute in dense storage structures for an object
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 3 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_name,
+ const char *new_name)
+{
+ H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
+ H5HF_t *fheap = NULL; /* Fractal heap handle */
+ 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 */
+
+ FUNC_ENTER_NOAPI(H5A_dense_rename, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(oh);
+ HDassert(old_name);
+ HDassert(new_name);
+
+ /* 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 */
+
+ /* 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")
+
+ /* Create the "udata" information for v2 B-tree record modify */
+ udata.f = f;
+ udata.dxpl_id = dxpl_id;
+ udata.fheap = fheap;
+ udata.shared_fheap = shared_fheap;
+ udata.name = old_name;
+ udata.name_hash = H5_checksum_lookup3(old_name, HDstrlen(old_name), 0);
+ udata.flags = 0;
+ udata.corder = -1; /* XXX: None yet */
+ udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */
+ udata.found_op_data = &attr_copy;
+
+ /* Get copy of attribute through 'name' tracking v2 B-tree */
+ if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to find record in v2 B-tree")
+ HDassert(attr_copy);
+
+ /* 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)
+ /* 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")
+
+ /* 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")
+
+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")
+ if(attr_copy)
+ H5O_msg_free(H5O_ATTR_ID, attr_copy);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_dense_write() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5A_dense_iterate_bt2_cb
*
* Purpose: v2 B-tree callback for dense attribute storage iterator
@@ -764,16 +876,14 @@ H5A_dense_iterate_bt2_cb(const void *_record, void *_bt2_udata)
/* down */
fh_udata.f = bt2_udata->f;
fh_udata.dxpl_id = bt2_udata->dxpl_id;
+ fh_udata.record = record;
+ 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, H5_ITER_ERROR, "heap op callback failed")
- /* Check whether we should "reconstitute" the shared message info */
- if(record->flags & H5O_MSG_FLAG_SHARED)
- H5SM_reconstitute(&(fh_udata.attr->sh_loc), record->id);
-
/* Check which type of callback to make */
switch(bt2_udata->attr_op->op_type) {
case H5A_ATTR_OP_APP:
@@ -922,46 +1032,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5A_dense_remove_fh_cb
- *
- * Purpose: Callback for fractal heap operator when removing attributes
- *
- * Return: SUCCEED/FAIL
- *
- * Programmer: Quincey Koziol
- * koziol@hdfgroup.org
- * Dec 11 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5A_dense_remove_fh_cb(const void *obj, size_t UNUSED obj_len, void *_udata)
-{
- H5A_fh_ud_rm_t *udata = (H5A_fh_ud_rm_t *)_udata; /* User data for fractal heap 'op' callback */
- H5A_t *attr = NULL; /* Pointer to attribute created from heap object */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5A_dense_remove_fh_cb)
-
- /* Decode attribute */
- if(NULL == (attr = (H5A_t *)H5O_msg_decode(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const unsigned char *)obj)))
- HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, FAIL, "can't decode attribute")
-
- /* Perform the deletion action on the attribute */
- /* (takes care of shared & committed datatype/dataspace components) */
- if(H5O_attr_delete(udata->f, udata->dxpl_id, attr, TRUE) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
-
-done:
- /* Release the space allocated for the message */
- if(attr)
- H5O_msg_free_real(H5O_MSG_ATTR, attr);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5A_dense_remove_fh_cb() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5A_dense_remove_bt2_cb
*
* Purpose: v2 B-tree callback for dense attribute storage record removal
@@ -985,41 +1055,21 @@ H5A_dense_remove_bt2_cb(const void *_record, void *_bt2_udata)
/* Check for inserting shared attribute */
if(record->flags & H5O_MSG_FLAG_SHARED) {
- H5A_fh_ud_cp_t fh_udata; /* User data for fractal heap 'op' callback */
H5O_shared_t sh_mesg; /* Shared object header message */
- /* Set up the user data for fractal heap 'op' callback */
- fh_udata.f = bt2_udata->f;
- fh_udata.dxpl_id = bt2_udata->dxpl_id;
- fh_udata.attr = NULL;
-
- /* Call fractal heap 'op' routine, to get copy of the attribute */
- if(H5HF_op(bt2_udata->shared_fheap, bt2_udata->dxpl_id, record->id,
- H5A_dense_copy_fh_cb, &fh_udata) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "attribute removal callback failed")
-
/* Get the shared information for the attribute */
- if(NULL == H5O_attr_get_share(fh_udata.attr, &sh_mesg))
+ 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)
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute")
-
- /* Release the space allocated for the attribute */
- H5O_msg_free(H5O_ATTR_ID, fh_udata.attr);
} /* end if */
else {
- H5A_fh_ud_rm_t fh_udata; /* User data for fractal heap 'op' callback */
-
- /* Set up the user data for fractal heap 'op' callback */
- fh_udata.f = bt2_udata->f;
- fh_udata.dxpl_id = bt2_udata->dxpl_id;
-
- /* Call fractal heap 'op' routine, to perform user callback */
- if(H5HF_op(bt2_udata->fheap, bt2_udata->dxpl_id, record->id,
- H5A_dense_remove_fh_cb, &fh_udata) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTOPERATE, FAIL, "attribute removal callback failed")
+ /* 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, *(H5A_t **)bt2_udata->found_op_data, TRUE) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute")
/* Remove record from fractal heap */
if(H5HF_remove(bt2_udata->fheap, bt2_udata->dxpl_id, record->id) < 0)
@@ -1050,6 +1100,7 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree record removal */
H5HF_t *fheap = NULL; /* Fractal heap handle */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
+ H5A_t *attr_copy = NULL; /* Copy of attribute to remove */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1092,8 +1143,8 @@ H5A_dense_remove(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *name)
udata.name_hash = H5_checksum_lookup3(name, HDstrlen(name), 0);
udata.flags = 0;
udata.corder = -1; /* XXX: None yet */
- udata.found_op = NULL;
- udata.found_op_data = NULL;
+ udata.found_op = H5A_dense_fnd_cb; /* v2 B-tree comparison callback */
+ udata.found_op_data = &attr_copy;
/* Remove the record from the name index v2 B-tree */
if(H5B2_remove(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, H5A_dense_remove_bt2_cb, &udata) < 0)
@@ -1105,6 +1156,9 @@ done:
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")
+ if(attr_copy)
+ H5O_msg_free_real(H5O_MSG_ATTR, attr_copy);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_remove() */