mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-23 16:20:57 +08:00
[svn-r11176] Purpose:
Bug fix Description: Correct problems when querying information about a group that was opened by dereferencing an object reference. Solution: Read in symbol table information instead of rely on it being cached. Platforms tested: FreeBSD 4.11 (sleipnir) Too minor to require h5committest
This commit is contained in:
parent
ddb2af421f
commit
0c9c34fab6
@ -305,6 +305,8 @@ Bug Fixes since HDF5-1.6.0 release
|
||||
|
||||
Library
|
||||
-------
|
||||
- Corrected errors when querying information about a group opened
|
||||
by dereferencing an object reference. QAK - 2005/07/30
|
||||
- Fixed a bug with named datatypes where a copy of a named datatype
|
||||
used to create a dataset would accidentally use the original
|
||||
named datatype for the dataset's datatype. QAK - 2005/07/23
|
||||
|
69
src/H5G.c
69
src/H5G.c
@ -104,7 +104,6 @@
|
||||
#include "H5HLprivate.h" /* Local Heaps */
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
#include "H5Oprivate.h" /* Object headers */
|
||||
#include "H5Pprivate.h" /* Property lists */
|
||||
|
||||
/* Local macros */
|
||||
@ -592,11 +591,8 @@ ssize_t
|
||||
H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size)
|
||||
{
|
||||
H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */
|
||||
#ifdef OLD_WAY
|
||||
hsize_t num_objs;
|
||||
#endif /* OLD_WAY */
|
||||
ssize_t ret_value = FAIL;
|
||||
|
||||
|
||||
FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL);
|
||||
H5TRACE4("Zs","ihsz",loc_id,idx,name,size);
|
||||
|
||||
@ -605,19 +601,7 @@ H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size)
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID");
|
||||
if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP)
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group");
|
||||
|
||||
#ifdef OLD_WAY
|
||||
/* Don't check for the number of objects in the group currently, because this
|
||||
* has to iterate through the group in order to find out the information.
|
||||
* We might as well just iterate through all the group entries and error out
|
||||
* if we didn't find the index we are looking for. -QAK
|
||||
*/
|
||||
if (H5G_get_num_objs(loc, &num_objs, H5AC_ind_dxpl_id)<0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unable to retrieve number of members");
|
||||
if(idx >= num_objs)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound");
|
||||
#endif /* OLD_WAY */
|
||||
|
||||
|
||||
/*call private function*/
|
||||
ret_value = H5G_get_objname_by_idx(loc, idx, name, size, H5AC_ind_dxpl_id);
|
||||
|
||||
@ -647,9 +631,6 @@ H5G_obj_t
|
||||
H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx)
|
||||
{
|
||||
H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */
|
||||
#ifdef OLD_WAY
|
||||
hsize_t num_objs;
|
||||
#endif /* OLD_WAY */
|
||||
H5G_obj_t ret_value;
|
||||
|
||||
FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN);
|
||||
@ -660,19 +641,7 @@ H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx)
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID");
|
||||
if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP)
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a group");
|
||||
|
||||
#ifdef OLD_WAY
|
||||
/* Don't check for the number of objects in the group currently, because this
|
||||
* has to iterate through the group in order to find out the information.
|
||||
* We might as well just iterate through all the group entries and error out
|
||||
* if we didn't find the index we are looking for. -QAK
|
||||
*/
|
||||
if (H5G_get_num_objs(loc, &num_objs, H5AC_ind_dxpl_id)<0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "unable to retrieve number of members");
|
||||
if(idx >= num_objs)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound");
|
||||
#endif /* OLD_WAY */
|
||||
|
||||
|
||||
/*call private function*/
|
||||
ret_value = H5G_get_objtype_by_idx(loc, idx, H5AC_ind_dxpl_id);
|
||||
|
||||
@ -2912,21 +2881,25 @@ done:
|
||||
static herr_t
|
||||
H5G_get_num_objs(H5G_entry_t *loc, hsize_t *num_objs, hid_t dxpl_id)
|
||||
{
|
||||
H5O_stab_t stab_mesg; /*info about B-tree */
|
||||
herr_t ret_value;
|
||||
|
||||
FUNC_ENTER_NOAPI(H5G_get_num_objs, FAIL);
|
||||
|
||||
/* Sanity check */
|
||||
assert(loc);
|
||||
assert(loc->type==H5G_CACHED_STAB);
|
||||
assert(num_objs);
|
||||
|
||||
/* Reset the number of objects in the group */
|
||||
*num_objs = 0;
|
||||
|
||||
/* Get the B-tree info */
|
||||
if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
|
||||
|
||||
/* Iterate over the group members */
|
||||
if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE,
|
||||
H5G_node_sumup, loc->cache.stab.btree_addr, num_objs))<0)
|
||||
H5G_node_sumup, stab_mesg.btree_addr, num_objs))<0)
|
||||
HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed");
|
||||
|
||||
done:
|
||||
@ -2954,6 +2927,7 @@ done:
|
||||
static ssize_t
|
||||
H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id)
|
||||
{
|
||||
H5O_stab_t stab_mesg; /*info about local heap & B-tree */
|
||||
H5G_bt_ud3_t udata; /* Iteration information */
|
||||
ssize_t ret_value; /* Return value */
|
||||
|
||||
@ -2961,17 +2935,20 @@ H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, h
|
||||
|
||||
/* Sanity check */
|
||||
assert(loc);
|
||||
assert(loc->type==H5G_CACHED_STAB);
|
||||
|
||||
/* Get the B-tree & local heap info */
|
||||
if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
|
||||
|
||||
/* Set iteration information */
|
||||
udata.idx = idx;
|
||||
udata.num_objs = 0;
|
||||
udata.ent = loc;
|
||||
udata.mesg = &stab_mesg;
|
||||
udata.name = NULL;
|
||||
|
||||
/* Iterate over the group members */
|
||||
if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE,
|
||||
H5G_node_name, loc->cache.stab.btree_addr, &udata))<0)
|
||||
H5G_node_name, stab_mesg.btree_addr, &udata))<0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed");
|
||||
|
||||
/* If we don't know the name now, we almost certainly went out of bounds */
|
||||
@ -3016,24 +2993,28 @@ done:
|
||||
static H5G_obj_t
|
||||
H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id)
|
||||
{
|
||||
H5G_bt_ud3_t udata; /* User data for B-tree callback */
|
||||
H5G_obj_t ret_value; /* Return value */
|
||||
H5O_stab_t stab_mesg; /*info about local heap & B-tree */
|
||||
H5G_bt_ud3_t udata; /* User data for B-tree callback */
|
||||
H5G_obj_t ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5G_get_objtype_by_idx, H5G_UNKNOWN);
|
||||
|
||||
/* Sanity check */
|
||||
assert(loc);
|
||||
assert(loc->type==H5G_CACHED_STAB);
|
||||
|
||||
/* Get the B-tree & local heap info */
|
||||
if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
|
||||
|
||||
/* Set iteration information */
|
||||
udata.idx = idx;
|
||||
udata.num_objs = 0;
|
||||
udata.ent = loc;
|
||||
udata.mesg = &stab_mesg;
|
||||
udata.type = H5G_UNKNOWN;
|
||||
|
||||
/* Iterate over the group members */
|
||||
if (H5B_iterate (loc->file, dxpl_id, H5B_SNODE,
|
||||
H5G_node_type, loc->cache.stab.btree_addr, &udata)<0)
|
||||
H5G_node_type, stab_mesg.btree_addr, &udata)<0)
|
||||
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed");
|
||||
|
||||
/* If we don't know the type now, we almost certainly went out of bounds */
|
||||
|
@ -1679,7 +1679,7 @@ H5G_node_name(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
|
||||
loc_idx = bt_udata->idx - bt_udata->num_objs;
|
||||
name_off = sn->entry[loc_idx].name_off;
|
||||
|
||||
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->mesg->heap_addr)))
|
||||
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name");
|
||||
|
||||
name = H5HL_offset_into(f, heap, name_off);
|
||||
@ -1687,7 +1687,7 @@ H5G_node_name(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
|
||||
bt_udata->name = H5MM_strdup (name);
|
||||
assert(bt_udata->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->mesg->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;
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
/* Other private headers needed by this file */
|
||||
#include "H5ACprivate.h" /* Metadata cache */
|
||||
#include "H5Oprivate.h" /* Object headers */
|
||||
|
||||
/*
|
||||
* A symbol table node is a collection of symbol table entries. It can
|
||||
@ -113,7 +114,7 @@ typedef struct H5G_bt_ud2_t {
|
||||
*/
|
||||
typedef struct H5G_bt_ud3_t {
|
||||
/* downward */
|
||||
H5G_entry_t *ent; /*the entry of group being queried */
|
||||
const H5O_stab_t *mesg; /*the symbol table message of group being queried */
|
||||
hsize_t idx; /*index of group member to be queried */
|
||||
hsize_t num_objs; /*the number of objects having been traversed*/
|
||||
|
||||
|
107
test/trefer.c
107
test/trefer.c
@ -54,6 +54,11 @@ typedef struct s1_t {
|
||||
float c;
|
||||
} s1_t;
|
||||
|
||||
#define GROUPNAME "/group"
|
||||
#define GROUPNAME2 "group2"
|
||||
#define DSETNAME "/dset"
|
||||
#define NAME_SIZE 16
|
||||
|
||||
|
||||
/****************************************************************
|
||||
**
|
||||
@ -908,6 +913,107 @@ test_reference_obj_deleted(void)
|
||||
|
||||
} /* test_reference_obj_deleted() */
|
||||
|
||||
/****************************************************************
|
||||
**
|
||||
** test_reference_group_query(): Test H5R (reference) object reference code.
|
||||
** Tests for correct behavior of query routines on dereferenced group
|
||||
**
|
||||
****************************************************************/
|
||||
static void
|
||||
test_reference_group_query(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 */
|
||||
hsize_t nobjs;
|
||||
hobj_ref_t wref; /* Reference to write */
|
||||
hobj_ref_t rref; /* Reference to read */
|
||||
char objname[NAME_SIZE]; /* Buffer to store name */
|
||||
H5G_obj_t objtype; /* Object type */
|
||||
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 group */
|
||||
gid2 = H5Gcreate(gid, GROUPNAME2, (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");
|
||||
|
||||
/* Various queries on the group opened */
|
||||
ret = H5Gget_num_objs(gid, &nobjs);
|
||||
CHECK(ret, FAIL, "H5Gget_num_objs");
|
||||
|
||||
VERIFY(nobjs, 1, "H5Gget_num_objs");
|
||||
|
||||
ret = H5Gget_objname_by_idx(gid, (hsize_t)0, objname, NAME_SIZE);
|
||||
CHECK(ret, FAIL, "H5Gget_objname_by_idx");
|
||||
|
||||
VERIFY_STR(objname, "group2", "H5Gget_objname_by_idx");
|
||||
|
||||
objtype = H5Gget_objtype_by_idx(gid, (hsize_t)0);
|
||||
VERIFY(objtype, H5G_GROUP, "H5Gget_objtype_by_idx");
|
||||
|
||||
/* 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_query() */
|
||||
|
||||
/****************************************************************
|
||||
**
|
||||
** test_reference(): Main H5R reference testing routine.
|
||||
@ -923,6 +1029,7 @@ test_reference(void)
|
||||
test_reference_region(); /* Test basic H5R dataset region reference code */
|
||||
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() */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user