summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-08-28 15:24:12 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-08-28 15:24:12 (GMT)
commit1b1be9918c1a654225f2040619f0b26ae83028fb (patch)
treedb8bfa193965145aea917d4f06f122238324555d
parent69ed3c270a64d5c60544126b34431d1a7e9a7c8c (diff)
downloadhdf5-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--README2
-rw-r--r--src/.distdep430
-rw-r--r--src/H5F.c6
-rw-r--r--src/H5G.c3
-rw-r--r--src/H5Gpublic.h1
-rw-r--r--src/H5O.c15
-rw-r--r--src/H5R.c128
-rw-r--r--test/.distdep24
-rw-r--r--test/Makefile.in9
-rw-r--r--test/ragged.c518
-rw-r--r--tools/h5ls.c357
11 files changed, 1070 insertions, 423 deletions
diff --git a/README b/README
index 154cc4a..f76c407 100644
--- a/README
+++ b/README
@@ -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
diff --git a/src/H5F.c b/src/H5F.c
index f6492b1..b0fdf4e 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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);
diff --git a/src/H5G.c b/src/H5G.c
index 62cbd42..74af27d 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -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 {
diff --git a/src/H5O.c b/src/H5O.c
index 81efca7..addd14b 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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,
diff --git a/src/H5R.c b/src/H5R.c
index 02c4e25..9d31119 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -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;
}