From 58c03f79fd15001ee30b36d0afba14fc8dcaf687 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 7 Oct 2003 10:27:19 -0500 Subject: [svn-r7561] Purpose: Feature add Description: Add a few new fields to the H5G_stat_t structure, to allow more information about the object header to be retrieved. Platforms tested: FreeBSD 4.9 (sleipnir) h5committest --- release_docs/RELEASE.txt | 2 + src/H5G.c | 5 ++- src/H5Gpublic.h | 2 + src/H5O.c | 61 +++++++++++++++++++++++++ src/H5Oprivate.h | 1 + src/H5Opublic.h | 9 +++- test/tmisc.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 191 insertions(+), 2 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 0ceae39..d5f1d95 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -41,6 +41,8 @@ New Features Library: -------- + - Added new fields to the H5G_stat_t for more information about an + object's object header. QAK 2003/10/06 - Added new H5Fget_freespace() routine to query the free space in a given file. QAK 2003/10/06 - Added backward compatability with v1.6 for new Error API. SLU - diff --git a/src/H5G.c b/src/H5G.c index 7d15dee..92cfa51 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -2539,7 +2539,6 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, /* Some other type of object */ statbuf->objno = obj_ent.header; statbuf->nlink = H5O_link (&obj_ent, 0, dxpl_id); - statbuf->type = H5G_LINK; if (NULL==H5O_read(&obj_ent, H5O_MTIME_ID, 0, &(statbuf->mtime), dxpl_id)) { H5E_clear(NULL); if (NULL==H5O_read(&obj_ent, H5O_MTIME_NEW_ID, 0, &(statbuf->mtime), dxpl_id)) { @@ -2549,6 +2548,10 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, } statbuf->type = H5G_get_type(&obj_ent, dxpl_id); H5E_clear(NULL); /*clear errors resulting from checking type*/ + + /* Get object header information */ + if(H5O_get_info(&obj_ent, &(statbuf->ohdr), dxpl_id)<0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information") } /* Common code to retrieve the file's fileno */ diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 2a37fef..c907f5e 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -33,6 +33,7 @@ #include "H5public.h" #include "H5Ipublic.h" +#include "H5Opublic.h" #ifdef __cplusplus extern "C" { @@ -77,6 +78,7 @@ typedef struct H5G_stat_t { H5G_obj_t type; /*basic object type */ time_t mtime; /*modification time */ size_t linklen; /*symbolic link value length */ + H5O_stat_t ohdr; /* Object header information */ } H5G_stat_t; #define H5G_SAME_LOC 0 diff --git a/src/H5O.c b/src/H5O.c index d9ef4ff..ebda246 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -3279,6 +3279,67 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_get_info + * + * Purpose: Retrieve information about an object header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Oct 7 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id) +{ + H5O_t *oh=NULL; /* Object header information */ + H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ + hsize_t total_size; /* Total amount of space used in file */ + hsize_t free_space; /* Free space in object header */ + unsigned u; /* Local index variable */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_get_info,FAIL); + + /* Check args */ + assert (ent); + assert (ostat); + + /* Get the object header information */ + if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header"); + + /* Iterate over all the messages, accumulating the total size & free space */ + total_size=H5O_SIZEOF_HDR(ent->file); + free_space=0; + for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) { + /* Accumulate the size for this message */ + total_size+= H5O_SIZEOF_MSGHDR(ent->file) + curr_msg->raw_size; + + /* Check for this message being free space */ + if (H5O_NULL_ID == curr_msg->type->id) + free_space+= H5O_SIZEOF_MSGHDR(ent->file) + curr_msg->raw_size; + } /* end for */ + + /* Set the information for this object header */ + ostat->size=total_size; + ostat->free=free_space; + ostat->nmesgs=oh->nmesgs; + ostat->nchunks=oh->nchunks; + +done: + if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, FALSE)<0) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header"); + + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5O_get_info() */ + + +/*------------------------------------------------------------------------- * Function: H5O_debug_id * * Purpose: Act as a proxy for calling the 'debug' method for a diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index bcd2e5b..78f8c0e 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -234,6 +234,7 @@ H5_DLL void *H5O_copy(hid_t type_id, const void *mesg, void *dst); H5_DLL size_t H5O_raw_size(hid_t type_id, H5F_t *f, const void *mesg); H5_DLL herr_t H5O_get_share(hid_t type_id, H5F_t *f, const void *mesg, H5O_shared_t *share); H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); +H5_DLL herr_t H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id); H5_DLL herr_t H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth); H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int fwidth); diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 59d117d..e71ff9c 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -14,7 +14,7 @@ /*------------------------------------------------------------------------- * - * Created: H5Oproto.h + * Created: H5Opublic.h * Aug 5 1997 * Robb Matzke * @@ -31,6 +31,13 @@ /* Public headers needed by this file */ #include "H5public.h" +typedef struct H5O_stat_t { + hsize_t size; /* Total size of object header in file */ + hsize_t free; /* Free space within object header */ + unsigned nmesgs; /* Number of object header messages */ + unsigned nchunks; /* Number of object header chunks */ +} H5O_stat_t; + #ifdef __cplusplus extern "C" { #endif diff --git a/test/tmisc.c b/test/tmisc.c index c1c3a50..816c8cc 100644 --- a/test/tmisc.c +++ b/test/tmisc.c @@ -208,6 +208,11 @@ unsigned m13_rdata[MISC13_DIM1][MISC13_DIM2]; /* Data read from dataset #define MISC17_SPACE_DIM2 8 #define MISC17_DSET_NAME "Dataset" +/* Definitions for misc. test #18 */ +#define MISC18_FILE "tmisc18.h5" +#define MISC18_DSET1_NAME "Dataset1" +#define MISC18_DSET2_NAME "Dataset2" + /**************************************************************** ** @@ -2796,6 +2801,112 @@ test_misc17(void) /**************************************************************** ** +** test_misc18(): Test new object header information in H5G_stat_t +** struct. +** +****************************************************************/ +static void +test_misc18(void) +{ + hid_t fid; /* File ID */ + hid_t sid; /* 'Space ID */ + hid_t did1, did2; /* Dataset IDs */ + hid_t aid; /* Attribute ID */ + H5G_stat_t statbuf; /* Information about object */ + char attr_name[32]; /* Attribute name buffer */ + unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ + + /* Create the file */ + fid = H5Fcreate(MISC18_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + CHECK(fid, FAIL, "H5Fcreate"); + + /* Create dataspace for attributes */ + sid = H5Screate(H5S_SCALAR); + CHECK(sid, FAIL, "H5Screate_simple"); + + /* Create first dataset */ + did1 = H5Dcreate(fid, MISC18_DSET1_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT); + CHECK(did1, FAIL, "H5Screate_simple"); + + /* Get object information */ + ret = H5Gget_objinfo(fid,MISC18_DSET1_NAME,0,&statbuf); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nmesgs, 6, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nchunks, 1, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.size, 272, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.free, 152, "H5Gget_objinfo"); + + /* Create second dataset */ + did2 = H5Dcreate(fid, MISC18_DSET2_NAME, H5T_NATIVE_INT, sid, H5P_DEFAULT); + CHECK(did2, FAIL, "H5Screate_simple"); + + /* Get object information */ + ret = H5Gget_objinfo(fid,MISC18_DSET2_NAME,0,&statbuf); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nmesgs, 6, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nchunks, 1, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.size, 272, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.free, 152, "H5Gget_objinfo"); + + /* Loop creating attributes on each dataset, flushing them to the file each time */ + for(u=0; u<10; u++) { + /* Set up attribute name */ + sprintf(attr_name,"Attr %u",u); + + /* Create & close attribute on first dataset */ + aid = H5Acreate(did1, attr_name, H5T_NATIVE_INT, sid, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Gget_objinfo"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "HAclose"); + + /* Create & close attribute on second dataset */ + aid = H5Acreate(did2, attr_name, H5T_NATIVE_INT, sid, H5P_DEFAULT); + CHECK(aid, FAIL, "H5Gget_objinfo"); + + ret = H5Aclose(aid); + CHECK(ret, FAIL, "HAclose"); + + /* Flush file, to 'fix' size of dataset object headers */ + ret = H5Fflush(fid,H5F_SCOPE_GLOBAL); + CHECK(ret, FAIL, "HAclose"); + } /* end for */ + + /* Get object information for dataset #1 now */ + ret = H5Gget_objinfo(fid,MISC18_DSET1_NAME,0,&statbuf); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nmesgs, 24, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nchunks, 9, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.free, 16, "H5Gget_objinfo"); + + /* Get object information for dataset #2 now */ + ret = H5Gget_objinfo(fid,MISC18_DSET2_NAME,0,&statbuf); + CHECK(ret, FAIL, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nmesgs, 24, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.nchunks, 9, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.size, 888, "H5Gget_objinfo"); + VERIFY(statbuf.ohdr.free, 16, "H5Gget_objinfo"); + + /* Close second dataset */ + ret = H5Dclose(did2); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close first dataset */ + ret = H5Dclose(did1); + CHECK(ret, FAIL, "H5Sclose"); + + /* Close disk dataspace */ + ret = H5Sclose(sid); + CHECK(ret, FAIL, "H5Sclose"); + + ret = H5Fclose(fid); + CHECK(ret, FAIL, "H5Fclose"); +} /* end test_misc18() */ + +/**************************************************************** +** ** test_misc(): Main misc. test routine. ** ****************************************************************/ @@ -2822,6 +2933,7 @@ test_misc(void) test_misc15(); /* Test that checking a file's access property list more than once works */ test_misc16(); /* Test array of fixed-length string */ test_misc17(); /* Test array of ASCII character */ + test_misc18(); /* Test new object header information in H5G_stat_t struct */ } /* test_misc() */ @@ -2863,4 +2975,5 @@ cleanup_misc(void) HDremove(MISC15_FILE); HDremove(MISC16_FILE); HDremove(MISC17_FILE); + HDremove(MISC18_FILE); } -- cgit v0.12