From d978a22b36d148a17f331eb51d0e13ede524770a Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 8 Jan 2007 17:25:26 -0500 Subject: [svn-r13121] Description: Add support & tests for using shared datatypes with shared & un-shared attributes. Involves some fairly icky code to make the "copy on write" paradigm for shared attributes work. Tested on: Linux/32 2.6 (chicago) Linux/64 2.6 (chicago2) --- src/H5Adense.c | 22 ++++++++- src/H5Atest.c | 6 +-- src/H5O.c | 7 +-- src/H5Oattr.c | 28 +++++------ src/H5Oattribute.c | 72 +++++++++++++++++++++++++---- src/H5Oshared.c | 2 +- src/H5SM.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5SMpkg.h | 22 ++++----- src/H5SMprivate.h | 2 + src/H5SMtest.c | 133 ----------------------------------------------------- src/H5Tcommit.c | 3 +- src/H5Tpkg.h | 1 - test/tattr.c | 7 +-- 13 files changed, 251 insertions(+), 187 deletions(-) diff --git a/src/H5Adense.c b/src/H5Adense.c index d64bb89..e4cf59e 100644 --- a/src/H5Adense.c +++ b/src/H5Adense.c @@ -801,9 +801,29 @@ H5A_dense_rename(H5F_t *f, hid_t dxpl_id, const H5O_t *oh, const char *old_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) + if((shared_mesg = H5SM_try_share(f, dxpl_id, H5O_ATTR_ID, attr_copy)) > 0) { + hsize_t attr_rc; /* Attribute's ref count in shared message storage */ + /* Mark the message as shared */ mesg_flags |= H5O_MSG_FLAG_SHARED; + + /* Retrieve ref count for shared attribute */ + if(H5SM_get_refcount(f, dxpl_id, H5O_ATTR_ID, &attr_copy->sh_loc, &attr_rc) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") + + /* If the newly shared attribute needs to share "ownership" of the shared + * components (ie. its reference count is 1), increment the reference + * count on any shared components of the attribute, so that they won't + * be removed from the file. (Essentially a "copy on write" operation). + * + * *ick* -QAK, 2007/01/08 + */ + if(attr_rc == 1) { + /* Increment reference count on attribute components */ + if(H5O_attr_link(f, dxpl_id, attr_copy) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count") + } /* end if */ + } /* end if */ else if(shared_mesg < 0) HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") diff --git a/src/H5Atest.c b/src/H5Atest.c index b2ee0d5..13d13f1 100644 --- a/src/H5Atest.c +++ b/src/H5Atest.c @@ -29,8 +29,6 @@ #define H5A_PACKAGE /*suppress error about including H5Apkg */ #define H5A_TESTING /*suppress warning about H5A testing funcs*/ -#define H5SM_PACKAGE /*suppress error about including H5SMpkg */ -#define H5SM_TESTING /*suppress warning about H5SM testing funcs*/ /***********/ @@ -40,7 +38,7 @@ #include "H5Apkg.h" /* Attributes */ #include "H5Eprivate.h" /* Error handling */ #include "H5Iprivate.h" /* IDs */ -#include "H5SMpkg.h" /* Shared object header messages */ +#include "H5SMprivate.h" /* Shared object header messages */ /****************/ @@ -140,7 +138,7 @@ H5A_get_shared_rc_test(hid_t attr_id, hsize_t *ref_count) HDassert(H5O_attr_is_shared(attr)); /* Retrieve ref count for shared attribute */ - if(H5SM_get_refcount_test(attr->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID, + if(H5SM_get_refcount(attr->oloc.file, H5AC_ind_dxpl_id, H5O_ATTR_ID, &attr->sh_loc, ref_count) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") diff --git a/src/H5O.c b/src/H5O.c index e235405..103352e 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -933,11 +933,8 @@ int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id) { H5O_t *oh = NULL; - unsigned oh_flags = H5AC__NO_FLAGS_SET; /* used to indicate whether the - * object was deleted as a result - * of this action. - */ - int ret_value = FAIL; + unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Whether the object was deleted */ + int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_link, FAIL) diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 8d2aa18..d8f4a1b 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -662,23 +662,23 @@ H5O_attr_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) * shared there. */ if((tri_ret = H5O_msg_is_shared(H5O_DTYPE_ID, attr->dt)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't tell if datatype is shared") + HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't tell if datatype is shared") if(tri_ret > 0) { if(NULL == H5O_msg_get_share(H5O_DTYPE_ID, attr->dt, &sh_mesg)) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't get shared message from datatype") - if(H5SM_try_delete(f, H5AC_dxpl_id, H5O_DTYPE_ID, &sh_mesg) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_CANTREMOVE, FAIL, "can't remove datatype from SOHM heap") + HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared message from datatype") + if(H5SM_try_delete(f, dxpl_id, H5O_DTYPE_ID, &sh_mesg) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTREMOVE, FAIL, "can't remove datatype from SOHM heap") } /* end if */ if((tri_ret = H5O_msg_is_shared(H5O_SDSPACE_ID, attr->ds)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't tell if dataspace is shared") + HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't tell if dataspace is shared") if(tri_ret > 0) { if(NULL == H5O_msg_get_share(H5O_SDSPACE_ID, attr->ds, &sh_mesg)) - HGOTO_ERROR(H5E_OHDR, H5E_BADMESG, FAIL, "can't get shared message from dataspace") - if(H5SM_try_delete(f, H5AC_dxpl_id, H5O_SDSPACE_ID, &sh_mesg) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_SOHM, FAIL, "can't remove dataspace from SOHM heap") + HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't get shared message from dataspace") + if(H5SM_try_delete(f, dxpl_id, H5O_SDSPACE_ID, &sh_mesg) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_SOHM, FAIL, "can't remove dataspace from SOHM heap") } /* end if */ /* Check whether datatype is shared */ @@ -686,7 +686,7 @@ H5O_attr_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) /* Decrement the reference count on the shared datatype, if requested */ if(adj_link) if(H5T_link(attr->dt, -1, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") + HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") } /* end if */ done: @@ -733,7 +733,7 @@ H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg) if(H5T_committed(attr->dt)) { /* Increment the reference count on the shared datatype */ if(H5T_link(attr->dt, 1, dxpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") + HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust shared datatype link count") } /* end if */ done: @@ -1155,7 +1155,6 @@ htri_t H5O_attr_is_shared(const void *_mesg) { const H5A_t *mesg = (const H5A_t *)_mesg; - htri_t ret_value; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_attr_is_shared) @@ -1165,12 +1164,7 @@ H5O_attr_is_shared(const void *_mesg) * library read a "committed attribute" if we ever create one in * the future. */ - if(H5O_IS_SHARED(mesg->sh_loc.flags)) - ret_value = TRUE; - else - ret_value = FALSE; - - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(H5O_IS_SHARED(mesg->sh_loc.flags)) } /* end H5O_attr_is_shared */ diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index b1e8d31..ea77e26 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -235,9 +235,54 @@ HDfprintf(stderr, "%s: adding attribute, attr->name = '%s'\n", FUNC, attr->name) HDassert(attr); /* Should this message be written as a SOHM? */ - if((shared_mesg = H5SM_try_share(loc->file, dxpl_id, H5O_ATTR_ID, attr)) > 0) + if((shared_mesg = H5SM_try_share(loc->file, dxpl_id, H5O_ATTR_ID, attr)) > 0) { + hsize_t attr_rc; /* Attribute's ref count in shared message storage */ + /* Mark the message as shared */ mesg_flags |= H5O_MSG_FLAG_SHARED; + + /* Check whether datatype is committed */ + /* (to maintain ref. count incr/decr similarity with "shared message" + * type of datatype sharing) + */ + if(H5T_committed(attr->dt)) { + /* Increment the reference count on the shared datatype */ + 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 */ + + /* Retrieve ref count for shared attribute */ + if(H5SM_get_refcount(loc->file, dxpl_id, H5O_ATTR_ID, &attr->sh_loc, &attr_rc) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") + + /* If this is not the first copy of the attribute in the shared message + * storage, decrement the reference count on any shared components + * of the attribute. This is done because the shared message + * storage's "try delete" call doesn't call the message class's + * "delete" callback until the reference count drops to zero. + * However, attributes have already increased the reference + * count on shared components before passing the attribute + * to the shared message code to manage, causing an assymetry + * in the reference counting for any shared components. + * + * The alternate solution is to have the shared message's "try + * delete" code always call the message class's "delete" callback, + * even when the reference count is positive. This can be done + * without an appreciable performance hit (by using H5HF_op() in + * the shared message comparison v2 B-tree callback), but it has + * the undesirable side-effect of leaving the reference count on + * the attribute's shared components artificially (and possibly + * misleadingly) high, because there's only one shared attribute + * referencing the shared components, not objects referencing the shared components. + * + * *ick* -QAK, 2007/01/08 + */ + if(attr_rc > 1) { + if(H5O_attr_delete(loc->file, dxpl_id, attr, TRUE) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute") + } /* end if */ + } /* end if */ else if(shared_mesg < 0) HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "error determining if message should be shared") @@ -535,6 +580,7 @@ herr_t H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, const H5O_shared_t *sh_mesg) { + hsize_t attr_rc; /* Attribute's ref count in shared message storage */ htri_t shared_mesg; /* Whether the message should be shared */ herr_t ret_value = SUCCEED; /* Return value */ @@ -545,13 +591,6 @@ H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, HDassert(attr); HDassert(sh_mesg); - /* Increment reference count on attribute components */ - /* (Otherwise they may be deleted when the old attribute - * message is removed from the shared message storage.) - */ - 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) @@ -559,6 +598,23 @@ H5O_attr_update_shared(H5F_t *f, hid_t dxpl_id, H5A_t *attr, else if(shared_mesg < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADMESG, FAIL, "can't share attribute") + /* Retrieve shared message storage ref count for new shared attribute */ + if(H5SM_get_refcount(f, dxpl_id, H5O_ATTR_ID, &attr->sh_loc, &attr_rc) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't retrieve shared message ref count") + + /* If the newly shared attribute needs to share "ownership" of the shared + * components (ie. its reference count is 1), increment the reference + * count on any shared components of the attribute, so that they won't + * be removed from the file. (Essentially a "copy on write" operation). + * + * *ick* -QAK, 2007/01/08 + */ + if(attr_rc == 1) { + /* Increment reference count on attribute components */ + if(H5O_attr_link(f, dxpl_id, attr) < 0) + HGOTO_ERROR(H5E_ATTR, H5E_LINKCOUNT, FAIL, "unable to adjust attribute link count") + } /* end if */ + /* Remove the old attribute from the SOHM storage */ 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") diff --git a/src/H5Oshared.c b/src/H5Oshared.c index 6c5189d..68d3494 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -37,7 +37,7 @@ #include "H5HFprivate.h" /* Fractal heap */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ -#include "H5SMprivate.h" /* Shared messages */ +#include "H5SMprivate.h" /* Shared object header messages */ static void *H5O_shared_decode(H5F_t*, hid_t dxpl_id, const uint8_t*); static herr_t H5O_shared_encode(H5F_t*, uint8_t*, const void*); diff --git a/src/H5SM.c b/src/H5SM.c index 6e5dba8..49052eb 100755 --- a/src/H5SM.c +++ b/src/H5SM.c @@ -1441,3 +1441,136 @@ H5SM_reconstitute(H5O_shared_t *sh_mesg, const uint8_t *heap_id) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM_reconstitute() */ + +/*------------------------------------------------------------------------- + * Function: H5SM_get_refcount_bt2_cb + * + * Purpose: v2 B-tree 'find' callback to retrieve the record for a message + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * Tuesday, December 19, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5SM_get_refcount_bt2_cb(const void *_record, void *_op_data) +{ + const H5SM_sohm_t *record = (const H5SM_sohm_t *)_record; /* v2 B-tree record for message */ + H5SM_sohm_t *op_data = (H5SM_sohm_t *)_op_data; /* "op data" from v2 B-tree find */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_get_refcount_bt2_cb) + + /* + * Check arguments. + */ + HDassert(record); + HDassert(op_data); + + /* Make a copy of the record */ + *op_data = *record; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM_get_refcount_bt2_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5SM_get_refcount + * + * Purpose: Retrieve the reference count for a message + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, December 19, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, + const H5O_shared_t *sh_mesg, hsize_t *ref_count) +{ + H5HF_t *fheap = NULL; /* Fractal heap that contains shared messages */ + H5SM_master_table_t *table = NULL; /* SOHM master table */ + H5SM_list_t *list = NULL; /* SOHM index list for message type (if in list form) */ + H5SM_index_header_t *header=NULL; /* Index header for message type */ + H5SM_mesg_key_t key; /* Key for looking up message */ + H5SM_fh_ud_gh_t udata; /* User data for fractal heap 'op' callback */ + H5SM_sohm_t message; /* Record for shared message */ + ssize_t index_num; /* Table index for message type */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5SM_get_refcount) + + /* Sanity check */ + HDassert(f); + HDassert(sh_mesg); + HDassert(ref_count); + + /* Look up the master SOHM table */ + if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") + + /* Find the correct index and try to delete from it */ + if((index_num = H5SM_get_index(table, type_id)) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") + header = &(table->indexes[index_num]); + + /* Open the heap that this message is in */ + if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") + + /* Prepare user data for callback */ + udata.type_id = type_id; + + /* Compute the hash value for the B-tree lookup */ + if(H5HF_op(fheap, dxpl_id, &(sh_mesg->u.heap_id), H5SM_get_hash_fh_cb, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't access message in fractal heap") + + /* Set up key for message to locate */ + key.hash = udata.hash; + key.encoding = NULL; + key.encoding_size = 0; + key.fheap = fheap; + key.mesg_heap_id = sh_mesg->u.heap_id; + + /* Try to find the message in the index */ + if(header->index_type == H5SM_LIST) { + size_t list_pos; /* Position of the message in the list */ + + /* If the index is stored as a list, get it from the cache */ + if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, NULL, header, H5AC_READ))) + HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") + + /* Find the message in the list */ + if((list_pos = H5SM_find_in_list(list, &key)) == UFAIL) + HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") + + /* Copy the message */ + message = list->messages[list_pos]; + } /* end if */ + else /* Index is a B-tree */ + { + HDassert(header->index_type == H5SM_BTREE); + + /* Look up the message in the v2 B-tree */ + if(H5B2_find(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_get_refcount_bt2_cb, &message) < 0) + HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") + } /* end else */ + + /* Set the refcount for the message */ + *ref_count = message.ref_count; + +done: + /* Release resources */ + if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") + if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") + if(fheap && H5HF_close(fheap, dxpl_id) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5SM_get_refcount() */ + diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h index 1f790fe..e2e839b 100755 --- a/src/H5SMpkg.h +++ b/src/H5SMpkg.h @@ -97,24 +97,24 @@ /* Typedef for a SOHM index node */ typedef struct { - uint32_t hash; /* Hash value for OHM */ - H5SM_fheap_id_t fheap_id; /* ID of the OHM in the fractal heap */ - hsize_t ref_count; /* Number of times this message is used */ + uint32_t hash; /* Hash value for OHM */ + H5SM_fheap_id_t fheap_id; /* ID of the OHM in the fractal heap */ + hsize_t ref_count; /* Number of times this message is used */ } H5SM_sohm_t; typedef enum { H5SM_BADTYPE = -1, - H5SM_LIST, /* Index is an unsorted list */ - H5SM_BTREE /* Index is a sorted B-tree */ + H5SM_LIST, /* Index is an unsorted list */ + H5SM_BTREE /* Index is a sorted B-tree */ } H5SM_index_type_t; /* Typedef for searching an index (list or B-tree) */ typedef struct { - uint32_t hash; /* The hash value for this message */ - const void *encoding; /* The message encoded */ - size_t encoding_size; /* Size of the encoding */ - H5HF_t *fheap; /* The heap for this message type, open. */ - H5SM_fheap_id_t mesg_heap_id; /* The heap_id for this message */ + uint32_t hash; /* The hash value for this message */ + const void *encoding; /* The message encoded */ + size_t encoding_size; /* Size of the encoding */ + H5HF_t *fheap; /* The heap for this message type, open. */ + H5SM_fheap_id_t mesg_heap_id; /* The heap_id for this message */ } H5SM_mesg_key_t; /* Typedef for a SOHM index header */ @@ -207,8 +207,6 @@ H5_DLL herr_t H5SM_get_hash_fh_cb(const void *obj, size_t obj_len, void *_udata) /* Testing functions */ #ifdef H5SM_TESTING -H5_DLL herr_t H5SM_get_refcount_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, - const H5O_shared_t *sh_mesg, hsize_t *ref_count); H5_DLL herr_t H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, size_t *mesg_count); #endif /* H5SM_TESTING */ diff --git a/src/H5SMprivate.h b/src/H5SMprivate.h index 8d395df..679b59f 100755 --- a/src/H5SMprivate.h +++ b/src/H5SMprivate.h @@ -42,6 +42,8 @@ H5_DLL htri_t H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id); H5_DLL herr_t H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_addr); H5_DLL herr_t H5SM_reconstitute(H5O_shared_t *sh_mesg, const uint8_t *heap_id); +H5_DLL herr_t H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, + const H5O_shared_t *sh_mesg, hsize_t *ref_count); #endif /*_H5SMprivate_H*/ diff --git a/src/H5SMtest.c b/src/H5SMtest.c index 20a23e9..36832d3 100644 --- a/src/H5SMtest.c +++ b/src/H5SMtest.c @@ -63,139 +63,6 @@ /*------------------------------------------------------------------------- - * Function: H5SM_get_refcount_bt2_cb - * - * Purpose: v2 B-tree 'find' callback to retrieve the record for a message - * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * Tuesday, December 19, 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5SM_get_refcount_bt2_cb(const void *_record, void *_op_data) -{ - const H5SM_sohm_t *record = (const H5SM_sohm_t *)_record; /* v2 B-tree record for message */ - H5SM_sohm_t *op_data = (H5SM_sohm_t *)_op_data; /* "op data" from v2 B-tree find */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_get_refcount_bt2_cb) - - /* - * Check arguments. - */ - HDassert(record); - HDassert(op_data); - - /* Make a copy of the record */ - *op_data = *record; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5SM_get_refcount_bt2_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5SM_get_refcount_test - * - * Purpose: Retrieve the reference count for a message - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, December 19, 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5SM_get_refcount_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, - const H5O_shared_t *sh_mesg, hsize_t *ref_count) -{ - H5HF_t *fheap = NULL; /* Fractal heap that contains shared messages */ - H5SM_master_table_t *table = NULL; /* SOHM master table */ - H5SM_list_t *list = NULL; /* SOHM index list for message type (if in list form) */ - H5SM_index_header_t *header=NULL; /* Index header for message type */ - H5SM_mesg_key_t key; /* Key for looking up message */ - H5SM_fh_ud_gh_t udata; /* User data for fractal heap 'op' callback */ - H5SM_sohm_t message; /* Record for shared message */ - ssize_t index_num; /* Table index for message type */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5SM_get_refcount_test) - - /* Sanity check */ - HDassert(f); - HDassert(sh_mesg); - HDassert(ref_count); - - /* Look up the master SOHM table */ - if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") - - /* Find the correct index and try to delete from it */ - if((index_num = H5SM_get_index(table, type_id)) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "unable to find correct SOHM index") - header = &(table->indexes[index_num]); - - /* Open the heap that this message is in */ - if(NULL == (fheap = H5HF_open(f, dxpl_id, header->heap_addr))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTOPENOBJ, FAIL, "unable to open fractal heap") - - /* Prepare user data for callback */ - udata.type_id = type_id; - - /* Compute the hash value for the B-tree lookup */ - if(H5HF_op(fheap, dxpl_id, &(sh_mesg->u.heap_id), H5SM_get_hash_fh_cb, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't access message in fractal heap") - - /* Set up key for message to locate */ - key.hash = udata.hash; - key.encoding = NULL; - key.encoding_size = 0; - key.fheap = fheap; - key.mesg_heap_id = sh_mesg->u.heap_id; - - /* Try to find the message in the index */ - if(header->index_type == H5SM_LIST) { - size_t list_pos; /* Position of the message in the list */ - - /* If the index is stored as a list, get it from the cache */ - if(NULL == (list = (H5SM_list_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, NULL, header, H5AC_READ))) - HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM index") - - /* Find the message in the list */ - if((list_pos = H5SM_find_in_list(list, &key)) == UFAIL) - HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") - - /* Copy the message */ - message = list->messages[list_pos]; - } /* end if */ - else /* Index is a B-tree */ - { - HDassert(header->index_type == H5SM_BTREE); - - /* Look up the message in the v2 B-tree */ - if(H5B2_find(f, dxpl_id, H5SM_INDEX, header->index_addr, &key, H5SM_get_refcount_bt2_cb, &message) < 0) - HGOTO_ERROR(H5E_SOHM, H5E_NOTFOUND, FAIL, "message not in index") - } /* end else */ - - /* Set the refcount for the message */ - *ref_count = message.ref_count; - -done: - /* Release resources */ - if(list && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_LIST, header->index_addr, list, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "unable to close SOHM index") - if(table && H5AC_unprotect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, table, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_CACHE, H5E_CANTRELEASE, FAIL, "unable to close SOHM master table") - if(fheap && H5HF_close(fheap, dxpl_id) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close fractal heap") - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5SM_get_refcount_test() */ - - -/*------------------------------------------------------------------------- * Function: H5SM_get_mesg_count_test * * Purpose: Retrieve the number of messages tracked of a certain type diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 7415342..6ed7856 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -406,8 +406,7 @@ H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id) { int ret_value; /* Return value */ - /* Use no-init for efficiency */ - FUNC_ENTER_NOAPI(H5T_link,FAIL) + FUNC_ENTER_NOAPI(H5T_link, FAIL) HDassert(type); HDassert(type->sh_loc.flags & H5O_COMMITTED_FLAG); diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index f8f03dc..14f77cf 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -41,7 +41,6 @@ #include "H5Fprivate.h" /* Files */ #include "H5FLprivate.h" /* Free Lists */ #include "H5Oprivate.h" /* Object headers */ -#include "H5SMprivate.h" /* Shared Messages */ /* Other public headers needed by this file */ #include "H5Spublic.h" /* Dataspace functions */ diff --git a/test/tattr.c b/test/tattr.c index 1f7a750..c9152e9 100644 --- a/test/tattr.c +++ b/test/tattr.c @@ -1590,6 +1590,7 @@ test_attr_dtype_shared(hid_t fapl) ret=H5Gget_objinfo(file_id,TYPE1_NAME,0,&statbuf); CHECK(ret, FAIL, "H5Gget_objinfo"); VERIFY(statbuf.nlink, 3, "H5Acreate"); + /* Close attribute */ ret=H5Aclose(attr_id); CHECK(ret, FAIL, "H5Aclose"); @@ -2661,7 +2662,7 @@ test_attr_shared_write(hid_t fcpl, hid_t fapl) MESSAGE(5, ("Testing Writing to Shared Attributes in Compact & Dense Storage\n")); /* Loop over type of shared components */ - for(test_shared = 0; test_shared < 1; test_shared++) { + for(test_shared = 0; test_shared < 2; test_shared++) { /* Make copy of file creation property list */ my_fcpl = H5Pcopy(fcpl); CHECK(my_fcpl, FAIL, "H5Pcopy"); @@ -2686,9 +2687,9 @@ test_attr_shared_write(hid_t fcpl, hid_t fapl) /* Make attributes & datatypes > 1 byte shared (i.e. all of them :-) */ ret = H5Pset_shared_mesg_nindexes(my_fcpl, (unsigned)2); CHECK_I(ret, "H5Pset_shared_mesg_nindexes"); - ret = H5Pset_shared_mesg_index(my_fcpl, (unsigned)1, H5O_MESG_ATTR_FLAG, (unsigned)1); + ret = H5Pset_shared_mesg_index(my_fcpl, (unsigned)0, H5O_MESG_ATTR_FLAG, (unsigned)1); CHECK_I(ret, "H5Pset_shared_mesg_index"); - ret = H5Pset_shared_mesg_index(my_fcpl, (unsigned)2, H5O_MESG_DTYPE_FLAG, (unsigned)1); + ret = H5Pset_shared_mesg_index(my_fcpl, (unsigned)1, H5O_MESG_DTYPE_FLAG, (unsigned)1); CHECK_I(ret, "H5Pset_shared_mesg_index"); break; } /* end switch */ -- cgit v0.12