summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5G.c9
-rw-r--r--src/H5Gnode.c6
-rw-r--r--src/H5Gpkg.h2
-rw-r--r--test/trefer.c129
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() */