diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-01-02 20:21:44 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-01-02 20:21:44 (GMT) |
commit | 76ee1b2bda4d6ab8f39ae1ca9da1940a3b457646 (patch) | |
tree | 59c726a50c3d5b7a34bdc4b5f265400b50e3d312 /src | |
parent | 8081ee4221812ef6f76b9b267bf3b71a930fe0ef (diff) | |
download | hdf5-76ee1b2bda4d6ab8f39ae1ca9da1940a3b457646.zip hdf5-76ee1b2bda4d6ab8f39ae1ca9da1940a3b457646.tar.gz hdf5-76ee1b2bda4d6ab8f39ae1ca9da1940a3b457646.tar.bz2 |
[svn-r13096] Description:
Fix updating values of shared attributes in dense storage & add test.
Tested on:
Linux/32 2.6 (chicago)
Linux/64 2.6 (chicago2)
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Adense.c | 110 | ||||
-rw-r--r-- | src/H5Apkg.h | 9 | ||||
-rw-r--r-- | src/H5Oattr.c | 19 | ||||
-rw-r--r-- | src/H5Oattribute.c | 83 | ||||
-rw-r--r-- | src/H5Omessage.c | 2 | ||||
-rw-r--r-- | src/H5Opkg.h | 1 | ||||
-rwxr-xr-x | src/H5SM.c | 12 |
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 */ - @@ -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 */ |