[svn-r627] Changes since 19980827

----------------------

./src/H5G.c
	Fixed a link count on groups.  Groups were always created with
	a link count of zero instead of one.

./src/H5Gpublic.h
	Added H5G_NTYPES so applications can easily declare arrays
	which are indexed by object type.

./src/H5O.c
	Calling `H5O_link(&ent,0)' will succeed when the file is open
	for read only because it's the only way to get the object's
	current link count.

./tools/h5ls.c
	Can take non-group object names on the command line (and
	multiple objects).  Reorganized to be more extendible. The
	link count is displayed for `-v'.

./src/H5F.c
	Dumping of cache statistics is controlled by only the
	HDF5_DEBUG environment variable and not the H5F_ACC_DEBUG flag
	for H5Fopen() and H5Fcreate() since this makes it similar to
	the other debugging options.

./src/H5R.c
./test/ragged.c
./test/Makefile.in
	Tests pass but still a little work left to be done.
This commit is contained in:
Robb Matzke 1998-08-28 10:24:12 -05:00
parent 69ed3c270a
commit 1b1be9918c
11 changed files with 1089 additions and 442 deletions

2
README
View File

@ -1,4 +1,4 @@
This is hdf5-1.0.74 released on Thu Aug 27 04:19:49 CDT 1998
This is hdf5-1.0.75 released on Fri Aug 28 09:54:16 CDT 1998
Please refer to the INSTALL file for installation instructions.
------------------------------------------------------------------------------

View File

@ -34,34 +34,6 @@ H5Fcore.o: \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h
H5Fmpio.o: \
H5Fmpio.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5Dprivate.h \
H5Dpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h \
H5MMprivate.h \
H5MMpublic.h
H5Fsec2.o: \
H5Fsec2.c \
H5private.h \
@ -612,34 +584,6 @@ H5HL.o: \
H5MFprivate.h \
H5MFpublic.h \
H5MMprivate.h
H5O.o: \
H5O.c \
H5private.h \
H5public.h \
H5config.h \
H5ACprivate.h \
H5ACpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Ipublic.h \
H5Dpublic.h \
H5Eprivate.h \
H5Epublic.h \
H5MFprivate.h \
H5MFpublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h
H5Omtime.o: \
H5Omtime.c \
H5private.h \
@ -691,6 +635,108 @@ H5Fistore.o: \
H5Epublic.h \
H5MFprivate.h \
H5MFpublic.h
H5E.o: \
H5E.c \
H5private.h \
H5public.h \
H5config.h \
H5Iprivate.h \
H5Ipublic.h \
H5Eprivate.h
H5Flow.o: \
H5Flow.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5MMprivate.h \
H5MMpublic.h
H5MF.o: \
H5MF.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h
H5Shyper.o: \
H5Shyper.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h
H5Tconv.o: \
H5Tconv.c \
H5Iprivate.h \
H5Ipublic.h \
H5public.h \
H5config.h \
H5private.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Tpkg.h \
H5HGprivate.h \
H5HGpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h
H5Z.o: \
H5Z.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h
H5.o: \
H5.c \
H5private.h \
@ -788,8 +834,87 @@ H5D.o: \
H5HLpublic.h \
H5MFprivate.h \
H5MFpublic.h
H5E.o: \
H5E.c \
H5P.o: \
H5P.c \
H5private.h \
H5public.h \
H5config.h \
H5Iprivate.h \
H5Ipublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Dprivate.h \
H5Gprivate.h \
H5Gpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h
H5S.o: \
H5S.c \
H5private.h \
H5public.h \
H5config.h \
H5Iprivate.h \
H5Ipublic.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h
H5T.o: \
H5T.c \
H5private.h \
H5public.h \
H5config.h \
H5Dprivate.h \
H5Dpublic.h \
H5Ipublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h \
H5Iprivate.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h
H5TB.o: \
H5TB.c \
H5private.h \
H5public.h \
H5config.h \
@ -829,17 +954,32 @@ H5F.o: \
H5Epublic.h \
H5MMprivate.h \
H5MMpublic.h
H5Flow.o: \
H5Flow.c \
H5Fmpio.o: \
H5Fmpio.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5Dprivate.h \
H5Dpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h \
H5MMprivate.h \
H5MMpublic.h
H5G.o: \
@ -875,42 +1015,34 @@ H5G.o: \
H5HLpublic.h \
H5Iprivate.h \
H5MMprivate.h
H5MF.o: \
H5MF.c \
H5O.o: \
H5O.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h
H5P.o: \
H5P.c \
H5private.h \
H5public.h \
H5config.h \
H5Iprivate.h \
H5Ipublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5ACprivate.h \
H5ACpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Ipublic.h \
H5Dpublic.h \
H5Dprivate.h \
H5Gprivate.h \
H5Gpublic.h \
H5Eprivate.h \
H5Epublic.h \
H5MFprivate.h \
H5MFpublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h
H5Sprivate.h
H5R.o: \
H5R.c \
H5Rprivate.h \
@ -939,52 +1071,6 @@ H5R.o: \
H5Zpublic.h \
H5Eprivate.h \
H5Epublic.h
H5S.o: \
H5S.c \
H5private.h \
H5public.h \
H5config.h \
H5Iprivate.h \
H5Ipublic.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h
H5Shyper.o: \
H5Shyper.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h
H5Smpio.o: \
H5Smpio.c \
H5private.h \
@ -1059,89 +1145,3 @@ H5Sselect.o: \
H5Tpublic.h \
H5Zprivate.h \
H5Zpublic.h
H5T.o: \
H5T.c \
H5private.h \
H5public.h \
H5config.h \
H5Dprivate.h \
H5Dpublic.h \
H5Ipublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h \
H5Iprivate.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h
H5Tconv.o: \
H5Tconv.c \
H5Iprivate.h \
H5Ipublic.h \
H5public.h \
H5config.h \
H5private.h \
H5Eprivate.h \
H5Epublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Tpkg.h \
H5HGprivate.h \
H5HGpublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h
H5TB.o: \
H5TB.c \
H5private.h \
H5public.h \
H5config.h \
H5Iprivate.h \
H5Ipublic.h \
H5Eprivate.h
H5Z.o: \
H5Z.c \
H5private.h \
H5public.h \
H5config.h \
H5Eprivate.h \
H5Epublic.h \
H5Ipublic.h \
H5MMprivate.h \
H5MMpublic.h \
H5Oprivate.h \
H5Opublic.h \
H5Fprivate.h \
H5Fpublic.h \
H5Dpublic.h \
H5Gprivate.h \
H5Gpublic.h \
H5Bprivate.h \
H5Bpublic.h \
H5HGprivate.h \
H5HGpublic.h \
H5Tprivate.h \
H5Tpublic.h \
H5Sprivate.h \
H5Spublic.h \
H5Zprivate.h \
H5Zpublic.h

