From f82fc6b33dfd1f752183330e61807ab94ef2c6b7 Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Thu, 26 Feb 1998 13:05:27 -0500 Subject: [svn-r299] Changes since 19980224 ---------------------- ./html/Files.html Added a few details for some of the new H5Pset/get functions. ./src/H5F.c ./src/H5Fpublic.h Fixed automatic closing of files on exit(). Added public H5F_ACC_DEBUG. Using it to create or open a file turns on debugging for that file, which currently just prints cache statistics when the file is closed. ./src/H5G.c An error is returned if one tries to set the current working group to something other than a group. ./src/H5Gnode.c Fixed a symbol table bug. Under certain circumstances it was possible to enter a symbol in such a way that lookup of that symbol failed. A bug report was sent to hdf5dev. ./src/H5P.c ./src/H5Ppublic.h Added the H5Pget_...() functions for file drivers. The H5Pget_mpi() is a no-op that always fails. --- src/H5F.c | 19 ++- src/H5Fpublic.h | 2 +- src/H5G.c | 13 +- src/H5Gnode.c | 4 + src/H5P.c | 396 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/H5Ppublic.h | 16 ++- 6 files changed, 428 insertions(+), 22 deletions(-) diff --git a/src/H5F.c b/src/H5F.c index e2b884e..36f23a6 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -130,11 +130,12 @@ H5F_init_interface(void) { herr_t ret_value = SUCCEED; + interface_initialize_g = TRUE; FUNC_ENTER(H5F_init_interface, FAIL); /* Initialize the atom group for the file IDs */ if (H5A_init_group(H5_FILE, H5A_FILEID_HASHSIZE, 0, - (herr_t (*)(void*))H5Fclose)<0 || + (herr_t (*)(void*))H5F_close)<0 || H5_add_exit(H5F_term_interface)<0) { HRETURN_ERROR (H5E_ATOM, H5E_CANTINIT, FAIL, "unable to initialize interface"); @@ -151,7 +152,7 @@ H5F_init_interface(void) /* nothing more to init */ break; - case H5F_LOW_MPIO: + case H5F_LOW_MPI: #ifdef HAVE_PARALLEL H5F_access_dflt.u.mpio.access_mode = 0; H5F_access_dflt.u.mpio.comm = MPI_COMM_NULL; @@ -1064,7 +1065,7 @@ H5Fcreate(const char *filename, uintn flags, hid_t create_id, if (!filename || !*filename) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file name"); } - if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC)) { + if (flags & ~(H5F_ACC_EXCL|H5F_ACC_TRUNC|H5F_ACC_DEBUG)) { HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid flags"); } if ((flags & H5F_ACC_EXCL) && (flags & H5F_ACC_EXCL)) { @@ -1400,13 +1401,11 @@ H5Fclose(hid_t fid) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't unatomize file"); } - /* Close the file */ - ret_value = H5F_close(file); - - /* Remove the file atom */ - if (NULL == H5A_remove(fid)) { - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't remove atom"); - } + /* + * Decrement reference count on atom. When it reaches zero the file will + * be closed. + */ + H5A_dec_ref (fid); done: FUNC_LEAVE(ret_value < 0 ? FAIL : SUCCEED); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index 5843103..fbd827c 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -52,7 +52,7 @@ typedef enum H5F_driver_t { H5F_LOW_ERROR = -1, /*error return value */ H5F_LOW_STDIO = 0, /*use functions declared in stdio.h */ H5F_LOW_SEC2 = 1, /*use functions declared in unistd.h */ - H5F_LOW_MPIO = 2, /*use indep or collective MPI-IO */ + H5F_LOW_MPI = 2, /*use indep or collective MPI-IO */ H5F_LOW_CORE = 3, /*use malloc() and free() */ H5F_LOW_SPLIT = 4, /*separate meta data from raw data */ H5F_LOW_FAMILY = 5, /*split addr space over many files */ diff --git a/src/H5G.c b/src/H5G.c index fd6f130..e1212b0 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -834,11 +834,12 @@ H5G_create(H5F_t *f, const char *name, size_t size_hint) * *------------------------------------------------------------------------- */ -H5G_t * +H5G_t * H5G_open(H5F_t *f, const char *name) { - H5G_t *grp = NULL; - H5G_t *ret_value = NULL; + H5G_t *grp = NULL; + H5G_t *ret_value = NULL; + H5O_stab_t mesg; FUNC_ENTER(H5G_open, NULL); @@ -846,7 +847,7 @@ H5G_open(H5F_t *f, const char *name) assert(f); assert(name && *name); - /* Open the group */ + /* Open the object, making sure it's a group */ grp = H5MM_xcalloc(1, sizeof(H5G_t)); if (H5G_find(f, name, NULL, &(grp->ent)) < 0) { HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "group not found"); @@ -854,6 +855,10 @@ H5G_open(H5F_t *f, const char *name) if (H5O_open(f, &(grp->ent)) < 0) { HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group"); } + if (NULL==H5O_read (&(grp->ent), H5O_STAB, 0, &mesg)) { + H5O_close (&(grp->ent)); + HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL, "not a group"); + } grp->nref = 1; ret_value = grp; diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 59bfd1c..d309d97 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -800,6 +800,10 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, } else { idx -= H5G_NODE_K(f); insert_into = snrt; + if (idx == H5G_NODE_K (f)) { + rt_key->offset = offset; + *rt_key_changed = TRUE; + } } } else { diff --git a/src/H5P.c b/src/H5P.c index 4e180e2b..00dbe46 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -282,17 +282,44 @@ H5Pclose(hid_t tid) herr_t H5P_close (H5P_class_t type, void *tmpl) { + H5F_access_t *fa_list = (H5F_access_t*)tmpl; + FUNC_ENTER (H5P_close, FAIL); /* Check args */ - assert (tmpl); + if (!tmpl) HRETURN (SUCCEED); /* Some templates may need to do special things */ switch (type) { case H5P_FILE_ACCESS: + switch (fa_list->driver) { + case H5F_LOW_ERROR: + case H5F_LOW_SEC2: + case H5F_LOW_STDIO: + case H5F_LOW_CORE: + /* Nothing to do */ + break; + + case H5F_LOW_MPI: #ifdef LATER - /* Need to free the COMM and INFO objects too. */ + /* Need to free the COMM and INFO objects too. */ #endif + break; + + case H5F_LOW_SPLIT: + /* Free member info */ + fa_list->driver = H5F_LOW_ERROR; /*prevent cycles*/ + H5P_close (H5P_FILE_ACCESS, fa_list->u.split.meta_access); + H5P_close (H5P_FILE_ACCESS, fa_list->u.split.raw_access); + H5MM_xfree (fa_list->u.split.meta_ext); + H5MM_xfree (fa_list->u.split.raw_ext); + break; + + case H5F_LOW_FAMILY: + /* Free member info */ + H5P_close (H5P_FILE_ACCESS, fa_list->u.fam.memb_access); + break; + } break; case H5P_FILE_CREATE: @@ -930,6 +957,41 @@ H5Pget_chunk(hid_t tid, int max_ndims, size_t dim[] /*out */ ) /*------------------------------------------------------------------------- + * Function: H5Pget_driver + * + * Purpose: Return the ID of the low-level file driver. TID should be a + * file access property list. + * + * Return: Success: A low-level driver ID + * + * Failure: H5F_LOW_ERROR (a negative value) + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +H5F_driver_t +H5Pget_driver (hid_t tid) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_driver, H5F_LOW_ERROR); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + + FUNC_LEAVE (tmpl->driver); +} + + +/*------------------------------------------------------------------------- * Function: H5Pset_stdio * * Purpose: Set the low level file driver to use the functions declared @@ -969,6 +1031,47 @@ H5Pset_stdio (hid_t tid) /*------------------------------------------------------------------------- + * Function: H5Pget_stdio + * + * Purpose: If the file access property list is set to the stdio driver + * then this function returns zero; otherwise it returns a + * negative value. In the future, additional arguments may be + * added to this function to match those added to H5Pset_stdio(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_stdio (hid_t tid) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_stdio, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + if (H5F_LOW_STDIO != tmpl->driver) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "the stdio driver is not set"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Pset_sec2 * * Purpose: Set the low-level file driver to use the functions declared @@ -1008,6 +1111,47 @@ H5Pset_sec2 (hid_t tid) /*------------------------------------------------------------------------- + * Function: H5Pget_sec2 + * + * Purpose: If the file access property list is set to the sec2 driver + * then this function returns zero; otherwise it returns a + * negative value. In the future, additional arguments may be + * added to this function to match those added to H5Pset_sec2(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_sec2 (hid_t tid) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_sec2, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + if (H5F_LOW_SEC2 != tmpl->driver) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "the sec2 driver is not set"); + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Pset_core * * Purpose: Set the low-level file driver to use malloc() and free(). @@ -1056,6 +1200,54 @@ H5Pset_core (hid_t tid, size_t increment) /*------------------------------------------------------------------------- + * Function: H5Pget_core + * + * Purpose: If the file access property list is set to the core driver + * then this function returns zero; otherwise it returns a + * negative value. On success, the block size is returned + * through the INCREMENT argument if it isn't the null pointer. + * In the future, additional arguments may be added to this + * function to match those added to H5Pset_core(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_core (hid_t tid, size_t *increment/*out*/) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_core, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + if (H5F_LOW_CORE != tmpl->driver) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "the core driver is not set"); + } + + /* Return values */ + if (increment) { + *increment = tmpl->u.core.increment; + } + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5Pset_split * * Purpose: Set the low-level driver to split meta data from raw data, @@ -1073,7 +1265,8 @@ H5Pset_core (hid_t tid, size_t increment) *------------------------------------------------------------------------- */ herr_t -H5Pset_split (hid_t tid, hid_t meta_tid, hid_t raw_tid) +H5Pset_split (hid_t tid, const char *meta_ext, hid_t meta_tid, + const char *raw_ext, hid_t raw_tid) { H5F_access_t *tmpl = NULL; H5F_access_t *meta_tmpl = NULL; @@ -1104,6 +1297,96 @@ H5Pset_split (hid_t tid, hid_t meta_tid, hid_t raw_tid) tmpl->driver = H5F_LOW_SPLIT; tmpl->u.split.meta_access = H5P_copy (H5P_FILE_ACCESS, meta_tmpl); tmpl->u.split.raw_access = H5P_copy (H5P_FILE_ACCESS, raw_tmpl); + tmpl->u.split.meta_ext = H5MM_xstrdup (meta_ext); + tmpl->u.split.raw_ext = H5MM_xstrdup (raw_ext); + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_split + * + * Purpose: If the file access property list is set to the sec2 driver + * then this function returns zero; otherwise it returns a + * negative value. On success, at most META_EXT_SIZE characters + * are copied to the META_EXT buffer if non-null and at most + * RAW_EXT_SIZE characters are copied to the RAW_EXT buffer if + * non-null. If the actual extension is larger than the number + * of characters requested then the buffer will not be null + * terminated (that is, behavior like strncpy()). In addition, + * if META_PROPERTIES and/or RAW_PROPERTIES are non-null then + * the file access property list of the meta file and/or raw + * file is copied and its OID returned through these arguments. + * If the meta file or raw file has no property list then an OID + * of FAIL (-1) is returned but the H5Pget_split() function + * still returns SUCCEED. In the future, additional arguments + * may be added to this function to match those added to + * H5Pset_sec2(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_split (hid_t tid, size_t meta_ext_size, char *meta_ext/*out*/, + hid_t *meta_properties/*out*/, size_t raw_ext_size, + char *raw_ext/*out*/, hid_t *raw_properties/*out*/) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_split, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + if (H5F_LOW_SPLIT != tmpl->driver) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "the split driver is not set"); + } + + /* Reset output args for error handling */ + if (meta_ext && meta_ext_size>0) *meta_ext = '\0'; + if (raw_ext && raw_ext_size>0) *raw_ext = '\0'; + if (meta_properties) *meta_properties = FAIL; + if (raw_properties) *raw_properties = FAIL; + + /* Output arguments */ + if (meta_ext && meta_ext_size>0) { + if (tmpl->u.split.meta_ext) { + strncpy (meta_ext, tmpl->u.split.meta_ext, meta_ext_size); + } else { + strncpy (meta_ext, ".meta", meta_ext_size); + } + } + if (raw_ext && raw_ext_size>0) { + if (tmpl->u.split.raw_ext) { + strncpy (raw_ext, tmpl->u.split.raw_ext, raw_ext_size); + } else { + strncpy (raw_ext, ".raw", raw_ext_size); + } + } + if (meta_properties && tmpl->u.split.meta_access) { + *meta_properties = H5P_create (H5P_FILE_ACCESS, + H5P_copy (H5P_FILE_ACCESS, + tmpl->u.split.meta_access)); + } + if (raw_properties && tmpl->u.split.raw_access) { + *raw_properties = H5P_create (H5P_FILE_ACCESS, + H5P_copy (H5P_FILE_ACCESS, + tmpl->u.split.raw_access)); + } + FUNC_LEAVE (SUCCEED); } @@ -1155,9 +1438,63 @@ H5Pset_family (hid_t tid, hid_t memb_tid) FUNC_LEAVE (SUCCEED); } - -#ifdef HAVE_PARALLEL +/*------------------------------------------------------------------------- + * Function: H5Pget_family + * + * Purpose: If the file access property list is set to the family driver + * then this function returns zero; otherwise it returns a + * negative value. On success, if MEMB_TID is a non-null + * pointer it will be initialized with the OID of a copy of the + * file access template used for the family members. If the + * family members have no file access template (that is, they + * are using the default values) then FAIL (-1) is returned for + * the member property list OID but the function still returns + * SUCCEED. In the future, additional arguments may be added to + * this function to match those added to H5Pset_family(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_family (hid_t tid, hid_t *memb_tid) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_family, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + if (H5F_LOW_FAMILY != tmpl->driver) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "the family driver is not set"); + } + + /* Output args */ + if (memb_tid && tmpl->u.fam.memb_access) { + *memb_tid = H5P_create (H5P_FILE_ACCESS, + H5P_copy (H5P_FILE_ACCESS, + tmpl->u.fam.memb_access)); + } else if (memb_tid) { + *memb_tid = FAIL; + } + + FUNC_LEAVE (SUCCEED); +} + + /*------------------------------------------------------------------------- * Function: H5Pset_mpi * @@ -1211,6 +1548,7 @@ H5Pset_family (hid_t tid, hid_t memb_tid) * *------------------------------------------------------------------------- */ +#ifdef HAVE_PARALLEL herr_t H5Pset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, uintn access_mode) { @@ -1268,9 +1606,57 @@ H5Pset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, uintn access_mode) FUNC_LEAVE(SUCCEED); } +#endif /*HAVE_PARALLEL*/ + +/*------------------------------------------------------------------------- + * Function: H5Pget_mpi + * + * Purpose: If the file access property list is set to the mpi driver + * then this function returns zero; otherwise it returns a + * negative value. In the future, additional arguments may be + * added to this function to match those added to H5Pset_mpi(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Thursday, February 26, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +#ifdef HAVE_PARALLEL +herr_t +H5Pget_mpi (hid_t tid, MPI_Comm *comm, MPI_Info *info, uintn *access_mode) +{ + H5F_access_t *tmpl = NULL; + + FUNC_ENTER (H5Pget_mpi, FAIL); + + /* Check arguments */ + if (H5P_FILE_ACCESS != H5Pget_class (tid) || + NULL == (tmpl = H5A_object (tid))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a file access property list"); + } + if (H5F_LOW_MPI != tmpl->driver) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "the mpi driver is not set"); + } + +#ifndef LATER + HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, + "not implemented yet"); +#endif + + FUNC_LEAVE (SUCCEED); +} #endif /*HAVE_PARALLEL*/ + /*-------------------------------------------------------------------------- NAME H5Pcopy diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index b8074d2..b57b8e1 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -24,6 +24,7 @@ #include #include #include +#include /* Template classes */ typedef enum H5P_class_t { @@ -61,14 +62,25 @@ herr_t H5Pset_layout (hid_t tid, H5D_layout_t layout); H5D_layout_t H5Pget_layout (hid_t tid); herr_t H5Pset_chunk (hid_t tid, int ndims, const size_t dim[]); int H5Pget_chunk (hid_t tid, int max_ndims, size_t dim[]/*out*/); +H5F_driver_t H5Pget_driver (hid_t tid); herr_t H5Pset_stdio (hid_t tid); +herr_t H5Pget_stdio (hid_t tid); herr_t H5Pset_sec2 (hid_t tid); +herr_t H5Pget_sec2 (hid_t tid); herr_t H5Pset_core (hid_t tid, size_t increment); -herr_t H5Pset_split (hid_t tid, hid_t meta_tid, hid_t raw_tid); +herr_t H5Pget_core (hid_t tid, size_t *increment/*out*/); +herr_t H5Pset_split (hid_t tid, const char *meta_ext, hid_t meta_tid, + const char *raw_ext, hid_t raw_tid); +herr_t H5Pget_split (hid_t tid, size_t meta_ext_size, char *meta_ext/*out*/, + hid_t *meta_properties/*out*/, size_t raw_ext_size, + char *raw_ext/*out*/, hid_t *raw_properties/*out*/); + herr_t H5Pset_family (hid_t tid, hid_t memb_tid); +herr_t H5Pget_family (hid_t tid, hid_t *memb_tid/*out*/); #ifdef HAVE_PARALLEL herr_t H5Pset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, uintn access_mode); -/* herr_t H5Pget_mpi (hid_t tid, int *ik); */ /* not defined yet */ +herr_t H5Pget_mpi (hid_t tid, MPI_Comm *comm/*out*/, MPI_Info *info/*out*/, + uintn *access_mode/*out*/); #endif #ifdef __cplusplus -- cgit v0.12