diff options
author | Robb Matzke <matzke@llnl.gov> | 1998-08-28 15:24:12 (GMT) |
---|---|---|
committer | Robb Matzke <matzke@llnl.gov> | 1998-08-28 15:24:12 (GMT) |
commit | 1b1be9918c1a654225f2040619f0b26ae83028fb (patch) | |
tree | db8bfa193965145aea917d4f06f122238324555d | |
parent | 69ed3c270a64d5c60544126b34431d1a7e9a7c8c (diff) | |
download | hdf5-1b1be9918c1a654225f2040619f0b26ae83028fb.zip hdf5-1b1be9918c1a654225f2040619f0b26ae83028fb.tar.gz hdf5-1b1be9918c1a654225f2040619f0b26ae83028fb.tar.bz2 |
[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.
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | src/.distdep | 430 | ||||
-rw-r--r-- | src/H5F.c | 6 | ||||
-rw-r--r-- | src/H5G.c | 3 | ||||
-rw-r--r-- | src/H5Gpublic.h | 1 | ||||
-rw-r--r-- | src/H5O.c | 15 | ||||
-rw-r--r-- | src/H5R.c | 128 | ||||
-rw-r--r-- | test/.distdep | 24 | ||||
-rw-r--r-- | test/Makefile.in | 9 | ||||
-rw-r--r-- | test/ragged.c | 518 | ||||
-rw-r--r-- | tools/h5ls.c | 357 |
11 files changed, 1070 insertions, 423 deletions
@@ -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. ------------------------------------------------------------------------------ diff --git a/src/.distdep b/src/.distdep index adc5f19..a260d68 100644 --- a/src/.distdep +++ b/src/.distdep @@ -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,30 +834,21 @@ 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 \ - H5Eprivate.h -H5F.o: \ - H5F.c \ - H5private.h \ - H5public.h \ - H5config.h \ - H5Aprivate.h \ - H5Apublic.h \ - H5Ipublic.h \ - H5Gprivate.h \ - H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ H5Dpublic.h \ H5Dprivate.h \ + H5Gprivate.h \ + H5Gpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ @@ -822,40 +859,46 @@ H5F.o: \ H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ - H5Iprivate.h \ - H5ACprivate.h \ - H5ACpublic.h \ H5Eprivate.h \ H5Epublic.h \ - H5MMprivate.h \ - H5MMpublic.h -H5Flow.o: \ - H5Flow.c \ + H5MMprivate.h +H5S.o: \ + H5S.c \ H5private.h \ H5public.h \ H5config.h \ + H5Iprivate.h \ + H5Ipublic.h \ H5Eprivate.h \ H5Epublic.h \ - H5Ipublic.h \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ H5Fprivate.h \ H5Fpublic.h \ H5Dpublic.h \ - H5MMprivate.h \ - H5MMpublic.h -H5G.o: \ - H5G.c \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h +H5T.o: \ + H5T.c \ H5private.h \ H5public.h \ H5config.h \ - H5Bprivate.h \ - H5Bpublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Ipublic.h \ H5Fprivate.h \ H5Fpublic.h \ - H5Ipublic.h \ - H5Dpublic.h \ - H5Dprivate.h \ H5Gprivate.h \ H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ @@ -866,38 +909,34 @@ H5G.o: \ H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ + H5Iprivate.h \ H5Eprivate.h \ H5Epublic.h \ - H5Gpkg.h \ - H5ACprivate.h \ - H5ACpublic.h \ - H5HLprivate.h \ - H5HLpublic.h \ - H5Iprivate.h \ H5MMprivate.h -H5MF.o: \ - H5MF.c \ +H5TB.o: \ + H5TB.c \ H5private.h \ H5public.h \ H5config.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Ipublic.h -H5P.o: \ - H5P.c \ + H5Iprivate.h \ + H5Ipublic.h \ + H5Eprivate.h +H5F.o: \ + H5F.c \ H5private.h \ H5public.h \ H5config.h \ - H5Iprivate.h \ + H5Aprivate.h \ + H5Apublic.h \ H5Ipublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ H5Bprivate.h \ H5Bpublic.h \ H5Fprivate.h \ H5Fpublic.h \ H5Dpublic.h \ H5Dprivate.h \ - H5Gprivate.h \ - H5Gpublic.h \ H5Oprivate.h \ H5Opublic.h \ H5HGprivate.h \ @@ -908,19 +947,23 @@ H5P.o: \ H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ + H5Iprivate.h \ + H5ACprivate.h \ + H5ACpublic.h \ H5Eprivate.h \ H5Epublic.h \ - H5MMprivate.h -H5R.o: \ - H5R.c \ - H5Rprivate.h \ - H5Rpublic.h \ - H5Ipublic.h \ + H5MMprivate.h \ + H5MMpublic.h +H5Fmpio.o: \ + H5Fmpio.c \ + H5private.h \ H5public.h \ H5config.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ H5Dprivate.h \ H5Dpublic.h \ - H5private.h \ H5Fprivate.h \ H5Fpublic.h \ H5Gprivate.h \ @@ -937,54 +980,97 @@ H5R.o: \ H5Spublic.h \ H5Zprivate.h \ H5Zpublic.h \ - H5Eprivate.h \ - H5Epublic.h -H5S.o: \ - H5S.c \ + H5MMprivate.h \ + H5MMpublic.h +H5G.o: \ + H5G.c \ H5private.h \ H5public.h \ H5config.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Ipublic.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 \ + H5Gpkg.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5HLprivate.h \ + H5HLpublic.h \ H5Iprivate.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 \ - 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 \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Sprivate.h +H5R.o: \ + H5R.c \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Ipublic.h \ H5public.h \ H5config.h \ - H5Eprivate.h \ - H5Epublic.h \ - H5Ipublic.h \ - H5Sprivate.h \ - H5Spublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5private.h \ + H5Fprivate.h \ + H5Fpublic.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 + H5Tpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.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 @@ -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); @@ -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); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index d7b8c6c..586a50f 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -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 { @@ -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, @@ -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,17 +1037,33 @@ 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)))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -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; + + /* 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; + } - HGOTO_ERROR(H5E_RAGGED, H5E_UNSUPPORTED, FAIL, - "not implemented yet"); + /* 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); } diff --git a/test/.distdep b/test/.distdep index 9eb0b5b..217d2b7 100644 --- a/test/.distdep +++ b/test/.distdep @@ -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 diff --git a/test/Makefile.in b/test/Makefile.in index 899452d..f4024b5 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -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@ diff --git a/test/ragged.c b/test/ragged.c index 43e3ca4..f5ba2f4 100644 --- a/test/ragged.c +++ b/test/ragged.c @@ -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,14 +86,37 @@ 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 * * Purpose: Returns a the length of a 1-d array according to the @@ -106,144 +134,488 @@ 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; - - 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; + double p = (rand() % 1000000)/1000000.0; + double total = 0.0; + size_t size, i; + static size_t ncalls=0; + + 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++; } - assert(i<NELMTS(quant_g)); + return size; } /*------------------------------------------------------------------------- - * Function: main + * Function: ragged_append * - * Purpose: + * Purpose: Writes rows to the end of ragged array RA. * - * Return: Success: + * Return: Success: 0 * - * Failure: + * Failure: -1 * * Programmer: Robb Matzke - * Friday, August 21, 1998 + * Thursday, August 27, 1998 * * Modifications: * *------------------------------------------------------------------------- */ -int -main(void) +static int +ragged_append(hid_t ra, hsize_t rows_at_once) { - hid_t file, dcpl, ra; - int *dd, max_nelmts=3000000, total_nelmts=0; - int i, rows_at_once=100; + 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 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 */ + char testname[80]; - /* Get a SIGALRM every few seconds */ - act.sa_handler = catch_alarm; - sigemptyset(&(act.sa_mask)); - act.sa_flags = 0; - sigaction(SIGALRM, &act, NULL); - alarm(1); - - /* Create the file and ragged array */ - if ((file=H5Fcreate("ragged.h5", H5F_ACC_TRUNC, H5P_DEFAULT, - 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*/ - 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 (H5Pclose(dcpl)<0) goto error; + 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(int)))) goto error; + 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; - 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(); + 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, H5T_NATIVE_INT, size, buf)<0) goto error; + 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(int), timer.etime); + 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, abort_g?" (aborting)":""); + 100.0*total_nelmts/MAX_NELMTS, s, + 0==timeout_g?" (aborting)":""); interval_nelmts = 0; H5_timer_begin(&timer); } } /* Conclusions */ - if (!abort_g) { + if (timeout_g) { /*a minor race condition, but who really cares?*/ H5_timer_end(&timer_total, &timer); - H5_bandwidth(s, (double)interval_nelmts*sizeof(int), timer.etime); + 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); + 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_bandwidth(s, (double)total_nelmts*sizeof(int), timer_total.etime); - printf(" %27s%10s\n\n", "", s); + 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; + } - 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); + /* 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; + } } - printf(" --------------- -------- --------\n"); + + /* 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 */ - if (H5Rclose(ra)<0) goto error; - if (H5Fclose(file)<0) goto error; - 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_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; +} + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: + * + * Return: Success: + * + * Failure: + * + * Programmer: Robb Matzke + * Friday, August 21, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +main(int argc, char *argv[]) +{ + hid_t file, dcpl, ra; + hsize_t ch_size[2]; /*chunk size */ + struct sigaction act; /*alarm signal handler */ + 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; + sigemptyset(&(act.sa_mask)); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + alarm(1); + + /* Create the file and ragged array */ + if ((file=H5Fcreate("ragged.h5", H5F_ACC_TRUNC, H5P_DEFAULT, + 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(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", H_FTYPE, dcpl))<0) goto error; + if (H5Pclose(dcpl)<0) goto error; + + /* 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 */ + printf("\n\nDistribution of row lengths:\n"); + rand_nelmts(1); + + /* Cleanup */ + if (H5Rclose(ra)<0) goto error; + if (H5Fclose(file)<0) goto error; + + puts("All ragged array tests passed."); return 0; error: + puts("*** RAGGED ARRAY TEST(S) FAILED ***"); return -1; } diff --git a/tools/h5ls.c b/tools/h5ls.c index f77beaa..13e4830 100644 --- a/tools/h5ls.c +++ b/tools/h5ls.c @@ -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 @@ -133,8 +152,8 @@ 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]; @@ -154,6 +173,149 @@ list_attr (hid_t obj, const char *attr_name, void __unused__ *op_data) /*------------------------------------------------------------------------- + * 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 * * Purpose: Prints the group member name. @@ -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 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"); + /* Print the object name */ + printf("%-25s ", name); + + /* 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; } |