View File

@ -1562,10 +1562,8 @@ H5F_close(H5F_t *f)
}
/* Dump debugging info */
if (f->intent & H5F_ACC_DEBUG) {
H5AC_debug(f);
H5F_istore_stats (f, FALSE);
}
H5AC_debug(f);
H5F_istore_stats (f, FALSE);
/* Close files and release resources */
H5F_low_close(f->shared->lf, f->shared->access_parms);

View File

@ -1278,6 +1278,9 @@ H5G_create(H5G_t *loc, const char *name, size_t size_hint)
}
/* insert child name into parent */
if (1!=H5O_link(&(grp->ent), 1)) {
HRETURN_ERROR(H5E_SYM, H5E_LINK, NULL, "link inc failure");
}
if (H5G_stab_insert(&grp_ent, rest, &(grp->ent)) < 0) {
H5O_close(&(grp->ent));
grp = H5MM_xfree(grp);

View File

@ -40,6 +40,7 @@ typedef enum H5G_link_t {
#define H5G_GROUP 1 /* Object is a group */
#define H5G_DATASET 2 /* Object is a dataset */
#define H5G_TYPE 3 /* Object is a named data type */
#define H5G_NTYPES 4 /* THIS MUST BE LAST */
/* Information about an object */
typedef struct H5G_stat_t {

View File

@ -779,6 +779,11 @@ H5O_copy (const H5O_class_t *type, const void *mesg, void *dst)
*
* Modifications:
*
* Robb Matzke, 1998-08-27
* This function can also be used to obtain the current number of links
* if zero is passed for ADJUST. If that's the case then we don't check
* for write access on the file.
*
*-------------------------------------------------------------------------
*/
intn
@ -793,7 +798,7 @@ H5O_link(H5G_entry_t *ent, intn adjust)
assert(ent);
assert(ent->file);
assert(H5F_addr_defined(&(ent->header)));
if (0==(ent->file->intent & H5F_ACC_RDWR)) {
if (adjust!=0 && 0==(ent->file->intent & H5F_ACC_RDWR)) {
HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL,
"no write intent on file");
}
@ -806,19 +811,19 @@ H5O_link(H5G_entry_t *ent, intn adjust)
}
/* adjust link count */
if (adjust < 0) {
if (adjust<0) {
if (oh->nlink + adjust < 0) {
HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL,
"link count would be negative");
}
oh->nlink += adjust;
} else {
oh->dirty = TRUE;
} else if (adjust>0) {
oh->nlink += adjust;
oh->dirty = TRUE;
}
oh->dirty = TRUE;
ret_value = oh->nlink;
done:
if (oh && H5AC_unprotect(ent->file, H5AC_OHDR, &(ent->header), oh) < 0) {
HRETURN_ERROR(H5E_OHDR, H5E_PROTECT, FAIL,

128
src/H5R.c
View File

@ -738,7 +738,7 @@ H5R_write(H5R_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
for (i=0; i<nrows; i++) {
if (size[i]>raw_cur_size[1]) {
H5R_fix_overflow(ra, type, meta+i, size[i]-raw_cur_size[1],
(uint8*)(buf[i])+raw_cur_size[1]);
(uint8*)(buf[i])+raw_cur_size[1]*type_size);
}
meta[i].nelmts = size[i];
}
@ -997,15 +997,18 @@ H5R_read(H5R_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
H5S_t *mm_space=NULL; /*meta memory data space */
H5S_t *rf_space=NULL; /*raw data file space */
H5S_t *rm_space=NULL; /*raw data memory space */
H5S_t *of_space=NULL; /*overflow data file space */
H5S_t *om_space=NULL; /*overflow data memory space */
hsize_t meta_cur_size; /*current meta data nelmts */
hsize_t meta_read_size; /*amount of meta data to read */
hsize_t raw_cur_size[2]; /*raw data current size */
hsize_t raw_read_size; /*amount of raw data to read */
hsize_t raw_read_size[2]; /*amount of raw data to read */
hssize_t hs_offset[2]; /*hyperslab offset */
hsize_t hs_size[2]; /*hyperslab size */
uint8 *raw_buf=NULL; /*raw buffer */
size_t type_size; /*size of the TYPE argument */
hsize_t i;
void **buf_out=NULL; /*output BUF values */
hsize_t i; /*counter */
FUNC_ENTER(H5R_read, FAIL);
@ -1017,6 +1020,16 @@ H5R_read(H5R_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
if (0==nrows) HRETURN(SUCCEED);
type_size = H5T_get_size(type);
/*
* Malloc `buf_out' to hold the output values for `buf'. We have to do
* this because if we return failure we want `buf' to have the original
* values.
*/
if (NULL==(buf_out=H5MM_calloc(nrows*sizeof(void*)))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for BUF output values");
}
/* Read from the raw dataset */
if (NULL==(rf_space=H5D_get_space(ra->raw)) ||
H5S_extent_dims(rf_space, raw_cur_size, NULL)<0) {
@ -1024,16 +1037,32 @@ H5R_read(H5R_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
"unable to determine current raw data extents");
}
if ((hsize_t)start_row>=raw_cur_size[0]) {
raw_read_size = 0;
raw_read_size[0] = 0;
raw_read_size[1] = raw_cur_size[1];
} else {
raw_read_size = MIN(nrows, raw_cur_size[0]-(hsize_t)start_row);
raw_read_size[0] = MIN(nrows, raw_cur_size[0]-(hsize_t)start_row);
raw_read_size[1] = raw_cur_size[1];
}
hs_offset[0] = start_row;
hs_offset[1] = 0;
if (NULL==(rm_space=H5S_create(H5S_SIMPLE)) ||
H5S_set_extent_simple(rm_space, 2, raw_read_size, NULL)<0 ||
H5S_select_hyperslab(rf_space, H5S_SELECT_SET, hs_offset, NULL,
raw_read_size, NULL)<0) {
HGOTO_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL,
"unable to set raw dataset selection");
}
if (NULL==(raw_buf=H5MM_malloc(nrows*raw_read_size[1]*type_size))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for raw dataset");
}
if (H5D_read(ra->raw, type, rm_space, rf_space, &H5D_xfer_dflt,
raw_buf)<0) {
HGOTO_ERROR(H5E_RAGGED, H5E_READERROR, FAIL,
"unable to read raw dataset");
}
HDmemset(raw_buf+raw_read_size[0]*raw_read_size[1]*type_size, 0,
(nrows-raw_read_size[0])*raw_read_size[1]*type_size);
/* Get the meta data */
if (NULL==(meta=H5MM_malloc(nrows*sizeof(H5R_meta_t)))) {
@ -1065,11 +1094,84 @@ H5R_read(H5R_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
HDmemset(meta+meta_read_size, 0,
(nrows-meta_read_size)*sizeof(H5R_meta_t));
/* Copy data into output buffers */
for (i=0; i<nrows; i++) {
/*
* If the caller didn't supply a buffer then allocate a buffer large
* enough to hold the entire row. Ignore the input value for the
* size and request the entire row.
*/
if (NULL==(buf_out[i]=buf[i])) {
if (meta[i].nelmts>0 &&
NULL==(buf_out[i]=H5MM_malloc(meta[i].nelmts*type_size))) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"memory allocation failed for result");
}
size[i] = meta[i].nelmts;
} else {
size[i] = MIN(size[i], meta[i].nelmts);
}
if (0==size[i]) continue;
HGOTO_ERROR(H5E_RAGGED, H5E_UNSUPPORTED, FAIL,
"not implemented yet");
/* Copy the part of the row from the raw dataset */
HDmemcpy(buf_out[i], raw_buf+i*raw_read_size[1]*type_size,
MIN(size[i], raw_read_size[1])*type_size);
/* Copy the part of the row from the overflow dataset */
if (size[i]>raw_read_size[1]) {
if (!of_space && NULL==(of_space=H5D_get_space(ra->over))) {
HGOTO_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL,
"unable to get overflow extents");
}
hs_size[0] = size[i]-raw_read_size[1];
if (NULL==(om_space=H5S_create(H5S_SIMPLE)) ||
H5S_set_extent_simple(om_space, 1, size+i, NULL)<0 ||
H5S_select_hyperslab(om_space, H5S_SELECT_SET,
(hssize_t*)(raw_read_size+1), NULL,
hs_size, NULL)<0 ||
H5S_select_hyperslab(of_space, H5S_SELECT_SET,
&(meta[i].offset), NULL, hs_size,
NULL)<0) {
HGOTO_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL,
"unable to set overflow selection");
}
if (H5D_read(ra->over, type, om_space, of_space, &H5D_xfer_dflt,
buf_out[i])<0) {
HGOTO_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL,
"unable to read overflow dataset");
}
if (H5S_close(om_space)<0) {
om_space = NULL;
HGOTO_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL,
"unable to close overflow memory space");
}
om_space = NULL;
}
/* Actual row size */
size[i] = meta[i].nelmts;
}
/* Copy output buffers into BUF argument */
for (i=0; i<nrows; i++) buf[i] = buf_out[i];
ret_value = SUCCEED;
done:
if (rf_space) H5S_close(rf_space);
if (rm_space) H5S_close(rm_space);
if (mf_space) H5S_close(mf_space);
if (mm_space) H5S_close(mm_space);
if (of_space) H5S_close(of_space);
if (om_space) H5S_close(om_space);
H5MM_xfree(meta);
H5MM_xfree(raw_buf);
if (buf_out) {
for (i=0; i<nrows; i++) {
if (!buf[i]) H5MM_xfree(buf_out[i]);
}
H5MM_xfree(buf_out);
}
FUNC_LEAVE(ret_value);
}

