diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2007-05-10 20:35:35 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2007-05-10 20:35:35 (GMT) |
commit | 670d598ff7a017cc4cbe1331b30ad645f04514a9 (patch) | |
tree | 30355200820c49c95ec44d14ed826e74df7459a5 /src/H5Gstab.c | |
parent | c751cdab335b24e069570dcec8a39856dfa2cd98 (diff) | |
download | hdf5-670d598ff7a017cc4cbe1331b30ad645f04514a9.zip hdf5-670d598ff7a017cc4cbe1331b30ad645f04514a9.tar.gz hdf5-670d598ff7a017cc4cbe1331b30ad645f04514a9.tar.bz2 |
[svn-r13745] Description:
Take further advantage of the readers/writer locking in the metadata cache
and push the locking of the local heap up to the routines which call B-tree
routines, which should drastically lower the number of metadata cache protect/
unprotect calls.
Tested on:
Mac OS X/32 10.4.9 (amazon)
Linux/32 2.6 (chicago)
Linux/64 2.6 (chicago2)
Diffstat (limited to 'src/H5Gstab.c')
-rw-r--r-- | src/H5Gstab.c | 236 |
1 files changed, 146 insertions, 90 deletions
diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 7bb07aa..22d90a7 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -30,50 +30,47 @@ #include "H5MMprivate.h" /* Memory management */ /* Private typedefs */ -/* User data for finding a name in the link messages */ +/* User data for finding link information from B-tree */ typedef struct { /* downward */ - H5F_t *f; /* Pointer to file for insertion */ + H5F_t *file; /* Pointer to file for query */ const char *name; /* Name to search for */ + H5HL_t *heap; /* Local heap for group */ /* upward */ - H5G_entry_t *ent; /* Entry to update when match found */ -} H5G_stab_ud1_t; + H5O_link_t *lnk; /* Caller's link location */ +} H5G_stab_fnd_ud_t; -/* User data for finding object info from B-tree */ -typedef struct { +/* Data passed through B-tree iteration for looking up a name by index */ +typedef struct H5G_bt_it_gnbi_t { /* downward */ - H5O_loc_t *grp_oloc; /* Object location of group */ - hid_t dxpl_id; /* DXPL during operation */ - haddr_t heap_addr; /* Local heap address for group */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ + H5HL_t *heap; /*symbol table heap */ /* upward */ - H5G_stat_t *statbuf; /* Caller's statbuf */ -} H5G_stab_fnd_ud1_t; + char *name; /*member name to be returned */ +} H5G_bt_it_gnbi_t; -/* User data for finding link information from B-tree */ -typedef struct { +/* Data passed through B-tree iteration for looking up a type by index */ +typedef struct H5G_bt_it_gtbi_t { /* downward */ - H5F_t *file; /* Pointer to file for query */ - hid_t dxpl_id; /* DXPL during operation */ - const char *name; /* Name to search for */ - haddr_t heap_addr; /* Local heap address for group */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ + hid_t dxpl_id; /* DXPL for operation */ /* upward */ - H5O_link_t *lnk; /* Caller's link location */ -} H5G_stab_fnd_ud2_t; + H5G_obj_t type; /*member type to be returned */ +} H5G_bt_it_gtbi_t; -/* User data for finding object location from B-tree */ -typedef struct { +/* Data passed through B-tree iteration for looking up a link by index */ +typedef struct H5G_bt_it_lbi_t { /* downward */ - H5F_t *file; /* Pointer to file for query */ - size_t size; /* Buffer size for link value */ - haddr_t heap_addr; /* Local heap address for group */ - hid_t dxpl_id; /* DXPL during operation */ + H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */ + H5HL_t *heap; /*symbol table heap */ /* upward */ - char *buf; /* Buffer to fill with link value */ -} H5G_stab_fnd_ud3_t; + H5O_link_t *lnk; /*link to be returned */ + hbool_t found; /*whether we found the link */ +} H5G_bt_it_lbi_t; /* Private prototypes */ @@ -100,6 +97,7 @@ typedef struct { herr_t H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ size_t name_offset; /* Offset of "" name */ herr_t ret_value = SUCCEED; /* Return value */ @@ -119,9 +117,14 @@ H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t d /* Create symbol table private heap */ if(H5HL_create(f, dxpl_id, size_hint, &(stab->heap_addr)/*out*/) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap") - name_offset = H5HL_insert(f, dxpl_id, stab->heap_addr, (size_t)1, ""); - if((size_t)(-1) == name_offset) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap") + + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + + /* Insert name into the heap */ + if((size_t)(-1) == (name_offset = H5HL_insert(f, dxpl_id, heap, (size_t)1, ""))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert name into heap") /* * B-tree's won't work if the first name isn't at the beginning @@ -130,6 +133,10 @@ H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t d HDassert(0 == name_offset); done: + /* Release resources */ + if(heap && H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_create_components() */ @@ -214,6 +221,7 @@ herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, H5O_link_t *obj_lnk, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_ins_t udata; /* Data to pass through B-tree */ herr_t ret_value = SUCCEED; /* Return value */ @@ -225,9 +233,13 @@ H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, HDassert(name && *name); HDassert(obj_lnk); + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Initialize data to pass through B-tree */ udata.common.name = name; - udata.common.heap_addr = stab->heap_addr; + udata.common.heap = heap; udata.lnk = obj_lnk; /* Insert into symbol table */ @@ -235,6 +247,10 @@ H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name, HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry") done: + /* Release resources */ + if(heap && H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_insert_real() */ @@ -296,8 +312,9 @@ herr_t H5G_stab_remove(H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, const char *name) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5O_stab_t stab; /*symbol table message */ - H5G_bt_rm_t udata; /*data to pass through B-tree */ + H5G_bt_rm_t udata; /*data to pass through B-tree */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_stab_remove, FAIL) @@ -309,9 +326,13 @@ H5G_stab_remove(H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, if(NULL == H5O_msg_read(loc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(loc->file, dxpl_id, stab.heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Initialize data to pass through B-tree */ udata.common.name = name; - udata.common.heap_addr = stab.heap_addr; + udata.common.heap = heap; udata.grp_full_path_r = grp_full_path_r; /* Remove from symbol table */ @@ -319,6 +340,10 @@ H5G_stab_remove(H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry") done: + /* Release resources */ + if(heap && H5HL_unprotect(loc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_remove() */ @@ -339,6 +364,7 @@ herr_t H5G_stab_remove_by_idx(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r, H5_iter_order_t order, hsize_t n) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5O_stab_t stab; /* Symbol table message */ H5G_bt_rm_t udata; /* Data to pass through B-tree */ H5O_link_t obj_lnk; /* Object's link within group */ @@ -358,9 +384,13 @@ H5G_stab_remove_by_idx(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_ if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Initialize data to pass through B-tree */ udata.common.name = obj_lnk.name; - udata.common.heap_addr = stab.heap_addr; + udata.common.heap = heap; udata.grp_full_path_r = grp_full_path_r; /* Remove link from symbol table */ @@ -368,12 +398,16 @@ H5G_stab_remove_by_idx(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry") done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + /* Reset the link information, if we have a copy */ if(lnk_copied) H5O_msg_reset(H5O_LINK_ID, &obj_lnk); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_stab_remove() */ +} /* end H5G_stab_remove_by_idx() */ /*------------------------------------------------------------------------- @@ -393,6 +427,7 @@ done: herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_rm_t udata; /*data to pass through B-tree */ herr_t ret_value = SUCCEED; @@ -403,19 +438,32 @@ H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab) HDassert(H5F_addr_defined(stab->btree_addr)); HDassert(H5F_addr_defined(stab->heap_addr)); + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC_WRITE))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Set up user data for B-tree deletion */ udata.common.name = NULL; - udata.common.heap_addr = stab->heap_addr; + udata.common.heap = heap; /* Delete entire B-tree */ if(H5B_delete(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table B-tree") + /* Release resources */ + if(H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + heap = NULL; + /* Delete local heap for names */ if(H5HL_delete(f, dxpl_id, stab->heap_addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table heap") done: + /* Release resources */ + if(heap && H5HL_unprotect(f, dxpl_id, heap, stab->heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_delete() */ @@ -437,6 +485,7 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, hsize_t skip, hsize_t *last_lnk, hid_t gid, H5G_link_iterate_t *lnk_op, void *op_data) { + H5HL_t *heap = NULL; /* Local heap for group */ H5O_stab_t stab; /* Info about symbol table */ H5G_link_table_t ltable = {0, NULL}; /* Link table */ herr_t ret_value; @@ -451,6 +500,10 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Check on iteration order */ /* ("native" iteration order is increasing for this link storage mechanism) */ if(order != H5_ITER_DEC) { @@ -458,15 +511,14 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ udata.group_id = gid; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.skip = skip; udata.final_ent = last_lnk; udata.lnk_op = lnk_op; udata.op_data = op_data; /* Iterate over the group members */ - if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, - H5G_node_iterate, stab.btree_addr, &udata)) < 0) + if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_iterate, stab.btree_addr, &udata)) < 0) HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); /* Check for too high of a starting index (ex post facto :-) */ @@ -477,9 +529,9 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, else { H5G_bt_it_bt_t udata; /* User data to pass to B-tree callback */ - /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ + /* Build udata to pass through H5B_iterate() to H5G_node_build_table() */ udata.alloc_nlinks = 0; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.ltable = <able; /* Iterate over the group members */ @@ -502,8 +554,10 @@ H5G_stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order, done: /* Release resources */ + if(heap && H5HL_unprotect(oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") if(ltable.lnks && H5G_link_release_table(<able) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table") + HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table") FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_iterate() */ @@ -567,34 +621,23 @@ static herr_t H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata) { H5G_bt_it_gnbi_t *udata = (H5G_bt_it_gnbi_t *)_udata; - H5HL_t *heap = NULL; /* Pointer to local heap for group */ size_t name_off; /* Offset of name in heap */ const char *name; /* Pointer to name string in heap */ - herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_stab_get_name_by_idx_cb) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_stab_get_name_by_idx_cb) /* Sanity check */ HDassert(ent); - HDassert(udata); + HDassert(udata && udata->heap); /* Get name offset in heap */ name_off = ent->name_off; - - /* Pin the heap down in memory */ - if(NULL == (heap = H5HL_protect(udata->common.f, udata->common.dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - name = H5HL_offset_into(udata->common.f, heap, name_off); + name = H5HL_offset_into(udata->common.f, udata->heap, name_off); HDassert(name); udata->name = H5MM_strdup(name); HDassert(udata->name); -done: - if(heap && H5HL_unprotect(udata->common.f, udata->common.dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_stab_get_name_by_idx_cb */ @@ -615,6 +658,7 @@ ssize_t H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, char* name, size_t size, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5O_stab_t stab; /* Info about local heap & B-tree */ H5G_bt_it_gnbi_t udata; /* Iteration information */ ssize_t ret_value; /* Return value */ @@ -628,6 +672,10 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Remap index for decreasing iteration order */ if(order == H5_ITER_DEC) { hsize_t nlinks = 0; /* Number of links in group */ @@ -642,11 +690,10 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, /* Set iteration information */ udata.common.f = oloc->file; - udata.common.dxpl_id = dxpl_id; udata.common.idx = n; udata.common.num_objs = 0; udata.common.op = H5G_stab_get_name_by_idx_cb; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.name = NULL; /* Iterate over the group members */ @@ -668,6 +715,10 @@ H5G_stab_get_name_by_idx(H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n, } /* end if */ done: + /* Release resources */ + if(heap && H5HL_unprotect(oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + /* Free the duplicated name */ if(udata.name != NULL) H5MM_xfree(udata.name); @@ -719,7 +770,7 @@ H5G_stab_get_type_by_idx_cb(const H5G_entry_t *ent, void *_udata) tmp_oloc.addr = ent->header; /* Get the type of the object */ - if(H5O_obj_type(&tmp_oloc, &obj_type, udata->common.dxpl_id) < 0) + if(H5O_obj_type(&tmp_oloc, &obj_type, udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object type") udata->type = H5G_map_obj_type(obj_type); } @@ -764,10 +815,10 @@ H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id) /* Set iteration information */ udata.common.f = oloc->file; - udata.common.dxpl_id = dxpl_id; udata.common.idx = idx; udata.common.num_objs = 0; udata.common.op = H5G_stab_get_type_by_idx_cb; + udata.dxpl_id = dxpl_id; udata.type = H5G_UNKNOWN; /* Iterate over the group members */ @@ -803,18 +854,16 @@ done: static herr_t H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) { - H5G_stab_fnd_ud2_t *udata = (H5G_stab_fnd_ud2_t *)_udata; /* 'User data' passed in */ + H5G_stab_fnd_ud_t *udata = (H5G_stab_fnd_ud_t *)_udata; /* 'User data' passed in */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_stab_lookup_cb) - /* Set link info */ - if(udata->lnk) { + /* Check for setting link info */ + if(udata->lnk) /* Convert the entry to a link */ - if(H5G_ent_to_link(udata->file, udata->dxpl_id, udata->lnk, udata->heap_addr, - NULL, ent, udata->name) < 0) + if(H5G_ent_to_link(udata->file, udata->lnk, udata->heap, ent, udata->name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") - } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -838,8 +887,9 @@ herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */ - H5G_stab_fnd_ud2_t udata; /* 'User data' to give to callback */ + H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */ H5O_stab_t stab; /* Symbol table message */ herr_t ret_value = SUCCEED; /* Return value */ @@ -850,28 +900,35 @@ H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk, HDassert(name && *name); HDassert(lnk); + /* Retrieve the symbol table message for the group */ + if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message") + + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Set up user data to pass to 'find' operation callback */ udata.file = grp_oloc->file; - udata.dxpl_id = dxpl_id; udata.name = name; udata.lnk = lnk; + udata.heap = heap; /* Set up the user data for actual B-tree find operation */ - if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message") bt_udata.common.name = name; - bt_udata.common.heap_addr = stab.heap_addr; + bt_udata.common.heap = heap; bt_udata.op = H5G_stab_lookup_cb; bt_udata.op_data = &udata; - /* Finish up user data to pass to 'find' operation callback */ - udata.heap_addr = stab.heap_addr; - /* Search the B-tree */ if(H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata) < 0) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found") done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup() */ @@ -894,7 +951,6 @@ static herr_t H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) { H5G_bt_it_lbi_t *udata = (H5G_bt_it_lbi_t *)_udata; - H5HL_t *heap = NULL; /* Pointer to local heap for group */ const char *name; /* Pointer to name string in heap */ herr_t ret_value = SUCCEED; /* Return value */ @@ -902,26 +958,18 @@ H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata) /* Sanity check */ HDassert(ent); - HDassert(udata); + HDassert(udata && udata->heap); - /* Pin the heap down in memory */ - if(NULL == (heap = H5HL_protect(udata->common.f, udata->common.dxpl_id, udata->heap_addr, H5AC_READ))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name") - - /* Duplicate the link name */ - name = H5HL_offset_into(udata->common.f, heap, ent->name_off); + /* Get a pointer to the link name */ + name = H5HL_offset_into(udata->common.f, udata->heap, ent->name_off); HDassert(name); /* Convert the entry to a link */ - if(H5G_ent_to_link(udata->common.f, udata->common.dxpl_id, udata->lnk, HADDR_UNDEF, heap, ent, name) < 0) + if(H5G_ent_to_link(udata->common.f, udata->lnk, udata->heap, ent, name) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link") udata->found = TRUE; done: - /* Unlock the heap */ - if(heap && H5HL_unprotect(udata->common.f, udata->common.dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup_by_idx_cb */ @@ -943,6 +991,7 @@ herr_t H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, H5O_link_t *lnk, hid_t dxpl_id) { + H5HL_t *heap = NULL; /* Pointer to local heap */ H5G_bt_it_lbi_t udata; /* Iteration information */ H5O_stab_t stab; /* Symbol table message */ herr_t ret_value = SUCCEED; /* Return value */ @@ -957,6 +1006,10 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id)) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Pin the heap down in memory */ + if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC_READ))) + HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap") + /* Remap index for decreasing iteration order */ if(order == H5_ITER_DEC) { hsize_t nlinks = 0; /* Number of links in group */ @@ -971,11 +1024,10 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, /* Set iteration information */ udata.common.f = grp_oloc->file; - udata.common.dxpl_id = dxpl_id; udata.common.idx = n; udata.common.num_objs = 0; udata.common.op = H5G_stab_lookup_by_idx_cb; - udata.heap_addr = stab.heap_addr; + udata.heap = heap; udata.lnk = lnk; udata.found = FALSE; @@ -988,6 +1040,10 @@ H5G_stab_lookup_by_idx(H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n, HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound") done: + /* Release resources */ + if(heap && H5HL_unprotect(grp_oloc->file, dxpl_id, heap, stab.heap_addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_stab_lookup_by_idx() */ |