summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5Adense.c110
-rw-r--r--src/H5Apkg.h9
-rw-r--r--src/H5Oattr.c19
-rw-r--r--src/H5Oattribute.c83
-rw-r--r--src/H5Omessage.c2
-rw-r--r--src/H5Opkg.h1
-rwxr-xr-xsrc/H5SM.c12
7 files changed, 144 insertions, 92 deletions
diff --git a/src/H5Adense.c b/src/H5Adense.c
index 458381b..f47f9c0 100644
--- a/src/H5Adense.c
+++ b/src/H5Adense.c
@@ -79,11 +79,11 @@
*/
typedef struct H5A_bt2_od_wrt_t {
/* downward */
+ H5F_t *f; /* Pointer to file that fractal heap is in */
+ hid_t dxpl_id; /* DXPL for operation */
H5HF_t *fheap; /* Fractal heap handle to operate on */
H5HF_t *shared_fheap; /* Fractal heap handle for shared messages */
- hid_t dxpl_id; /* DXPL for operation */
- void *attr_buf; /* Pointer to encoded attribute to store */
- size_t attr_size; /* Size of encode attribute */
+ H5A_t *attr; /* Attribute to write */
} H5A_bt2_od_wrt_t;
/*
@@ -508,7 +508,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5A_dense_write_bt2_cb
*
- * Purpose: v2 B-tree 'find' callback to update the data for an attribute
+ * Purpose: v2 B-tree 'modify' callback to update the data for an attribute
*
* Return: Success: 0
* Failure: 1
@@ -519,12 +519,12 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_dense_write_bt2_cb(const void *_record, void *_op_data)
+H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
{
- const H5A_dense_bt2_name_rec_t *record = (const H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
+ H5A_dense_bt2_name_rec_t *record = (H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
H5A_bt2_od_wrt_t *op_data = (H5A_bt2_od_wrt_t *)_op_data; /* "op data" from v2 B-tree modify */
- H5HF_t *fheap; /* Fractal heap handle for attribute storage */
- hbool_t id_changed = FALSE; /* Whether the heap ID changed */
+ uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
+ void *attr_ptr = NULL; /* Pointer to serialized attribute */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_write_bt2_cb)
@@ -536,28 +536,67 @@ H5A_dense_write_bt2_cb(const void *_record, void *_op_data)
HDassert(op_data);
/* Check for modifying shared attribute */
- if(record->flags & H5O_MSG_FLAG_SHARED)
- fheap = op_data->shared_fheap;
- else
- fheap = op_data->fheap;
+ if(record->flags & H5O_MSG_FLAG_SHARED) {
+ H5O_shared_t sh_mesg; /* Shared object header message */
+
+ /* Extract shared message info from current attribute */
+ if(NULL == H5O_attr_get_share(op_data->attr, &sh_mesg))
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared info")
+
+ /* Update the shared attribute in the SOHM info */
+ if(H5O_attr_update_shared(op_data->f, op_data->dxpl_id, op_data->attr, &sh_mesg) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute in shared storage")
+
+ /* Extract new shared message info from updated attribute */
+ if(NULL == H5O_attr_get_share(op_data->attr, &sh_mesg))
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared info")
+
+ /* Update record's heap ID */
+ HDmemcpy(record->id, &op_data->attr->sh_loc.u.heap_id, sizeof(record->id));
+
+ /* Note that the record changed */
+ *changed = TRUE;
+ } /* end if */
+ else {
+ size_t attr_size; /* Size of serialized attribute in the heap */
+
+ /* Find out the size of buffer needed for serialized attribute */
+ if((attr_size = H5O_msg_raw_size(op_data->f, H5O_ATTR_ID, op_data->attr)) == 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get attribute size")
+
+ /* Allocate space for serialized attribute, if necessary */
+ if(attr_size > sizeof(attr_buf)) {
+ if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
+ HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+ else
+ attr_ptr = attr_buf;
+
+ /* Create serialized form of attribute */
+ if(H5O_msg_encode(op_data->f, H5O_ATTR_ID, (unsigned char *)attr_ptr, op_data->attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute")
/* Sanity check */
#ifndef NDEBUG
{
size_t obj_len; /* Length of existing encoded attribute */
- if(H5HF_get_obj_len(fheap, op_data->dxpl_id, record->id, &obj_len) < 0)
+ if(H5HF_get_obj_len(op_data->fheap, op_data->dxpl_id, record->id, &obj_len) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get object size")
- HDassert(obj_len == op_data->attr_size);
+ HDassert(obj_len == attr_size);
}
#endif /* NDEBUG */
- /* Update existing attribute in heap */
- /* (would be more efficient as fractal heap 'op' callback, but leave that for later -QAK) */
- /* (Casting away const OK - QAK) */
- if(H5HF_write(fheap, op_data->dxpl_id, (void *)record->id, &id_changed, op_data->attr_buf) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute in heap")
+ /* Update existing attribute in heap */
+ /* (would be more efficient as fractal heap 'op' callback, but leave that for later -QAK) */
+ if(H5HF_write(op_data->fheap, op_data->dxpl_id, record->id, changed, attr_ptr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, FAIL, "unable to update attribute in heap")
+ } /* end else */
done:
+ /* Release resources */
+ if(attr_ptr && attr_ptr != attr_buf)
+ (void)H5FL_BLK_FREE(ser_attr, attr_ptr);
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_write_bt2_cb() */
@@ -576,15 +615,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
+H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, H5A_t *attr)
{
H5A_bt2_ud_common_t udata; /* User data for v2 B-tree modify */
H5A_bt2_od_wrt_t op_data; /* "Op 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 */
- size_t attr_size; /* Size of serialized attribute in the heap */
- uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
- void *attr_ptr = NULL; /* Pointer to serialized attribute */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -614,22 +650,6 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap")
} /* end if */
- /* Find out the size of buffer needed for serialized attribute */
- if((attr_size = H5O_msg_raw_size(f, H5O_ATTR_ID, attr)) == 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get attribute size")
-
- /* Allocate space for serialized attribute, if necessary */
- if(attr_size > sizeof(attr_buf)) {
- if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
- HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
- } /* end if */
- else
- attr_ptr = attr_buf;
-
- /* Create serialized form of attribute */
- if(H5O_msg_encode(f, H5O_ATTR_ID, (unsigned char *)attr_ptr, attr) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute")
-
/* 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")
@@ -646,15 +666,15 @@ H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const H5A_t *attr)
udata.found_op = NULL;
udata.found_op_data = NULL;
- /* Create the "op_data" for the v2 B-tree record 'find' callback */
+ /* Create the "op_data" for the v2 B-tree record 'modify' callback */
+ op_data.f = f;
+ op_data.dxpl_id = dxpl_id;
op_data.fheap = fheap;
op_data.shared_fheap = shared_fheap;
- op_data.dxpl_id = dxpl_id;
- op_data.attr_buf = attr_ptr;
- op_data.attr_size = attr_size;
+ op_data.attr = attr;
/* Modify attribute through 'name' tracking v2 B-tree */
- if(H5B2_find(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, H5A_dense_write_bt2_cb, &op_data) < 0)
+ if(H5B2_modify(f, dxpl_id, H5A_BT2_NAME, oh->name_bt2_addr, &udata, H5A_dense_write_bt2_cb, &op_data) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree")
done:
@@ -663,8 +683,6 @@ 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_ptr && attr_ptr != attr_buf)
- (void)H5FL_BLK_FREE(ser_attr, attr_ptr);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_write() */
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 6b618c8..8aa73fb 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -165,7 +165,7 @@ H5_DLL herr_t H5A_close(H5A_t *attr);
H5_DLL H5A_t *H5A_dense_open(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
const char *name);
H5_DLL herr_t H5A_dense_write(H5F_t *f, hid_t dxpl_id, const H5O_t *oh,
- const H5A_t *attr);
+ H5A_t *attr);
H5_DLL herr_t H5A_dense_iterate(H5F_t *f, hid_t dxpl_id, hid_t loc_id,
haddr_t attr_fheap_addr, haddr_t name_bt2_addr, H5_iter_order_t order,
unsigned skip, unsigned *last_attr, const H5A_attr_iter_op_t *attr_op,
@@ -190,8 +190,13 @@ H5_DLL herr_t H5A_attr_release_table(H5A_attr_table_t *atable);
/* Attribute object header routines */
H5_DLL herr_t H5O_attr_reset(void *_mesg);
H5_DLL herr_t H5O_attr_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
-H5_DLL htri_t H5O_attr_is_shared(const void *_mesg);
+H5_DLL herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
H5_DLL void *H5O_attr_get_share(const void *_mesg, H5O_shared_t *sh);
+H5_DLL htri_t H5O_attr_is_shared(const void *_mesg);
+
+/* Attribute operations */
+H5_DLL herr_t H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr,
+ const H5O_shared_t *sh_mesg);
/* Testing functions */
#ifdef H5A_TESTING
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 619dcac..acfc720 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -33,7 +33,6 @@ static void *H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static void *H5O_attr_copy(const void *_mesg, void *_dest);
static size_t H5O_attr_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_attr_free(void *mesg);
-static herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
static herr_t H5O_attr_pre_copy_file(H5F_t *file_src, const H5O_msg_class_t *type,
const void *mesg_src, hbool_t *deleted, const H5O_copy_t *cpy_info, void *udata);
static void *H5O_attr_copy_file(H5F_t *file_src, const H5O_msg_class_t *mesg_type,
@@ -706,12 +705,10 @@ done:
* Programmer: Quincey Koziol
* Friday, September 26, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-static herr_t
-H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg)
+herr_t
+H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg)
{
const H5A_t *attr = (const H5A_t *) _mesg;
herr_t ret_value = SUCCEED; /* Return value */
@@ -722,10 +719,20 @@ H5O_attr_link(H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg)
HDassert(f);
HDassert(attr);
+ /* Re-share attribute's datatype and dataspace to increment their
+ * reference count if they're shared.
+ * Otherwise they may be deleted when the attribute
+ * message is deleted.
+ */
+ if(H5SM_try_share(f, dxpl_id, H5O_DTYPE_ID, attr->dt) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "error trying to re-share attribute datatype")
+ if(H5SM_try_share(f, dxpl_id, H5O_SDSPACE_ID, attr->ds) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "error trying to re-share attribute dataspace")
+
/* Check whether datatype is shared */
if(H5T_committed(attr->dt)) {
/* Increment the reference count on the shared datatype */
- if(H5T_link(attr->dt,1,dxpl_id) < 0)
+ if(H5T_link(attr->dt, 1, dxpl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
} /* end if */
diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c
index ce7a8e5..63a35e5 100644
--- a/src/H5Oattribute.c
+++ b/src/H5Oattribute.c
@@ -519,6 +519,56 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_attr_update_shared
+ *
+ * Purpose: Update a shared attribute.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Jan 2 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr,
+ const H5O_shared_t *sh_mesg)
+{
+ htri_t shared_mesg; /* Whether the message should be shared */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_update_shared)
+
+ /* check args */
+ HDassert(f);
+ HDassert(attr);
+ HDassert(sh_mesg);
+
+ /* Increment reference count on attribute components */
+ /* (Otherwise they may be deleted when the old attribute
+ * message is deleted.)
+ */
+ if(H5O_attr_link(f, dxpl_id, attr) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count")
+
+ /* Store new version of message as a SOHM */
+ /* (should always work, since we're not changing the size of the attribute) */
+ if((shared_mesg = H5SM_try_share(f, dxpl_id, H5O_ATTR_ID, attr)) == 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "attribute changed sharing status")
+ else if(shared_mesg < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't share attribute")
+
+ /* Remove the old attribute from the SOHM index */
+ if(H5SM_try_delete(f, dxpl_id, H5O_ATTR_ID, sh_mesg) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "unable to delete shared attribute in shared storage")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_attr_update_shared() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_attr_write_cb
*
* Purpose: Object header iterator callback routine to update an
@@ -560,36 +610,9 @@ H5O_attr_write_cb(H5O_t UNUSED *oh, H5O_mesg_t *mesg/*in,out*/,
/* Check for correct attribute message to modify */
if(HDstrcmp(shared_attr.name, udata->attr->name) == 0) {
- htri_t shared_mesg; /* Whether the message should be shared */
-
- /* Re-share attribute's datatype and dataspace to increment their
- * reference count if they're shared.
- * Otherwise they may be deleted when the old attribute
- * message is deleted.
- */
- if(H5SM_try_share(udata->f, udata->dxpl_id, H5O_DTYPE_ID, udata->attr->dt) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, H5_ITER_ERROR, "error trying to re-share attribute datatype")
- if(H5SM_try_share(udata->f, udata->dxpl_id, H5O_SDSPACE_ID, udata->attr->ds) < 0)
- HGOTO_ERROR(H5E_SOHM, H5E_BADMESG, H5_ITER_ERROR, "error trying to re-share attribute datatype")
-
- /* Likewise, increment reference count if this attribute has a named datatype */
- /* JAMES: this is identical to the attr_link callback. */
- if(H5T_committed(udata->attr->dt)) {
- /* Increment the reference count on the shared datatype */
- if(H5T_link(udata->attr->dt,1,udata->dxpl_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count")
- } /* end if */
-
- /* Store new version of message as a SOHM */
- /* (should always work, since we're not changing the size of the attribute) */
- if((shared_mesg = H5SM_try_share(udata->f, udata->dxpl_id, H5O_ATTR_ID, udata->attr)) == 0)
- HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, H5_ITER_ERROR, "attribute changed sharing status")
- else if(shared_mesg < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, H5_ITER_ERROR, "can't share attribute")
-
- /* Remove the old attribute from the SOHM index */
- if(H5SM_try_delete(udata->f, udata->dxpl_id, H5O_ATTR_ID, (const H5O_shared_t *)mesg->native) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, H5_ITER_ERROR, "unable to delete shared attribute in shared storage")
+ /* Update the shared attribute in the SOHM info */
+ if(H5O_attr_update_shared(udata->f, udata->dxpl_id, udata->attr, (const H5O_shared_t *)mesg->native) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTUPDATE, H5_ITER_ERROR, "unable to update attribute in shared storage")
/* Extract shared message info from current attribute */
if(NULL == H5O_attr_get_share(udata->attr, (H5O_shared_t *)mesg->native))
diff --git a/src/H5Omessage.c b/src/H5Omessage.c
index 70e2b2a..1dd0287 100644
--- a/src/H5Omessage.c
+++ b/src/H5Omessage.c
@@ -2032,7 +2032,7 @@ H5O_msg_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id, const void *mesg)
/* delete */
if((type->del) && (type->del)(f, dxpl_id, mesg, 1) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 2b367db..e9d9171 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -456,4 +456,3 @@ H5_DLL herr_t H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, F
#endif /* _H5Opkg_H */
-
diff --git a/src/H5SM.c b/src/H5SM.c
index 7b0d6ec..ae00a51 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -796,7 +796,7 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header,
HGOTO_ERROR(H5E_BTREE, H5E_CANTCREATE, FAIL, "B-tree creation failed for SOHM index")
/* Insert each record into the new B-tree */
- for(x=0; x<header->list_to_btree; x++)
+ for(x = 0; x < header->list_to_btree; x++)
{
/* JAMES: I'd like to stop relying on H5O_HASH_UNDEF */
if(list->messages[x].hash != H5O_HASH_UNDEF)
@@ -826,15 +826,15 @@ H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5SM_index_header_t *header,
/* Insert the new message into the SOHM index */
if(header->index_type == H5SM_LIST)
{
- for(x=0; x<header->list_to_btree; x++)
+ for(x = 0; x < header->list_to_btree; x++)
{
- if(list->messages[x].hash == H5O_HASH_UNDEF) /* JAMES: is this a valid test? */
- {
+ if(list->messages[x].hash == H5O_HASH_UNDEF) /* JAMES: is this a valid test? */
+ {
list->messages[x].fheap_id = shared.u.heap_id;
list->messages[x].hash = key.hash;
list->messages[x].ref_count = 1;
break;
- }
+ }
}
}
else /* Index is a B-tree */
@@ -941,7 +941,7 @@ H5SM_try_delete(H5F_t *f, hid_t dxpl_id, unsigned type_id,
if(H5O_msg_delete(f, dxpl_id, type_id, native_mesg) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "can't delete shared message.")
- }
+ } /* end if */
done:
/* Release the master SOHM table on error */