View File

@ -496,3 +496,27 @@ bittests.o: \
../src/H5Tpublic.h \
../src/H5Gprivate.h \
../src/H5Gpublic.h
ragged.o: \
ragged.c \
../src/hdf5.h \
../src/H5public.h \
../src/H5config.h \
../src/H5Ipublic.h \
../src/H5Apublic.h \
../src/H5ACpublic.h \
../src/H5Bpublic.h \
../src/H5Dpublic.h \
../src/H5Epublic.h \
../src/H5Fpublic.h \
../src/H5Gpublic.h \
../src/H5HGpublic.h \
../src/H5HLpublic.h \
../src/H5MFpublic.h \
../src/H5MMpublic.h \
../src/H5Opublic.h \
../src/H5Ppublic.h \
../src/H5Zpublic.h \
../src/H5Rpublic.h \
../src/H5Spublic.h \
../src/H5Tpublic.h \
../src/H5private.h

View File

@ -12,7 +12,7 @@ CPPFLAGS=-I. -I../src @CPPFLAGS@
# These are our main targets. They should be listed in the order to be
# executed, generally most specific tests to least specific tests.
TESTS=testhdf5 gheap hyperslab istore bittests dtypes dsets cmpd_dset extend \
external shtype links big mtime
external shtype links big mtime ragged
TIMINGS=iopipe chunk
# Temporary files
@ -24,7 +24,7 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \
gheap1.h5 gheap2.h5 gheap3.h5 gheap4.h5 shtype0.h5 shtype1.h5 \
shtype2a.h5 shtype2b.h5 shtype3.h5 links.h5 chunk.h5 big.data \
big[0-9][0-9][0-9][0-9][0-9].h5 dtypes1.h5 dtypes2.h5 tattr.h5 \
tselect.h5 mtime.h5
tselect.h5 mtime.h5 ragged.h5
# Source and object files for programs... The TEST_SRC list contains all the
# source files and is used for things like dependencies, archiving, etc. The
@ -33,7 +33,7 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \
TEST_SRC=testhdf5.c tattr.c tfile.c theap.c tmeta.c tohdr.c tselect.c tstab.c \
th5s.c dtypes.c hyperslab.c istore.c dsets.c cmpd_dset.c extend.c \
external.c iopipe.c gheap.c shtype.c big.c links.c chunk.c bittests.c \
mtime.c
mtime.c ragged.c
TEST_OBJ=$(PROG_SRC:.c=.o)
# Private header files (not to be installed)...
@ -102,4 +102,7 @@ chunk: chunk.o ../src/libhdf5.a
mtime: mtime.o ../src/libhdf5.a
$(CC) $(CFLAGS) -o $@ mtime.o ../src/libhdf5.a $(LIBS)
ragged: ragged.o ../src/libhdf5.a
$(CC) $(CFLAGS) -o $@ ragged.o ../src/libhdf5.a $(LIBS)
@CONCLUDE@

