From 0e1b41d0fd1521784128e8637b5afa8371d2779d Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 10 Aug 2005 15:28:32 -0500 Subject: [svn-r11229] Purpose: Big fix Description: A group opened by dereferencing a object reference would not work for H5Giterate(), due to the local heap & B-tree information not being cached. Solution: Get the local heap & B-tree info & point to that structure instead of the group entry for the group. Platforms tested: FreeBSD 4.11 (sleipnir) Too minor to require h5committest --- src/H5G.c | 9 +++- src/H5Gnode.c | 6 +-- src/H5Gpkg.h | 2 +- test/trefer.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 6 deletions(-) diff --git a/src/H5G.c b/src/H5G.c index 1f04f61..c133e90 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -468,6 +468,7 @@ herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { + H5O_stab_t stab_mesg; /*info about B-tree */ int idx; H5G_bt_ud2_t udata; H5G_t *grp = NULL; @@ -498,9 +499,13 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL, "bad group atom"); } + /* Get the B-tree info */ + if (NULL==H5O_read (&(grp->ent), H5O_STAB_ID, 0, &stab_mesg, H5AC_dxpl_id)) + HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ udata.skip = idx; - udata.ent = &(grp->ent); + udata.stab = &stab_mesg; udata.op = op; udata.op_data = op_data; @@ -509,7 +514,7 @@ H5Giterate(hid_t loc_id, const char *name, int *idx_p, /* Iterate over the group members */ if ((ret_value = H5B_iterate (H5G_fileof(grp), H5AC_dxpl_id, H5B_SNODE, - H5G_node_iterate, udata.ent->cache.stab.btree_addr, &udata))<0) + H5G_node_iterate, stab_mesg.btree_addr, &udata))<0) HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); H5I_dec_ref (udata.group_id); /*also closes 'grp'*/ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index dfa607e..4c08b9c 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1533,7 +1533,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t a if (bt_udata->skip>0) { --bt_udata->skip; } else { - if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->ent->cache.stab.heap_addr))) + if (NULL == (heap = H5HL_protect(f, dxpl_id, bt_udata->stab->heap_addr))) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name"); name = H5HL_offset_into(f, heap, name_off[i]); @@ -1548,7 +1548,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t a } HDstrcpy (s, name); - if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->ent->cache.stab.heap_addr, H5AC__NO_FLAGS_SET) < 0) + if (H5HL_unprotect(f, dxpl_id, heap, bt_udata->stab->heap_addr, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name"); heap=NULL; name=NULL; @@ -1565,7 +1565,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t a HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); done: - if (heap && H5HL_unprotect(f, dxpl_id, heap, bt_udata->ent->cache.stab.heap_addr, H5AC__NO_FLAGS_SET) < 0) + if (heap && H5HL_unprotect(f, dxpl_id, heap, bt_udata->stab->heap_addr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name"); if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED) diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index f970b2d..9b299ed 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -98,7 +98,7 @@ typedef struct H5G_bt_ud1_t { typedef struct H5G_bt_ud2_t { /* downward */ hid_t group_id; /*group id to pass to iteration operator */ - H5G_entry_t *ent; /*the entry to which group_id points */ + H5O_stab_t *stab; /*the cached symbol table info to which group_id points */ H5G_iterate_t op; /*iteration operator */ void *op_data; /*user-defined operator data */ int skip; /*initial entries to skip */ diff --git a/test/trefer.c b/test/trefer.c index cf2e99b..fe592f4 100644 --- a/test/trefer.c +++ b/test/trefer.c @@ -56,6 +56,7 @@ typedef struct s1_t { #define GROUPNAME "/group" #define GROUPNAME2 "group2" +#define GROUPNAME3 "group3" #define DSETNAME "/dset" #define NAME_SIZE 16 @@ -1016,6 +1017,133 @@ test_reference_group_query(void) /**************************************************************** ** +** test_deref_iter_op(): Iterator callback for test_reference_group_iterate() +** test. +** +****************************************************************/ +static herr_t +test_deref_iter_op(hid_t UNUSED group, const char *name, void *op_data) +{ + int *count = (int *)op_data; /* Pointer to name counter */ + herr_t ret_value; + + /* Simple check for correct names */ + if(*count == 0) { + if(HDstrcmp(name, GROUPNAME2) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else if(*count == 1) { + if(HDstrcmp(name, GROUPNAME3) == 0) + ret_value = 0; + else + ret_value = -1; + } /* end if */ + else + ret_value = -1; + + (*count)++; + + return(ret_value); +} /* end test_deref_iter_op() */ + +/**************************************************************** +** +** test_reference_group_iterate(): Test H5R (reference) object reference code. +** Tests for correct behavior of iteration routines on dereferenced group +** +****************************************************************/ +static void +test_reference_group_iterate(void) +{ + hid_t fid = -1; /* File ID */ + hid_t gid = -1, gid2 = -1; /* Group IDs */ + hid_t did; /* Dataset ID */ + hid_t sid; /* Dataspace ID */ + hobj_ref_t wref; /* Reference to write */ + hobj_ref_t rref; /* Reference to read */ + int count = 0; /* Count within iterated group */ + herr_t ret; + + /* Create file with a group and a dataset containing an object reference to the group */ + fid = H5Fcreate(FILE1, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create group to refer to */ + gid = H5Gcreate(fid, GROUPNAME, (size_t)0); + CHECK(gid, FAIL, "H5Gcreate"); + + /* Create nested groups */ + gid2 = H5Gcreate(gid, GROUPNAME2, (size_t)0); + CHECK(gid2, FAIL, "H5Gcreate"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + gid2 = H5Gcreate(gid, GROUPNAME3, (size_t)0); + CHECK(gid2, FAIL, "H5Gcreate"); + ret = H5Gclose(gid2); + CHECK(ret, FAIL, "H5Gclose"); + + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + + /* Create dataspace to use for dataset */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate"); + + /* Create dataset */ + did = H5Dcreate(fid, DSETNAME, H5T_STD_REF_OBJ, sid, H5P_DEFAULT); + CHECK(did, FAIL, "H5Dcreate"); + + /* Create reference to group */ + ret = H5Rcreate(&wref, fid, GROUPNAME, H5R_OBJECT, -1); + CHECK(ret, FAIL, "H5Rcreate"); + + /* Write reference to disk */ + ret = H5Dwrite(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &wref); + CHECK(ret, FAIL, "H5Dwrite"); + + /* Close objects */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); + + + /* Re-open file */ + fid = H5Fopen(FILE1, H5F_ACC_RDONLY, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fopen"); + + /* Re-open dataset */ + did = H5Dopen(fid, DSETNAME); + CHECK(did, FAIL, "H5Dopen"); + + /* Read in the reference */ + ret = H5Dread(did, H5T_STD_REF_OBJ, H5S_ALL, H5S_ALL, H5P_DEFAULT, &rref); + CHECK(ret, FAIL, "H5Dread"); + + /* Dereference to get the group */ + gid = H5Rdereference(did, H5R_OBJECT, &rref); + CHECK(gid, FAIL, "H5Rdereference"); + + /* Iterate through objects in dereferenced group */ + ret = H5Giterate(gid, ".", NULL, test_deref_iter_op, &count); + CHECK(ret, FAIL, "H5Giterate"); + + /* Close objects */ + ret = H5Dclose(did); + CHECK(ret, FAIL, "H5Dclose"); + ret = H5Gclose(gid); + CHECK(ret, FAIL, "H5Gclose"); + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* test_reference_group_iterate() */ + +/**************************************************************** +** ** test_reference(): Main H5R reference testing routine. ** ****************************************************************/ @@ -1030,6 +1158,7 @@ test_reference(void) test_reference_region_1D(); /* Test H5R dataset region reference code for 1-D datasets */ test_reference_obj_deleted(); /* Test H5R object reference code for deleted objects */ test_reference_group_query(); /* Test queries on dereferenced groups */ + test_reference_group_iterate(); /* Test iterations on dereferenced groups */ } /* test_reference() */ -- cgit v0.12