summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:27:56 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:27:56 (GMT)
commit0b7306beed3616d5e259ce3efa1dd0105f436fdb (patch)
tree4d5d467a608e5fc9ada867f913136de744750860
parentad2f3285b3a0e55aab2014c9e395009df758fef6 (diff)
downloadhdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.zip
hdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.tar.gz
hdf5-0b7306beed3616d5e259ce3efa1dd0105f436fdb.tar.bz2
[svn-r19133] Description:
Correct traversal of user-defined links (including external links) to retain path information of object, allowing H5Iget_name() queries to work quickly (without searching entire destination file). This required some refactoring and addition of a mechanism to detect if a "fast" query was performed (for the tests). Minor code cleanups, etc. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (amani) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, w/threadsafe, in production mode Linux/PPC 2.6 (heiwa) w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.4 (amazon) in debug mode Mac OS X/32 10.6.4 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode Mac OS X/32 10.6.4 (amazon) w/parallel, in debug mode
-rw-r--r--MANIFEST1
-rw-r--r--src/H5Dtest.c2
-rw-r--r--src/H5Gname.c72
-rw-r--r--src/H5Gprivate.h4
-rw-r--r--src/H5Gtraverse.c95
-rw-r--r--src/H5I.c50
-rw-r--r--src/H5Ipkg.h6
-rw-r--r--src/H5Itest.c98
-rw-r--r--src/H5Lexternal.c52
-rwxr-xr-xsrc/Makefile.am2
-rw-r--r--src/Makefile.in5
-rw-r--r--test/getname.c109
12 files changed, 339 insertions, 157 deletions
diff --git a/MANIFEST b/MANIFEST
index 6f67124..e4efb7a 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -638,6 +638,7 @@
./src/H5Ipkg.h
./src/H5Iprivate.h
./src/H5Ipublic.h
+./src/H5Itest.c
./src/H5L.c
./src/H5Lexternal.c
./src/H5Lpkg.h
diff --git a/src/H5Dtest.c b/src/H5Dtest.c
index a933c88..0a69ff7 100644
--- a/src/H5Dtest.c
+++ b/src/H5Dtest.c
@@ -14,7 +14,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
- * Thusdayr, May 27, 2004
+ * Thursday, May 27, 2004
*
* Purpose: Dataset testing functions.
*/
diff --git a/src/H5Gname.c b/src/H5Gname.c
index b298ccf..96b2e3a 100644
--- a/src/H5Gname.c
+++ b/src/H5Gname.c
@@ -426,49 +426,57 @@ H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth)
*-------------------------------------------------------------------------
*/
ssize_t
-H5G_get_name(hid_t id, char *name/*out*/, size_t size, hid_t lapl_id,
- hid_t dxpl_id)
+H5G_get_name(const H5G_loc_t *loc, char *name/*out*/, size_t size,
+ hbool_t *cached, hid_t lapl_id, hid_t dxpl_id)
{
- H5G_loc_t loc; /* Object location */
- ssize_t ret_value = FAIL;
+ ssize_t len = 0; /* Length of object's name */
+ ssize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5G_get_name, FAIL)
- /* get object location */
- if(H5G_loc(id, &loc) >= 0) {
- ssize_t len = 0;
+ /* Sanity check */
+ HDassert(loc);
- /* If the user path is available and it's not "hidden", use it */
- if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0) {
- len = H5RS_len(loc.path->user_path_r);
+ /* If the user path is available and it's not "hidden", use it */
+ if(loc->path->user_path_r != NULL && loc->path->obj_hidden == 0) {
+ len = H5RS_len(loc->path->user_path_r);
- if(name) {
- HDstrncpy(name, H5RS_get_str(loc.path->user_path_r), MIN((size_t)(len + 1), size));
- if((size_t)len >= size)
- name[size - 1] = '\0';
- } /* end if */
+ if(name) {
+ HDstrncpy(name, H5RS_get_str(loc->path->user_path_r), MIN((size_t)(len + 1), size));
+ if((size_t)len >= size)
+ name[size - 1] = '\0';
} /* end if */
- else if(!loc.path->obj_hidden) {
- hid_t file;
- /* Retrieve file ID for name search */
- if((file = H5I_get_file_id(id, FALSE)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve file ID")
+ /* Indicate that the name is cached, if requested */
+ /* (Currently only used for testing - QAK, 2010/07/26) */
+ if(cached)
+ *cached = TRUE;
+ } /* end if */
+ else if(!loc->path->obj_hidden) {
+ hid_t file;
- /* Search for name of object */
- if((len = H5G_get_name_by_addr(file, lapl_id, dxpl_id, loc.oloc, name, size)) < 0) {
- H5I_dec_ref(file, FALSE);
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name")
- } /* end if */
+ /* Retrieve file ID for name search */
+ if((file = H5F_get_id(loc->oloc->file, FALSE)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get file ID")
- /* Close file ID used for search */
- if(H5I_dec_ref(file, FALSE) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEFILE, FAIL, "can't determine name")
- } /* end else */
+ /* Search for name of object */
+ if((len = H5G_get_name_by_addr(file, lapl_id, dxpl_id, loc->oloc, name, size)) < 0) {
+ H5I_dec_ref(file, FALSE);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't determine name")
+ } /* end if */
- /* Set return value */
- ret_value = len;
- } /* end if */
+ /* Close file ID used for search */
+ if(H5I_dec_ref(file, FALSE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCLOSEFILE, FAIL, "can't determine name")
+
+ /* Indicate that the name is _not_ cached, if requested */
+ /* (Currently only used for testing - QAK, 2010/07/26) */
+ if(cached)
+ *cached = FALSE;
+ } /* end else */
+
+ /* Set return value */
+ ret_value = len;
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 3e66777..7b09423 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -196,8 +196,8 @@ H5_DLL herr_t H5G_name_replace(const struct H5O_link_t *lnk, H5G_names_op_t op,
H5_DLL herr_t H5G_name_reset(H5G_name_t *name);
H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5_copy_depth_t depth);
H5_DLL herr_t H5G_name_free(H5G_name_t *name);
-H5_DLL ssize_t H5G_get_name(hid_t id, char *name/*out*/, size_t size,
- hid_t lapl_id, hid_t dxpl_id);
+H5_DLL ssize_t H5G_get_name(const H5G_loc_t *loc, char *name/*out*/, size_t size,
+ hbool_t *cached, hid_t lapl_id, hid_t dxpl_id);
H5_DLL ssize_t H5G_get_name_by_addr(hid_t fid, hid_t lapl_id, hid_t dxpl_id,
const struct H5O_loc_t *loc, char* name, size_t size);
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
index 5b1f71c..61c08fa 100644
--- a/src/H5Gtraverse.c
+++ b/src/H5Gtraverse.c
@@ -171,8 +171,7 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
H5G_loc_t grp_loc_copy;
H5G_name_t grp_path_copy;
H5O_loc_t grp_oloc_copy;
- H5O_loc_t *new_oloc = NULL;
- H5F_t *temp_file = NULL;
+ H5G_loc_t new_loc; /* Group location for newly opened external object */
H5G_t *grp;
hid_t lapl_id = (-1); /* LAPL local to this routine */
H5P_genplist_t *lapl; /* LAPL with nlinks set */
@@ -189,13 +188,9 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
HDassert(nlinks);
HDassert(_lapl_id >= 0);
- /* Reset the object's path information, because we can't detect any changes
- * in the "path" the user-defined callback takes */
- H5G_name_free(obj_loc->path);
-
/* Get the link class for this type of link. */
if(NULL == (link_class = H5L_find_class(lnk->type)))
- HGOTO_ERROR(H5E_LINK, H5E_NOTREGISTERED, FAIL, "unable to get UD link class")
+ HGOTO_ERROR(H5E_SYM, H5E_NOTREGISTERED, FAIL, "unable to get UD link class")
/* Set up location for user-defined callback. Use a copy of our current
* grp_loc. */
@@ -203,37 +198,37 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
grp_loc_copy.oloc = &grp_oloc_copy;
H5G_loc_reset(&grp_loc_copy);
if(H5G_loc_copy(&grp_loc_copy, grp_loc, H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy object location")
- /* Create a group to pass to the user-defined callback */
- if((grp = H5G_open(&grp_loc_copy, dxpl_id)) == NULL)
+ /* Create a group ID to pass to the user-defined callback */
+ if(NULL == (grp = H5G_open(&grp_loc_copy, dxpl_id)))
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
if((cur_grp = H5I_register(H5I_GROUP, grp, FALSE)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "unable to register group")
/* Check for generic default property list and use link access default if so */
if(_lapl_id == H5P_DEFAULT) {
HDassert(H5P_LINK_ACCESS_DEFAULT != -1);
if(NULL == (lapl = (H5P_genplist_t *)H5I_object(H5P_LINK_ACCESS_DEFAULT)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get default property list")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "unable to get default property list")
} /* end if */
else {
/* Get the underlying property list passed in */
if(NULL == (lapl = (H5P_genplist_t *)H5I_object(_lapl_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "unable to get property list from ID")
} /* end else */
/* Copy the property list passed in */
if((lapl_id = H5P_copy_plist(lapl, FALSE)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unable to copy property list")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy property list")
/* Get the underlying property list copy */
if(NULL == (lapl = (H5P_genplist_t *)H5I_object(lapl_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "unable to get property list from ID")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "unable to get property list from ID")
/* Record number of soft links left to traverse in the property list. */
if(H5P_set(lapl, H5L_ACS_NLINKS_NAME, nlinks) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set nlink info")
/* User-defined callback function */
cb_return = (link_class->trav_func)(lnk->name, cur_grp, lnk->u.ud.udata, lnk->u.ud.size, lapl_id);
@@ -253,79 +248,45 @@ H5G_traverse_ud(const H5G_loc_t *grp_loc/*in,out*/, const H5O_link_t *lnk,
} /* end if */
/* else, we really needed to open the object */
else
- HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "traversal callback returned invalid ID")
+ HGOTO_ERROR(H5E_SYM, H5E_BADATOM, FAIL, "traversal callback returned invalid ID")
} /* end if */
- /* Get the oloc from the ID the user callback returned */
- switch(H5I_get_type(cb_return)) {
- case H5I_GROUP:
- if((new_oloc = H5G_oloc((H5G_t *)H5I_object(cb_return))) == NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from group ID")
- break;
-
- case H5I_DATASET:
- if((new_oloc = H5D_oloc((H5D_t *)H5I_object(cb_return))) ==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from dataset ID")
- break;
-
- case H5I_DATATYPE:
- if((new_oloc = H5T_oloc((H5T_t *)H5I_object(cb_return))) ==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location from datatype ID")
- break;
-
- case H5I_FILE:
- if((temp_file = (H5F_t *)H5I_object(cb_return)) == NULL)
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "couldn't get file from ID")
- if((new_oloc = H5G_oloc(temp_file->shared->root_grp)) ==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get root group location from file ID")
- break;
-
- case H5I_UNINIT:
- case H5I_BADID:
- case H5I_DATASPACE:
- case H5I_ATTR:
- case H5I_REFERENCE:
- case H5I_VFL:
- case H5I_GENPROP_CLS:
- case H5I_GENPROP_LST:
- case H5I_ERROR_CLASS:
- case H5I_ERROR_MSG:
- case H5I_ERROR_STACK:
- case H5I_NTYPES:
- default:
- HGOTO_ERROR(H5E_ATOM, H5E_BADTYPE, FAIL, "not a valid location or object ID")
- } /* end switch */
-
- /* Copy the location the user returned to us */
- if(H5O_loc_copy(obj_loc->oloc, new_oloc, H5_COPY_DEEP) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+ /* Get the object location information from the ID the user callback returned */
+ if(H5G_loc(cb_return, &new_loc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to get object location from ID")
+
+ /* Release any previous location information for the object */
+ H5G_loc_free(obj_loc);
+
+ /* Copy new object's location information */
+ H5G_loc_copy(obj_loc, &new_loc, H5_COPY_DEEP);
/* Hold the file open until we free this object header (otherwise the
* object location will be invalidated when the file closes).
*/
if(H5O_loc_hold_file(obj_loc->oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to hold file open")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to hold file open")
/* We have a copy of the location and we're holding the file open.
* Close the open ID the user passed back.
*/
if(H5I_dec_ref(cb_return, FALSE) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
cb_return = (-1);
done:
/* Close location given to callback. */
if(cur_grp > 0)
if(H5I_dec_ref(cur_grp, FALSE) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location")
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom for current location")
if(ret_value < 0 && cb_return > 0)
if(H5I_dec_ref(cb_return, FALSE) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close atom from UD callback")
/* Close the LAPL, if we copied one */
if(lapl_id > 0 && H5I_dec_ref(lapl_id, FALSE) < 0)
- HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close copied link access property list")
+ HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close copied link access property list")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_traverse_ud() */
@@ -573,7 +534,7 @@ H5G_traverse_special(const H5G_loc_t *grp_loc, const H5O_link_t *lnk,
*/
if(grp_loc->oloc->holding_file && grp_loc->oloc->file == obj_loc->oloc->file)
if(H5O_loc_hold_file(obj_loc->oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to hold file open")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to hold file open")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -845,7 +806,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
*/
if(grp_loc.oloc->holding_file)
if(H5O_loc_hold_file(obj_loc.oloc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "unable to hold file open")
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to hold file open")
} /* end if */
else
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
diff --git a/src/H5I.c b/src/H5I.c
index d6655e0..be3c9d6 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -896,7 +896,7 @@ H5I_register(H5I_type_t type, const void *object, hbool_t app_ref)
/* new ID to check for */
next_id = H5I_MAKE(type, type_ptr->nextid);
- hash_loc = H5I_LOC(type_ptr->nextid, type_ptr->hash_size);
+ hash_loc = (unsigned)H5I_LOC(type_ptr->nextid, type_ptr->hash_size);
curr_id = type_ptr->id_list[hash_loc];
if(curr_id == NULL)
break; /* Ha! this is not likely... */
@@ -1421,15 +1421,16 @@ H5I_dec_ref(hid_t id, hbool_t app_ref)
if(!type_ptr->free_func || (type_ptr->free_func)((void *)id_ptr->obj_ptr) >= 0) {
H5I_remove(id);
ret_value = 0;
- } else {
+ } /* end if */
+ else
ret_value = FAIL;
- }
- } else {
+ } /* end if */
+ else {
--(id_ptr->count);
- if (app_ref)
+ if(app_ref)
--(id_ptr->app_count);
HDassert(id_ptr->count >= id_ptr->app_count);
- ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
+ ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count);
}
done:
@@ -1525,7 +1526,7 @@ H5I_inc_ref(hid_t id, hbool_t app_ref)
++(id_ptr->app_count);
/* Set return value */
- ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
+ ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1615,7 +1616,7 @@ H5I_get_ref(hid_t id, hbool_t app_ref)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't locate ID")
/* Set return value */
- ret_value = app_ref ? id_ptr->app_count : id_ptr->count;
+ ret_value = (int)(app_ref ? id_ptr->app_count : id_ptr->count);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1696,7 +1697,7 @@ H5I_inc_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
- ret_value = ++(type_ptr->count);
+ ret_value = (int)(++(type_ptr->count));
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1797,7 +1798,7 @@ H5I_dec_type_ref(H5I_type_t type)
} /* end if */
else {
--(type_ptr->count);
- ret_value = type_ptr->count;
+ ret_value = (herr_t)type_ptr->count;
} /* end else */
done:
@@ -1879,7 +1880,7 @@ H5I_get_type_ref(H5I_type_t type)
HGOTO_ERROR(H5E_ATOM, H5E_BADGROUP, FAIL, "invalid type")
/* Set return value */
- ret_value = type_ptr->count;
+ ret_value = (int)type_ptr->count;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2133,13 +2134,18 @@ done:
ssize_t
H5Iget_name(hid_t id, char *name/*out*/, size_t size)
{
+ H5G_loc_t loc; /* Object location */
ssize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Iget_name, FAIL)
H5TRACE3("Zs", "ixz", id, name, size);
+ /* Get object location */
+ if(H5G_loc(id, &loc) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location")
+
/* Call internal group routine to retrieve object's name */
- if((ret_value = H5G_get_name(id, name, size, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ if((ret_value = H5G_get_name(&loc, name, size, NULL, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name")
done:
@@ -2187,7 +2193,6 @@ done:
* ID given an object ID.
*
* Return: Success: file ID
- *
* Failure: a negative value
*
* Programmer: Raymond Lu
@@ -2198,7 +2203,6 @@ done:
hid_t
H5I_get_file_id(hid_t obj_id, hbool_t app_ref)
{
- H5G_loc_t loc; /* Location of object */
H5I_type_t type; /* ID type */
hid_t ret_value; /* Return value */
@@ -2207,18 +2211,24 @@ H5I_get_file_id(hid_t obj_id, hbool_t app_ref)
/* Get object type */
type = H5I_TYPE(obj_id);
if(type == H5I_FILE) {
- ret_value = obj_id;
-
- /* Increment reference count on atom. */
- if(H5I_inc_ref(ret_value, app_ref) < 0)
+ /* Increment reference count on file ID */
+ if(H5I_inc_ref(obj_id, app_ref) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
- }
+
+ /* Set return value */
+ ret_value = obj_id;
+ } /* end if */
else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) {
+ H5G_loc_t loc; /* Location of object */
+
+ /* Get the object location information */
if(H5G_loc(obj_id, &loc) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get object location")
+
+ /* Get the file ID for the object */
if((ret_value = H5F_get_id(loc.oloc->file, app_ref)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get file ID")
- }
+ } /* end if */
else
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID")
diff --git a/src/H5Ipkg.h b/src/H5Ipkg.h
index e86f134..f17a4b0 100644
--- a/src/H5Ipkg.h
+++ b/src/H5Ipkg.h
@@ -67,4 +67,10 @@
/* Package Private Prototypes */
/******************************/
+/* Testing functions */
+#ifdef H5I_TESTING
+H5_DLL ssize_t H5I_get_name_test(hid_t id, char *name/*out*/, size_t size,
+ hbool_t *cached);
+#endif /* H5I_TESTING */
+
#endif /*_H5Ipkg_H*/
diff --git a/src/H5Itest.c b/src/H5Itest.c
new file mode 100644
index 0000000..1c6892d
--- /dev/null
+++ b/src/H5Itest.c
@@ -0,0 +1,98 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Quincey Koziol <koziol@hdfgoup.org>
+ * Tuesday, July 27, 2010
+ *
+ * Purpose: ID testing functions.
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5I_PACKAGE /*suppress error about including H5Ipkg */
+#define H5I_TESTING /*suppress warning about H5I testing funcs*/
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gprivate.h" /* Groups */
+#include "H5Ipkg.h" /* IDs */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5I_get_name_test
+ *
+ * Purpose: Testing version of H5Iget_name()
+ *
+ * Return: Success: The length of name.
+ * Failure: -1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 27, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5I_get_name_test(hid_t id, char *name/*out*/, size_t size, hbool_t *cached)
+{
+ H5G_loc_t loc; /* Object location */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5I_get_name_test, FAIL)
+
+ /* Get object location */
+ if(H5G_loc(id, &loc) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object location")
+
+ /* Call internal group routine to retrieve object's name */
+ if((ret_value = H5G_get_name(&loc, name, size, cached, H5P_DEFAULT, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve object name")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_get_name_test() */
+
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index c5ae92f..d98a843 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -53,6 +53,9 @@ const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{
/* Valid flags for external links */
#define H5L_EXT_FLAGS_ALL 0
+/* Size of local link name buffer for traversing external links */
+#define H5L_EXT_TRAVERSE_BUF_SIZE 256
+
/*--------------------------------------------------------------------------
NAME
@@ -205,7 +208,8 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
H5L_elink_cb_t cb_info; /* Callback info struct */
hid_t fapl_id = -1; /* File access property list for external link's file */
hid_t ext_obj = -1; /* ID for external link's object */
- char *temp_group_name = NULL;/* Temporary pointer to group name */
+ char *parent_group_name = NULL;/* Temporary pointer to group name */
+ char local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE]; /* Local buffer to hold group name */
char *temp_file_name = NULL; /* Temporary pointer to file name */
char *actual_file_name = NULL; /* Parent file's actual name */
H5P_genplist_t *fa_plist; /* File access property list pointer */
@@ -264,41 +268,34 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
/* Make callback if it exists */
if(cb_info.func) {
const char *parent_file_name; /* Parent file name */
- const char *parent_group_name; /* Parent group name */
+ ssize_t group_name_len; /* Length of parent group name */
/* Get parent file name */
parent_file_name = H5F_OPEN_NAME(loc.oloc->file);
+ /* Query length of parent group name */
+ if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
+
+ /* Account for null terminator */
+ group_name_len++;
+
+ /* Check if we need to allocate larger buffer */
+ if((size_t)group_name_len > sizeof(local_group_name)) {
+ if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %Zu", group_name_len)
+ } /* end if */
+ else
+ parent_group_name = local_group_name;
+
/* Get parent group name */
- if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0)
- /* Use user_path_r if possible */
- parent_group_name = H5RS_get_str(loc.path->user_path_r);
- else {
- /* Otherwise use H5G_get_name */
- ssize_t group_name_len; /* Length of parent group name */
-
- /* Get length of parent group name */
- if((group_name_len = H5G_get_name(cur_group, NULL, (size_t) 0, lapl_id, H5AC_ind_dxpl_id)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
-
- /* account for null terminator */
- group_name_len++;
-
- /* Copy parent group name */
- if(NULL == (temp_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
- HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(H5G_get_name(cur_group, temp_group_name, (size_t) group_name_len, lapl_id, H5AC_ind_dxpl_id) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
- parent_group_name = temp_group_name;
- } /* end else */
+ if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL, lapl_id, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
/* Make callback */
if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")
- /* Free temp_group_name */
- temp_group_name = (char *)H5MM_xfree(temp_group_name);
-
/* Check access flags */
if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
@@ -460,8 +457,9 @@ done:
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
if(ext_file && H5F_try_close(ext_file) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file")
+ if(parent_group_name && parent_group_name != local_group_name)
+ parent_group_name = (char *)H5MM_xfree(parent_group_name);
full_name = (char *)H5MM_xfree(full_name);
- temp_group_name = (char *)H5MM_xfree(temp_group_name);
temp_file_name = (char *)H5MM_xfree(temp_file_name);
actual_file_name = (char *)H5MM_xfree(actual_file_name);
diff --git a/src/Makefile.am b/src/Makefile.am
index 65e2bac..dc0edb3 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -72,7 +72,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
H5HG.c H5HGcache.c H5HGdbg.c \
H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c \
- H5HP.c H5I.c H5L.c H5Lexternal.c H5lib_settings.c \
+ H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \
H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 88d8793..c7fb1b4 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -122,7 +122,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo H5HFiblock.lo H5HFiter.lo \
H5HFman.lo H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo \
H5HFtiny.lo H5HG.lo H5HGcache.lo H5HGdbg.lo H5HL.lo \
- H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5L.lo \
+ H5HLcache.lo H5HLdbg.lo H5HLint.lo H5HP.lo H5I.lo H5Itest.lo H5L.lo \
H5Lexternal.lo H5lib_settings.lo H5MF.lo H5MFaggr.lo \
H5MFdbg.lo H5MFsection.lo H5MM.lo H5MP.lo H5MPtest.lo H5O.lo \
H5Oainfo.lo H5Oalloc.lo H5Oattr.lo H5Oattribute.lo H5Obogus.lo \
@@ -492,7 +492,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \
H5HG.c H5HGcache.c H5HGdbg.c \
H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c \
- H5HP.c H5I.c H5L.c H5Lexternal.c H5lib_settings.c \
+ H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \
H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
@@ -803,6 +803,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HLint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HP.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Itest.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Lexternal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@
diff --git a/test/getname.c b/test/getname.c
index 0dc623e..eba0f6b 100644
--- a/test/getname.c
+++ b/test/getname.c
@@ -21,12 +21,15 @@
*/
#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+#define H5I_PACKAGE /*suppress error about including H5Ipkg */
-/* Define this macro to indicate that the testing APIs should be available */
+/* Define these macros to indicate that the testing APIs should be available */
#define H5G_TESTING
+#define H5I_TESTING
#include "h5test.h"
#include "H5Gpkg.h" /* Groups */
+#include "H5Ipkg.h" /* IDs */
/* Compound datatype */
@@ -1145,7 +1148,7 @@ test_main(hid_t file_id, hid_t fapl)
/* Get name */
*name2 = '\0';
- name_len=H5Iget_name(group_id, name2, SMALL_NAME_BUF_SIZE);
+ name_len=(size_t)H5Iget_name(group_id, name2, SMALL_NAME_BUF_SIZE);
/* Check that name is longer */
if(name_len <= SMALL_NAME_BUF_SIZE) TEST_ERROR
@@ -1172,14 +1175,14 @@ test_main(hid_t file_id, hid_t fapl)
if((group_id = H5Gopen2(file_id, "/g17", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR
/* Get name */
- name_len = H5Iget_name(group_id, NULL, NAME_BUF_SIZE);
+ name_len = (size_t)H5Iget_name(group_id, NULL, NAME_BUF_SIZE);
{
/* dynamic buffer to hold name */
char *name3;
/* Include the extra null character */
- name3 = HDmalloc(name_len + 1);
+ name3 = (char *)HDmalloc(name_len + 1);
if(!name3) TEST_ERROR
/* Get name with dynamic buffer */
@@ -2679,7 +2682,7 @@ test_reg_ref(hid_t fapl)
hsize_t count[2];
hsize_t coord[2][3] = {{0, 0, 1}, {6, 0, 8}};
unsigned num_points = 3;
- size_t name_size1, name_size2;
+ ssize_t name_size1, name_size2;
char buf1[NAME_BUF_SIZE], buf2[NAME_BUF_SIZE];
/* Initialize the file name */
@@ -2808,6 +2811,101 @@ error:
return 1;
}
+
+/*-------------------------------------------------------------------------
+ * Function: test_elinks
+ *
+ * Purpose: Verify that querying names of objects reached via external
+ * links uses cached path/name information for object and doesn't
+ * search the file.
+ *
+ * Return: Success: 0
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, July 27, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_elinks(hid_t fapl)
+{
+ char filename1[1024], filename2[1024]; /* Filenames */
+ hid_t fid1, fid2; /* HDF5 File IDs */
+ hid_t group, group2; /* Group IDs */
+ char name[NAME_BUF_SIZE]; /* Buffer for storing object's name */
+ ssize_t namelen; /* Length of object's name */
+ hbool_t name_cached; /* Indicate if name is cached */
+ unsigned u; /* Counting variables */
+
+ /* Initialize the file names */
+ h5_fixname(FILENAME[1], fapl, filename1, sizeof filename1);
+ h5_fixname(FILENAME[2], fapl, filename2, sizeof filename2);
+
+ /* Create files */
+ if((fid1 = H5Fcreate(filename1, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ FAIL_STACK_ERROR
+ if((fid2 = H5Fcreate(filename2, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create a group in the second file */
+ if((group2 = H5Gcreate2(fid2, "Group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close Group */
+ if(H5Gclose(group2) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create an external link in first file to the group in the second file */
+ if(H5Lcreate_external(filename2, "Group2", fid1, "Link_to_Group2", H5P_DEFAULT, H5P_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+
+ /* Create an external link in second file to the external link in the first file */
+ if(H5Lcreate_external(filename1, "Link_to_Group2", fid2, "Link_to_Link_to_Group2", H5P_DEFAULT, H5P_DEFAULT) < 0)
+ FAIL_STACK_ERROR
+
+ /* Open the group in thesecond file through the external link */
+ if((group = H5Gopen2(fid1, "Link_to_Group2", H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Query the external link object's name */
+ *name = '\0';
+ name_cached = FALSE;
+ namelen = H5I_get_name_test(group, (char*)name, sizeof(name), &name_cached);
+ if(!((HDstrcmp(name, "/Group2") == 0) && (namelen == 7) && name_cached))
+ TEST_ERROR
+
+ /* Close Group */
+ if(H5Gclose(group) < 0)
+ FAIL_STACK_ERROR
+
+ /* Open the group in the second file through the external link to the external link */
+ if((group = H5Gopen2(fid2, "Link_to_Link_to_Group2", H5P_DEFAULT)) < 0)
+ FAIL_STACK_ERROR
+
+ /* Query the external link to external link object's name */
+ *name = '\0';
+ name_cached = FALSE;
+ namelen = H5I_get_name_test(group, (char*)name, sizeof(name), &name_cached);
+ if(!((HDstrcmp(name, "/Group2") == 0) && (namelen == 7) && name_cached))
+ TEST_ERROR
+
+ /* Close Group */
+ if(H5Gclose(group) < 0)
+ FAIL_STACK_ERROR
+
+ /* Close files */
+ if(H5Fclose(fid1) < 0)
+ FAIL_STACK_ERROR
+ if(H5Fclose(fid2) < 0)
+ FAIL_STACK_ERROR
+
+ return 0;
+
+error:
+ return 1;
+}
+
int
main(void)
{
@@ -2830,6 +2928,7 @@ main(void)
nerrors += test_main(file_id, fapl);
nerrors += test_obj_ref(fapl);
nerrors += test_reg_ref(fapl);
+ nerrors += test_elinks(fapl);
/* Close file */
H5Fclose(file_id);