View File

@ -16,6 +16,11 @@
#define NOTIFY_INTERVAL 2 /*seconds*/
#define TIME_LIMIT 60 /*seconds*/
#define CH_SIZE 8192*8 /*approx chunk size in bytes*/
#define MAX_NELMTS 3000000
#define C_MTYPE unsigned int /*type in memory */
#define H_MTYPE H5T_NATIVE_UINT /*type in memory */
#define H_FTYPE H5T_NATIVE_UINT /*type in file */
typedef struct {
double percent;
@ -54,7 +59,7 @@ static quant_t quant_g[] = {
#endif
static volatile sig_atomic_t alarm_g = 0;
static volatile sig_atomic_t abort_g = 0;
static volatile sig_atomic_t timeout_g = 0;
/*-------------------------------------------------------------------------
@ -73,7 +78,7 @@ static volatile sig_atomic_t abort_g = 0;
*-------------------------------------------------------------------------
*/
static void
catch_alarm(int signum)
catch_alarm(int __unused__ signum)
{
static int ncalls=0;
@ -81,12 +86,35 @@ catch_alarm(int signum)
if (0==ncalls % NOTIFY_INTERVAL) {
alarm_g++;
}
if (ncalls>=TIME_LIMIT) {
abort_g=1;
}
if (timeout_g>0) --timeout_g;
alarm(1);
}
/*-------------------------------------------------------------------------
* Function: display_error_cb
*
* Purpose: Displays the error stack after printing "*FAILED*".
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Wednesday, March 4, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
display_error_cb (void __unused__ *client_data)
{
putchar('\n');
H5Eprint (stdout);
return 0;
}
/*-------------------------------------------------------------------------
* Function: rand_nelmts
@ -106,22 +134,416 @@ catch_alarm(int signum)
*-------------------------------------------------------------------------
*/
static size_t
rand_nelmts(void)
rand_nelmts(int reset_counters)
{
double p = (rand() % 1000000)/1000000.0;
double total = 0.0;
size_t size, i;
double p = (rand() % 1000000)/1000000.0;
double total = 0.0;
size_t size, i;
static size_t ncalls=0;
for (i=0; i<NELMTS(quant_g); i++) {
total += quant_g[i].percent/100.0;
if (p<total) {
size = rand()%(1+(quant_g[i].hi-quant_g[i].lo)) + quant_g[i].lo;
quant_g[i].nhits++;
if (reset_counters) {
printf(" %9s %8s %8s\n", "Length", "Requsted", "Actual");
printf(" --------------- -------- --------\n");
for (i=0; i<NELMTS(quant_g); i++) {
printf(" [%6lu,%6lu] %7.3f%% %7.3f%%\n",
(unsigned long)(quant_g[i].lo),
(unsigned long)(quant_g[i].hi),
quant_g[i].percent,
100.0*(double)(quant_g[i].nhits)/(double)ncalls);
quant_g[i].nhits = 0;
}
printf(" --------------- -------- --------\n");
ncalls = 0;
size = 0;
} else {
for (i=0; i<NELMTS(quant_g); i++) {
total += quant_g[i].percent/100.0;
if (p<total) {
size = rand()%(1+(quant_g[i].hi-quant_g[i].lo)) +
quant_g[i].lo;
quant_g[i].nhits++;
break;
}
}
assert(i<NELMTS(quant_g));
ncalls++;
}
return size;
}
/*-------------------------------------------------------------------------
* Function: ragged_append
*
* Purpose: Writes rows to the end of ragged array RA.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ragged_append(hid_t ra, hsize_t rows_at_once)
{
int *dd, total_nelmts=0;
hssize_t row; /*current row number */
hsize_t i; /*counter */
hsize_t max_width = quant_g[NELMTS(quant_g)-1].hi;
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t *size=NULL; /*size of each row */
void **buf=NULL; /*buffer for each row */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
char testname[80];
sprintf(testname, "Testing append, units of %lu",
(unsigned long)rows_at_once);
printf("%s...\n", testname);
fflush(stdout);
timeout_g = 60;
/* Create the ragged array row in memory */
if (NULL==(dd = malloc(max_width*sizeof(C_MTYPE))) ||
NULL==(size = malloc(rows_at_once*sizeof(*size))) ||
NULL==(buf = malloc(rows_at_once*sizeof(*buf)))) {
puts("Memory allocation failed");
goto error;
}
for (i=0; i<max_width; i++) dd[i] = i+1;
/*
* Describe a few rows then add them to the ragged array. Print a status
* report every once in a while too.
*/
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<MAX_NELMTS && timeout_g>0; row+=i) {
for (i=0; i<rows_at_once && total_nelmts<MAX_NELMTS; i++) {
size[i] = rand_nelmts(0);
total_nelmts += size[i];
buf[i] = dd;
interval_nelmts += size[i];
}
if (H5Rwrite(ra, row, i, H_MTYPE, size, buf)<0) goto error;
if (0==row || alarm_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE),
timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s,
0==timeout_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
}
/* Conclusions */
if (timeout_g) { /*a minor race condition, but who really cares?*/
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)total_nelmts*sizeof(C_MTYPE), timer_total.etime);
printf(" %27s%10s\n", "", s);
/* Cleanup */
free(dd);
free(size);
free(buf);
printf("%-70s PASSED\n\n", testname);
return 0;
error:
printf("%-70s*FAILED*\n\n", testname);
return -1;
}
/*-------------------------------------------------------------------------
* Function: ragged_readall
*
* Purpose: Reads all rows of a ragged array in row order a few rows at a
* time.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ragged_readall(hid_t ra, hsize_t rows_at_once)
{
int total_nelmts=0;
hsize_t i, j; /*counters */
hssize_t row; /*current row number */
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t *size=NULL; /*size of each row */
C_MTYPE **buf=NULL; /*buffer for each row */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
char testname[80];
sprintf(testname, "Testing read all, units of %lu",
(unsigned long)rows_at_once);
printf("%s...\n", testname);
fflush(stdout);
timeout_g = 60;
/* Create the ragged array row in memory */
if (NULL==(size = malloc(rows_at_once*sizeof(*size))) ||
NULL==(buf = malloc(rows_at_once*sizeof(*buf)))) {
puts("Memory allocation failed");
goto error;
}
/*
* Read a few rows at a time from the ragged array. Print a status report
* every once in a while too.
*/
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<MAX_NELMTS && timeout_g>0; row+=i) {
/* Clear data then read */
HDmemset(size, 0, rows_at_once*sizeof(*size));
HDmemset(buf, 0, rows_at_once*sizeof(*buf));
if (H5Rread(ra, row, rows_at_once, H_MTYPE, size,
(void**)buf)<0) {
goto error;
}
/* Check values read */
for (i=0; i<rows_at_once && size[i]; i++) {
interval_nelmts += size[i];
total_nelmts += size[i];
for (j=0; j<size[i]; j++) {
if (buf[i][j]!=j+1) {
printf("Wrong value(s) read for row %ld.\n",
(long)(row+i));
for (j=0; j<size[i]; j++) {
printf("%s%d", j?",":"", buf[i][j]);
}
putchar('\n');
goto error;
}
}
free(buf[i]);
buf[i] = NULL;
}
/* Print statistics? */
if (0==row || alarm_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE),
timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s,
0==timeout_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
if (0==size[rows_at_once-1]) {
/* Reached the end of the array */
assert(total_nelmts>=MAX_NELMTS);
row += i;
break;
}
}
assert(i<NELMTS(quant_g));
return size;
/* Conclusions */
if (timeout_g) { /*a minor race condition, but who really cares?*/
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)total_nelmts*sizeof(C_MTYPE), timer_total.etime);
printf(" %27s%10s\n", "", s);
/* Cleanup */
free(size);
free(buf);
printf("%-70s PASSED\n\n", testname);
return 0;
error:
printf("%-70s*FAILED*\n\n", testname);
return -1;
}
/*-------------------------------------------------------------------------
* Function: ragged_readshort
*
* Purpose: Reads all the data but only the part that is in the `raw'
* dataset. We should see a nice speed increase because we
* don't have to perform the little reads into the overflow
* array.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Friday, August 28, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static int
ragged_readshort(hid_t ra, hsize_t rows_at_once, hsize_t width)
{
int total_nelmts=0;
hsize_t i, j;
hssize_t row; /*current row number */
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t *size=NULL; /*size of each row */
C_MTYPE **buf=NULL; /*buffer for each row */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
char testname[80];
sprintf(testname, "Testing read short, units of %lu",
(unsigned long)rows_at_once);
printf("%s...\n", testname);
fflush(stdout);
timeout_g = 60;
/* Create the ragged array row in memory */
if (NULL==(size = malloc(rows_at_once*sizeof(*size))) ||
NULL==(buf = malloc(rows_at_once*sizeof(*buf)))) {
puts("Memory allocation failed");
goto error;
}
for (i=0; i<rows_at_once; i++) {
if (NULL==(buf[i] = malloc(width*sizeof(C_MTYPE)))) {
puts("Memory allocation failed");
goto error;
}
}
/*
* Read a few rows at a time from the ragged array. Print a status report
* every once in a while too.
*/
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<MAX_NELMTS && timeout_g>0; row+=i) {
/* Read data */
for (i=0; i<rows_at_once; i++) size[i] = width;
if (H5Rread(ra, row, rows_at_once, H_MTYPE, size,
(void**)buf)<0) {
goto error;
}
/* Check values read */
for (i=0; i<rows_at_once && size[i]; i++) {
/*
* Number of useful elements actually read in this timing
* interval. This is used to calculate bandwidth.
*/
interval_nelmts += MIN(width, size[i]);
/*
* Total number of elements for all the rows read so far. This
* is used to calculate the percent done.
*/
total_nelmts += size[i];
/* Check the values */
for (j=0; j<MIN(width, size[i]); j++) {
if (buf[i][j]!=j+1) {
printf("Wrong value(s) read for row %ld.\n",
(long)(row+i));
for (j=0; j<MIN(width, size[i]); j++) {
printf("%s%d", j?",":"", buf[i][j]);
}
putchar('\n');
goto error;
}
}
}
/* Print statistics? */
if (0==row || alarm_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE),
timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s,
0==timeout_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
if (0==size[rows_at_once-1]) {
/* Reached the end of the array */
assert(total_nelmts>=MAX_NELMTS);
row += i;
break;
}
}
/* Conclusions */
if (timeout_g) { /*a minor race condition, but who really cares?*/
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(C_MTYPE), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)total_nelmts,
100.0*total_nelmts/MAX_NELMTS, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)total_nelmts*sizeof(C_MTYPE), timer_total.etime);
printf(" %27s%10s\n", "", s);
/* Cleanup */
for (i=0; i<rows_at_once; i++) free(buf[i]);
free(size);
free(buf);
printf("%-70s PASSED\n\n", testname);
return 0;
error:
printf("%-70s*FAILED*\n\n", testname);
return -1;
}
@ -142,20 +564,21 @@ rand_nelmts(void)
*-------------------------------------------------------------------------
*/
int
main(void)
main(int argc, char *argv[])
{
hid_t file, dcpl, ra;
int *dd, max_nelmts=3000000, total_nelmts=0;
int i, rows_at_once=100;
hssize_t row; /*current row number */
hsize_t max_width = quant_g[NELMTS(quant_g)-1].hi;
hsize_t ch_size[2]; /*chunk size */
hsize_t interval_nelmts; /*elmts/interval timer */
hsize_t *size=NULL; /*size of each row */
void **buf=NULL; /*buffer for each row */
struct sigaction act; /*alarm signal handler */
H5_timer_t timer, timer_total; /*performance timers */
char s[64]; /*tempory string buffer */
hsize_t rows_at_once=100; /*row aggregation */
int argno=1;
/* Parse command line options */
if (argno<argc) {
rows_at_once = strtol(argv[argno++], NULL, 0);
}
/* Display HDF5 API errors in a special way */
H5Eset_auto(display_error_cb, NULL);
/* Get a SIGALRM every few seconds */
act.sa_handler = catch_alarm;
@ -169,81 +592,30 @@ main(void)
H5P_DEFAULT))<0) goto error;
if ((dcpl=H5Pcreate(H5P_DATASET_CREATE))<0) goto error;
ch_size[1] = 20;
ch_size[0] = MAX(1, CH_SIZE/(ch_size[1]*sizeof(int))); /*length*/
ch_size[0] = MAX(1, CH_SIZE/(ch_size[1]*sizeof(C_MTYPE))); /*length*/
printf("Chunk size is %lu by %lu\n",
(unsigned long)(ch_size[0]), (unsigned long)(ch_size[1]));
if (H5Pset_chunk(dcpl, 2, ch_size)<0) goto error;
if ((ra=H5Rcreate(file, "ra", H5T_NATIVE_INT, dcpl))<0) goto error;
if ((ra=H5Rcreate(file, "ra", H_FTYPE, dcpl))<0) goto error;
if (H5Pclose(dcpl)<0) goto error;
/* Create the ragged array row in memory */
if (NULL==(dd = malloc(max_width*sizeof(int)))) goto error;
for (i=0; i<max_width; i++) dd[i] = i+1;
size = malloc(rows_at_once*sizeof(*size));
buf = malloc(rows_at_once*sizeof(*buf));
/*
* Describe a few rows then add them to the ragged array. Print a status
* report every once in a while too.
*/
printf("Aggregated to %d row%s\n", rows_at_once, 1==rows_at_once?"":"s");
printf(" %8s %8s %8s %10s\n",
"Row", "Nelmts", "Complete", "Bandwidth");
printf(" -------- -------- -------- ----------\n");
H5_timer_reset(&timer_total);
H5_timer_begin(&timer);
interval_nelmts = 0;
for (row=0; total_nelmts<max_nelmts && !abort_g; row+=i) {
for (i=0; i<rows_at_once && total_nelmts<max_nelmts; i++) {
size[i] = rand_nelmts();
total_nelmts += size[i];
buf[i] = dd;
interval_nelmts += size[i];
}
if (H5Rwrite(ra, row, i, H5T_NATIVE_INT, size, buf)<0) goto error;
if (0==row || alarm_g) {
alarm_g = 0;
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(int), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s%s\n",
(unsigned long)(row+i), (unsigned long)total_nelmts,
100.0*total_nelmts/max_nelmts, s, abort_g?" (aborting)":"");
interval_nelmts = 0;
H5_timer_begin(&timer);
}
}
/* The tests */
if (ragged_append(ra, rows_at_once)<0) goto error;
if (ragged_readall(ra, rows_at_once)<0) goto error;
if (ragged_readshort(ra, rows_at_once, ch_size[1])<0) goto error;
/* Conclusions */
if (!abort_g) {
H5_timer_end(&timer_total, &timer);
H5_bandwidth(s, (double)interval_nelmts*sizeof(int), timer.etime);
printf(" %8lu %8lu %7.3f%% %10s\n",
(unsigned long)row, (unsigned long)total_nelmts,
100.0*total_nelmts/max_nelmts, s);
}
printf(" -------- -------- -------- ----------\n");
H5_bandwidth(s, (double)total_nelmts*sizeof(int), timer_total.etime);
printf(" %27s%10s\n\n", "", s);
printf(" %9s %8s %8s\n", "Length", "Requsted", "Actual");
printf(" --------------- -------- --------\n");
for (i=0; i<NELMTS(quant_g); i++) {
printf(" [%6lu,%6lu] %7.3f%% %7.3f%%\n",
(unsigned long)(quant_g[i].lo), (unsigned long)(quant_g[i].hi),
quant_g[i].percent,
100.0*(double)(quant_g[i].nhits)/(double)row);
}
printf(" --------------- -------- --------\n");
printf("\n\nDistribution of row lengths:\n");
rand_nelmts(1);
/* Cleanup */
if (H5Rclose(ra)<0) goto error;
if (H5Fclose(file)<0) goto error;
free(dd);
free(size);
free(buf);
puts("All ragged array tests passed.");
return 0;
error:
puts("*** RAGGED ARRAY TEST(S) FAILED ***");
return -1;
}

View File

@ -26,6 +26,25 @@ static int verbose_g = 0;
static int dump_g = 0;
static int width_g = 80;
/* Information about how to display each type of object */
static struct dispatch_t {
const char *name;
hid_t (*open)(hid_t loc, const char *name);
herr_t (*close)(hid_t obj);
herr_t (*list1)(hid_t obj);
herr_t (*list2)(hid_t obj);
} dispatch_g[H5G_NTYPES];
#define DISPATCH(TYPE,NAME,OPEN,CLOSE,LIST1,LIST2) { \
dispatch_g[TYPE].name = (NAME); \
dispatch_g[TYPE].open = (OPEN); \
dispatch_g[TYPE].close = (CLOSE); \
dispatch_g[TYPE].list1 = (LIST1); \
dispatch_g[TYPE].list2 = (LIST2); \
}
static herr_t list (hid_t group, const char *name, void *cd);
/*-------------------------------------------------------------------------
* Function: usage
@ -134,7 +153,7 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data)
hid_t attr;
int i;
printf ("%*s%s", 26, "", attr_name);
printf(" %-10s %-10s", "Attribute:", attr_name);
if ((attr = H5Aopen_name (obj, attr_name))) {
hid_t space = H5Aget_space (attr);
hsize_t size[64];
@ -152,6 +171,149 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data)
return 0;
}
/*-------------------------------------------------------------------------
* Function: dataset_list1
*
* Purpose: List information about a dataset which should appear on the
* same line as the dataset name. This information will precede
* information which is applicable to all objects which will be
* printed by the caller.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
dataset_list1(hid_t dset)
{
hsize_t cur_size[64]; /*current dataset dimensions */
hsize_t max_size[64]; /*maximum dataset dimensions */
hid_t space; /*data space */
int ndims; /*dimensionality */
int i;
/*
* Information that goes on the same row as the name. The name has
* already been printed.
*/
space = H5Dget_space(dset);
ndims = H5Sextent_dims(space, cur_size, max_size);
printf (" {");
for (i=0; i<ndims; i++) {
HDfprintf (stdout, "%s%Hu", i?", ":"", cur_size[i]);
if (max_size[i]==H5S_UNLIMITED) {
HDfprintf (stdout, "/%s", "Inf");
} else if (max_size[i]!=cur_size[i] || verbose_g>0) {
HDfprintf(stdout, "/%Hu", max_size[i]);
}
}
putchar('}');
H5Sclose (space);
return 0;
}
/*-------------------------------------------------------------------------
* Function: dataset_list2
*
* Purpose: List information about a dataset which should appear after
* information which is general to all objects.
*
* Return: Success: 0
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
dataset_list2(hid_t dset)
{
hid_t dcpl; /*dataset creation property list*/
int nf; /*number of filters */
unsigned filt_flags; /*filter flags */
H5Z_filter_t filt_id; /*filter identification number */
unsigned cd_values[20]; /*filter client data values */
size_t cd_nelmts; /*filter client number of values*/
size_t cd_num; /*filter client data counter */
char f_name[32]; /*filter name */
char s[64]; /*temporary string buffer */
int i;
if (verbose_g>0) {
dcpl = H5Dget_create_plist(dset);
/* Print information about raw data filters */
if ((nf = H5Pget_nfilters(dcpl))>0) {
for (i=0; i<nf; i++) {
cd_nelmts = NELMTS(cd_values);
filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts,
cd_values, sizeof(f_name), f_name);
f_name[sizeof(f_name)-1] = '\0';
sprintf(s, "Filter-%d:", i);
printf(" %-10s %s-%u %s {", s,
f_name[0]?f_name:"method",
(unsigned)filt_id,
filt_flags & H5Z_FLAG_OPTIONAL?"OPT":"");
for (cd_num=0; cd_num<cd_nelmts; cd_num++) {
printf("%s%u", cd_num?", ":"", cd_values[cd_num]);
}
printf("}\n");
}
}
H5Pclose(dcpl);
}
if (dump_g) dump_dataset_values(dset);
return 0;
}
/*-------------------------------------------------------------------------
* Function: link_open
*
* Purpose: This gets called to open a symbolic link. Since symbolic
* links don't correspond to actual objects we simply print the
* link information and return failure.
*
* Return: Success: never succeeds
*
* Failure: -1
*
* Programmer: Robb Matzke
* Thursday, August 27, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static hid_t
link_open(hid_t location, const char *name)
{
char buf[64];
if (H5Gget_linkval (location, name, sizeof(buf), buf)<0) return -1;
if (NULL==HDmemchr(buf, 0, sizeof(buf))) {
strcpy(buf+sizeof(buf)-4, "...");
}
puts(buf);
return -1;
}
/*-------------------------------------------------------------------------
* Function: list
@ -170,113 +332,67 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data)
*-------------------------------------------------------------------------
*/
static herr_t
list (hid_t group, const char *name, void __unused__ *op_data)
list (hid_t group, const char *name, void __unused__ *cd)
{
hid_t obj;
hid_t (*func)(void*);
void *edata;
int i, nf;
char buf[512], comment[50];
H5G_stat_t statbuf;
H5G_stat_t sb;
struct tm *tm;
herr_t status;
/* Disable error reporting */
H5Eget_auto (&func, &edata);
H5Eset_auto (NULL, NULL);
/* Print the object name */
printf("%-25s ", name);
/* Print info about each name */
printf ("%-25s ", name);
if ((obj=H5Dopen (group, name))>=0) {
hsize_t size[64];
hsize_t maxsize[64];
hid_t space = H5Dget_space (obj);
int ndims = H5Sextent_dims(space, size, maxsize);
printf ("Dataset {");
for (i=0; i<ndims; i++) {
HDfprintf (stdout, "%s%Hu", i?", ":"", size[i]);
if (maxsize[i]==H5S_UNLIMITED) {
HDfprintf (stdout, "/%s", "Inf");
} else if (maxsize[i]!=size[i] || verbose_g>0) {
HDfprintf(stdout, "/%Hu", maxsize[i]);
}
}
printf ("}\n");
H5Dclose (space);
H5Aiterate (obj, NULL, list_attr, NULL);
/* Print additional information about datasets */
if (verbose_g>0) {
hid_t dcpl = H5Dget_create_plist(obj);
if ((nf = H5Pget_nfilters(dcpl))>0) {
for (i=0; i<nf; i++) {
unsigned filt_flags;
H5Z_filter_t filt_id;
unsigned cd_values[20];
size_t cd_nelmts = NELMTS(cd_values);
size_t cd_num;
char f_name[32];
filt_id = H5Pget_filter(dcpl, i, &filt_flags, &cd_nelmts,
cd_values, sizeof(f_name), f_name);
f_name[sizeof(f_name)-1] = '\0';
sprintf(comment, "Filter-%d:", i);
printf(" %-10s %s-%u %s {", comment,
f_name[0]?f_name:"method",
(unsigned)filt_id,
filt_flags & H5Z_FLAG_OPTIONAL?"OPT":"");
for (cd_num=0; cd_num<cd_nelmts; cd_num++) {
printf("%s%u", cd_num?", ":"", cd_values[cd_num]);
}
printf("}\n");
}
}
H5Pclose(dcpl);
}
H5Dclose (obj);
} else if ((obj=H5Gopen (group, name))>=0) {
printf ("Group\n");
H5Aiterate (obj, NULL, list_attr, NULL);
H5Gclose (obj);
} else if (H5Gget_linkval (group, name, sizeof(buf), buf)>=0) {
if (NULL==HDmemchr (buf, 0, sizeof(buf))) {
strcpy (buf+sizeof(buf)-4, "...");
}
printf (" -> %s\n", buf);
} else if ((obj=H5Topen (group, name))>=0) {
printf ("Data type\n");
H5Aiterate (obj, NULL, list_attr, NULL);
H5Tclose (obj);
} else {
printf ("Unknown Type\n");
/* Get object information */
H5E_BEGIN_TRY {
status = H5Gstat(group, name, FALSE, &sb);
} H5E_END_TRY;
if (status<0) {
puts("**NOT FOUND**");
return 0;
} else if (sb.type<0 || sb.type>=H5G_NTYPES) {
printf("Unknown type=%d", sb.type);
return 0;
}
if (dispatch_g[sb.type].name) fputs(dispatch_g[sb.type].name, stdout);
/*
* Open the object. Not all objects can be opened. If this is the case
* then return right away.
*/
if (NULL==dispatch_g[sb.type].open ||
(obj=(dispatch_g[sb.type].open)(group, name))<0) return 0;
/*
* List the first line of information for the object.
*/
if (dispatch_g[sb.type].list1) (dispatch_g[sb.type].list1)(obj);
putchar('\n');
/*
* Show detailed information about the object, beginning with information
* which is common to all objects.
*/
if (verbose_g>0) {
if (H5Gstat(group, name, TRUE, &statbuf)>=0) {
printf(" %-10s %lu:%lu:%lu:%lu\n",
"Location:", statbuf.fileno[1], statbuf.fileno[0],
statbuf.objno[1], statbuf.objno[0]);
if (statbuf.mtime>0 && NULL!=(tm = localtime(&(statbuf.mtime)))) {
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
printf(" %-10s %s\n", "Modtime:", buf);
}
H5Aiterate(obj, NULL, list_attr, NULL);
printf(" %-10s %lu:%lu:%lu:%lu\n", "Location:",
sb.fileno[1], sb.fileno[0], sb.objno[1], sb.objno[0]);
printf(" %-10s %u\n", "Links:", sb.nlink);
if (sb.mtime>0 && NULL!=(tm=localtime(&(sb.mtime)))) {
strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
printf(" %-10s %s\n", "Modtime:", buf);
}
/* Display the comment if the object has one */
comment[0] = '\0';
H5Gget_comment(group, name, sizeof(comment), comment);
strcpy(comment+sizeof(comment)-4, "...");
if (comment[0]) printf(" %-10s %s\n", "Comment:", comment);
if (dispatch_g[sb.type].list2) (dispatch_g[sb.type].list2)(obj);
}
if (dump_g && (obj=H5Dopen(group, name))>=0) {
/* Turn on error reporting before dumping the data */
H5Eset_auto(func, edata);
dump_dataset_values(obj);
H5Dclose(obj);
}
/* Restore error reporting */
H5Eset_auto (func, edata);
/*
* Close the object.
*/
(dispatch_g[sb.type].close)(obj);
return 0;
}
@ -301,14 +417,22 @@ list (hid_t group, const char *name, void __unused__ *op_data)
int
main (int argc, char *argv[])
{
hid_t file, plist=H5P_DEFAULT;
hid_t file, plist=H5P_DEFAULT, root;
const char *fname = NULL;
const char *gname = "/";
const char *progname;
const char *s;
char *rest;
int argno;
DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose,
dataset_list1, dataset_list2);
DISPATCH(H5G_GROUP, "Group", H5Gopen, H5Gclose,
NULL, NULL);
DISPATCH(H5G_TYPE, "Type", H5Topen, H5Tclose,
NULL, NULL);
DISPATCH(H5G_LINK, "-> ", link_open, NULL,
NULL, NULL);
/* Name of this program without the path */
if ((progname=strrchr (argv[0], '/'))) progname++;
else progname = argv[0];
@ -380,29 +504,44 @@ main (int argc, char *argv[])
}
}
/* Non-switch arguments */
/*
* The first non-switch argument is a file name. If the file name
* contains a `%' then assume that a file family is being opened.
*/
if (argno<argc) {
fname = argv[argno++];
} else {
usage(progname);
exit(1);
}
if (argno<argc) gname = argv[argno++];
if (argno<argc) {
usage(progname);
exit(1);
}
/*
* Open the file. If the file name contains a `%' then assume that a
* file family is being opened.
*/
if (strchr (fname, '%')) {
plist = H5Pcreate (H5P_FILE_ACCESS);
H5Pset_family (plist, 0, H5P_DEFAULT);
}
if ((file = H5Fopen (fname, H5F_ACC_RDONLY, plist))<0) exit (1);
if (H5Giterate (file, gname, NULL, list, NULL)<0) exit (1);
if (H5Fclose (file)<0) exit (1);
/*
* The remaining optional arguments are the names of the objects to list.
* If there are no arguments then list `/'.
*/
if (argno>=argc) {
H5Giterate(file, "/", NULL, list, NULL);
} else {
for (/*void*/; argno<argc; argno++) {
H5E_BEGIN_TRY {
root = H5Gopen (file, argv[argno]);
} H5E_END_TRY;
if (root>=0) {
H5Giterate(file, argv[argno], NULL, list, NULL);
} else if ((root=H5Gopen(file, "/"))<0) {
exit(1);
} else {
list(root, argv[argno], NULL);
}
if (H5Gclose(root)<0) exit(1);
}
}
if (H5Fclose(file)<0) exit(1);
return 0;
}