summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Dependencies862
-rw-r--r--src/H5D.c1215
-rw-r--r--src/H5Dcompact.c92
-rw-r--r--src/H5Dcontig.c1271
-rw-r--r--src/H5Dio.c2293
-rw-r--r--src/H5Distore.c431
-rw-r--r--src/H5Dpkg.h76
-rw-r--r--src/H5Dprivate.h46
-rw-r--r--src/H5Dseq.c754
-rw-r--r--src/H5E.c3
-rw-r--r--src/H5Epublic.h3
-rw-r--r--src/H5Farray.c511
-rw-r--r--src/H5Fcompact.c92
-rw-r--r--src/H5Fcontig.c1271
-rw-r--r--src/H5Fistore.c431
-rw-r--r--src/H5Fpkg.h56
-rw-r--r--src/H5Fprivate.h53
-rw-r--r--src/H5Fseq.c754
-rw-r--r--src/H5G.c2
-rw-r--r--src/H5Oefl.c172
-rw-r--r--src/H5Oprivate.h12
-rw-r--r--src/H5S.c16
-rw-r--r--src/H5Sall.c122
-rw-r--r--src/H5Shyper.c1115
-rw-r--r--src/H5Snone.c91
-rw-r--r--src/H5Spkg.h69
-rw-r--r--src/H5Spoint.c118
-rw-r--r--src/H5Sprivate.h78
-rw-r--r--src/H5Sselect.c638
-rw-r--r--src/H5V.c322
-rw-r--r--src/H5Vprivate.h15
-rw-r--r--src/H5Z.c2
-rw-r--r--src/Makefile.in32
33 files changed, 6666 insertions, 6352 deletions
diff --git a/src/Dependencies b/src/Dependencies
index 43961a9..b488a04 100644
--- a/src/Dependencies
+++ b/src/Dependencies
@@ -19,10 +19,6 @@ H5.lo: \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -30,19 +26,23 @@ H5.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5Sprivate.h \
$(srcdir)/H5FDmpio.h
H5A.lo: \
$(srcdir)/H5A.c \
@@ -104,12 +104,6 @@ H5AC.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5Bprivate.h \
- $(srcdir)/H5Bpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -117,13 +111,15 @@ H5AC.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5Bpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -132,6 +128,9 @@ H5AC.lo: \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5FDfphdf5.h \
$(srcdir)/H5FDmpio.h \
$(srcdir)/H5FDmpiposix.h
@@ -174,12 +173,20 @@ H5D.lo: \
$(srcdir)/H5api_adpt.h \
$(srcdir)/H5MPprivate.h \
$(srcdir)/H5FSprivate.h \
+ $(srcdir)/H5Dpkg.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -187,14 +194,57 @@ H5D.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
+ $(srcdir)/H5Rprivate.h \
+ $(srcdir)/H5Rpublic.h \
+ $(srcdir)/H5Zprivate.h \
+ $(srcdir)/H5Zpublic.h \
+ $(srcdir)/H5Sprivate.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Eprivate.h \
+ $(srcdir)/H5Epublic.h \
+ $(srcdir)/H5FDprivate.h \
+ $(srcdir)/H5FLprivate.h \
+ $(srcdir)/H5FOprivate.h \
+ $(srcdir)/H5TBprivate.h \
+ $(srcdir)/H5HLprivate.h \
+ $(srcdir)/H5HLpublic.h \
+ $(srcdir)/H5Iprivate.h \
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5Vprivate.h \
+ $(srcdir)/H5FDfphdf5.h \
+ $(srcdir)/H5FDmpio.h \
+ $(srcdir)/H5FDmpiposix.h
+H5Dio.lo: \
+ $(srcdir)/H5Dio.c \
+ $(srcdir)/H5private.h \
+ $(srcdir)/H5public.h \
+ H5pubconf.h \
+ $(srcdir)/H5api_adpt.h \
+ $(srcdir)/H5MPprivate.h \
+ $(srcdir)/H5FSprivate.h \
+ $(srcdir)/H5Dpkg.h \
+ $(srcdir)/H5Dprivate.h \
+ $(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Ipublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
$(srcdir)/H5HGprivate.h \
$(srcdir)/H5HGpublic.h \
+ $(srcdir)/H5Fprivate.h \
+ $(srcdir)/H5Fpublic.h \
+ $(srcdir)/H5FDpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5Bpublic.h \
+ $(srcdir)/H5ACprivate.h \
+ $(srcdir)/H5ACpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
@@ -202,18 +252,12 @@ H5D.lo: \
$(srcdir)/H5Sprivate.h \
$(srcdir)/H5Pprivate.h \
$(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
- $(srcdir)/H5FDprivate.h \
$(srcdir)/H5FLprivate.h \
- $(srcdir)/H5FOprivate.h \
- $(srcdir)/H5TBprivate.h \
- $(srcdir)/H5HLprivate.h \
- $(srcdir)/H5HLpublic.h \
$(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MFprivate.h \
$(srcdir)/H5MMprivate.h \
- $(srcdir)/H5Spkg.h \
$(srcdir)/H5Vprivate.h \
$(srcdir)/H5FDfphdf5.h \
$(srcdir)/H5FDmpio.h \
@@ -280,8 +324,6 @@ H5F.lo: \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -291,9 +333,10 @@ H5F.lo: \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5FPprivate.h \
$(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MMprivate.h
-H5Farray.lo: \
- $(srcdir)/H5Farray.c \
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5Pprivate.h
+H5Fcontig.lo: \
+ $(srcdir)/H5Fcontig.c \
$(srcdir)/H5private.h \
$(srcdir)/H5public.h \
H5pubconf.h \
@@ -303,55 +346,16 @@ H5Farray.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
- $(srcdir)/H5Fprivate.h \
- $(srcdir)/H5Fpublic.h \
- $(srcdir)/H5FDpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5Bprivate.h \
- $(srcdir)/H5Bpublic.h \
- $(srcdir)/H5ACprivate.h \
- $(srcdir)/H5ACpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
$(srcdir)/H5HGprivate.h \
$(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
- $(srcdir)/H5Rprivate.h \
- $(srcdir)/H5Rpublic.h \
- $(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
- $(srcdir)/H5Eprivate.h \
- $(srcdir)/H5Epublic.h \
- $(srcdir)/H5Fpkg.h \
- $(srcdir)/H5FOprivate.h \
- $(srcdir)/H5TBprivate.h \
- $(srcdir)/H5FDprivate.h \
- $(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MMprivate.h \
- $(srcdir)/H5Vprivate.h \
- $(srcdir)/H5FDmpio.h
-H5Fcontig.lo: \
- $(srcdir)/H5Fcontig.c \
- $(srcdir)/H5private.h \
- $(srcdir)/H5public.h \
- H5pubconf.h \
- $(srcdir)/H5api_adpt.h \
- $(srcdir)/H5MPprivate.h \
- $(srcdir)/H5FSprivate.h \
- $(srcdir)/H5Dprivate.h \
- $(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Ipublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -359,21 +363,10 @@ H5Fcontig.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -381,6 +374,11 @@ H5Fcontig.lo: \
$(srcdir)/H5TBprivate.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5FLprivate.h \
+ $(srcdir)/H5MFprivate.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Sprivate.h \
$(srcdir)/H5Vprivate.h \
$(srcdir)/H5FDfphdf5.h \
$(srcdir)/H5FDmpio.h \
@@ -422,7 +420,8 @@ H5Fcompact.lo: \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
$(srcdir)/H5FDprivate.h \
- $(srcdir)/H5FLprivate.h
+ $(srcdir)/H5FLprivate.h \
+ $(srcdir)/H5Vprivate.h
H5Fistore.lo: \
$(srcdir)/H5Fistore.c \
$(srcdir)/H5private.h \
@@ -441,10 +440,6 @@ H5Fistore.lo: \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -452,13 +447,13 @@ H5Fistore.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -469,6 +464,10 @@ H5Fistore.lo: \
$(srcdir)/H5MFprivate.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5Sprivate.h \
$(srcdir)/H5Vprivate.h \
$(srcdir)/H5FDfphdf5.h \
$(srcdir)/H5FDmpio.h \
@@ -484,9 +483,16 @@ H5Fseq.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -494,21 +500,10 @@ H5Fseq.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -518,6 +513,9 @@ H5Fseq.lo: \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MFprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Vprivate.h \
$(srcdir)/H5FDmpio.h \
$(srcdir)/H5FDmpiposix.h
@@ -532,9 +530,16 @@ H5FD.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -542,21 +547,10 @@ H5FD.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -565,7 +559,10 @@ H5FD.lo: \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MMprivate.h
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h
H5FDcore.lo: \
$(srcdir)/H5FDcore.c \
$(srcdir)/H5private.h \
@@ -628,12 +625,6 @@ H5FDfphdf5.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5Bprivate.h \
- $(srcdir)/H5Bpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -641,20 +632,25 @@ H5FDfphdf5.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5Bpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5FDfphdf5.h \
$(srcdir)/H5FDmpio.h \
$(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MMprivate.h
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h
H5FDgass.lo: \
$(srcdir)/H5FDgass.c \
$(srcdir)/H5private.h \
@@ -718,12 +714,6 @@ H5FDmpio.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5Bprivate.h \
- $(srcdir)/H5Bpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -731,19 +721,24 @@ H5FDmpio.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5Bpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5FDmpio.h \
$(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MMprivate.h
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h
H5FDmpiposix.lo: \
$(srcdir)/H5FDmpiposix.c \
$(srcdir)/H5private.h \
@@ -895,7 +890,20 @@ H5FDstream.lo: \
H5pubconf.h \
$(srcdir)/H5api_adpt.h \
$(srcdir)/H5MPprivate.h \
- $(srcdir)/H5FSprivate.h
+ $(srcdir)/H5FSprivate.h \
+ $(srcdir)/H5Eprivate.h \
+ $(srcdir)/H5Epublic.h \
+ $(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Fpublic.h \
+ $(srcdir)/H5FDstream.h \
+ $(srcdir)/H5Iprivate.h \
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Zpublic.h
H5FL.lo: \
$(srcdir)/H5FL.c \
$(srcdir)/H5private.h \
@@ -928,7 +936,25 @@ H5FO.lo: \
$(srcdir)/H5FOprivate.h \
$(srcdir)/H5TBprivate.h \
$(srcdir)/H5Bpublic.h \
- $(srcdir)/H5FLprivate.h
+ $(srcdir)/H5FLprivate.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5ACprivate.h \
+ $(srcdir)/H5ACpublic.h \
+ $(srcdir)/H5RSprivate.h \
+ $(srcdir)/H5Rprivate.h \
+ $(srcdir)/H5Rpublic.h \
+ $(srcdir)/H5Zprivate.h \
+ $(srcdir)/H5Zpublic.h
H5FP.lo: \
$(srcdir)/H5FP.c \
$(srcdir)/H5private.h \
@@ -979,12 +1005,6 @@ H5FPclient.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5Bprivate.h \
- $(srcdir)/H5Bpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -992,20 +1012,26 @@ H5FPclient.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5Bpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5Gpkg.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Spkg.h \
+ $(srcdir)/H5Sprivate.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5TBprivate.h
H5FPserver.lo: \
$(srcdir)/H5FPserver.c \
@@ -1075,7 +1101,6 @@ H5G.lo: \
$(srcdir)/H5RSprivate.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
- $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
@@ -1087,9 +1112,6 @@ H5G.lo: \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
@@ -1100,7 +1122,8 @@ H5G.lo: \
$(srcdir)/H5HLprivate.h \
$(srcdir)/H5HLpublic.h \
$(srcdir)/H5Iprivate.h \
- $(srcdir)/H5MMprivate.h
+ $(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h
H5Gent.lo: \
$(srcdir)/H5Gent.c \
$(srcdir)/H5private.h \
@@ -1551,10 +1574,7 @@ H5Odtype.lo: \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
$(srcdir)/H5Tpkg.h \
- $(srcdir)/H5Dprivate.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Dprivate.h
H5Oefl.lo: \
$(srcdir)/H5Oefl.c \
$(srcdir)/H5private.h \
@@ -1647,9 +1667,16 @@ H5Olayout.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -1657,25 +1684,17 @@ H5Olayout.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FLprivate.h \
+ $(srcdir)/H5MFprivate.h \
+ $(srcdir)/H5FDprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Opkg.h
H5Omtime.lo: \
$(srcdir)/H5Omtime.c \
@@ -1944,9 +1963,16 @@ H5P.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -1954,27 +1980,19 @@ H5P.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Ppkg.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5TBprivate.h
H5Pdcpl.lo: \
$(srcdir)/H5Pdcpl.c \
@@ -1987,9 +2005,16 @@ H5Pdcpl.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -1997,26 +2022,18 @@ H5Pdcpl.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Ppkg.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5TBprivate.h
H5Pdxpl.lo: \
$(srcdir)/H5Pdxpl.c \
@@ -2029,9 +2046,16 @@ H5Pdxpl.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2039,24 +2063,16 @@ H5Pdxpl.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Ppkg.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5TBprivate.h
H5Pfapl.lo: \
$(srcdir)/H5Pfapl.c \
@@ -2069,9 +2085,16 @@ H5Pfapl.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2079,26 +2102,18 @@ H5Pfapl.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FDprivate.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5Ppkg.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5TBprivate.h \
$(srcdir)/H5FDsec2.h
H5Pfcpl.lo: \
@@ -2138,9 +2153,16 @@ H5R.lo: \
$(srcdir)/H5Ipublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2148,28 +2170,21 @@ H5R.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Fpkg.h \
$(srcdir)/H5FOprivate.h \
$(srcdir)/H5TBprivate.h \
$(srcdir)/H5MMprivate.h \
- $(srcdir)/H5Spkg.h
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Spkg.h \
+ $(srcdir)/H5Sprivate.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h
H5RS.lo: \
$(srcdir)/H5RS.c \
$(srcdir)/H5Eprivate.h \
@@ -2443,9 +2458,16 @@ H5Sselect.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2453,26 +2475,19 @@ H5Sselect.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5Spkg.h \
+ $(srcdir)/H5Sprivate.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5MMpublic.h \
$(srcdir)/H5Vprivate.h
H5ST.lo: \
$(srcdir)/H5ST.c \
@@ -2498,9 +2513,16 @@ H5T.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2508,26 +2530,18 @@ H5T.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5FLprivate.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Tpkg.h
H5Tarray.lo: \
$(srcdir)/H5Tarray.c \
@@ -2550,6 +2564,11 @@ H5Tarray.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2557,19 +2576,10 @@ H5Tarray.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tbit.lo: \
$(srcdir)/H5Tbit.c \
$(srcdir)/H5private.h \
@@ -2590,6 +2600,11 @@ H5Tbit.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2597,19 +2612,10 @@ H5Tbit.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tcommit.lo: \
$(srcdir)/H5Tcommit.c \
$(srcdir)/H5private.h \
@@ -2630,6 +2636,11 @@ H5Tcommit.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2637,19 +2648,10 @@ H5Tcommit.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tcompound.lo: \
$(srcdir)/H5Tcompound.c \
$(srcdir)/H5private.h \
@@ -2672,6 +2674,11 @@ H5Tcompound.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2679,18 +2686,10 @@ H5Tcompound.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tconv.lo: \
$(srcdir)/H5Tconv.c \
$(srcdir)/H5private.h \
@@ -2717,6 +2716,11 @@ H5Tconv.lo: \
$(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Dprivate.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2724,15 +2728,9 @@ H5Tconv.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
- $(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Sprivate.h
+ $(srcdir)/H5Zprivate.h
H5Tcset.lo: \
$(srcdir)/H5Tcset.c \
$(srcdir)/H5private.h \
@@ -2753,6 +2751,11 @@ H5Tcset.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2760,19 +2763,10 @@ H5Tcset.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tenum.lo: \
$(srcdir)/H5Tenum.c \
$(srcdir)/H5private.h \
@@ -2796,6 +2790,11 @@ H5Tenum.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2803,18 +2802,10 @@ H5Tenum.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tfields.lo: \
$(srcdir)/H5Tfields.c \
$(srcdir)/H5private.h \
@@ -2837,6 +2828,11 @@ H5Tfields.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2844,18 +2840,10 @@ H5Tfields.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tfixed.lo: \
$(srcdir)/H5Tfixed.c \
$(srcdir)/H5private.h \
@@ -2876,6 +2864,11 @@ H5Tfixed.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2883,19 +2876,10 @@ H5Tfixed.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tfloat.lo: \
$(srcdir)/H5Tfloat.c \
$(srcdir)/H5private.h \
@@ -2916,6 +2900,11 @@ H5Tfloat.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2923,19 +2912,49 @@ H5Tfloat.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
+ $(srcdir)/H5Rprivate.h \
+ $(srcdir)/H5Rpublic.h \
+ $(srcdir)/H5Zprivate.h \
+ $(srcdir)/H5Zpublic.h
+H5Tinit.lo: \
+ H5Tinit.c \
+ $(srcdir)/H5private.h \
+ $(srcdir)/H5public.h \
+ H5pubconf.h \
+ $(srcdir)/H5api_adpt.h \
+ $(srcdir)/H5MPprivate.h \
+ $(srcdir)/H5FSprivate.h \
+ $(srcdir)/H5Iprivate.h \
+ $(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Eprivate.h \
+ $(srcdir)/H5Epublic.h \
+ $(srcdir)/H5FLprivate.h \
+ $(srcdir)/H5MMprivate.h \
$(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Tpkg.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
+ $(srcdir)/H5Fprivate.h \
+ $(srcdir)/H5Fpublic.h \
+ $(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Dprivate.h \
+ $(srcdir)/H5Dpublic.h \
$(srcdir)/H5Oprivate.h \
$(srcdir)/H5Opublic.h \
$(srcdir)/H5Spublic.h \
$(srcdir)/H5Tprivate.h \
$(srcdir)/H5Tpublic.h \
+ $(srcdir)/H5Gprivate.h \
+ $(srcdir)/H5Gpublic.h \
+ $(srcdir)/H5Bprivate.h \
+ $(srcdir)/H5Bpublic.h \
+ $(srcdir)/H5ACprivate.h \
+ $(srcdir)/H5ACpublic.h \
+ $(srcdir)/H5RSprivate.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tnative.lo: \
$(srcdir)/H5Tnative.c \
$(srcdir)/H5private.h \
@@ -2958,6 +2977,11 @@ H5Tnative.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -2965,18 +2989,10 @@ H5Tnative.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Toffset.lo: \
$(srcdir)/H5Toffset.c \
$(srcdir)/H5private.h \
@@ -2997,6 +3013,11 @@ H5Toffset.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3004,19 +3025,10 @@ H5Toffset.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Topaque.lo: \
$(srcdir)/H5Topaque.c \
$(srcdir)/H5private.h \
@@ -3039,6 +3051,11 @@ H5Topaque.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3046,18 +3063,10 @@ H5Topaque.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Torder.lo: \
$(srcdir)/H5Torder.c \
$(srcdir)/H5private.h \
@@ -3078,6 +3087,11 @@ H5Torder.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3085,19 +3099,10 @@ H5Torder.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tpad.lo: \
$(srcdir)/H5Tpad.c \
$(srcdir)/H5private.h \
@@ -3118,6 +3123,11 @@ H5Tpad.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3125,19 +3135,10 @@ H5Tpad.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tprecis.lo: \
$(srcdir)/H5Tprecis.c \
$(srcdir)/H5private.h \
@@ -3158,6 +3159,11 @@ H5Tprecis.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3165,19 +3171,10 @@ H5Tprecis.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tstrpad.lo: \
$(srcdir)/H5Tstrpad.c \
$(srcdir)/H5private.h \
@@ -3198,6 +3195,11 @@ H5Tstrpad.lo: \
$(srcdir)/H5FDpublic.h \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3205,19 +3207,10 @@ H5Tstrpad.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
+ $(srcdir)/H5Zpublic.h
H5Tvlen.lo: \
$(srcdir)/H5Tvlen.c \
$(srcdir)/H5private.h \
@@ -3244,6 +3237,11 @@ H5Tvlen.lo: \
$(srcdir)/H5Zpublic.h \
$(srcdir)/H5Tpkg.h \
$(srcdir)/H5Dprivate.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3251,15 +3249,9 @@ H5Tvlen.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
- $(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Sprivate.h
+ $(srcdir)/H5Zprivate.h
H5TB.lo: \
$(srcdir)/H5TB.c \
$(srcdir)/H5private.h \
@@ -3336,9 +3328,16 @@ H5Z.lo: \
$(srcdir)/H5Dprivate.h \
$(srcdir)/H5Dpublic.h \
$(srcdir)/H5Ipublic.h \
+ $(srcdir)/H5Oprivate.h \
+ $(srcdir)/H5Opublic.h \
+ $(srcdir)/H5Spublic.h \
+ $(srcdir)/H5HGprivate.h \
+ $(srcdir)/H5HGpublic.h \
$(srcdir)/H5Fprivate.h \
$(srcdir)/H5Fpublic.h \
$(srcdir)/H5FDpublic.h \
+ $(srcdir)/H5Tprivate.h \
+ $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Gprivate.h \
$(srcdir)/H5Gpublic.h \
$(srcdir)/H5Bprivate.h \
@@ -3346,25 +3345,18 @@ H5Z.lo: \
$(srcdir)/H5ACprivate.h \
$(srcdir)/H5ACpublic.h \
$(srcdir)/H5RSprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
$(srcdir)/H5Rprivate.h \
$(srcdir)/H5Rpublic.h \
$(srcdir)/H5Zprivate.h \
$(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h \
$(srcdir)/H5Eprivate.h \
$(srcdir)/H5Epublic.h \
$(srcdir)/H5Iprivate.h \
$(srcdir)/H5MMprivate.h \
+ $(srcdir)/H5MMpublic.h \
+ $(srcdir)/H5Pprivate.h \
+ $(srcdir)/H5Ppublic.h \
+ $(srcdir)/H5Sprivate.h \
$(srcdir)/H5Zpkg.h
H5Zdeflate.lo: \
$(srcdir)/H5Zdeflate.c \
@@ -3459,45 +3451,3 @@ H5Zszip.lo: \
$(srcdir)/H5Zpublic.h \
$(srcdir)/H5Ppublic.h \
$(srcdir)/H5Zpkg.h
-H5Tinit.lo: \
- H5Tinit.c \
- $(srcdir)/H5private.h \
- $(srcdir)/H5public.h \
- H5pubconf.h \
- $(srcdir)/H5api_adpt.h \
- $(srcdir)/H5MPprivate.h \
- $(srcdir)/H5FSprivate.h \
- $(srcdir)/H5Iprivate.h \
- $(srcdir)/H5Ipublic.h \
- $(srcdir)/H5Eprivate.h \
- $(srcdir)/H5Epublic.h \
- $(srcdir)/H5FLprivate.h \
- $(srcdir)/H5MMprivate.h \
- $(srcdir)/H5MMpublic.h \
- $(srcdir)/H5Tpkg.h \
- $(srcdir)/H5HGprivate.h \
- $(srcdir)/H5HGpublic.h \
- $(srcdir)/H5Fprivate.h \
- $(srcdir)/H5Fpublic.h \
- $(srcdir)/H5FDpublic.h \
- $(srcdir)/H5Dprivate.h \
- $(srcdir)/H5Dpublic.h \
- $(srcdir)/H5Gprivate.h \
- $(srcdir)/H5Gpublic.h \
- $(srcdir)/H5Bprivate.h \
- $(srcdir)/H5Bpublic.h \
- $(srcdir)/H5ACprivate.h \
- $(srcdir)/H5ACpublic.h \
- $(srcdir)/H5RSprivate.h \
- $(srcdir)/H5Oprivate.h \
- $(srcdir)/H5Opublic.h \
- $(srcdir)/H5Spublic.h \
- $(srcdir)/H5Tprivate.h \
- $(srcdir)/H5Tpublic.h \
- $(srcdir)/H5Rprivate.h \
- $(srcdir)/H5Rpublic.h \
- $(srcdir)/H5Zprivate.h \
- $(srcdir)/H5Zpublic.h \
- $(srcdir)/H5Sprivate.h \
- $(srcdir)/H5Pprivate.h \
- $(srcdir)/H5Ppublic.h
diff --git a/src/H5D.c b/src/H5D.c
index f701b88..1713d71 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -12,24 +12,19 @@
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#define H5S_PACKAGE /*suppress error about including H5Spkg */
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
#include "H5private.h" /* Generic Functions */
-#include "H5Dprivate.h" /* Dataset functions */
+#include "H5Dpkg.h" /* Dataset functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free Lists */
#include "H5FOprivate.h" /* File objects */
-#include "H5Gprivate.h" /* Group headers */
#include "H5HLprivate.h" /* Name heap */
#include "H5Iprivate.h" /* IDs */
-#include "H5MFprivate.h" /* File space management */
#include "H5MMprivate.h" /* Memory management */
-#include "H5Oprivate.h" /* Object headers */
-#include "H5Pprivate.h" /* Property lists */
-#include "H5Spkg.h" /* Dataspace functions */
+#include "H5Sprivate.h" /* Dataspace functions */
#include "H5Vprivate.h" /* Vector and array functions */
-#include "H5Zprivate.h" /* Data filters */
/*#define H5D_DEBUG*/
@@ -42,45 +37,20 @@
#include "H5FDmpio.h"
#include "H5FDmpiposix.h"
-#ifdef H5_HAVE_PARALLEL
-/* Remove this if H5R_DATASET_REGION is no longer used in this file */
-# include "H5Rpublic.h"
-#endif /*H5_HAVE_PARALLEL*/
-
/* Pablo information */
#define PABLO_MASK H5D_mask
-/* Local typedefs */
-
-/* Enumerated type for allocating dataset's storage */
-typedef enum {
- H5D_ALLOC_CREATE, /* Dataset is being created */
- H5D_ALLOC_OPEN, /* Dataset is being opened */
- H5D_ALLOC_EXTEND, /* Dataset's dataspace is being extended */
- H5D_ALLOC_WRITE /* Dataset is being extended */
-} H5D_time_alloc_t;
-
/* Interface initialization */
static int interface_initialize_g = 0;
#define INTERFACE_INIT H5D_init_interface
/* Local functions */
static herr_t H5D_init_interface(void);
-static herr_t H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset,H5D_time_alloc_t time_alloc,
- hbool_t update_time, hbool_t full_overwrite);
static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite, hid_t dxpl_id);
static H5D_t * H5D_new(hid_t dcpl_id, hbool_t creating);
static H5D_t * H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id,
const H5S_t *space, hid_t dcpl_id, hid_t dxpl_id);
static H5D_t * H5D_open_oid(H5G_entry_t *ent, hid_t dxpl_id);
-static herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type,
- const H5S_t *mem_space, const H5S_t *file_space,
- hid_t dset_xfer_plist, void *buf/*out*/);
-static herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type,
- const H5S_t *mem_space, const H5S_t *file_space,
- hid_t dset_xfer_plist, const void *buf);
-static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
- const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id);
static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id);
static hsize_t H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id);
static haddr_t H5D_get_offset(H5D_t *dset);
@@ -91,12 +61,6 @@ static herr_t H5D_close(H5D_t *dataset);
/* Declare a free list to manage the H5D_t struct */
H5FL_DEFINE_STATIC(H5D_t);
-/* Declare a free list to manage blocks of type conversion data */
-H5FL_BLK_DEFINE(type_conv);
-
-/* Declare a free list to manage blocks of single datatype element data */
-H5FL_BLK_DEFINE(type_elem);
-
/* Declare a free list to manage blocks of VL data */
H5FL_BLK_DEFINE_STATIC(vlen_vl_buf);
@@ -1192,193 +1156,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Dread
- *
- * Purpose: Reads (part of) a DSET from the file into application
- * memory BUF. The part of the dataset to read is defined with
- * MEM_SPACE_ID and FILE_SPACE_ID. The data points are
- * converted from their file type to the MEM_TYPE_ID specified.
- * Additional miscellaneous data transfer properties can be
- * passed to this function with the PLIST_ID argument.
- *
- * The FILE_SPACE_ID can be the constant H5S_ALL which indicates
- * that the entire file data space is to be referenced.
- *
- * The MEM_SPACE_ID can be the constant H5S_ALL in which case
- * the memory data space is the same as the file data space
- * defined when the dataset was created.
- *
- * The number of elements in the memory data space must match
- * the number of elements in the file data space.
- *
- * The PLIST_ID can be the constant H5P_DEFAULT in which
- * case the default data transfer properties are used.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Errors:
- * ARGS BADTYPE Not a data space.
- * ARGS BADTYPE Not a data type.
- * ARGS BADTYPE Not a dataset.
- * ARGS BADTYPE Not xfer parms.
- * ARGS BADVALUE No output buffer.
- * DATASET READERROR Can't read data.
- *
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
- hid_t file_space_id, hid_t plist_id, void *buf/*out*/)
-{
- H5D_t *dset = NULL;
- const H5T_t *mem_type = NULL;
- const H5S_t *mem_space = NULL;
- const H5S_t *file_space = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_API(H5Dread, FAIL);
- H5TRACE6("e","iiiiix",dset_id,mem_type_id,mem_space_id,file_space_id,
- plist_id,buf);
-
- /* check arguments */
- if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
- if (NULL == dset->ent.file)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
- if (NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (H5S_ALL != mem_space_id) {
- if (NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
-
- /* Check for valid selection */
- if((*mem_space->select.is_valid)(mem_space)!=TRUE)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
- }
- if (H5S_ALL != file_space_id) {
- if (NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
-
- /* Check for valid selection */
- if((*file_space->select.is_valid)(file_space)!=TRUE)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
- }
-
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == plist_id)
- plist_id= H5P_DATASET_XFER_DEFAULT;
- else
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
- if (!buf)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
-
- /* read raw data */
- if (H5D_read(dset, mem_type, mem_space, file_space, plist_id, buf/*out*/) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data");
-
-done:
- FUNC_LEAVE_API(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Dwrite
- *
- * Purpose: Writes (part of) a DSET from application memory BUF to the
- * file. The part of the dataset to write is defined with the
- * MEM_SPACE_ID and FILE_SPACE_ID arguments. The data points
- * are converted from their current type (MEM_TYPE_ID) to their
- * file data type. Additional miscellaneous data transfer
- * properties can be passed to this function with the
- * PLIST_ID argument.
- *
- * The FILE_SPACE_ID can be the constant H5S_ALL which indicates
- * that the entire file data space is to be referenced.
- *
- * The MEM_SPACE_ID can be the constant H5S_ALL in which case
- * the memory data space is the same as the file data space
- * defined when the dataset was created.
- *
- * The number of elements in the memory data space must match
- * the number of elements in the file data space.
- *
- * The PLIST_ID can be the constant H5P_DEFAULT in which
- * case the default data transfer properties are used.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Errors:
- *
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
- hid_t file_space_id, hid_t plist_id, const void *buf)
-{
- H5D_t *dset = NULL;
- const H5T_t *mem_type = NULL;
- const H5S_t *mem_space = NULL;
- const H5S_t *file_space = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_API(H5Dwrite, FAIL);
- H5TRACE6("e","iiiiix",dset_id,mem_type_id,mem_space_id,file_space_id,
- plist_id,buf);
-
- /* check arguments */
- if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
- if (NULL == dset->ent.file)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
- if (NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- if (H5S_ALL != mem_space_id) {
- if (NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
-
- /* Check for valid selection */
- if ((*mem_space->select.is_valid)(mem_space)!=TRUE)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
- }
- if (H5S_ALL != file_space_id) {
- if (NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
-
- /* Check for valid selection */
- if ((*file_space->select.is_valid)(file_space)!=TRUE)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
- }
-
- /* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == plist_id)
- plist_id= H5P_DATASET_XFER_DEFAULT;
- else
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
- if (!buf)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
-
- /* write raw data */
- if (H5D_write(dset, mem_type, mem_space, file_space, plist_id, buf) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data");
-
-done:
- FUNC_LEAVE_API(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Dextend
*
* Purpose: This function makes sure that the dataset is at least of size
@@ -2434,837 +2211,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_read
- *
- * Purpose: Reads (part of) a DATASET into application memory BUF. See
- * H5Dread() for complete details.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
- *
- * Modifications:
- * Robb Matzke, 1998-06-09
- * The data space is no longer cached in the dataset struct.
- *
- * Robb Matzke, 1998-08-11
- * Added timing calls around all the data space I/O functions.
- *
- * rky, 1998-09-18
- * Added must_convert to do non-optimized read when necessary.
- *
- * Quincey Koziol, 1999-07-02
- * Changed xfer_parms parameter to xfer plist parameter, so it
- * could be passed to H5T_convert.
- *
- * Albert Cheng, 2000-11-21
- * Added the code that when it detects it is not safe to process a
- * COLLECTIVE read request without hanging, it changes it to
- * INDEPENDENT calls.
- *
- * Albert Cheng, 2000-11-27
- * Changed to use the optimized MPIO transfer for Collective calls only.
- *
- * Raymond Lu, 2001-10-2
- * Changed the way to retrieve property for generic property list.
- *
- * Raymond Lu, 2002-2-26
- * For the new fill value design, data space can either be allocated
- * or not allocated at this stage. Fill value or data from space is
- * returned to outgoing buffer.
- *
- * QAK - 2002/04/02
- * Removed the must_convert parameter and move preconditions to
- * H5S_<foo>_opt_possible() routine
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
- const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/)
-{
- hsize_t nelmts; /*total number of elmts */
- hsize_t smine_start; /*strip mine start loc */
- hsize_t n, smine_nelmts; /*elements per strip */
- uint8_t *tconv_buf = NULL; /*data type conv buffer */
- uint8_t *bkg_buf = NULL; /*background buffer */
- H5T_path_t *tpath = NULL; /*type conversion info */
- hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
- H5S_conv_t *sconv=NULL; /*space conversion funcs*/
- H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
- hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
- H5S_sel_iter_t bkg_iter; /*background iteration info*/
- hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
- H5S_sel_iter_t file_iter; /*file selection iteration info*/
- hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
- herr_t ret_value = SUCCEED; /*return value */
- herr_t status; /*function return status*/
- size_t src_type_size; /*size of source type */
- size_t dst_type_size; /*size of destination type*/
- size_t target_size; /*desired buffer size */
- hsize_t request_nelmts; /*requested strip mine */
- H5T_bkg_t need_bkg; /*type of background buf*/
-#ifdef H5_HAVE_PARALLEL
- H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
- hbool_t xfer_mode_changed=0; /*xfer_mode needs restore */
- hbool_t doing_mpio=0; /*This is an MPIO access */
-#endif /*H5_HAVE_PARALLEL*/
-#ifdef H5S_DEBUG
- H5_timer_t timer;
-#endif
- H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */
- H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
- unsigned sconv_flags=0; /* Flags for the space conversion */
-
- FUNC_ENTER_NOAPI(H5D_read, FAIL);
-
- /* check args */
- assert(dataset && dataset->ent.file);
- assert(mem_type);
- assert(buf);
-
- /* Get the dataset's creation property list */
- if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
-
- /* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5I_object(dxpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
-
- if (!file_space)
- file_space = dataset->space;
- if (!mem_space)
- mem_space = file_space;
- nelmts = (*mem_space->select.get_npoints)(mem_space);
-
-#ifdef H5_HAVE_PARALLEL
- /* Collect Parallel I/O information for possible later use */
- if (H5FD_MPIO==H5P_peek_hid_t(dx_plist,H5D_XFER_VFL_ID_NAME)) {
- doing_mpio++;
- xfer_mode=H5P_peek_unsigned(dx_plist, H5D_XFER_IO_XFER_MODE_NAME);
- } /* end if */
- /* Collective access is not permissible without the MPIO or MPIPOSIX driver */
- if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE &&
- !(IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)))
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPIO & MPIPOSIX drivers only");
-
- /* Set the "parallel I/O possible" flag, for H5S_find() */
- if (H5S_mpi_opt_types_g && IS_H5FD_MPIO(dataset->ent.file)) {
- /* Only collective write should call this since it eventually
- * calls MPI_File_set_view which is a collective call.
- * See H5S_mpio_spaces_xfer() for details.
- */
- if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE)
- sconv_flags |= H5S_CONV_PAR_IO_POSSIBLE;
- } /* end if */
-#endif /*H5_HAVE_PARALLEL*/
-
- /* Make certain that the number of elements in each selection is the same */
- if (nelmts!=(*file_space->select.get_npoints) (file_space))
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
-
- /* Retrieve dataset properties */
- /* <none needed in the general case> */
-
- /* If space hasn't been allocated and not using external storage,
- * return fill value to buffer if fill time is upon allocation, or
- * do nothing if fill time is never. If the dataset is compact and
- * fill time is NEVER, there is no way to tell whether part of data
- * has been overwritten. So just proceed in reading.
- */
- if(nelmts > 0 && dataset->efl.nused==0 && dataset->layout.type!=H5D_COMPACT
- && dataset->layout.addr==HADDR_UNDEF) {
- H5O_fill_t fill; /* Fill value info */
- H5D_fill_time_t fill_time; /* When to write the fill values */
- H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
-
- /* Retrieve dataset's fill-value properties */
- if(H5P_fill_value_defined(dc_plist, &fill_status)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
- if((fill_status==H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED)
- && H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill value");
- if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill time");
-
- /* Should be impossible, but check anyway... */
- if(fill_status == H5D_FILL_VALUE_UNDEFINED && fill_time == H5D_FILL_TIME_ALLOC)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "read failed: dataset doesn't exist, no data can be read");
-
- /* If we're never going to fill this dataset, just leave the junk in the user's buffer */
- if(fill_time == H5D_FILL_TIME_NEVER)
- HGOTO_DONE(SUCCEED);
-
- /* Go fill the user's selection with the dataset's fill value */
- if(H5D_fill(fill.buf,fill.type,buf,mem_type,mem_space, dxpl_id)<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed");
- } else
- HGOTO_DONE(SUCCEED);
- } /* end if */
-
- /*
- * Locate the type conversion function and data space conversion
- * functions, and set up the element numbering information. If a data
- * type conversion is necessary then register data type atoms. Data type
- * conversion is necessary if the user has set the `need_bkg' to a high
- * enough value in xfer_parms since turning off data type conversion also
- * turns off background preservation.
- */
- if (NULL==(tpath=H5T_path_find(dataset->type, mem_type, NULL, NULL, dxpl_id))) {
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
- } else if (!H5T_IS_NOOP(tpath)) {
- if ((src_id=H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0 ||
- (dst_id=H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
- } /* end if */
-
- /* Set the storage flags for the space conversion check */
- switch(dataset->layout.type) {
- case H5D_COMPACT:
- sconv_flags |= H5S_CONV_STORAGE_COMPACT;
- break;
-
- case H5D_CONTIGUOUS:
- sconv_flags |= H5S_CONV_STORAGE_CONTIGUOUS;
- break;
-
- case H5D_CHUNKED:
- sconv_flags |= H5S_CONV_STORAGE_CHUNKED;
- break;
-
- default:
- assert(0 && "Unhandled layout type!");
- } /* end switch */
-
- /* Get dataspace functions */
- if (NULL==(sconv=H5S_find(mem_space, file_space, sconv_flags)))
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert from file to memory data space");
-
- /*
- * If there is no type conversion then read directly into the
- * application's buffer. This saves at least one mem-to-mem copy.
- */
- if (H5T_IS_NOOP(tpath)) {
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- /* Sanity check dataset, then read it */
- assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 || dataset->layout.type==H5D_COMPACT);
- status = (sconv->read)(dataset->ent.file, &(dataset->layout),
- dc_plist, &(dataset->efl), H5T_get_size(dataset->type),
- file_space, mem_space, dxpl_id, buf/*out*/);
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[1].read_timer), &timer);
- sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->type);
- sconv->stats[1].read_ncalls++;
-#endif
-
- /* Check return value from optimized read */
- if (status<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed");
- } else
- /* direct xfer accomplished successfully */
- HGOTO_DONE(SUCCEED);
- } /* end if */
-
-#ifdef H5_HAVE_PARALLEL
- /* The following may not handle a collective call correctly
- * since it does not ensure all processes can handle the read
- * request according to the MPI collective specification.
- * Do the collective request via independent mode.
- */
- if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE) {
- /* Kludge: change the xfer_mode to independent, handle the request,
- * then xfer_mode before return.
- * Better way is to get a temporary data_xfer property with
- * INDEPENDENT xfer_mode and pass it downwards.
- */
- xfer_mode = H5FD_MPIO_INDEPENDENT;
- if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
- xfer_mode_changed++; /* restore it before return */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- fprintf(H5DEBUG(D),
- "H5D: Cannot handle this COLLECTIVE read request. Do it via INDEPENDENT calls\n");
-#endif
- } /* end if */
-#endif /*H5_HAVE_PARALLEL*/
- /*
- * This is the general case.
- */
-
- /* Compute element sizes and other parameters */
- src_type_size = H5T_get_size(dataset->type);
- dst_type_size = H5T_get_size(mem_type);
- target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME);
- request_nelmts = target_size / MAX(src_type_size, dst_type_size);
-
- /* Figure out the strip mine size. */
- if ((*file_space->select.iter_init)(file_space, src_type_size, &file_iter)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
- file_iter_init=1; /*file selection iteration info has been initialized */
- if ((*mem_space->select.iter_init)(mem_space, dst_type_size, &mem_iter)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
- mem_iter_init=1; /*file selection iteration info has been initialized */
- if ((*mem_space->select.iter_init)(mem_space, dst_type_size, &bkg_iter)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
- bkg_iter_init=1; /*file selection iteration info has been initialized */
-
- /* Sanity check elements in temporary buffer */
- if (request_nelmts<=0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small");
-
- /*
- * Get a temporary buffer for type conversion unless the app has already
- * supplied one through the xfer properties. Instead of allocating a
- * buffer which is the exact size, we allocate the target size. The
- * malloc() is usually less resource-intensive if we allocate/free the
- * same size over and over.
- */
- if (tpath->cdata.need_bkg) {
- /* Retrieve the bkgr buffer property */
- if(H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &need_bkg)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
- need_bkg = MAX(tpath->cdata.need_bkg, need_bkg);
- } else {
- need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
- } /* end else */
- if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
- /* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
- } /* end if */
- if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
- /* Allocate background buffer */
- H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
- if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
- } /* end if */
-
- /* Start strip mining... */
- for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) {
- /* Go figure out how many elements to read from the file */
- assert((*file_space->select.iter_nelmts)(&file_iter)==(nelmts-smine_start));
- smine_nelmts = MIN(request_nelmts, (nelmts-smine_start));
-
- /*
- * Gather the data from disk into the data type conversion
- * buffer. Also gather data from application to background buffer
- * if necessary.
- */
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- /* Sanity check that space is allocated, then read data from it */
- assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 || dataset->layout.type==H5D_COMPACT);
- n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
- dc_plist, &(dataset->efl), src_type_size, file_space,
- &file_iter, smine_nelmts, dxpl_id, tconv_buf/*out*/);
-
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[1].gath_timer), &timer);
- sconv->stats[1].gath_nbytes += n * src_type_size;
- sconv->stats[1].gath_ncalls++;
-#endif
- if (n!=smine_nelmts)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
-
- if (need_bkg) {
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- n = H5S_select_mgath(buf, dst_type_size, mem_space, &bkg_iter,
- smine_nelmts, dxpl_id, bkg_buf/*out*/);
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[1].bkg_timer), &timer);
- sconv->stats[1].bkg_nbytes += n * dst_type_size;
- sconv->stats[1].bkg_ncalls++;
-#endif
- if (n!=smine_nelmts)
- HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
- } /* end if */
-
- /*
- * Perform data type conversion.
- */
- if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed");
-
- /*
- * Scatter the data into memory.
- */
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- status = H5S_select_mscat(tconv_buf, dst_type_size, mem_space,
- &mem_iter, smine_nelmts, dxpl_id, buf/*out*/);
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[1].scat_timer), &timer);
- sconv->stats[1].scat_nbytes += smine_nelmts * dst_type_size;
- sconv->stats[1].scat_ncalls++;
-#endif
- if (status<0)
- HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "scatter failed");
-
- } /* end for */
-
-done:
-#ifdef H5_HAVE_PARALLEL
- /* restore xfer_mode due to the kludge */
- if (doing_mpio && xfer_mode_changed) {
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- fprintf (H5DEBUG(D), "H5D: dx->xfer_mode was COLLECTIVE, restored to INDEPENDENT\n");
-#endif
- xfer_mode = H5FD_MPIO_COLLECTIVE;
- if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
- } /* end if */
-#endif /*H5_HAVE_PARALLEL*/
- /* Release selection iterators */
- if(file_iter_init)
- (*file_space->select.iter_release)(&file_iter);
- if(mem_iter_init)
- (*mem_space->select.iter_release)(&mem_iter);
- if(bkg_iter_init)
- (*mem_space->select.iter_release)(&bkg_iter);
-
- if (src_id >= 0)
- H5I_dec_ref(src_id);
- if (dst_id >= 0)
- H5I_dec_ref(dst_id);
- assert(dx_plist);
- if (tconv_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))
- H5FL_BLK_FREE(type_conv,tconv_buf);
- if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
- H5FL_BLK_FREE(type_conv,bkg_buf);
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5D_read() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5D_write
- *
- * Purpose: Writes (part of) a DATASET to a file from application memory
- * BUF. See H5Dwrite() for complete details.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Thursday, December 4, 1997
- *
- * Modifications:
- * Robb Matzke, 9 Jun 1998
- * The data space is no longer cached in the dataset struct.
- *
- * rky 980918
- * Added must_convert to do non-optimized read when necessary.
- *
- * Quincey Koziol, 2 July 1999
- * Changed xfer_parms parameter to xfer plist parameter, so it could
- * be passed to H5T_convert
- *
- * Albert Cheng, 2000-11-21
- * Added the code that when it detects it is not safe to process a
- * COLLECTIVE write request without hanging, it changes it to
- * INDEPENDENT calls.
- *
- * Albert Cheng, 2000-11-27
- * Changed to use the optimized MPIO transfer for Collective calls only.
- *
- * Raymond Lu, 2001-10-2
- * Changed the way to retrieve property for generic property list.
- *
- * Raymond Lu, 2002-2-26
- * For the new fill value design, space may not be allocated until
- * this function is called. Allocate and initialize space if it
- * hasn't been.
- *
- * QAK - 2002/04/02
- * Removed the must_convert parameter and move preconditions to
- * H5S_<foo>_opt_possible() routine
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
- const H5S_t *file_space, hid_t dxpl_id, const void *buf)
-{
- hsize_t nelmts; /*total number of elmts */
- hsize_t smine_start; /*strip mine start loc */
- hsize_t n, smine_nelmts; /*elements per strip */
- uint8_t *tconv_buf = NULL; /*data type conv buffer */
- uint8_t *bkg_buf = NULL; /*background buffer */
- H5T_path_t *tpath = NULL; /*type conversion info */
- hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
- H5S_conv_t *sconv=NULL; /*space conversion funcs*/
- H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
- hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
- H5S_sel_iter_t bkg_iter; /*background iteration info*/
- hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
- H5S_sel_iter_t file_iter; /*file selection iteration info*/
- hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
- herr_t ret_value = SUCCEED; /*return value */
- herr_t status; /*function return status*/
- size_t src_type_size; /*size of source type */
- size_t dst_type_size; /*size of destination type*/
- size_t target_size; /*desired buffer size */
- hsize_t request_nelmts; /*requested strip mine */
- H5T_bkg_t need_bkg; /*type of background buf*/
-#ifdef H5_HAVE_PARALLEL
- H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
- hbool_t xfer_mode_changed=0; /*xfer_mode needs restore */
- hbool_t doing_mpio=0; /*This is an MPIO access */
-#endif /*H5_HAVE_PARALLEL*/
-#ifdef H5S_DEBUG
- H5_timer_t timer;
-#endif
- H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */
- H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
- unsigned sconv_flags=0; /* Flags for the space conversion */
-
- FUNC_ENTER_NOAPI(H5D_write, FAIL);
-
- /* check args */
- assert(dataset && dataset->ent.file);
- assert(mem_type);
- assert(H5I_GENPROP_LST==H5I_get_type(dxpl_id));
- assert(buf);
-
- /* Get the dataset's creation property list */
- if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
-
- /* Get the dataset transfer property list */
- if (NULL == (dx_plist = H5I_object(dxpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
-
- if (!file_space)
- file_space = dataset->space;
- if (!mem_space)
- mem_space = file_space;
- nelmts = (*mem_space->select.get_npoints)(mem_space);
-
- /* If MPIO, MPIPOSIX, or FPHDF5 is used, no VL datatype support yet. */
- /* This is because they use the global heap in the file and we don't */
- /* support parallel access of that yet */
- if ( (IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)) && H5T_get_class(mem_type)==H5T_VLEN)
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing VL datatypes yet");
- /* If MPIO, MPIPOSIX, or FPHDF5 is used, no dataset region reference datatype support yet. */
- /* This is because they use the global heap in the file and we don't */
- /* support parallel access of that yet */
- if ((IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)) &&
- H5T_get_class(mem_type)==H5T_REFERENCE &&
- H5T_get_ref_type(mem_type)==H5R_DATASET_REGION)
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing region reference datatypes yet");
-
- if (0==(H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file");
-
-#ifdef H5_HAVE_PARALLEL
- /* Collect Parallel I/O information for possible later use */
- if (H5FD_MPIO==H5P_peek_hid_t(dx_plist,H5D_XFER_VFL_ID_NAME)) {
- doing_mpio++;
- xfer_mode=H5P_peek_unsigned(dx_plist, H5D_XFER_IO_XFER_MODE_NAME);
- } /* end if */
-
- /* Collective access is not permissible without the MPIO or MPIPOSIX driver */
- if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE &&
- !(IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)))
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPIO driver only");
-
- /* If dataset is compact, collective access is only allowed when file space
- * selection is H5S_ALL */
- if(doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE
- && dataset->layout.type==H5D_COMPACT) {
- if(file_space->select.type != H5S_SEL_ALL)
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access to compact dataset doesn't support partial access");
- }
-
- /* Set the "parallel I/O possible" flag, for H5S_find() */
- if (H5S_mpi_opt_types_g && IS_H5FD_MPIO(dataset->ent.file)) {
- /* Only collective write should call this since it eventually
- * calls MPI_File_set_view which is a collective call.
- * See H5S_mpio_spaces_xfer() for details.
- */
- if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE)
- sconv_flags |= H5S_CONV_PAR_IO_POSSIBLE;
- } /* end if */
-#endif /*H5_HAVE_PARALLEL*/
-
- /* Make certain that the number of elements in each selection is the same */
- if (nelmts!=(*file_space->select.get_npoints) (file_space))
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
-
- /* Retrieve dataset properties */
- /* <none needed currently> */
-
- /* Allocate data space and initialize it if it hasn't been. */
- if(nelmts > 0 && dataset->layout.type!=H5D_COMPACT &&
- dataset->layout.addr==HADDR_UNDEF) {
- hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
-
- /* Get the number of elements in file dataset's dataspace */
- if((file_nelmts=H5S_get_simple_extent_npoints(file_space))<0)
- HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset");
-
- /* Allocate storage */
- if(H5D_alloc_storage(dataset->ent.file,dxpl_id,dataset,H5D_ALLOC_WRITE, TRUE, (hbool_t)((hsize_t)file_nelmts==nelmts ? TRUE : FALSE))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
- } /* end if */
-
- /*
- * Locate the type conversion function and data space conversion
- * functions, and set up the element numbering information. If a data
- * type conversion is necessary then register data type atoms. Data type
- * conversion is necessary if the user has set the `need_bkg' to a high
- * enough value in xfer_parms since turning off data type conversion also
- * turns off background preservation.
- */
- if (NULL==(tpath=H5T_path_find(mem_type, dataset->type, NULL, NULL, dxpl_id))) {
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
- } else if (!H5T_IS_NOOP(tpath)) {
- if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
- } /* end if */
-
- /* Set the storage flags for the space conversion check */
- switch(dataset->layout.type) {
- case H5D_COMPACT:
- sconv_flags |= H5S_CONV_STORAGE_COMPACT;
- break;
-
- case H5D_CONTIGUOUS:
- sconv_flags |= H5S_CONV_STORAGE_CONTIGUOUS;
- break;
-
- case H5D_CHUNKED:
- sconv_flags |= H5S_CONV_STORAGE_CHUNKED;
- break;
-
- default:
- assert(0 && "Unhandled layout type!");
- } /* end switch */
-
- /* Get dataspace functions */
- if (NULL==(sconv=H5S_find(mem_space, file_space, sconv_flags)))
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert from memory to file data space");
-
- /*
- * If there is no type conversion then write directly from the
- * application's buffer. This saves at least one mem-to-mem copy.
- */
- if (H5T_IS_NOOP(tpath)) {
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- status = (sconv->write)(dataset->ent.file, &(dataset->layout),
- dc_plist, &(dataset->efl), H5T_get_size(dataset->type),
- file_space, mem_space, dxpl_id, buf);
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[0].write_timer), &timer);
- sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type);
- sconv->stats[0].write_ncalls++;
-#endif
-
- /* Check return value from optimized write */
- if (status<0) {
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed");
- } else
- /* direct xfer accomplished successfully */
- HGOTO_DONE(SUCCEED);
- } /* end if */
-
-#ifdef H5_HAVE_PARALLEL
- /* The following may not handle a collective call correctly
- * since it does not ensure all processes can handle the write
- * request according to the MPI collective specification.
- * Do the collective request via independent mode.
- */
- if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE) {
- /* Kludge: change the xfer_mode to independent, handle the request,
- * then xfer_mode before return.
- * Better way is to get a temporary data_xfer property with
- * INDEPENDENT xfer_mode and pass it downwards.
- */
- xfer_mode = H5FD_MPIO_INDEPENDENT;
- if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
- xfer_mode_changed++; /* restore it before return */
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- fprintf(H5DEBUG(D), "H5D: Cannot handle this COLLECTIVE write request. Do it via INDEPENDENT calls\n");
-#endif
- } /* end if */
-#endif /*H5_HAVE_PARALLEL*/
- /*
- * This is the general case.
- */
-
- /* Compute element sizes and other parameters */
- src_type_size = H5T_get_size(mem_type);
- dst_type_size = H5T_get_size(dataset->type);
- target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME);
- request_nelmts = target_size / MAX (src_type_size, dst_type_size);
-
- /* Sanity check elements in temporary buffer */
- if (request_nelmts<=0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small");
-
- /* Figure out the strip mine size. */
- if ((*file_space->select.iter_init)(file_space, dst_type_size, &file_iter)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
- file_iter_init=1; /*file selection iteration info has been initialized */
- if ((*mem_space->select.iter_init)(mem_space, src_type_size, &mem_iter)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
- mem_iter_init=1; /*file selection iteration info has been initialized */
- if ((*file_space->select.iter_init)(file_space, dst_type_size, &bkg_iter)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
- bkg_iter_init=1; /*file selection iteration info has been initialized */
-
- /*
- * Get a temporary buffer for type conversion unless the app has already
- * supplied one through the xfer properties. Instead of allocating a
- * buffer which is the exact size, we allocate the target size. The
- * malloc() is usually less resource-intensive if we allocate/free the
- * same size over and over.
- */
- if (tpath->cdata.need_bkg) {
- /* Retrieve the bkgr buffer property */
- if(H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &need_bkg)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
- need_bkg = MAX (tpath->cdata.need_bkg, need_bkg);
- } else if(H5T_detect_class(dataset->type, H5T_VLEN)) {
- /* Old data is retrieved into background buffer for VL datatype. The
- * data is used later for freeing heap objects. */
- need_bkg = H5T_BKG_YES;
- } else {
- need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
- } /* end else */
- if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
- /* Allocate temporary buffer */
- if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
- } /* end if */
- if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
- /* Allocate background buffer */
- H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
- if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
- } /* end if */
-
- /* Start strip mining... */
- for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) {
- /* Go figure out how many elements to read from the file */
- assert((*file_space->select.iter_nelmts)(&file_iter)==(nelmts-smine_start));
- smine_nelmts = MIN(request_nelmts, (nelmts-smine_start));
-
- /*
- * Gather data from application buffer into the data type conversion
- * buffer. Also gather data from the file into the background buffer
- * if necessary.
- */
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- n = H5S_select_mgath(buf, src_type_size, mem_space, &mem_iter,
- smine_nelmts, dxpl_id, tconv_buf/*out*/);
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[0].gath_timer), &timer);
- sconv->stats[0].gath_nbytes += n * src_type_size;
- sconv->stats[0].gath_ncalls++;
-#endif
- if (n!=smine_nelmts)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed");
-
- if (need_bkg) {
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
- dc_plist, &(dataset->efl), dst_type_size, file_space,
- &bkg_iter, smine_nelmts, dxpl_id, bkg_buf/*out*/);
-
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[0].bkg_timer), &timer);
- sconv->stats[0].bkg_nbytes += n * dst_type_size;
- sconv->stats[0].bkg_ncalls++;
-#endif
- if (n!=smine_nelmts)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed");
- } /* end if */
-
- /*
- * Perform data type conversion.
- */
- if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed");
-
- /*
- * Scatter the data out to the file.
- */
-#ifdef H5S_DEBUG
- H5_timer_begin(&timer);
-#endif
- status = H5S_select_fscat(dataset->ent.file, &(dataset->layout),
- dc_plist, &(dataset->efl), dst_type_size, file_space, &file_iter,
- smine_nelmts, dxpl_id, tconv_buf);
-
-#ifdef H5S_DEBUG
- H5_timer_end(&(sconv->stats[0].scat_timer), &timer);
- sconv->stats[0].scat_nbytes += smine_nelmts * dst_type_size;
- sconv->stats[0].scat_ncalls++;
-#endif
- if (status<0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "scatter failed");
- } /* end for */
-
- /*
- * Update modification time. We have to do this explicitly because
- * writing to a dataset doesn't necessarily change the object header.
- */
- if (H5O_touch(&(dataset->ent), FALSE, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time");
-
-done:
-#ifdef H5_HAVE_PARALLEL
- /* restore xfer_mode due to the kludge */
- if (doing_mpio && xfer_mode_changed) {
-#ifdef H5D_DEBUG
- if (H5DEBUG(D))
- fprintf (H5DEBUG(D), "H5D: dx->xfer_mode was COLLECTIVE, restored to INDEPENDENT\n");
-#endif
- xfer_mode = H5FD_MPIO_COLLECTIVE;
- if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
- } /* end if */
-#endif /*H5_HAVE_PARALLEL*/
- /* Release selection iterators */
- if(file_iter_init)
- (*file_space->select.iter_release)(&file_iter);
- if(mem_iter_init)
- (*mem_space->select.iter_release)(&mem_iter);
- if(bkg_iter_init)
- (*file_space->select.iter_release)(&bkg_iter);
-
- if (src_id >= 0)
- H5I_dec_ref(src_id);
- if (dst_id >= 0)
- H5I_dec_ref(dst_id);
- assert(dx_plist);
- if (tconv_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))
- H5FL_BLK_FREE(type_conv,tconv_buf);
- if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
- H5FL_BLK_FREE(type_conv,bkg_buf);
-
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5D_write() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_extend
*
* Purpose: Increases the size of a dataset.
@@ -3426,14 +2372,12 @@ H5D_get_file (const H5D_t *dset)
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_alloc_t time_alloc,
hbool_t update_time, hbool_t full_overwrite)
{
struct H5O_layout_t *layout; /* The dataset's layout information */
- hsize_t nbytes; /* The number of bytes in the dataset */
unsigned space_allocated=0; /* Flag to indicate that space was allocated */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOINIT(H5D_alloc_storage);
@@ -3454,11 +2398,8 @@ H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_allo
case H5D_CONTIGUOUS:
if(layout->addr==HADDR_UNDEF) {
/* Reserve space in the file for the entire array */
- for (u=0, nbytes=1; u<layout->ndims; u++)
- nbytes *= layout->dim[u];
- assert (nbytes>0);
- if (HADDR_UNDEF==(layout->addr=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, nbytes)))
- HGOTO_ERROR (H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space");
+ if (H5F_contig_create (f, dxpl_id, layout/*out*/)<0)
+ HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize contiguous storage");
/* Indicate that we allocated space */
space_allocated=1;
@@ -3587,7 +2528,7 @@ H5D_init_storage(H5D_t *dset, hbool_t full_overwrite, hid_t dxpl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
if (H5F_contig_fill(dset->ent.file, dxpl_id, &(dset->layout),
- plist, &(dset->efl), space, &dset->fill, H5T_get_size(dset->type))<0)
+ plist, space, &dset->fill, H5T_get_size(dset->type))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to allocate all chunks of dataset");
} /* end if */
break;
@@ -4148,148 +3089,6 @@ done:
} /* end H5Dvlen_get_buf_size() */
-/*--------------------------------------------------------------------------
- NAME
- H5D_fill
- PURPOSE
- Fill a selection in memory with a value (internal version)
- USAGE
- herr_t H5Dfill(fill, fill_type, buf, buf_type, space)
- const void *fill; IN: Pointer to fill value to use
- H5T_t *fill_type; IN: Datatype of the fill value
- void *buf; IN/OUT: Memory buffer to fill selection within
- H5T_t *buf_type; IN: Datatype of the elements in buffer
- H5S_t *space; IN: Dataspace describing memory buffer &
- containing selection to use.
- RETURNS
- Non-negative on success/Negative on failure.
- DESCRIPTION
- Use the selection in the dataspace to fill elements in a memory buffer.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- If "fill" parameter is NULL, use all zeros as fill value. If "fill_type"
- parameter is NULL, use "buf_type" for the fill value datatype.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id)
-{
- H5T_path_t *tpath = NULL; /* Conversion information*/
- uint8_t *tconv_buf = NULL; /* Data type conv buffer */
- uint8_t *bkg_buf = NULL; /* Temp conversion buffer */
- hid_t src_id = -1, dst_id = -1; /* Temporary type IDs */
- size_t src_type_size; /* Size of source type */
- size_t dst_type_size; /* Size of destination type*/
- size_t buf_size; /* Desired buffer size */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOINIT(H5D_fill);
-
- /* Check args */
- assert(buf);
- assert(buf_type);
- assert(space);
-
- /* Check for "default" fill value */
- if(fill_type==NULL)
- fill_type=buf_type;
-
- /* Get the memory and file datatype sizes */
- src_type_size = H5T_get_size(fill_type);
- dst_type_size = H5T_get_size(buf_type);
-
- /* Get the maximum buffer size needed and allocate it */
- buf_size=MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5FL_BLK_MALLOC(type_elem,buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(type_elem,buf_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
-
- /* Copy the user's data into the buffer for conversion */
- if(fill==NULL)
- HDmemset(tconv_buf,0,src_type_size);
- else
- HDmemcpy(tconv_buf,fill,src_type_size);
-
- /* Convert memory buffer into disk buffer */
- /* Set up type conversion function */
- if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id))) {
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
- } else if (!H5T_IS_NOOP(tpath)) {
- if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL)))<0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL)))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
- }
-
- /* Perform data type conversion */
- if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
-
- /* Fill the selection in the memory buffer */
- if(H5S_select_fill(tconv_buf, dst_type_size, space, buf)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed");
-
-done:
- if (tconv_buf)
- H5FL_BLK_FREE(type_elem,tconv_buf);
- if (bkg_buf)
- H5FL_BLK_FREE(type_elem,bkg_buf);
- FUNC_LEAVE_NOAPI(ret_value);
-} /* H5D_fill() */
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5Dfill
- PURPOSE
- Fill a selection in memory with a value
- USAGE
- herr_t H5Dfill(fill, fill_type, space, buf, buf_type)
- const void *fill; IN: Pointer to fill value to use
- hid_t fill_type_id; IN: Datatype of the fill value
- void *buf; IN/OUT: Memory buffer to fill selection within
- hid_t buf_type_id; IN: Datatype of the elements in buffer
- hid_t space_id; IN: Dataspace describing memory buffer &
- containing selection to use.
- RETURNS
- Non-negative on success/Negative on failure.
- DESCRIPTION
- Use the selection in the dataspace to fill elements in a memory buffer.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- If "fill" parameter is NULL, use all zeros as fill value
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-herr_t
-H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id)
-{
- H5S_t *space; /* Dataspace */
- H5T_t *fill_type; /* Fill-value datatype */
- H5T_t *buf_type; /* Buffer datatype */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_API(H5Dfill, FAIL);
- H5TRACE5("e","xixii",fill,fill_type_id,buf,buf_type_id,space_id);
-
- /* Check args */
- if (buf==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer");
- if (NULL == (space=H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataspace");
- if (NULL == (fill_type=H5I_object_verify(fill_type_id, H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
- if (NULL == (buf_type=H5I_object_verify(buf_type_id, H5I_DATATYPE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
-
- /* Fill the selection in the memory buffer */
- if(H5D_fill(fill,fill_type,buf,buf_type,space, H5AC_dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed");
-
-done:
- FUNC_LEAVE_API(ret_value);
-} /* H5Dfill() */
-
-
/*-------------------------------------------------------------------------
* Function: H5Dset_extent
*
diff --git a/src/H5Dcompact.c b/src/H5Dcompact.c
index 1f77d92..829ba63 100644
--- a/src/H5Dcompact.c
+++ b/src/H5Dcompact.c
@@ -28,60 +28,55 @@
#include "H5Oprivate.h"
#include "H5FDprivate.h" /*file driver */
#include "H5FLprivate.h" /*Free Lists */
+#include "H5Vprivate.h" /* Vector and array functions */
/* Interface initialization */
#define PABLO_MASK H5Fcompact_mask
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+
/*-------------------------------------------------------------------------
- * Function: H5F_compact_readv
- *
+ * Function: H5F_compact_readvv
+ *
* Purpose: Reads some data vectors from a dataset into a buffer.
* The data is in compact dataset. The address is relative
* to the beginning address of the dataset. The offsets and
* sequence lengths are in bytes.
- *
+ *
* Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * August 5, 2002
- *
- * Notes:
- * Offsets in the sequences must be monotonically increasing
*
+ * Programmer: Quincey Koziol
+ * May 7, 2003
+ *
+ * Notes:
+ * Offsets in the sequences must be monotonically increasing
+ *
* Modifications:
- *
+ *
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_compact_readv(H5F_t UNUSED *f, const H5O_layout_t *layout, size_t nseq,
- size_t size_arr[], hsize_t offset_arr[],
- hid_t UNUSED dxpl_id, void *_buf/*out*/)
+ssize_t
+H5F_compact_readvv(H5F_t UNUSED *f, const H5O_layout_t *layout,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[],
+ hid_t UNUSED dxpl_id, void *buf)
{
- unsigned char *buf=(unsigned char *)_buf;
- size_t size;
- haddr_t offset;
- unsigned u;
- herr_t ret_value=SUCCEED;
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_compact_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_compact_readvv, FAIL);
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- offset=offset_arr[u];
- if(size > 0) {
- HDmemcpy(buf, (unsigned char*)layout->buf+offset, size);
- buf +=size;
- }
- }
+ /* Use the vectorized memory copy routine to do actual work */
+ if((ret_value=H5V_memcpyvv(buf,mem_max_nseq,mem_curr_seq,mem_size_arr,mem_offset_arr,layout->buf,dset_max_nseq,dset_curr_seq,dset_size_arr,dset_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed");
-done:
+done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_compact_readv() */
+} /* end H5F_compact_readvv() */
+
/*-------------------------------------------------------------------------
- * Function: H5F_compact_writev
+ * Function: H5F_compact_writevv
*
* Purpose: Writes some data vectors from a dataset into a buffer.
* The data is in compact dataset. The address is relative
@@ -93,8 +88,8 @@ done:
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Raymond Lu
- * August 5, 2002
+ * Programmer: Quincey Koziol
+ * May 2, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
@@ -103,30 +98,23 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_compact_writev(H5F_t UNUSED *f, H5O_layout_t *layout, size_t nseq,
- size_t size_arr[], hsize_t offset_arr[],
- hid_t UNUSED dxpl_id, const void *_buf)
+ssize_t
+H5F_compact_writevv(H5F_t UNUSED *f, H5O_layout_t *layout,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[],
+ hid_t UNUSED dxpl_id, const void *buf)
{
- const unsigned char *buf=(const unsigned char *)_buf;
- size_t size;
- haddr_t offset;
- unsigned u;
- herr_t ret_value=SUCCEED;
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_compact_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_compact_writevv, FAIL);
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- offset=offset_arr[u];
- if(size > 0) {
- HDmemcpy((unsigned char*)layout->buf+offset, buf, size);
- buf += size;
- }
- }
+ /* Use the vectorized memory copy routine to do actual work */
+ if((ret_value=H5V_memcpyvv(layout->buf,dset_max_nseq,dset_curr_seq,dset_size_arr,dset_offset_arr,buf,mem_max_nseq,mem_curr_seq,mem_size_arr,mem_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed");
layout->dirty = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_compact_writev */
+} /* end H5F_compact_writevv() */
+
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index 2593d83..3a14175 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -18,9 +18,8 @@
*
* Purpose:
* Contiguous dataset I/O functions. These routines are similar to
- * the H5F_istore_* routines and really only abstract away dealing
- * with the data sieve buffer from the H5F_arr_read/write and
- * H5F_seg_read/write.
+ * the H5F_istore_* routines and really only an abstract way of dealing
+ * with the data sieve buffer from H5F_seg_read/write.
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
@@ -34,6 +33,7 @@
#include "H5MFprivate.h" /*file memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspace functions */
#include "H5Vprivate.h" /* Vector and array functions */
/* MPIO, MPIPOSIX, & FPHDF5 drivers needed for special checks */
@@ -41,6 +41,11 @@
#include "H5FDmpio.h"
#include "H5FDmpiposix.h"
+/* Private prototypes */
+static herr_t
+H5F_contig_write(H5F_t *f, hsize_t max_data, haddr_t addr,
+ const size_t size, hid_t dxpl_id, const void *buf);
+
/* Interface initialization */
#define PABLO_MASK H5Fcontig_mask
static int interface_initialize_g = 0;
@@ -57,6 +62,48 @@ H5FL_BLK_DEFINE_STATIC(zero_fill);
/*-------------------------------------------------------------------------
+ * Function: H5F_contig_create
+ *
+ * Purpose: Allocate file space for a contiguously stored dataset
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * April 19, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_contig_create(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout)
+{
+ hsize_t size; /* Size of contiguous block of data */
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_contig_create, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(layout);
+
+ /* Compute size */
+ size=layout->dim[0];
+ for (u = 1; u < layout->ndims; u++)
+ size *= layout->dim[u];
+ assert (size>0);
+
+ /* Allocate space for the contiguous data */
+ if (HADDR_UNDEF==(layout->addr=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, size)))
+ HGOTO_ERROR (H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5F_contig_create */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_contig_fill
*
* Purpose: Write fill values to a contiguously stored dataset.
@@ -75,8 +122,7 @@ H5FL_BLK_DEFINE_STATIC(zero_fill);
*/
herr_t
H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *space,
+ struct H5P_genplist_t *dc_plist, const struct H5S_t *space,
const struct H5O_fill_t *fill, size_t elmt_size)
{
hssize_t snpoints; /* Number of points in space (for error checking) */
@@ -84,7 +130,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
size_t ptsperbuf; /* Maximum # of points which fit in the buffer */
size_t bufsize=64*1024; /* Size of buffer to write */
size_t size; /* Current # of points to write */
- hsize_t addr; /* Offset in dataset */
+ haddr_t addr; /* Offset of dataset */
void *buf = NULL; /* Buffer for fill value writing */
#ifdef H5_HAVE_PARALLEL
MPI_Comm mpi_comm=MPI_COMM_NULL; /* MPI communicator for file */
@@ -173,8 +219,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
* this quite efficiently by making sure we copy the fill value
* in relatively large pieces.
*/
- ptsperbuf = MAX(1, bufsize/elmt_size);
- bufsize = ptsperbuf*elmt_size;
+ ptsperbuf = MAX(1, bufsize/elmt_size);
+ bufsize = ptsperbuf*elmt_size;
/* Fill the buffer with the user's fill value */
if(fill->buf) {
@@ -207,7 +253,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end else */
/* Start at the beginning of the dataset */
- addr = 0;
+ addr = layout->addr;
/* Loop through writing the fill value to the dataset */
while (npoints>0) {
@@ -218,8 +264,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
if(using_mpi) {
/* Round-robin write the chunks out from only one process */
if(mpi_round==mpi_rank) {
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
- elmt_size, size, addr, buf)<0)
+ if (H5F_contig_write(f, size, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
} /* end if */
++mpi_round;
@@ -230,8 +275,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
- elmt_size, size, addr, buf)<0)
+ H5_CHECK_OVERFLOW(size,size_t,hsize_t);
+ if (H5F_contig_write(f, (hsize_t)size, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -314,44 +359,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_contig_read
- *
- * Purpose: Reads some data from a dataset into a buffer.
- * The data is contiguous. The address is relative to the base
- * address for the file.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, September 28, 2000
- *
- * Modifications:
- * Re-written in terms of the new readv call, QAK, 7/7/01
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
- size_t size, hid_t dxpl_id, void *buf/*out*/)
-{
- hsize_t offset=0; /* Offset for vector call */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_contig_read, FAIL);
-
- /* Check args */
- assert(f);
- assert(buf);
-
- if (H5F_contig_readv(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_read() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5F_contig_write
*
* Purpose: Writes some data from a dataset into a buffer.
@@ -364,23 +371,28 @@ done:
* Thursday, September 28, 2000
*
* Modifications:
- * Re-written in terms of the new readv call, QAK, 7/7/01
+ * Re-written in terms of the new writevv call, QAK, 5/7/03
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, size_t size,
- hid_t dxpl_id, const void *buf)
+static herr_t
+H5F_contig_write(H5F_t *f, hsize_t max_data, haddr_t addr,
+ const size_t size, hid_t dxpl_id, const void *buf)
{
- hsize_t offset=0; /* Offset for vector call */
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t dset_off=0; /* Offset in dataset */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t dset_len=size; /* Length in dataset */
+ size_t mem_len=size; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_contig_write, FAIL);
assert (f);
assert (buf);
- if (H5F_contig_writev(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0)
+ if (H5F_contig_writevv(f, max_data, addr, 1, &dset_curr_seq, &dset_len, &dset_off, 1, &mem_curr_seq, &mem_len, &mem_off, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -389,7 +401,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_contig_readv
+ * Function: H5F_contig_readvv
*
* Purpose: Reads some data vectors from a dataset into a buffer.
* The data is contiguous. The address is the start of the dataset,
@@ -409,9 +421,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
- size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id,
- void *_buf/*out*/)
+H5F_contig_readvv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, void *_buf)
{
unsigned char *buf=(unsigned char *)_buf; /* Pointer to buffer to fill */
haddr_t abs_eoa; /* Absolute end of file address */
@@ -420,18 +433,10 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
hsize_t max_data; /* Actual maximum size of data to cache */
size_t size; /* Size of sequence in bytes */
size_t u; /* Counting variable */
-#ifndef SLOW_WAY
- size_t max_seq; /* Maximum sequence to copy */
- haddr_t temp_end; /* Temporary end of buffer variable */
- size_t max_search; /* Maximum number of sequences to search */
- size_t mask; /* Bit mask */
- int bit_loc; /* Bit location of the leftmost '1' in max_search */
- size_t *size_arr_p; /* Pointer into the size array */
- hsize_t *offset_arr_p; /* Pointer into the offset array */
-#endif /* SLOW_WAY */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
- FUNC_ENTER_NOAPI(H5F_contig_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_contig_readvv, FAIL);
/* Check args */
assert(f);
@@ -439,325 +444,143 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
+ haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
+ haddr_t contig_end; /* End locations of block to write */
+ size_t sieve_size; /* size of sieve buffer */
+
+ /* Set offsets in sequence lists */
+ u=*dset_curr_seq;
+ v=*mem_curr_seq;
+
+ /* No data sieve buffer yet, go allocate one */
+ if(f->shared->sieve_buf==NULL) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Set up the buffer parameters */
+ max_data=_max_data-dset_offset_arr[u];
+
+ /* Check if we can actually hold the I/O request in the sieve buffer */
+ if(size>f->shared->sieve_buf_size) {
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
+ else {
+ /* Allocate room for the data sieve buffer */
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- /* Outer loop, guarantees working through all the sequences */
- for(u=0; u<nseq; ) {
-
- /* Try reading from the data sieve buffer */
- if(f->shared->sieve_buf) {
- haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
- haddr_t contig_end; /* End locations of block to write */
- size_t sieve_size; /* size of sieve buffer */
-
- /* Stash local copies of these value */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- /* Next-outer loop works through sequences as fast as possible */
- for(; u<nseq; ) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
-
- /* Compute end of sequence to retrieve */
- contig_end=addr+size-1;
-
- /* If entire read is within the sieve buffer, read it from the buffer */
- if(addr>=sieve_start && contig_end<sieve_end) {
- unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start);
- unsigned char *temp_sieve_buf;
- haddr_t temp_addr=_addr-1; /* Temporary address */
-
-#ifdef SLOW_WAY
- /* Retrieve all the sequences out of the current sieve buffer */
- while(contig_end<sieve_end) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+offset_arr[u];
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,size_arr[u]);
-
- /* Increment offset in buffer */
- buf += size_arr[u];
-
- /* Increment sequence number, check for finished with sequences */
- if((++u) >= nseq)
- break;
-
- /* Re-compute end of sequence to retrieve */
- contig_end=temp_addr+offset_arr[u]+size_arr[u];
- } /* end while */
-#else /* SLOW_WAY */
- /* Find log2(n) where n is the number of elements to search */
-
- /* Set initial parameters */
- mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */
- max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */
- assert(max_search>0); /* Sanity check */
- bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */
-
- /* Search for the first byte with a bit set */
- while((max_search & mask)==0) {
- mask>>=8;
- bit_loc-=8;
- } /* end while */
-
- /* Switch to searching for a bit */
- mask=1<<bit_loc;
- while((max_search & mask)==0) {
- mask>>=1;
- bit_loc--;
- } /* end while */
-
- /* location of the leftmost bit, plus 1, is log2(n) */
- max_seq=bit_loc+1;
-
- /* Don't walk off the array */
- max_seq=MIN(u+max_seq,nseq-1);
-
- /* Determine if a linear search is faster than a binary search */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- if(temp_end>=sieve_end) {
- /* Linear search is faster */
-
- /* Set the initial search values */
- max_seq=u;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Search for the first sequence ending greater than the sieve buffer end */
- while(temp_end<sieve_end) {
- if(++max_seq>=nseq)
- break;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- } /* end while */
-
- /* Adjust back one element */
- max_seq--;
-
- } /* end if */
- else {
- size_t lo,hi; /* Low and high bounds for binary search */
- unsigned found=0; /* Flag to indicate bounds have been found */
-
- /* Binary search is faster */
-
- /* Find the value 'u' which will be beyond the end of the sieve buffer */
- lo=u;
- hi=nseq-1;
- max_seq=(lo+hi)/2;
- while(!found) {
- /* Get the address of the end of sequence for the 'max_seq' position */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Current high bound is too large */
- if(temp_end>=sieve_end) {
- if((lo+1)<hi) {
- hi=max_seq;
- max_seq=(lo+hi)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end if */
- /* Current low bound is too small */
- else {
- if((lo+1)<hi) {
- lo=max_seq;
- max_seq=(lo+hi+1)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end else */
- } /* end while */
-
- /* Check for non-exact match */
- if(lo!=hi) {
- temp_end=temp_addr+offset_arr[hi]+size_arr[hi];
- if(temp_end<sieve_end)
- max_seq=hi;
- else
- max_seq=lo;
- } /* end if */
- } /* end else */
-
- /* Set the pointers to the correct locations in the offset & size arrays */
- size_arr_p=&size_arr[u];
- offset_arr_p=&offset_arr[u];
-
-#ifdef NO_DUFFS_DEVICE
- /* Retrieve all the sequences out of the current sieve buffer */
- while(u<=max_seq) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
- } /* end while */
-#else /* NO_DUFFS_DEVICE */
-{
- size_t seq_count;
-
- seq_count=(max_seq-u)+1;
- switch (seq_count % 4) {
- case 0:
- do
- {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- case 3:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- case 2:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- case 1:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- } while (u<=max_seq);
- } /* end switch */
-
-}
-#endif /* NO_DUFFS_DEVICE */
-#endif /* SLOW_WAY */
- } /* end if */
- /* Entire request is not within this data sieve buffer */
- else {
- /* Check if we can actually hold the I/O request in the sieve buffer */
- if(size>f->shared->sieve_buf_size) {
- /* Check for any overlap with the current sieve buffer */
- if((sieve_start>=addr && sieve_start<(contig_end+1))
- || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
- /* Flush the sieve buffer, if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
- } /* end if */
-
- /* Read directly into the user's buffer */
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
- /* Element size fits within the buffer size */
- else {
- /* Flush the sieve buffer if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
-
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Only need this when resizing sieve buffer */
- max_data=_max_data-offset_arr[u];
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Compute the size of the sieve buffer */
- /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Compute the size of the sieve buffer */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- /* Update local copies of sieve information */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
+ /* Read the new sieve buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- /* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(buf,f->shared->sieve_buf,size);
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end else */
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(buf,f->shared->sieve_buf,size);
- } /* end else */
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
- /* Increment sequence number */
- u++;
- } /* end else */
- } /* end for */
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end if */
+
+ /* Stash local copies of these value */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
+
+ /* Works through sequences as fast as possible */
+ for(; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Compute end of sequence to retrieve */
+ contig_end=addr+size-1;
+
+ /* If entire read is within the sieve buffer, read it from the buffer */
+ if(addr>=sieve_start && contig_end<sieve_end) {
+ unsigned char *base_sieve_buf=f->shared->sieve_buf+(addr-sieve_start);
+
+ /* Grab the data out of the buffer */
+ HDmemcpy(buf,base_sieve_buf,size);
} /* end if */
- /* No data sieve buffer yet, go allocate one */
+ /* Entire request is not within this data sieve buffer */
else {
- /* Set up the buffer parameters */
- size=size_arr[u];
- addr=_addr+offset_arr[u];
- max_data=_max_data-offset_arr[u];
-
/* Check if we can actually hold the I/O request in the sieve buffer */
if(size>f->shared->sieve_buf_size) {
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
+ /* Check for any overlap with the current sieve buffer */
+ if((sieve_start>=addr && sieve_start<(contig_end+1))
+ || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
+ /* Flush the sieve buffer, if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
+ } /* end if */
+
+ /* Read directly into the user's buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
} /* end if */
+ /* Element size fits within the buffer size */
else {
- /* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* Flush the sieve buffer if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
/* Determine the new sieve buffer size & location */
f->shared->sieve_loc=addr;
@@ -769,59 +592,103 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Adjust absolute EOA address to relative EOA address */
rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Only need this when resizing sieve buffer */
+ max_data=_max_data-dset_offset_arr[u];
+
/* Compute the size of the sieve buffer */
+ /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
+
/* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
-
/* Grab the data out of the buffer (must be first piece of data in buffer ) */
HDmemcpy(buf,f->shared->sieve_buf,size);
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
} /* end else */
+ } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment sequence number */
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
u++;
- } /* end else */
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end if */
else {
/* Work through all the sequences */
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
+ for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
+
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end else */
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_readv() */
+} /* end H5F_contig_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_contig_writev
+ * Function: H5F_contig_writevv
*
- * Purpose: Writes some data vectors into a dataset from a buffer.
- * The data is contiguous. The address is the start of the dataset,
+ * Purpose: Writes some data vectors into a dataset from vectors into a
+ * buffer. The address is the start of the dataset,
* relative to the base address for the file and the offsets and
* sequence lengths are in bytes.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Thursday, July 5, 2001
+ * Friday, May 2, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
@@ -830,10 +697,11 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
- size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id,
- const void *_buf)
+ssize_t
+H5F_contig_writevv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, const void *_buf)
{
const unsigned char *buf=_buf; /* Pointer to buffer to fill */
haddr_t abs_eoa; /* Absolute end of file address */
@@ -842,18 +710,10 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
hsize_t max_data; /* Actual maximum size of data to cache */
size_t size; /* Size of sequence in bytes */
size_t u; /* Counting variable */
-#ifndef SLOW_WAY
- size_t max_seq; /* Maximum sequence to copy */
- haddr_t temp_end; /* Temporary end of buffer variable */
- size_t max_search; /* Maximum number of sequences to search */
- size_t mask; /* Bit mask */
- int bit_loc; /* Bit location of the leftmost '1' in max_search */
- size_t *size_arr_p; /* Pointer into the size array */
- hsize_t *offset_arr_p; /* Pointer into the offset array */
-#endif /* SLOW_WAY */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
- FUNC_ENTER_NOAPI(H5F_contig_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_contig_writevv, FAIL);
/* Check args */
assert(f);
@@ -861,421 +721,284 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
+ haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
+ haddr_t contig_end; /* End locations of block to write */
+ size_t sieve_size; /* size of sieve buffer */
+
+ /* Set offsets in sequence lists */
+ u=*dset_curr_seq;
+ v=*mem_curr_seq;
+
+ /* No data sieve buffer yet, go allocate one */
+ if(f->shared->sieve_buf==NULL) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Set up the buffer parameters */
+ max_data=_max_data-dset_offset_arr[u];
+
+ /* Check if we can actually hold the I/O request in the sieve buffer */
+ if(size>f->shared->sieve_buf_size) {
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+ } /* end if */
+ else {
+ /* Allocate room for the data sieve buffer */
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- /* Outer loop, guarantees working through all the sequences */
- for(u=0; u<nseq; ) {
-
- /* Try writing into the data sieve buffer */
- if(f->shared->sieve_buf) {
- haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
- haddr_t contig_end; /* End locations of block to write */
- size_t sieve_size; /* size of sieve buffer */
-
- /* Stash local copies of these value */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- /* Next-outer loop works through sequences as fast as possible */
- for(; u<nseq; ) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
-
- /* Compute end of sequence to retrieve */
- contig_end=addr+size-1;
-
- /* If entire write is within the sieve buffer, write it to the buffer */
- if(addr>=sieve_start && contig_end<sieve_end) {
- unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start);
- unsigned char *temp_sieve_buf;
- haddr_t temp_addr=_addr-1; /* Temporary address */
-
-#ifdef SLOW_WAY
- /* Retrieve all the sequences out of the current sieve buffer */
- while(contig_end<sieve_end) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+offset_arr[u];
-
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,size_arr[u]);
-
- /* Increment offset in buffer */
- buf += size_arr[u];
-
- /* Increment sequence number, check for finished with sequences */
- if((++u) >= nseq)
- break;
-
- /* Re-compute end of sequence to retrieve */
- contig_end=temp_addr+offset_arr[u]+size_arr[u];
- } /* end while */
-#else /* SLOW_WAY */
- /* Find log2(n) where n is the number of elements to search */
-
- /* Set initial parameters */
- mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */
- max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */
- assert(max_search>0); /* Sanity check */
- bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */
-
- /* Search for the first byte with a bit set */
- while((max_search & mask)==0) {
- mask>>=8;
- bit_loc-=8;
- } /* end while */
-
- /* Switch to searching for a bit */
- mask=1<<bit_loc;
- while((max_search & mask)==0) {
- mask>>=1;
- bit_loc--;
- } /* end while */
-
- /* location of the leftmost bit, plus 1, is log2(n) */
- max_seq=bit_loc+1;
-
- /* Don't walk off the array */
- max_seq=MIN(u+max_seq,nseq-1);
-
- /* Determine if a linear search is faster than a binary search */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- if(temp_end>=sieve_end) {
- /* Linear search is faster */
-
- /* Set the initial search values */
- max_seq=u;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Search for the first sequence ending greater than the sieve buffer end */
- while(temp_end<sieve_end) {
- if(++max_seq>=nseq)
- break;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- } /* end while */
-
- /* Adjust back one element */
- max_seq--;
-
- } /* end if */
- else {
- size_t lo,hi; /* Low and high bounds for binary search */
- unsigned found=0; /* Flag to indicate bounds have been found */
-
- /* Binary search is faster */
-
- /* Find the value 'u' which will be beyond the end of the sieve buffer */
- lo=u;
- hi=nseq-1;
- max_seq=(lo+hi)/2;
- while(!found) {
- /* Get the address of the end of sequence for the 'max_seq' position */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Current high bound is too large */
- if(temp_end>=sieve_end) {
- if((lo+1)<hi) {
- hi=max_seq;
- max_seq=(lo+hi)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end if */
- /* Current low bound is too small */
- else {
- if((lo+1)<hi) {
- lo=max_seq;
- max_seq=(lo+hi+1)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end else */
- } /* end while */
-
- /* Check for non-exact match */
- if(lo!=hi) {
- temp_end=temp_addr+offset_arr[hi]+size_arr[hi];
- if(temp_end<sieve_end)
- max_seq=hi;
- else
- max_seq=lo;
- } /* end if */
- } /* end else */
-
- /* Set the pointers to the correct locations in the offset & size arrays */
- size_arr_p=&size_arr[u];
- offset_arr_p=&offset_arr[u];
-
-#ifdef NO_DUFFS_DEVICE
- /* Retrieve all the sequences out of the current sieve buffer */
- while(u<=max_seq) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Increment the offset in the array */
- u++;
- } /* end while */
-#else /* NO_DUFFS_DEVICE */
-{
- size_t seq_count;
+ /* Compute the size of the sieve buffer */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- seq_count=(max_seq-u)+1;
- switch (seq_count % 4) {
- case 0:
- do
- {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Check if there is any point in reading the data from the file */
+ if(f->shared->sieve_size>size) {
+ /* Read the new sieve buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
+ } /* end else */
- /* Increment the offset in the array */
- u++;
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- case 3:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end if */
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Stash local copies of these value */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
+
+ /* Works through sequences as fast as possible */
+ for(; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
- /* Increment the offset in the array */
- u++;
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
- case 2:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Compute end of sequence to retrieve */
+ contig_end=addr+size-1;
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* If entire write is within the sieve buffer, write it to the buffer */
+ if(addr>=sieve_start && contig_end<sieve_end) {
+ unsigned char *base_sieve_buf=f->shared->sieve_buf+(addr-sieve_start);
- /* Increment the offset in the array */
- u++;
+ /* Put the data into the sieve buffer */
+ HDmemcpy(base_sieve_buf,buf,size);
- case 1:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ } /* end if */
+ /* Entire request is not within this data sieve buffer */
+ else {
+ /* Check if we can actually hold the I/O request in the sieve buffer */
+ if(size>f->shared->sieve_buf_size) {
+ /* Check for any overlap with the current sieve buffer */
+ if((sieve_start>=addr && sieve_start<(contig_end+1))
+ || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
+ /* Flush the sieve buffer, if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
- /* Increment the offset in the array */
- u++;
+ /* Force the sieve buffer to be re-read the next time */
+ f->shared->sieve_loc=HADDR_UNDEF;
+ f->shared->sieve_size=0;
+ } /* end if */
- } while (u<=max_seq);
- } /* end switch */
+ /* Write directly from the user's buffer */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+ } /* end if */
+ /* Element size fits within the buffer size */
+ else {
+ /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */
+ if(((addr+size)==sieve_start || addr==sieve_end) &&
+ (size+sieve_size)<=f->shared->sieve_buf_size &&
+ f->shared->sieve_dirty) {
+ /* Prepend to existing sieve buffer */
+ if((addr+size)==sieve_start) {
+ /* Move existing sieve information to correct location */
+ HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,sieve_size);
+
+ /* Copy in new information (must be first in sieve buffer) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
+
+ /* Adjust sieve location */
+ f->shared->sieve_loc=addr;
+
+ } /* end if */
+ /* Append to existing sieve buffer */
+ else {
+ /* Copy in new information */
+ HDmemcpy(f->shared->sieve_buf+sieve_size,buf,size);
+ } /* end else */
-}
-#endif /* NO_DUFFS_DEVICE */
-#endif /* SLOW_WAY */
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
+ /* Adjust sieve size */
+ f->shared->sieve_size += size;
+
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
} /* end if */
- /* Entire request is not within this data sieve buffer */
+ /* Can't add the new data onto the existing sieve buffer */
else {
- /* Check if we can actually hold the I/O request in the sieve buffer */
- if(size>f->shared->sieve_buf_size) {
- /* Check for any overlap with the current sieve buffer */
- if((sieve_start>=addr && sieve_start<(contig_end+1))
- || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
- /* Flush the sieve buffer, if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Force the sieve buffer to be re-read the next time */
- f->shared->sieve_loc=HADDR_UNDEF;
- f->shared->sieve_size=0;
- } /* end if */
-
- /* Write directly from the user's buffer */
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
+ /* Flush the sieve buffer if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
} /* end if */
- /* Element size fits within the buffer size */
- else {
- /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */
- if(((addr+size)==sieve_start || addr==sieve_end) &&
- (size+sieve_size)<=f->shared->sieve_buf_size &&
- f->shared->sieve_dirty) {
- /* Prepend to existing sieve buffer */
- if((addr+size)==sieve_start) {
- /* Move existing sieve information to correct location */
- HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,sieve_size);
-
- /* Copy in new information (must be first in sieve buffer) */
- HDmemcpy(f->shared->sieve_buf,buf,size);
-
- /* Adjust sieve location */
- f->shared->sieve_loc=addr;
-
- } /* end if */
- /* Append to existing sieve buffer */
- else {
- /* Copy in new information */
- HDmemcpy(f->shared->sieve_buf+sieve_size,buf,size);
- } /* end else */
-
- /* Adjust sieve size */
- f->shared->sieve_size += size;
-
- /* Update local copies of sieve information */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- } /* end if */
- /* Can't add the new data onto the existing sieve buffer */
- else {
- /* Flush the sieve buffer if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
-
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
-
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
-
- /* Only need this when resizing sieve buffer */
- max_data=_max_data-offset_arr[u];
-
- /* Compute the size of the sieve buffer */
- /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
-
- /* Update local copies of sieve information */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- /* Check if there is any point in reading the data from the file */
- if(f->shared->sieve_size>size) {
- /* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
-
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(f->shared->sieve_buf,buf,size);
-
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
-
- } /* end else */
- } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Increment sequence number */
- u++;
- } /* end else */
- } /* end for */
- } /* end if */
- /* No data sieve buffer yet, go allocate one */
- else {
- /* Set up the buffer parameters */
- size=size_arr[u];
- addr=_addr+offset_arr[u];
- max_data=_max_data-offset_arr[u];
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Check if we can actually hold the I/O request in the sieve buffer */
- if(size>f->shared->sieve_buf_size) {
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- } /* end if */
- else {
- /* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
+ /* Only need this when resizing sieve buffer */
+ max_data=_max_data-dset_offset_arr[u];
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
+ /* Compute the size of the sieve buffer */
+ /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
- /* Compute the size of the sieve buffer */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Check if there is any point in reading the data from the file */
+ if(f->shared->sieve_size>size) {
+ /* Read the new sieve buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
- /* Check if there is any point in reading the data from the file */
- if(f->shared->sieve_size>size) {
- /* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(f->shared->sieve_buf,buf,size);
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
+ } /* end else */
} /* end else */
+ } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment sequence number */
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
u++;
- } /* end else */
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end if */
else {
/* Work through all the sequences */
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
+ for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
+
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end else */
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_writev() */
+} /* end H5F_contig_writevv() */
diff --git a/src/H5Dio.c b/src/H5Dio.c
new file mode 100644
index 0000000..51e66a3
--- /dev/null
+++ b/src/H5Dio.c
@@ -0,0 +1,2293 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Dpkg.h" /* Dataset functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Sprivate.h" /* Dataspace functions */
+#include "H5Vprivate.h" /* Vector and array functions */
+
+/*#define H5D_DEBUG*/
+
+/*
+ * The MPIO, MPIPOSIX, & FPHDF5 drivers are needed because there are
+ * file and places where we check for things that aren't handled by these
+ * drivers.
+ */
+#include "H5FDfphdf5.h"
+#include "H5FDmpio.h"
+#include "H5FDmpiposix.h"
+
+#ifdef H5_HAVE_PARALLEL
+/* Remove this if H5R_DATASET_REGION is no longer used in this file */
+# include "H5Rpublic.h"
+#endif /*H5_HAVE_PARALLEL*/
+
+/* Pablo information */
+#define PABLO_MASK H5Dio_mask
+
+/* Local typedefs */
+
+/*information for mapping between file space and memory space*/
+typedef struct fm_map {
+ H5S_t **fspace; /*file spaces for all chunks*/
+ H5S_t **mspace; /*memory spaces for all chunks*/
+ hsize_t elmt_count; /*indicate which element is being processed*/
+ hsize_t nchunks; /*total number of chunks*/
+ H5S_sel_iter_t mem_iter; /* Iterator for elements in memory selection */
+ unsigned m_ndims; /* Number of dimensions for memory dataspace */
+ hsize_t chunks[H5O_LAYOUT_NDIMS]; /* Number of chunks in each dimension */
+ hsize_t down_chunks[H5O_LAYOUT_NDIMS]; /* "down" size of number of chunks in each dimension */
+ hssize_t *chunk_coords; /*coordinates for all chunks*/
+ H5O_layout_t *layout; /*dataset layout information*/
+} fm_map;
+
+/* Interface initialization */
+static int interface_initialize_g = 0;
+#define INTERFACE_INIT NULL
+
+/* Local functions */
+static herr_t H5D_read(H5D_t *dataset, const H5T_t *mem_type,
+ const H5S_t *mem_space, const H5S_t *file_space,
+ hid_t dset_xfer_plist, void *buf/*out*/);
+static herr_t H5D_write(H5D_t *dataset, const H5T_t *mem_type,
+ const H5S_t *mem_space, const H5S_t *file_space,
+ hid_t dset_xfer_plist, const void *buf);
+static herr_t
+H5D_contig_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t doing_mpio, H5FD_mpio_xfer_t xfer_mode,
+ hid_t src_id, hid_t dst_id, void *buf/*out*/);
+static herr_t
+H5D_contig_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t doing_mpio, H5FD_mpio_xfer_t xfer_mode,
+ hid_t src_id, hid_t dst_id, const void *buf);
+static herr_t
+H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t doing_mpio, H5FD_mpio_xfer_t xfer_mode,
+ hid_t src_id, hid_t dst_id, void *buf/*out*/);
+static herr_t
+H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t doing_mpio, H5FD_mpio_xfer_t xfer_mode,
+ hid_t src_id, hid_t dst_id, const void *buf);
+#ifdef H5_HAVE_PARALLEL
+static herr_t
+H5D_io_assist_mpio(H5P_genplist_t *dx_plist, hbool_t doing_mpio, H5FD_mpio_xfer_t xfer_mode,
+ hbool_t *xfer_mode_changed);
+#endif /*H5_HAVE_PARALLEL*/
+static herr_t
+H5D_chunk_mem_file_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_space,
+ const H5S_t *mem_space, fm_map *fm_struct);
+static herr_t H5D_chunk_coords_assist(hssize_t *coords, size_t ndims,
+ hsize_t chunks[], hsize_t chunk_ptr);
+static herr_t H5D_chunk_cb(void *elem, hid_t type_id, hsize_t ndims,
+ hssize_t *coords, void *fm);
+static herr_t H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
+ const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id);
+
+
+/* Declare a free list to manage blocks of single datatype element data */
+H5FL_BLK_DEFINE(type_elem);
+
+/* Declare a free list to manage blocks of type conversion data */
+H5FL_BLK_DEFINE(type_conv);
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Dfill
+ PURPOSE
+ Fill a selection in memory with a value
+ USAGE
+ herr_t H5Dfill(fill, fill_type, space, buf, buf_type)
+ const void *fill; IN: Pointer to fill value to use
+ hid_t fill_type_id; IN: Datatype of the fill value
+ void *buf; IN/OUT: Memory buffer to fill selection within
+ hid_t buf_type_id; IN: Datatype of the elements in buffer
+ hid_t space_id; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ If "fill" parameter is NULL, use all zeros as fill value
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Dfill(const void *fill, hid_t fill_type_id, void *buf, hid_t buf_type_id, hid_t space_id)
+{
+ H5S_t *space; /* Dataspace */
+ H5T_t *fill_type; /* Fill-value datatype */
+ H5T_t *buf_type; /* Buffer datatype */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Dfill, FAIL);
+ H5TRACE5("e","xixii",fill,fill_type_id,buf,buf_type_id,space_id);
+
+ /* Check args */
+ if (buf==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer");
+ if (NULL == (space=H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataspace");
+ if (NULL == (fill_type=H5I_object_verify(fill_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
+ if (NULL == (buf_type=H5I_object_verify(buf_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a datatype");
+
+ /* Fill the selection in the memory buffer */
+ if(H5D_fill(fill,fill_type,buf,buf_type,space, H5AC_dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* H5Dfill() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5D_fill
+ PURPOSE
+ Fill a selection in memory with a value (internal version)
+ USAGE
+ herr_t H5D_fill(fill, fill_type, buf, buf_type, space)
+ const void *fill; IN: Pointer to fill value to use
+ H5T_t *fill_type; IN: Datatype of the fill value
+ void *buf; IN/OUT: Memory buffer to fill selection within
+ H5T_t *buf_type; IN: Datatype of the elements in buffer
+ H5S_t *space; IN: Dataspace describing memory buffer &
+ containing selection to use.
+ RETURNS
+ Non-negative on success/Negative on failure.
+ DESCRIPTION
+ Use the selection in the dataspace to fill elements in a memory buffer.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ If "fill" parameter is NULL, use all zeros as fill value. If "fill_type"
+ parameter is NULL, use "buf_type" for the fill value datatype.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5D_fill(const void *fill, const H5T_t *fill_type, void *buf, const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id)
+{
+ H5T_path_t *tpath = NULL; /* Conversion information*/
+ uint8_t *tconv_buf = NULL; /* Data type conv buffer */
+ uint8_t *bkg_buf = NULL; /* Temp conversion buffer */
+ hid_t src_id = -1, dst_id = -1; /* Temporary type IDs */
+ size_t src_type_size; /* Size of source type */
+ size_t dst_type_size; /* Size of destination type*/
+ size_t buf_size; /* Desired buffer size */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5D_fill);
+
+ /* Check args */
+ assert(buf);
+ assert(buf_type);
+ assert(space);
+
+ /* Check for "default" fill value */
+ if(fill_type==NULL)
+ fill_type=buf_type;
+
+ /* Get the memory and file datatype sizes */
+ src_type_size = H5T_get_size(fill_type);
+ dst_type_size = H5T_get_size(buf_type);
+
+ /* Get the maximum buffer size needed and allocate it */
+ buf_size=MAX(src_type_size,dst_type_size);
+ if (NULL==(tconv_buf = H5FL_BLK_MALLOC(type_elem,buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(type_elem,buf_size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+
+ /* Copy the user's data into the buffer for conversion */
+ if(fill==NULL)
+ HDmemset(tconv_buf,0,src_type_size);
+ else
+ HDmemcpy(tconv_buf,fill,src_type_size);
+
+ /* Convert memory buffer into disk buffer */
+ /* Set up type conversion function */
+ if (NULL == (tpath = H5T_path_find(fill_type, buf_type, NULL, NULL, dxpl_id))) {
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
+ } else if (!H5T_IS_NOOP(tpath)) {
+ if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(fill_type, H5T_COPY_ALL)))<0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(buf_type, H5T_COPY_ALL)))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
+ }
+
+ /* Perform data type conversion */
+ if (H5T_convert(tpath, src_id, dst_id, (hsize_t)1, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed");
+
+ /* Fill the selection in the memory buffer */
+ if(H5S_select_fill(tconv_buf, dst_type_size, space, buf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed");
+
+done:
+ if (tconv_buf)
+ H5FL_BLK_FREE(type_elem,tconv_buf);
+ if (bkg_buf)
+ H5FL_BLK_FREE(type_elem,bkg_buf);
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5D_fill() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dread
+ *
+ * Purpose: Reads (part of) a DSET from the file into application
+ * memory BUF. The part of the dataset to read is defined with
+ * MEM_SPACE_ID and FILE_SPACE_ID. The data points are
+ * converted from their file type to the MEM_TYPE_ID specified.
+ * Additional miscellaneous data transfer properties can be
+ * passed to this function with the PLIST_ID argument.
+ *
+ * The FILE_SPACE_ID can be the constant H5S_ALL which indicates
+ * that the entire file data space is to be referenced.
+ *
+ * The MEM_SPACE_ID can be the constant H5S_ALL in which case
+ * the memory data space is the same as the file data space
+ * defined when the dataset was created.
+ *
+ * The number of elements in the memory data space must match
+ * the number of elements in the file data space.
+ *
+ * The PLIST_ID can be the constant H5P_DEFAULT in which
+ * case the default data transfer properties are used.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Errors:
+ * ARGS BADTYPE Not a data space.
+ * ARGS BADTYPE Not a data type.
+ * ARGS BADTYPE Not a dataset.
+ * ARGS BADTYPE Not xfer parms.
+ * ARGS BADVALUE No output buffer.
+ * DATASET READERROR Can't read data.
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t plist_id, void *buf/*out*/)
+{
+ H5D_t *dset = NULL;
+ const H5T_t *mem_type = NULL;
+ const H5S_t *mem_space = NULL;
+ const H5S_t *file_space = NULL;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Dread, FAIL);
+ H5TRACE6("e","iiiiix",dset_id,mem_type_id,mem_space_id,file_space_id,
+ plist_id,buf);
+
+ /* check arguments */
+ if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ if (NULL == dset->ent.file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ if (NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if (H5S_ALL != mem_space_id) {
+ if (NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if(H5S_select_valid(mem_space)!=TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+ if (H5S_ALL != file_space_id) {
+ if (NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if(H5S_select_valid(file_space)!=TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == plist_id)
+ plist_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ if (!buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
+
+ /* read raw data */
+ if (H5D_read(dset, mem_type, mem_space, file_space, plist_id, buf/*out*/) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dwrite
+ *
+ * Purpose: Writes (part of) a DSET from application memory BUF to the
+ * file. The part of the dataset to write is defined with the
+ * MEM_SPACE_ID and FILE_SPACE_ID arguments. The data points
+ * are converted from their current type (MEM_TYPE_ID) to their
+ * file data type. Additional miscellaneous data transfer
+ * properties can be passed to this function with the
+ * PLIST_ID argument.
+ *
+ * The FILE_SPACE_ID can be the constant H5S_ALL which indicates
+ * that the entire file data space is to be referenced.
+ *
+ * The MEM_SPACE_ID can be the constant H5S_ALL in which case
+ * the memory data space is the same as the file data space
+ * defined when the dataset was created.
+ *
+ * The number of elements in the memory data space must match
+ * the number of elements in the file data space.
+ *
+ * The PLIST_ID can be the constant H5P_DEFAULT in which
+ * case the default data transfer properties are used.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Errors:
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+ hid_t file_space_id, hid_t plist_id, const void *buf)
+{
+ H5D_t *dset = NULL;
+ const H5T_t *mem_type = NULL;
+ const H5S_t *mem_space = NULL;
+ const H5S_t *file_space = NULL;
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Dwrite, FAIL);
+ H5TRACE6("e","iiiiix",dset_id,mem_type_id,mem_space_id,file_space_id,
+ plist_id,buf);
+
+ /* check arguments */
+ if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ if (NULL == dset->ent.file)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ if (NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ if (H5S_ALL != mem_space_id) {
+ if (NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if (H5S_select_valid(mem_space)!=TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+ if (H5S_ALL != file_space_id) {
+ if (NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+
+ /* Check for valid selection */
+ if (H5S_select_valid(file_space)!=TRUE)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent");
+ }
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if (H5P_DEFAULT == plist_id)
+ plist_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+ if (!buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer");
+
+ /* write raw data */
+ if (H5D_write(dset, mem_type, mem_space, file_space, plist_id, buf) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_read
+ *
+ * Purpose: Reads (part of) a DATASET into application memory BUF. See
+ * H5Dread() for complete details.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ * Robb Matzke, 1998-06-09
+ * The data space is no longer cached in the dataset struct.
+ *
+ * Robb Matzke, 1998-08-11
+ * Added timing calls around all the data space I/O functions.
+ *
+ * rky, 1998-09-18
+ * Added must_convert to do non-optimized read when necessary.
+ *
+ * Quincey Koziol, 1999-07-02
+ * Changed xfer_parms parameter to xfer plist parameter, so it
+ * could be passed to H5T_convert.
+ *
+ * Albert Cheng, 2000-11-21
+ * Added the code that when it detects it is not safe to process a
+ * COLLECTIVE read request without hanging, it changes it to
+ * INDEPENDENT calls.
+ *
+ * Albert Cheng, 2000-11-27
+ * Changed to use the optimized MPIO transfer for Collective calls only.
+ *
+ * Raymond Lu, 2001-10-2
+ * Changed the way to retrieve property for generic property list.
+ *
+ * Raymond Lu, 2002-2-26
+ * For the new fill value design, data space can either be allocated
+ * or not allocated at this stage. Fill value or data from space is
+ * returned to outgoing buffer.
+ *
+ * QAK - 2002/04/02
+ * Removed the must_convert parameter and move preconditions to
+ * H5S_<foo>_opt_possible() routine
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, hid_t dxpl_id, void *buf/*out*/)
+{
+ hssize_t snelmts; /*total number of elmts (signed) */
+ hsize_t nelmts; /*total number of elmts */
+ H5T_path_t *tpath = NULL; /*type conversion info */
+ hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
+ H5S_conv_t *sconv=NULL; /*space conversion funcs*/
+ H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
+ hbool_t doing_mpio=0; /*This is an MPIO access */
+ H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */
+ H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
+ unsigned sconv_flags=0; /* Flags for the space conversion */
+ H5S_sel_type fsel_type; /* Selection type on disk */
+ H5S_sel_type msel_type; /* Selection type in memory */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5D_read);
+
+ /* check args */
+ assert(dataset && dataset->ent.file);
+ assert(mem_type);
+ assert(buf);
+
+ /* Get the dataset's creation property list */
+ if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
+ /* Get the dataset transfer property list */
+ if (NULL == (dx_plist = H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
+ if (!file_space)
+ file_space = dataset->space;
+ if (!mem_space)
+ mem_space = file_space;
+ if((snelmts = H5S_get_select_npoints(mem_space))<0)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection");
+ nelmts=snelmts;
+
+#ifdef H5_HAVE_PARALLEL
+ /* Collect Parallel I/O information for possible later use */
+ if (H5FD_MPIO==H5P_peek_hid_t(dx_plist,H5D_XFER_VFL_ID_NAME)) {
+ doing_mpio++;
+ xfer_mode=H5P_peek_unsigned(dx_plist, H5D_XFER_IO_XFER_MODE_NAME);
+ } /* end if */
+ /* Collective access is not permissible without the MPIO or MPIPOSIX driver */
+ if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE &&
+ !(IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)))
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPIO & MPIPOSIX drivers only");
+
+ /* Set the "parallel I/O possible" flag, for H5S_find() */
+ if (H5S_mpi_opt_types_g && IS_H5FD_MPIO(dataset->ent.file)) {
+ /* Only collective write should call this since it eventually
+ * calls MPI_File_set_view which is a collective call.
+ * See H5S_mpio_spaces_xfer() for details.
+ */
+ if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE)
+ sconv_flags |= H5S_CONV_PAR_IO_POSSIBLE;
+ } /* end if */
+#endif /*H5_HAVE_PARALLEL*/
+
+ /* Make certain that the number of elements in each selection is the same */
+ if (nelmts!=(hsize_t)H5S_get_select_npoints(file_space))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
+
+ /* Retrieve dataset properties */
+ /* <none needed in the general case> */
+
+ /* If space hasn't been allocated and not using external storage,
+ * return fill value to buffer if fill time is upon allocation, or
+ * do nothing if fill time is never. If the dataset is compact and
+ * fill time is NEVER, there is no way to tell whether part of data
+ * has been overwritten. So just proceed in reading.
+ */
+ if(nelmts > 0 && dataset->efl.nused==0 && dataset->layout.type!=H5D_COMPACT
+ && dataset->layout.addr==HADDR_UNDEF) {
+ H5O_fill_t fill; /* Fill value info */
+ H5D_fill_time_t fill_time; /* When to write the fill values */
+ H5D_fill_value_t fill_status; /* Whether/How the fill value is defined */
+
+ /* Retrieve dataset's fill-value properties */
+ if(H5P_fill_value_defined(dc_plist, &fill_status)<0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
+ if((fill_status==H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED)
+ && H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill value");
+ if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,"can't retrieve fill time");
+
+ /* Should be impossible, but check anyway... */
+ if(fill_status == H5D_FILL_VALUE_UNDEFINED && fill_time == H5D_FILL_TIME_ALLOC)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "read failed: dataset doesn't exist, no data can be read");
+
+ /* If we're never going to fill this dataset, just leave the junk in the user's buffer */
+ if(fill_time == H5D_FILL_TIME_NEVER)
+ HGOTO_DONE(SUCCEED);
+
+ /* Go fill the user's selection with the dataset's fill value */
+ if(H5D_fill(fill.buf,fill.type,buf,mem_type,mem_space, dxpl_id)<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "filling buf failed");
+ } else
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+
+ /*
+ * Locate the type conversion function and data space conversion
+ * functions, and set up the element numbering information. If a data
+ * type conversion is necessary then register data type atoms. Data type
+ * conversion is necessary if the user has set the `need_bkg' to a high
+ * enough value in xfer_parms since turning off data type conversion also
+ * turns off background preservation.
+ */
+ if (NULL==(tpath=H5T_path_find(dataset->type, mem_type, NULL, NULL, dxpl_id))) {
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
+ } else if (!H5T_IS_NOOP(tpath)) {
+ if ((src_id=H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0 ||
+ (dst_id=H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
+ } /* end if */
+
+ /* Set the storage flags for the space conversion check */
+ switch(dataset->layout.type) {
+ case H5D_COMPACT:
+ sconv_flags |= H5S_CONV_STORAGE_COMPACT;
+ break;
+
+ case H5D_CONTIGUOUS:
+ sconv_flags |= H5S_CONV_STORAGE_CONTIGUOUS;
+ break;
+
+ case H5D_CHUNKED:
+ sconv_flags |= H5S_CONV_STORAGE_CHUNKED;
+ break;
+
+ default:
+ assert(0 && "Unhandled layout type!");
+ } /* end switch */
+
+ /* Get dataspace functions */
+ if (NULL==(sconv=H5S_find(mem_space, file_space, sconv_flags)))
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert from file to memory data space");
+
+ /* Get type of selection on disk & in memory */
+ if((fsel_type=H5S_get_select_type(file_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADSELECT, FAIL, "unable to convert from file to memory data space");
+ if((msel_type=H5S_get_select_type(mem_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADSELECT, FAIL, "unable to convert from file to memory data space");
+
+ /* Determine correct I/O routine to invoke */
+ if((fsel_type==H5S_SEL_POINTS || msel_type==H5S_SEL_POINTS) ||
+ dataset->layout.type!=H5D_CHUNKED) {
+ /* Must use "contiguous" code for point selections,
+ * since order of I/O accesses can be different from that of the
+ * other kinds of selections
+ */
+ if(H5D_contig_read(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, dc_plist,
+ dx_plist, dxpl_id, doing_mpio, xfer_mode, src_id, dst_id, buf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data");
+ } /* end if */
+ else {
+ if(H5D_chunk_read(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, dc_plist,
+ dx_plist, dxpl_id, doing_mpio, xfer_mode, src_id, dst_id, buf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read data");
+ } /* end else */
+
+done:
+ if (src_id >= 0)
+ H5I_dec_ref(src_id);
+ if (dst_id >= 0)
+ H5I_dec_ref(dst_id);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_write
+ *
+ * Purpose: Writes (part of) a DATASET to a file from application memory
+ * BUF. See H5Dwrite() for complete details.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, December 4, 1997
+ *
+ * Modifications:
+ * Robb Matzke, 9 Jun 1998
+ * The data space is no longer cached in the dataset struct.
+ *
+ * rky 980918
+ * Added must_convert to do non-optimized read when necessary.
+ *
+ * Quincey Koziol, 2 July 1999
+ * Changed xfer_parms parameter to xfer plist parameter, so it could
+ * be passed to H5T_convert
+ *
+ * Albert Cheng, 2000-11-21
+ * Added the code that when it detects it is not safe to process a
+ * COLLECTIVE write request without hanging, it changes it to
+ * INDEPENDENT calls.
+ *
+ * Albert Cheng, 2000-11-27
+ * Changed to use the optimized MPIO transfer for Collective calls only.
+ *
+ * Raymond Lu, 2001-10-2
+ * Changed the way to retrieve property for generic property list.
+ *
+ * Raymond Lu, 2002-2-26
+ * For the new fill value design, space may not be allocated until
+ * this function is called. Allocate and initialize space if it
+ * hasn't been.
+ *
+ * QAK - 2002/04/02
+ * Removed the must_convert parameter and move preconditions to
+ * H5S_<foo>_opt_possible() routine
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, hid_t dxpl_id, const void *buf)
+{
+ hssize_t snelmts; /*total number of elmts (signed) */
+ hsize_t nelmts; /*total number of elmts */
+ H5T_path_t *tpath = NULL; /*type conversion info */
+ hid_t src_id = -1, dst_id = -1;/*temporary type atoms */
+ H5S_conv_t *sconv=NULL; /*space conversion funcs*/
+ H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT; /*xfer_mode for this request */
+ hbool_t doing_mpio=0; /*This is an MPIO access */
+ H5P_genplist_t *dx_plist=NULL; /* Data transfer property list */
+ H5P_genplist_t *dc_plist; /* Dataset creation roperty list */
+ unsigned sconv_flags=0; /* Flags for the space conversion */
+ H5S_sel_type fsel_type; /* Selection type on disk */
+ H5S_sel_type msel_type; /* Selection type in memory */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5D_write);
+
+ /* check args */
+ assert(dataset && dataset->ent.file);
+ assert(mem_type);
+ assert(buf);
+
+ /* If MPIO, MPIPOSIX, or FPHDF5 is used, no VL datatype support yet. */
+ /* This is because they use the global heap in the file and we don't */
+ /* support parallel access of that yet */
+ if ( (IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)) &&
+ H5T_get_class(mem_type)==H5T_VLEN)
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing VL datatypes yet");
+ /* If MPIO, MPIPOSIX, or FPHDF5 is used, no dataset region reference datatype support yet. */
+ /* This is because they use the global heap in the file and we don't */
+ /* support parallel access of that yet */
+ if ((IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)) &&
+ H5T_get_class(mem_type)==H5T_REFERENCE &&
+ H5T_get_ref_type(mem_type)==H5R_DATASET_REGION)
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Parallel IO does not support writing region reference datatypes yet");
+
+ /* Check if we are allowed to write to this file */
+ if (0==(H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file");
+
+ /* Get the dataset's creation property list */
+ if (NULL == (dc_plist = H5I_object(dataset->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
+ /* Get the dataset transfer property list */
+ if (NULL == (dx_plist = H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset creation property list");
+
+ if (!file_space)
+ file_space = dataset->space;
+ if (!mem_space)
+ mem_space = file_space;
+ if((snelmts = H5S_get_select_npoints(mem_space))<0)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection");
+ nelmts=snelmts;
+
+#ifdef H5_HAVE_PARALLEL
+ /* Collect Parallel I/O information for possible later use */
+ if (H5FD_MPIO==H5P_peek_hid_t(dx_plist,H5D_XFER_VFL_ID_NAME)) {
+ doing_mpio++;
+ xfer_mode=H5P_peek_unsigned(dx_plist, H5D_XFER_IO_XFER_MODE_NAME);
+ } /* end if */
+
+ /* Collective access is not permissible without the MPIO or MPIPOSIX driver */
+ if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE &&
+ !(IS_H5FD_MPIO(dataset->ent.file) || IS_H5FD_MPIPOSIX(dataset->ent.file) || IS_H5FD_FPHDF5(dataset->ent.file)))
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPIO driver only");
+
+ /* If dataset is compact, collective access is only allowed when file space
+ * selection is H5S_ALL */
+ if(doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE
+ && dataset->layout.type==H5D_COMPACT) {
+ if(H5S_get_select_type(file_space) != H5S_SEL_ALL)
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access to compact dataset doesn't support partial access");
+ }
+
+ /* Set the "parallel I/O possible" flag, for H5S_find() */
+ if (H5S_mpi_opt_types_g && IS_H5FD_MPIO(dataset->ent.file)) {
+ /* Only collective write should call this since it eventually
+ * calls MPI_File_set_view which is a collective call.
+ * See H5S_mpio_spaces_xfer() for details.
+ */
+ if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE)
+ sconv_flags |= H5S_CONV_PAR_IO_POSSIBLE;
+ } /* end if */
+#endif /*H5_HAVE_PARALLEL*/
+
+ /* Make certain that the number of elements in each selection is the same */
+ if (nelmts!=(hsize_t)H5S_get_select_npoints(file_space))
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes");
+
+ /* Retrieve dataset properties */
+ /* <none needed currently> */
+
+ /* Allocate data space and initialize it if it hasn't been. */
+ if(nelmts > 0 && dataset->efl.nused==0 && dataset->layout.type!=H5D_COMPACT
+ && dataset->layout.addr==HADDR_UNDEF) {
+ hssize_t file_nelmts; /* Number of elements in file dataset's dataspace */
+
+ /* Get the number of elements in file dataset's dataspace */
+ if((file_nelmts=H5S_get_simple_extent_npoints(file_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset");
+
+ /* Allocate storage */
+ if(H5D_alloc_storage(dataset->ent.file,dxpl_id,dataset,H5D_ALLOC_WRITE, TRUE, (hbool_t)((hsize_t)file_nelmts==nelmts ? TRUE : FALSE))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage");
+ } /* end if */
+
+ /*
+ * Locate the type conversion function and data space conversion
+ * functions, and set up the element numbering information. If a data
+ * type conversion is necessary then register data type atoms. Data type
+ * conversion is necessary if the user has set the `need_bkg' to a high
+ * enough value in xfer_parms since turning off data type conversion also
+ * turns off background preservation.
+ */
+ if (NULL==(tpath=H5T_path_find(mem_type, dataset->type, NULL, NULL, dxpl_id))) {
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types");
+ } else if (!H5T_IS_NOOP(tpath)) {
+ if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register types for conversion");
+ } /* end if */
+
+ /* Set the storage flags for the space conversion check */
+ switch(dataset->layout.type) {
+ case H5D_COMPACT:
+ sconv_flags |= H5S_CONV_STORAGE_COMPACT;
+ break;
+
+ case H5D_CONTIGUOUS:
+ sconv_flags |= H5S_CONV_STORAGE_CONTIGUOUS;
+ break;
+
+ case H5D_CHUNKED:
+ sconv_flags |= H5S_CONV_STORAGE_CHUNKED;
+ break;
+
+ default:
+ assert(0 && "Unhandled layout type!");
+ } /* end switch */
+
+ /* Get dataspace functions */
+ if (NULL==(sconv=H5S_find(mem_space, file_space, sconv_flags)))
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert from memory to file data space");
+
+ /* Get type of selection on disk & in memory */
+ if((fsel_type=H5S_get_select_type(file_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADSELECT, FAIL, "unable to convert from file to memory data space");
+ if((msel_type=H5S_get_select_type(mem_space))<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_BADSELECT, FAIL, "unable to convert from file to memory data space");
+
+ /* Determine correct I/O routine to invoke */
+ if((fsel_type==H5S_SEL_POINTS || msel_type==H5S_SEL_POINTS) ||
+ dataset->layout.type!=H5D_CHUNKED) {
+ /* Must use "contiguous" code for point selections,
+ * since order of I/O accesses can be different from that of the
+ * other kinds of selections
+ */
+ if(H5D_contig_write(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, dc_plist,
+ dx_plist, dxpl_id, doing_mpio, xfer_mode, src_id, dst_id, buf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data");
+ } /* end if */
+ else {
+ if(H5D_chunk_write(nelmts, dataset, mem_type, mem_space, file_space, tpath, sconv, dc_plist,
+ dx_plist, dxpl_id, doing_mpio, xfer_mode, src_id, dst_id, buf)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data");
+ } /* end else */
+
+ /*
+ * Update modification time. We have to do this explicitly because
+ * writing to a dataset doesn't necessarily change the object header.
+ */
+ if (H5O_touch(&(dataset->ent), FALSE, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time");
+
+done:
+ if (src_id >= 0)
+ H5I_dec_ref(src_id);
+ if (dst_id >= 0)
+ H5I_dec_ref(dst_id);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_contig_read
+ *
+ * Purpose: Read from a contiguous dataset.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_contig_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ doing_mpio, H5FD_mpio_xfer_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ xfer_mode,
+ hid_t src_id, hid_t dst_id, void *buf/*out*/)
+{
+ herr_t status; /*function return status*/
+#ifdef H5S_DEBUG
+ H5_timer_t timer;
+#endif
+ size_t src_type_size; /*size of source type */
+ size_t dst_type_size; /*size of destination type*/
+ size_t target_size; /*desired buffer size */
+ hsize_t request_nelmts; /*requested strip mine */
+ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
+ H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
+ H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
+ H5T_bkg_t need_bkg; /*type of background buf*/
+ uint8_t *tconv_buf = NULL; /*data type conv buffer */
+ uint8_t *bkg_buf = NULL; /*background buffer */
+ hsize_t smine_start; /*strip mine start loc */
+ hsize_t n, smine_nelmts; /*elements per strip */
+#ifdef H5_HAVE_PARALLEL
+ hbool_t xfer_mode_changed; /* Whether the transfer mode was changed */
+#endif /*H5_HAVE_PARALLEL*/
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOINIT(H5D_contig_read);
+
+ /*
+ * If there is no type conversion then read directly into the
+ * application's buffer. This saves at least one mem-to-mem copy.
+ */
+ if (H5T_IS_NOOP(tpath)) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ /* Sanity check dataset, then read it */
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 ||
+ dataset->layout.type==H5D_COMPACT);
+ status = (sconv->read)(dataset->ent.file, &(dataset->layout),
+ dc_plist, (H5D_storage_t *)&(dataset->efl), H5T_get_size(dataset->type),
+ file_space, mem_space, dxpl_id, buf/*out*/);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].read_timer), &timer);
+ sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->type);
+ sconv->stats[1].read_ncalls++;
+#endif
+
+ /* Check return value from optimized read */
+ if (status<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed");
+ } else
+ /* direct xfer accomplished successfully */
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+
+ /*
+ * This is the general case(type conversion).
+ */
+
+#ifdef H5_HAVE_PARALLEL
+ H5D_io_assist_mpio(dx_plist, doing_mpio, xfer_mode, &xfer_mode_changed);
+#endif /*H5_HAVE_PARALLEL*/
+
+ /* Compute element sizes and other parameters */
+ src_type_size = H5T_get_size(dataset->type);
+ dst_type_size = H5T_get_size(mem_type);
+ target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME);
+ request_nelmts = target_size / MAX(src_type_size, dst_type_size);
+
+ /* Figure out the strip mine size. */
+ if (H5S_select_iter_init(&file_iter, file_space, src_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&mem_iter, mem_space, dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&bkg_iter, mem_space, dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
+
+ /* Sanity check elements in temporary buffer */
+ if (request_nelmts<=0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small");
+
+ /*
+ * Get a temporary buffer for type conversion unless the app has already
+ * supplied one through the xfer properties. Instead of allocating a
+ * buffer which is the exact size, we allocate the target size. The
+ * malloc() is usually less resource-intensive if we allocate/free the
+ * same size over and over.
+ */
+ if (tpath->cdata.need_bkg) {
+ /* Retrieve the bkgr buffer property */
+ if(H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &need_bkg)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
+ need_bkg = MAX(tpath->cdata.need_bkg, need_bkg);
+ } else {
+ need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
+ } /* end else */
+ if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
+ /* Allocate temporary buffer */
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+ if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
+ /* Allocate background buffer */
+ H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
+ if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
+ } /* end if */
+
+ /* Start strip mining... */
+ for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) {
+ /* Go figure out how many elements to read from the file */
+ assert(H5S_select_iter_nelmts(&file_iter)==(nelmts-smine_start));
+ smine_nelmts = MIN(request_nelmts, (nelmts-smine_start));
+
+ /*
+ * Gather the data from disk into the data type conversion
+ * buffer. Also gather data from application to background buffer
+ * if necessary.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ /* Sanity check that space is allocated, then read data from it */
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 ||
+ dataset->layout.type==H5D_COMPACT);
+ n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
+ dc_plist, (H5D_storage_t *)&dataset->efl, src_type_size, file_space,
+ &file_iter, smine_nelmts, dxpl_id, tconv_buf/*out*/);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].gath_timer), &timer);
+ sconv->stats[1].gath_nbytes += n * src_type_size;
+ sconv->stats[1].gath_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
+
+ if (need_bkg) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ n = H5S_select_mgath(buf, dst_type_size, mem_space, &bkg_iter,
+ smine_nelmts, dxpl_id, bkg_buf/*out*/);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].bkg_timer), &timer);
+ sconv->stats[1].bkg_nbytes += n * dst_type_size;
+ sconv->stats[1].bkg_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
+ } /* end if */
+
+ /*
+ * Perform data type conversion.
+ */
+ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ /*
+ * Scatter the data into memory.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ status = H5S_select_mscat(tconv_buf, dst_type_size, mem_space,
+ &mem_iter, smine_nelmts, dxpl_id, buf/*out*/);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].scat_timer), &timer);
+ sconv->stats[1].scat_nbytes += smine_nelmts * dst_type_size;
+ sconv->stats[1].scat_ncalls++;
+#endif
+ if (status<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "scatter failed");
+
+ } /* end for */
+
+done:
+#ifdef H5_HAVE_PARALLEL
+ /* restore xfer_mode due to the kludge */
+ if (doing_mpio && xfer_mode_changed) {
+#ifdef H5D_DEBUG
+ if (H5DEBUG(D))
+ fprintf (H5DEBUG(D), "H5D: dx->xfer_mode was COLLECTIVE, restored to INDEPENDENT\n");
+#endif
+ xfer_mode = H5FD_MPIO_COLLECTIVE;
+ if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
+ } /* end if */
+#endif /*H5_HAVE_PARALLEL*/
+ /* Release selection iterators */
+ if(file_iter_init)
+ H5S_select_iter_release(&file_iter);
+ if(mem_iter_init)
+ H5S_select_iter_release(&mem_iter);
+ if(bkg_iter_init)
+ H5S_select_iter_release(&bkg_iter);
+
+ assert(dx_plist);
+ if (tconv_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,tconv_buf);
+ if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,bkg_buf);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_contig_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_contig_write
+ *
+ * Purpose: Write to a contiguous dataset.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_contig_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ doing_mpio, H5FD_mpio_xfer_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ xfer_mode,
+ hid_t src_id, hid_t dst_id, const void *buf)
+{
+ herr_t status; /*function return status*/
+#ifdef H5S_DEBUG
+ H5_timer_t timer;
+#endif
+ size_t src_type_size; /*size of source type */
+ size_t dst_type_size; /*size of destination type*/
+ size_t target_size; /*desired buffer size */
+ hsize_t request_nelmts; /*requested strip mine */
+ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
+ H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
+ H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
+ H5T_bkg_t need_bkg; /*type of background buf*/
+ uint8_t *tconv_buf = NULL; /*data type conv buffer */
+ uint8_t *bkg_buf = NULL; /*background buffer */
+ hsize_t smine_start; /*strip mine start loc */
+ hsize_t n, smine_nelmts; /*elements per strip */
+#ifdef H5_HAVE_PARALLEL
+ hbool_t xfer_mode_changed; /* Whether the transfer mode was changed */
+#endif /*H5_HAVE_PARALLEL*/
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOINIT(H5D_contig_write);
+
+ /*
+ * If there is no type conversion then write directly from the
+ * application's buffer. This saves at least one mem-to-mem copy.
+ */
+ if (H5T_IS_NOOP(tpath)) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ status = (sconv->write)(dataset->ent.file, &(dataset->layout),
+ dc_plist, (H5D_storage_t *)&(dataset->efl), H5T_get_size(dataset->type),
+ file_space, mem_space, dxpl_id, buf);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].write_timer), &timer);
+ sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type);
+ sconv->stats[0].write_ncalls++;
+#endif
+
+ /* Check return value from optimized write */
+ if (status<0) {
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed");
+ } else
+ /* direct xfer accomplished successfully */
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+
+ /*
+ * This is the general case.
+ */
+
+#ifdef H5_HAVE_PARALLEL
+ H5D_io_assist_mpio(dx_plist, doing_mpio, xfer_mode, &xfer_mode_changed);
+#endif /*H5_HAVE_PARALLEL*/
+
+ /* Compute element sizes and other parameters */
+ src_type_size = H5T_get_size(mem_type);
+ dst_type_size = H5T_get_size(dataset->type);
+ target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME);
+ request_nelmts = target_size / MAX (src_type_size, dst_type_size);
+
+ /* Sanity check elements in temporary buffer */
+ if (request_nelmts<=0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small");
+
+ /* Figure out the strip mine size. */
+ if (H5S_select_iter_init(&file_iter, file_space, dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&mem_iter, mem_space, src_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&bkg_iter, file_space, dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
+
+ /*
+ * Get a temporary buffer for type conversion unless the app has already
+ * supplied one through the xfer properties. Instead of allocating a
+ * buffer which is the exact size, we allocate the target size. The
+ * malloc() is usually less resource-intensive if we allocate/free the
+ * same size over and over.
+ */
+ if (tpath->cdata.need_bkg) {
+ /* Retrieve the bkgr buffer property */
+ if(H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &need_bkg)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
+ need_bkg = MAX (tpath->cdata.need_bkg, need_bkg);
+ } else if(H5T_detect_class(dataset->type, H5T_VLEN)) {
+ /* Old data is retrieved into background buffer for VL datatype. The
+ * data is used later for freeing heap objects. */
+ need_bkg = H5T_BKG_YES;
+ } else {
+ need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
+ } /* end else */
+ if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
+ /* Allocate temporary buffer */
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+ if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
+ /* Allocate background buffer */
+ H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
+ if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
+ } /* end if */
+
+ /* Start strip mining... */
+ for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) {
+ /* Go figure out how many elements to read from the file */
+ assert(H5S_select_iter_nelmts(&file_iter)==(nelmts-smine_start));
+ smine_nelmts = MIN(request_nelmts, (nelmts-smine_start));
+
+ /*
+ * Gather data from application buffer into the data type conversion
+ * buffer. Also gather data from the file into the background buffer
+ * if necessary.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ n = H5S_select_mgath(buf, src_type_size, mem_space, &mem_iter,
+ smine_nelmts, dxpl_id, tconv_buf/*out*/);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].gath_timer), &timer);
+ sconv->stats[0].gath_nbytes += n * src_type_size;
+ sconv->stats[0].gath_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "mem gather failed");
+
+ if (need_bkg) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
+ dc_plist, (H5D_storage_t *)&(dataset->efl), dst_type_size, file_space,
+ &bkg_iter, smine_nelmts, dxpl_id, bkg_buf/*out*/);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].bkg_timer), &timer);
+ sconv->stats[0].bkg_nbytes += n * dst_type_size;
+ sconv->stats[0].bkg_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed");
+ } /* end if */
+
+ /*
+ * Perform data type conversion.
+ */
+ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0, tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ /*
+ * Scatter the data out to the file.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ status = H5S_select_fscat(dataset->ent.file, &(dataset->layout),
+ dc_plist, (H5D_storage_t *)&(dataset->efl), dst_type_size, file_space, &file_iter,
+ smine_nelmts, dxpl_id, tconv_buf);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].scat_timer), &timer);
+ sconv->stats[0].scat_nbytes += smine_nelmts * dst_type_size;
+ sconv->stats[0].scat_ncalls++;
+#endif
+ if (status<0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "scatter failed");
+ } /* end for */
+
+done:
+#ifdef H5_HAVE_PARALLEL
+ /* restore xfer_mode due to the kludge */
+ if (doing_mpio && xfer_mode_changed) {
+#ifdef H5D_DEBUG
+ if (H5DEBUG(D))
+ fprintf (H5DEBUG(D), "H5D: dx->xfer_mode was COLLECTIVE, restored to INDEPENDENT\n");
+#endif
+ xfer_mode = H5FD_MPIO_COLLECTIVE;
+ if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
+ } /* end if */
+#endif /*H5_HAVE_PARALLEL*/
+ /* Release selection iterators */
+ if(file_iter_init)
+ H5S_select_iter_release(&file_iter);
+ if(mem_iter_init)
+ H5S_select_iter_release(&mem_iter);
+ if(bkg_iter_init)
+ H5S_select_iter_release(&bkg_iter);
+
+ assert(dx_plist);
+ if (tconv_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,tconv_buf);
+ if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,bkg_buf);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_contig_write() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_read
+ *
+ * Purpose: Read from a chunked dataset.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_read(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ doing_mpio, H5FD_mpio_xfer_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ xfer_mode, hid_t src_id, hid_t dst_id, void *buf/*out*/)
+{
+ fm_map fm_struct;
+ herr_t status; /*function return status*/
+#ifdef H5S_DEBUG
+ H5_timer_t timer;
+#endif
+ size_t src_type_size; /*size of source type */
+ size_t dst_type_size; /*size of destination type*/
+ size_t target_size; /*desired buffer size */
+ hsize_t request_nelmts; /*requested strip mine */
+ hsize_t smine_start; /*strip mine start loc */
+ hsize_t n, smine_nelmts; /*elements per strip */
+ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
+ H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
+ H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
+ H5T_bkg_t need_bkg; /*type of background buf*/
+ uint8_t *tconv_buf = NULL; /*data type conv buffer */
+ uint8_t *bkg_buf = NULL; /*background buffer */
+ H5D_storage_t store; /*union of EFL and chunk pointer in file space */
+ hsize_t h; /* Local index variable */
+#ifdef H5_HAVE_PARALLEL
+ hbool_t xfer_mode_changed; /* Whether the transfer mode was changed */
+#endif /*H5_HAVE_PARALLEL*/
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOINIT(H5D_chunk_read);
+
+ /* Initialize fm_map*/
+ HDmemset(&fm_struct, 0, sizeof(fm_map));
+ fm_struct.layout = &(dataset->layout);
+
+ /* Map elements between file and memory for each chunk*/
+ H5D_chunk_mem_file_map(dataset, mem_type, file_space, mem_space, &fm_struct);
+
+ /*
+ * If there is no type conversion then read directly into the
+ * application's buffer. This saves at least one mem-to-mem copy.
+ */
+ if (H5T_IS_NOOP(tpath)) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ /* Sanity check dataset, then read it */
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 ||
+ dataset->layout.type==H5D_COMPACT);
+
+ /*loop through each chunk, read data*/
+ for(h=0; h<fm_struct.nchunks; h++) {
+ if(H5S_get_select_npoints(fm_struct.fspace[h]) > 0) {
+ /*pass in chunk's coordinates in a union. LAYOUT puts datatype size as an extra dimension,
+ * have to take it out.*/
+ store.chunk_coords = fm_struct.chunk_coords + h*dataset->layout.ndims;
+
+ status = (sconv->read)(dataset->ent.file, &(dataset->layout),
+ dc_plist, &store, H5T_get_size(dataset->type),
+ fm_struct.fspace[h], fm_struct.mspace[h], dxpl_id, buf/*out*/);
+
+ /* Check return value from optimized read */
+ if (status<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "optimized read failed");
+ } /* end if */
+ } /* end for */
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].read_timer), &timer);
+ sconv->stats[1].read_nbytes += nelmts * H5T_get_size(dataset->type);
+ sconv->stats[1].read_ncalls++;
+#endif
+
+ /* direct xfer accomplished successfully */
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+
+ /*
+ * This is the general case(type conversion).
+ */
+
+#ifdef H5_HAVE_PARALLEL
+ H5D_io_assist_mpio(dx_plist, doing_mpio, xfer_mode, &xfer_mode_changed);
+#endif /*H5_HAVE_PARALLEL*/
+
+ /* Compute element sizes and other parameters */
+ src_type_size = H5T_get_size(dataset->type);
+ dst_type_size = H5T_get_size(mem_type);
+ target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME);
+ request_nelmts = target_size / MAX(src_type_size, dst_type_size);
+
+ /* Sanity check elements in temporary buffer */
+ if (request_nelmts<=0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small");
+
+ /*
+ * Get a temporary buffer for type conversion unless the app has already
+ * supplied one through the xfer properties. Instead of allocating a
+ * buffer which is the exact size, we allocate the target size. The
+ * malloc() is usually less resource-intensive if we allocate/free the
+ * same size over and over.
+ */
+ if (tpath->cdata.need_bkg) {
+ /* Retrieve the bkgr buffer property */
+ if(H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &need_bkg)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
+ need_bkg = MAX(tpath->cdata.need_bkg, need_bkg);
+ } else {
+ need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
+ } /* end else */
+ if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
+ /* Allocate temporary buffer */
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+ if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
+ /* Allocate background buffer */
+ H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
+ if((bkg_buf=H5FL_BLK_MALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
+ } /* end if */
+
+ /* Loop over all the chunks, performing I/O on each */
+ for(h=0; h<fm_struct.nchunks; h++) {
+ hsize_t chunk_nelmts; /* Number of elements selected in current chunk */
+
+ /* Get the number of elements selected in this chunk */
+ chunk_nelmts=H5S_get_select_npoints(fm_struct.fspace[h]);
+ assert(chunk_nelmts<=nelmts);
+ if(chunk_nelmts > 0) {
+ /* initialize selection iterator */
+ if (H5S_select_iter_init(&file_iter, fm_struct.fspace[h], src_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&mem_iter, fm_struct.mspace[h], dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&bkg_iter, fm_struct.mspace[h], dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
+
+ /*pass in chunk's coordinates in a union*/
+ store.chunk_coords = fm_struct.chunk_coords + h*dataset->layout.ndims;
+
+ for (smine_start=0; smine_start<chunk_nelmts; smine_start+=smine_nelmts) {
+ /* Go figure out how many elements to read from the file */
+ assert(H5S_select_iter_nelmts(&file_iter)==(chunk_nelmts-smine_start));
+ smine_nelmts = MIN(request_nelmts, (chunk_nelmts-smine_start));
+
+ /*
+ * Gather the data from disk into the data type conversion
+ * buffer. Also gather data from application to background buffer
+ * if necessary.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ /* Sanity check that space is allocated, then read data from it */
+ assert(dataset->layout.addr!=HADDR_UNDEF || dataset->efl.nused>0 ||
+ dataset->layout.type==H5D_COMPACT);
+ n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
+ dc_plist, &store, src_type_size, fm_struct.fspace[h],
+ &file_iter, smine_nelmts, dxpl_id, tconv_buf/*out*/);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].gath_timer), &timer);
+ sconv->stats[1].gath_nbytes += n * src_type_size;
+ sconv->stats[1].gath_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
+
+ if (need_bkg) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ n = H5S_select_mgath(buf, dst_type_size, fm_struct.mspace[h], &bkg_iter,
+ smine_nelmts, dxpl_id, bkg_buf/*out*/);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].bkg_timer), &timer);
+ sconv->stats[1].bkg_nbytes += n * dst_type_size;
+ sconv->stats[1].bkg_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "mem gather failed");
+ } /* end if */
+
+ /*
+ * Perform data type conversion.
+ */
+ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0,
+ tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ /*
+ * Scatter the data into memory.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ status = H5S_select_mscat(tconv_buf, dst_type_size, fm_struct.mspace[h],
+ &mem_iter, smine_nelmts, dxpl_id, buf/*out*/);
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].scat_timer), &timer);
+ sconv->stats[1].scat_nbytes += smine_nelmts * dst_type_size;
+ sconv->stats[1].scat_ncalls++;
+#endif
+ if (status<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "scatter failed");
+ } /* end for */
+
+ /* Release selection iterators */
+ if(file_iter_init) {
+ H5S_select_iter_release(&file_iter);
+ file_iter_init=0;
+ } /* end if */
+ if(mem_iter_init) {
+ H5S_select_iter_release(&mem_iter);
+ mem_iter_init=0;
+ } /* end if */
+ if(bkg_iter_init) {
+ H5S_select_iter_release(&bkg_iter);
+ bkg_iter_init=0;
+ } /* end if */
+ } /* end if */
+
+ /*close file space and memory space for each chunk*/
+ /*H5S_close(fm_struct.mspace[h]);
+ H5S_close(fm_struct.fspace[h]);*/
+ } /* end for */
+
+done:
+#ifdef H5_HAVE_PARALLEL
+ /* restore xfer_mode due to the kludge */
+ if (doing_mpio && xfer_mode_changed) {
+#ifdef H5D_DEBUG
+ if (H5DEBUG(D))
+ fprintf (H5DEBUG(D), "H5D: dx->xfer_mode was COLLECTIVE, restored to INDEPENDENT\n");
+#endif
+ xfer_mode = H5FD_MPIO_COLLECTIVE;
+ if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
+ } /* end if */
+#endif /*H5_HAVE_PARALLEL*/
+
+ assert(dx_plist);
+ if (tconv_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,tconv_buf);
+ if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,bkg_buf);
+
+ /* Release selection iterators, if necessary */
+ if(file_iter_init)
+ H5S_select_iter_release(&file_iter);
+ if(mem_iter_init)
+ H5S_select_iter_release(&mem_iter);
+ if(bkg_iter_init)
+ H5S_select_iter_release(&bkg_iter);
+
+ /* Close file space and memory space for each chunk*/
+ for(h=0; h<fm_struct.nchunks; h++) {
+ if(fm_struct.mspace[h])
+ H5S_close(fm_struct.mspace[h]);
+ if(fm_struct.fspace[h])
+ H5S_close(fm_struct.fspace[h]);
+ }
+ if(fm_struct.fspace)
+ H5MM_free(fm_struct.fspace);
+ if(fm_struct.mspace)
+ H5MM_free(fm_struct.mspace);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5D_chunk_read() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_write
+ *
+ * Purpose: Writes to a chunked dataset.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_write(hsize_t nelmts, H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
+ const H5S_t *file_space, H5T_path_t *tpath, H5S_conv_t *sconv, H5P_genplist_t *dc_plist,
+ H5P_genplist_t *dx_plist, hid_t dxpl_id, hbool_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ doing_mpio, H5FD_mpio_xfer_t
+#ifndef H5_HAVE_PARALLEL
+ UNUSED
+#endif /*H5_HAVE_PARALLEL*/
+ xfer_mode, hid_t src_id, hid_t dst_id, const void *buf)
+{
+ fm_map fm_struct;
+ herr_t status; /*function return status*/
+#ifdef H5S_DEBUG
+ H5_timer_t timer;
+#endif
+ size_t src_type_size; /*size of source type */
+ size_t dst_type_size; /*size of destination type*/
+ size_t target_size; /*desired buffer size */
+ hsize_t request_nelmts; /*requested strip mine */
+ hsize_t smine_start; /*strip mine start loc */
+ hsize_t n, smine_nelmts; /*elements per strip */
+ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/
+ hbool_t mem_iter_init=0; /*memory selection iteration info has been initialized */
+ H5S_sel_iter_t bkg_iter; /*background iteration info*/
+ hbool_t bkg_iter_init=0; /*background iteration info has been initialized */
+ H5S_sel_iter_t file_iter; /*file selection iteration info*/
+ hbool_t file_iter_init=0; /*file selection iteration info has been initialized */
+ H5T_bkg_t need_bkg; /*type of background buf*/
+ uint8_t *tconv_buf = NULL; /*data type conv buffer */
+ uint8_t *bkg_buf = NULL; /*background buffer */
+ H5D_storage_t store; /*union of EFL and chunk pointer in file space */
+ hsize_t h; /* Local index variable */
+#ifdef H5_HAVE_PARALLEL
+ hbool_t xfer_mode_changed; /* Whether the transfer mode was changed */
+#endif /*H5_HAVE_PARALLEL*/
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOINIT(H5D_chunk_write);
+
+ /* Initialize fm_map*/
+ HDmemset(&fm_struct, 0, sizeof(fm_map));
+ fm_struct.layout = &(dataset->layout);
+
+ /* Map elements between file and memory for each chunk*/
+ H5D_chunk_mem_file_map(dataset, mem_type, file_space, mem_space, &fm_struct);
+
+ /*
+ * If there is no type conversion then write directly from the
+ * application's buffer. This saves at least one mem-to-mem copy.
+ */
+ if (H5T_IS_NOOP(tpath)) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ /*loop through each chunk, write data*/
+ for(h=0; h<fm_struct.nchunks; h++) {
+ if(H5S_get_select_npoints(fm_struct.fspace[h]) > 0) {
+ /*pass in chunk's coordinates in a union. LAYOUT puts datatype size as an extra dimension,
+ * have to take it out.*/
+ store.chunk_coords = fm_struct.chunk_coords + h*dataset->layout.ndims;
+
+ status = (sconv->write)(dataset->ent.file, &(dataset->layout),
+ dc_plist, &store, H5T_get_size(dataset->type),
+ fm_struct.fspace[h], fm_struct.mspace[h], dxpl_id, buf);
+
+ /* Check return value from optimized write */
+ if (status<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "optimized write failed");
+ }
+ }
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].write_timer), &timer);
+ sconv->stats[0].write_nbytes += nelmts * H5T_get_size(mem_type);
+ sconv->stats[0].write_ncalls++;
+#endif
+
+ /* direct xfer accomplished successfully */
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+
+ /*
+ * This is the general case(type conversion).
+ */
+
+#ifdef H5_HAVE_PARALLEL
+ H5D_io_assist_mpio(dx_plist, doing_mpio, xfer_mode, &xfer_mode_changed);
+#endif /*H5_HAVE_PARALLEL*/
+
+ /* Compute element sizes and other parameters */
+ src_type_size = H5T_get_size(mem_type);
+ dst_type_size = H5T_get_size(dataset->type);
+ target_size = H5P_peek_size_t(dx_plist,H5D_XFER_MAX_TEMP_BUF_NAME);
+ request_nelmts = target_size / MAX (src_type_size, dst_type_size);
+
+ /* Sanity check elements in temporary buffer */
+ if (request_nelmts<=0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "temporary buffer max size is too small");
+
+ /*
+ * Get a temporary buffer for type conversion unless the app has already
+ * supplied one through the xfer properties. Instead of allocating a
+ * buffer which is the exact size, we allocate the target size. The
+ * malloc() is usually less resource-intensive if we allocate/free the
+ * same size over and over.
+ */
+ if (tpath->cdata.need_bkg) {
+ /* Retrieve the bkgr buffer property */
+ if(H5P_get(dx_plist, H5D_XFER_BKGR_BUF_TYPE_NAME, &need_bkg)<0)
+ HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve background buffer type");
+ need_bkg = MAX (tpath->cdata.need_bkg, need_bkg);
+ } else if(H5T_detect_class(dataset->type, H5T_VLEN)) {
+ /* Old data is retrieved into background buffer for VL datatype. The
+ * data is used later for freeing heap objects. */
+ need_bkg = H5T_BKG_YES;
+ } else {
+ need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/
+ } /* end else */
+ if (NULL==(tconv_buf=H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))) {
+ /* Allocate temporary buffer */
+ if((tconv_buf=H5FL_BLK_MALLOC(type_conv,target_size))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
+ if (need_bkg && NULL==(bkg_buf=H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))) {
+ /* Allocate background buffer */
+ H5_CHECK_OVERFLOW((request_nelmts*dst_type_size),hsize_t,size_t);
+ if((bkg_buf=H5FL_BLK_CALLOC(type_conv,(size_t)(request_nelmts*dst_type_size)))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for background conversion");
+ } /* end if */
+
+ /* Loop over all the chunks, performing I/O on each */
+ for(h=0; h<fm_struct.nchunks; h++) {
+ hsize_t chunk_nelmts; /* Number of elements selected in current chunk */
+
+ /* Get the number of elements selected in this chunk */
+ chunk_nelmts=H5S_get_select_npoints(fm_struct.fspace[h]);
+ assert(chunk_nelmts<=nelmts);
+ if(chunk_nelmts > 0) {
+
+ /* initialize selection iterator */
+ if (H5S_select_iter_init(&file_iter, fm_struct.fspace[h], dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file selection information");
+ file_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&mem_iter, fm_struct.mspace[h], src_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize memory selection information");
+ mem_iter_init=1; /*file selection iteration info has been initialized */
+ if (H5S_select_iter_init(&bkg_iter, fm_struct.fspace[h], dst_type_size)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize background selection information");
+ bkg_iter_init=1; /*file selection iteration info has been initialized */
+
+ /*pass in chunk's coordinates in a union*/
+ store.chunk_coords = fm_struct.chunk_coords + h*dataset->layout.ndims;
+
+ for (smine_start=0; smine_start<chunk_nelmts; smine_start+=smine_nelmts) {
+ /* Go figure out how many elements to read from the file */
+ assert(H5S_select_iter_nelmts(&file_iter)==(chunk_nelmts-smine_start));
+ smine_nelmts = MIN(request_nelmts, (chunk_nelmts-smine_start));
+
+ /*
+ * Gather the data from disk into the data type conversion
+ * buffer. Also gather data from application to background buffer
+ * if necessary.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ n = H5S_select_mgath(buf, src_type_size, fm_struct.mspace[h], &mem_iter,
+ smine_nelmts, dxpl_id, tconv_buf/*out*/);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[1].gath_timer), &timer);
+ sconv->stats[1].gath_nbytes += n * src_type_size;
+ sconv->stats[1].gath_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file gather failed");
+
+ if (need_bkg) {
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ n = H5S_select_fgath(dataset->ent.file, &(dataset->layout),
+ dc_plist, &store, dst_type_size, fm_struct.fspace[h],
+ &bkg_iter, smine_nelmts, dxpl_id, bkg_buf/*out*/);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].bkg_timer), &timer);
+ sconv->stats[0].bkg_nbytes += n * dst_type_size;
+ sconv->stats[0].bkg_ncalls++;
+#endif
+ if (n!=smine_nelmts)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "file gather failed");
+ } /* end if */
+
+ /*
+ * Perform data type conversion.
+ */
+ if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, 0, 0,
+ tconv_buf, bkg_buf, dxpl_id)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed");
+
+ /*
+ * Scatter the data out to the file.
+ */
+#ifdef H5S_DEBUG
+ H5_timer_begin(&timer);
+#endif
+ status = H5S_select_fscat(dataset->ent.file, &(dataset->layout),
+ dc_plist, &store, dst_type_size, fm_struct.fspace[h],
+ &file_iter, smine_nelmts, dxpl_id, tconv_buf);
+
+#ifdef H5S_DEBUG
+ H5_timer_end(&(sconv->stats[0].scat_timer), &timer);
+ sconv->stats[0].scat_nbytes += n * dst_type_size;
+ sconv->stats[0].scat_ncalls++;
+#endif
+ if (status<0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "scatter failed");
+ } /* end for */
+
+ /* Release selection iterators */
+ if(file_iter_init) {
+ H5S_select_iter_release(&file_iter);
+ file_iter_init=0;
+ } /* end if */
+ if(mem_iter_init) {
+ H5S_select_iter_release(&mem_iter);
+ mem_iter_init=0;
+ } /* end if */
+ if(bkg_iter_init) {
+ H5S_select_iter_release(&bkg_iter);
+ bkg_iter_init=0;
+ } /* end if */
+ } /* end if */
+
+ /*close file space and memory space for each chunk*/
+ /*H5S_close(fm_struct.mspace[h]);
+ H5S_close(fm_struct.fspace[h]);*/
+ } /* end for */
+
+done:
+#ifdef H5_HAVE_PARALLEL
+ /* restore xfer_mode due to the kludge */
+ if (doing_mpio && xfer_mode_changed) {
+#ifdef H5D_DEBUG
+ if (H5DEBUG(D))
+ fprintf (H5DEBUG(D), "H5D: dx->xfer_mode was COLLECTIVE, restored to INDEPENDENT\n");
+#endif
+ xfer_mode = H5FD_MPIO_COLLECTIVE;
+ if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
+ } /* end if */
+#endif /*H5_HAVE_PARALLEL*/
+
+ assert(dx_plist);
+ if (tconv_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_TCONV_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,tconv_buf);
+ if (bkg_buf && NULL==H5P_peek_voidp(dx_plist,H5D_XFER_BKGR_BUF_NAME))
+ H5FL_BLK_FREE(type_conv,bkg_buf);
+
+ /* Release selection iterators, if necessary */
+ if(file_iter_init)
+ H5S_select_iter_release(&file_iter);
+ if(mem_iter_init)
+ H5S_select_iter_release(&mem_iter);
+ if(bkg_iter_init)
+ H5S_select_iter_release(&bkg_iter);
+
+ /* Close file space and memory space for each chunk*/
+ for(h=0; h<fm_struct.nchunks; h++) {
+ if(fm_struct.mspace[h])
+ H5S_close(fm_struct.mspace[h]);
+ if(fm_struct.fspace[h])
+ H5S_close(fm_struct.fspace[h]);
+ }
+ if(fm_struct.fspace)
+ H5MM_free(fm_struct.fspace);
+ if(fm_struct.mspace)
+ H5MM_free(fm_struct.mspace);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5D_chunk_write() */
+
+#ifdef H5_HAVE_PARALLEL
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_io_assist_mpio
+ *
+ * Purpose: Common logic for determining if the MPI transfer mode should
+ * be changed.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_io_assist_mpio(H5P_genplist_t *dx_plist, hbool_t doing_mpio, H5FD_mpio_xfer_t xfer_mode,
+ hbool_t *xfer_mode_changed)
+{
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOINIT(H5D_io_assist_mpio);
+
+ /* The following may not handle a collective call correctly
+ * since it does not ensure all processes can handle the write
+ * request according to the MPI collective specification.
+ * Do the collective request via independent mode.
+ */
+ if (doing_mpio && xfer_mode==H5FD_MPIO_COLLECTIVE) {
+ /* Kludge: change the xfer_mode to independent, handle the request,
+ * then xfer_mode before return.
+ * Better way is to get a temporary data_xfer property with
+ * INDEPENDENT xfer_mode and pass it downwards.
+ */
+ xfer_mode = H5FD_MPIO_INDEPENDENT;
+ if(H5P_set (dx_plist, H5D_XFER_IO_XFER_MODE_NAME, &xfer_mode) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set transfer mode");
+ *xfer_mode_changed=TRUE; /* restore it before return */
+#ifdef H5D_DEBUG
+ if (H5DEBUG(D))
+ fprintf(H5DEBUG(D), "H5D: Cannot handle this COLLECTIVE write request. Do it via INDEPENDENT calls\n");
+#endif
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+}
+#endif /*H5_HAVE_PARALLEL*/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_coords_assist
+ *
+ * Purpose: Compute the coords for a particular chunk (in CHUNK_PTR),
+ * based on the size of the dataset's dataspace (given in
+ * NDIMS and CHUNKS), putting the resulting chunk's coordinate
+ * offsets in the COORDS array.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_coords_assist(hssize_t *coords, size_t ndims, hsize_t chunks[], hsize_t chunk_ptr)
+{
+ hsize_t tmp; /* Size of "down elements" in each dimension */
+ size_t i, j; /* Local index variables */
+
+ FUNC_ENTER_NOINIT(H5D_chunk_coords_assist);
+
+ for(i=0; i<ndims; i++) {
+ tmp=1;
+ for(j=i+1; j<ndims; j++)
+ tmp *= chunks[j];
+ coords[i] = (hssize_t)(chunk_ptr / tmp);
+ chunk_ptr = chunk_ptr % tmp;
+ }
+ coords[ndims] = 0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_mem_file_map
+ *
+ * Purpose: Creates the mapping between elements selected in each chunk
+ * and the elements in the memory selection.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_mem_file_map(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *file_space,
+ const H5S_t *mem_space, fm_map *fm)
+{
+ H5S_t *tmp_fspace=NULL, /* Temporary file dataspace */
+ *tmp_mspace=NULL; /* Temporary memory dataspace */
+ hid_t f_tid=(-1); /* Temporary copy of file datatype for iteration */
+ size_t elmt_size; /* Memory datatype size */
+ hbool_t iter_init=0; /* Selection iteration info has been initialized */
+ unsigned f_ndims; /* The number of dimensions of the file's dataspace */
+ int sm_ndims; /* The number of dimensions of the memory buffer's dataspace (signed) */
+ unsigned m_ndims; /* The number of dimensions of the memory buffer's dataspace */
+ hsize_t f_dims[H5O_LAYOUT_NDIMS]; /* Dimensionality of file dataspace */
+ char bogus; /* "bogus" buffer to pass to selection iterator */
+ unsigned u; /* Local index variable */
+ hsize_t j; /* Local index variable */
+ herr_t ret_value = SUCCEED; /*return value */
+
+ FUNC_ENTER_NOINIT(H5D_chunk_mem_file_map);
+
+ /* Create a file space of a chunk's size, instead of whole file space*/
+ if(NULL==(tmp_fspace=H5S_create_simple((dataset->layout.ndims-1),dataset->layout.dim,NULL)))
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
+
+ /*make a copy of mem_space*/
+ if((tmp_mspace = H5S_copy(mem_space))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space");
+
+ /*de-select the file space and mem space copies*/
+ if(H5S_select_none(tmp_fspace)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select file space");
+ if(H5S_select_none(tmp_mspace)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to de-select memory space");
+
+ /* Get dim number and dimensionality for each dataspace */
+ f_ndims=dataset->layout.ndims-1;
+ if((sm_ndims = H5S_get_simple_extent_ndims(tmp_mspace))<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimension number");
+ fm->m_ndims=m_ndims=sm_ndims;
+
+ if(H5S_get_simple_extent_dims(file_space, f_dims, NULL)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality");
+
+ /* Decide the number of chunks in each dimension*/
+ fm->nchunks = 1;
+ for(u=0; u<f_ndims; u++) {
+ fm->chunks[u] = ((f_dims[u]+dataset->layout.dim[u])-1) / dataset->layout.dim[u];
+ fm->nchunks *= fm->chunks[u];
+ }
+
+ /* Compute the "down" size of 'chunks' information */
+ if(H5V_array_down(f_ndims,fm->chunks,fm->down_chunks)<0)
+ HGOTO_ERROR (H5E_INTERNAL, H5E_BADVALUE, FAIL, "can't compute 'down' sizes");
+
+ /* Allocate arrays to hold each chunk's dataspace & selection, for both the
+ * file and memory */
+ H5_CHECK_OVERFLOW((sizeof(H5S_t*)*fm->nchunks),hsize_t,size_t);
+ fm->fspace = (H5S_t**)H5MM_malloc((size_t)(sizeof(H5S_t*)*fm->nchunks));
+ fm->mspace = (H5S_t**)H5MM_malloc((size_t)(sizeof(H5S_t*)*fm->nchunks));
+ fm->elmt_count = 0;
+
+ /* Allocate array to hold coordinates of each chunk in file's dataspace */
+ H5_CHECK_OVERFLOW((sizeof(hsize_t)*fm->nchunks*(f_ndims+1)),hsize_t,size_t);
+ fm->chunk_coords = (hssize_t*)H5MM_malloc((size_t)(sizeof(hsize_t)*fm->nchunks*(f_ndims+1)));
+
+ /* Make per-chunk copies of memory and chunk dataspaces
+ * (with each one's selection set to "none"
+ */
+ for(j=0; j<fm->nchunks; j++) {
+ if((fm->mspace[j] = H5S_copy(tmp_mspace))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space");
+ if((fm->fspace[j] = H5S_copy(tmp_fspace))==NULL)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy file space");
+
+ /* Initialize chunk_coords for each chunk. each stride is the number of
+ * file space dimensions, with fast-growing dimension at the last
+ */
+ H5D_chunk_coords_assist(fm->chunk_coords+j*(f_ndims+1), f_ndims, fm->chunks, j);
+ }
+
+ /* Create temporary datatypes for selection iteration */
+ if((f_tid = H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0)
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register file datatype");
+
+ /* Create selection iterator for memory selection */
+ if((elmt_size=H5T_get_size(mem_type))==0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid");
+ if (H5S_select_iter_init(&(fm->mem_iter), mem_space, elmt_size)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ iter_init=1; /* Selection iteration info has been initialized */
+
+ /* Build the file & memory selection for each chunk */
+ if(H5S_select_iterate(&bogus, f_tid, file_space, H5D_chunk_cb, fm)<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to iterate file space");
+
+ /* Clean hyperslab span "scratch" information */
+ for(j=0; j<fm->nchunks; j++) {
+ if(H5S_hyper_reset_scratch(fm->fspace[j])<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info");
+ if(H5S_hyper_reset_scratch(fm->mspace[j])<0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTFREE, FAIL, "unable to reset span scratch info");
+ } /* end for */
+
+done:
+ if(iter_init) {
+ if (H5S_select_iter_release(&(fm->mem_iter))<0)
+ HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
+ }
+ if(tmp_fspace)
+ H5S_close(tmp_fspace);
+ if(tmp_mspace)
+ H5S_close(tmp_mspace);
+ if(f_tid!=(-1))
+ H5Tclose(f_tid);
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_chunk_mem_file_map() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_chunk_cb
+ *
+ * Purpose: Callback routine for file selection iterator. Used when
+ * creating selections in memory and each chunk for each chunk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Raymond Lu
+ * Thursday, April 10, 2003
+ *
+ * Modifications:
+ * QAK - 2003/04/17
+ * Hacked on it a lot. :-)
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_chunk_cb(void UNUSED *elem, hid_t UNUSED type_id, hsize_t ndims, hssize_t *coords, void *_fm)
+{
+ fm_map *fm = (fm_map*)_fm; /* File<->memory chunk mapping info */
+ hssize_t coords_in_chunk[H5O_LAYOUT_NDIMS]; /* Coordinates of element in chunk */
+ hssize_t coords_in_mem[H5O_LAYOUT_NDIMS]; /* Coordinates of element in memory */
+ hsize_t chunk_idx; /* Chunk index */
+ hsize_t u; /* Local index variables */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5D_chunk_cb);
+#ifdef QAK
+{
+ unsigned u;
+ HDfprintf(stderr,"%s: coords={",FUNC);
+ for(u=0; u<ndims; u++)
+ HDfprintf(stderr,"%Hd%s",coords[u],(u<(ndims-1)?", ":"}\n"));
+}
+#endif /* QAK */
+
+ /* Calculate the index of this chunk */
+ if(H5V_chunk_index((unsigned)ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_idx)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index");
+#ifdef QAK
+HDfprintf(stderr,"%s: chunk_idx=%Hu\n",FUNC,chunk_idx);
+#endif /* QAK */
+
+ /*convert coords from relative to whole file space to relative to its chunk space,
+ *pass into H5S_select_hyperslab.*/
+ for(u=0; u<ndims; u++)
+ coords_in_chunk[u] = coords[u] % fm->layout->dim[u];
+
+#ifdef QAK
+{
+ unsigned u;
+ HDfprintf(stderr,"%s: coords_in_chunk={",FUNC);
+ for(u=0; u<ndims; u++)
+ HDfprintf(stderr,"%Hd%s",coords_in_chunk[u],(u<(ndims-1)?", ":"}\n"));
+}
+#endif /* QAK */
+ /* Add point to file selection for chunk */
+ if(H5S_hyper_add_span_element(fm->fspace[chunk_idx], (unsigned)ndims, coords_in_chunk)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element");
+
+ /* Get coordinates of selection iterator for memory */
+ if(H5S_select_iter_coords(&fm->mem_iter,coords_in_mem)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator coordinates");
+
+#ifdef QAK
+{
+ unsigned u;
+ HDfprintf(stderr,"%s: coords_in_mem={",FUNC);
+ for(u=0; u<fm->m_ndims; u++)
+ HDfprintf(stderr,"%Hd%s",coords_in_mem[u],(u<(fm->m_ndims-1)?", ":"}\n"));
+}
+#endif /* QAK */
+ /* Add point to memory selection for chunk */
+ if(H5S_hyper_add_span_element(fm->mspace[chunk_idx], fm->m_ndims, coords_in_mem)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSELECT, FAIL, "unable to select element");
+
+ /* Move memory selection iterator to next element in selection */
+ if(H5S_select_iter_next(&fm->mem_iter,1)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to move to next iterator location");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5D_chunk_cb() */
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 7f8d7e1..9629963 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -1685,246 +1685,154 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/*-------------------------------------------------------------------------
- * Function: H5F_istore_read
+ * Function: H5F_istore_readvv
*
* Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
* storage array.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Wednesday, October 15, 1997
+ * Programmer: Quincey Koziol
+ * Wednesday, May 7, 2003
*
* Modifications:
- * Robb Matzke, 1999-08-02
- * The data transfer property list is passed as an object ID
- * since that's how the virtual file layer wants it.
*
- * Quincey Koziol, 2002-04-02
- * Enable hyperslab I/O into memory buffer
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const hsize_t size_m[], const hssize_t offset_m[],
- const hssize_t offset_f[], const hsize_t size[], void *buf)
+ssize_t
+H5F_istore_readvv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+ H5P_genplist_t *dc_plist, hssize_t chunk_coords[],
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf)
{
- hsize_t idx_cur[H5O_LAYOUT_NDIMS];
- hsize_t idx_min[H5O_LAYOUT_NDIMS];
- hsize_t idx_max[H5O_LAYOUT_NDIMS];
- hsize_t sub_size[H5O_LAYOUT_NDIMS];
- hssize_t offset_wrt_chunk[H5O_LAYOUT_NDIMS];
- hssize_t sub_offset_m[H5O_LAYOUT_NDIMS];
- hssize_t chunk_offset[H5O_LAYOUT_NDIMS];
- int i, carry;
- unsigned u;
- hsize_t naccessed; /*bytes accessed in chnk*/
- uint8_t *chunk=NULL; /*ptr to a chunk buffer */
- unsigned idx_hint=0; /*cache index hint */
- hsize_t chunk_size; /* Bytes in chunk */
+ hsize_t chunk_size; /* Chunk size, in bytes */
haddr_t chunk_addr; /* Chunk address on disk */
+ hssize_t chunk_coords_in_elmts[H5O_LAYOUT_NDIMS];
H5O_pline_t pline; /* I/O pipeline information */
- H5O_fill_t fill; /* Fill value information */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_istore_read, FAIL);
+ size_t u; /* Local index variables */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_istore_readvv, FAIL);
/* Check args */
assert(f);
assert(layout && H5D_CHUNKED==layout->type);
assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS);
- assert(H5F_addr_defined(layout->addr));
- assert(size_m);
- assert(offset_m);
- assert(offset_f);
- assert(size);
+ assert(chunk_len_arr);
+ assert(chunk_offset_arr);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
assert(buf);
/* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline");
/* Compute chunk size */
for (u=0, chunk_size=1; u<layout->ndims; u++)
chunk_size *= layout->dim[u];
-
+
#ifndef NDEBUG
- for (u=0; u<layout->ndims; u++) {
- assert(offset_f[u]>=0); /*negative offsets not supported*/
- assert(offset_m[u]>=0); /*negative offsets not supported*/
- assert(size[u]<SIZET_MAX);
- assert(offset_m[u]+(hssize_t)size[u]<=(hssize_t)size_m[u]);
- assert(layout->dim[u]>0);
- }
+ for (u=0; u<layout->ndims; u++)
+ assert(chunk_coords[u]>=0); /*negative coordinates not supported (yet) */
#endif
+
+ for (u=0; u<layout->ndims; u++)
+ chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
+
+ /* Get the address of this chunk on disk */
+ chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
/*
- * Set up multi-dimensional counters (idx_min, idx_max, and idx_cur) and
- * loop through the chunks copying each to its final destination in the
- * application buffer.
+ * If the chunk is too large to load into the cache and it has no
+ * filters in the pipeline (i.e. not compressed) and if the address
+ * for the chunk has been defined, then don't load the chunk into the
+ * cache, just write the data to it directly.
*/
- for (u=0; u<layout->ndims; u++) {
- idx_min[u] = offset_f[u] / layout->dim[u];
- idx_max[u] = (offset_f[u]+size[u]-1) / layout->dim[u] + 1;
- idx_cur[u] = idx_min[u];
- }
-
- /* Loop over all chunks */
- carry=0;
- while (carry==0) {
- for (u=0, naccessed=1; u<layout->ndims; u++) {
- /* The location and size of the chunk being accessed */
- assert(layout->dim[u] < HSSIZET_MAX);
- chunk_offset[u] = idx_cur[u] * (hssize_t)(layout->dim[u]);
-
- /* The offset and size wrt the chunk */
- offset_wrt_chunk[u] = MAX(offset_f[u], chunk_offset[u]) -
- chunk_offset[u];
- sub_size[u] = MIN((idx_cur[u]+1)*layout->dim[u],
- offset_f[u]+size[u]) -
- (chunk_offset[u] + offset_wrt_chunk[u]);
- naccessed *= sub_size[u];
-
- /* Offset into mem buffer */
- sub_offset_m[u] = chunk_offset[u] + offset_wrt_chunk[u] +
- offset_m[u] - offset_f[u];
- }
+ if (chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
+ chunk_addr!=HADDR_UNDEF) {
+ if ((ret_value=H5F_contig_readvv(f, chunk_size, chunk_addr, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, dxpl_id, buf))<0)
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data to file");
+ } /* end if */
+ else {
+ uint8_t *chunk; /* Pointer to cached chunk in memory */
+ H5O_fill_t fill; /* Fill value information */
+ unsigned idx_hint=0; /* Cache index hint */
+ ssize_t naccessed; /* Number of bytes accessed in chunk */
- /* Get the address of this chunk on disk */
- chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_offset);
+ /* Get necessary properties from property list */
+ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
/*
- * If the chunk is too large to load into the cache and it has no
- * filters in the pipeline (i.e. not compressed) and if the address
- * for the chunk has been defined, then don't load the chunk into the
- * cache, just read the data from it directly.
+ * Lock the chunk, copy from application to chunk, then unlock the
+ * chunk.
*/
- if ((chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
- chunk_addr!=HADDR_UNDEF)
+ if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
+ chunk_coords_in_elmts, FALSE, &idx_hint)))
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk");
- /*
- * If MPIO, MPIPOSIX, or FPHDF5 is used and file can be written
- * to, we must bypass the chunk-cache scheme because other MPI
- * processes could be writing to other elements in the same
- * chunk. Do a direct write-through of only the elements
- * requested.
- */
- || ((IS_H5FD_MPIO(f) ||IS_H5FD_MPIPOSIX(f) || IS_H5FD_FPHDF5(f)) && (H5F_ACC_RDWR & f->shared->flags))
- ) {
- H5O_layout_t l; /* temporary layout */
+ /* Use the vectorized memory copy routine to do actual work */
+ if((naccessed=H5V_memcpyvv(buf,mem_max_nseq,mem_curr_seq,mem_len_arr,mem_offset_arr,chunk,chunk_max_nseq,chunk_curr_seq,chunk_len_arr,chunk_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vectorized memcpy failed");
-#ifdef H5_HAVE_PARALLEL
- /* Additional sanity checks when operating in parallel */
- if (chunk_addr==HADDR_UNDEF || pline.nfilters>0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
-#endif /* H5_HAVE_PARALLEL */
-
- /*
- * use default transfer mode as we do not support collective
- * transfer mode since each data write could decompose into
- * multiple chunk writes and we are not doing the calculation yet.
- */
- l.type = H5D_CONTIGUOUS;
- l.ndims = layout->ndims;
- for (u=l.ndims; u-- > 0; /*void*/)
- l.dim[u] = layout->dim[u];
- l.addr = chunk_addr;
- if (H5F_arr_read(f, dxpl_id, &l, dc_plist, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0)
- HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data from file");
- } /* end if */
- else {
- /*
- * Lock the chunk, transfer data to the application, then unlock
- * the chunk.
- */
- if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
- chunk_offset, FALSE, &idx_hint)))
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk");
- H5V_hyper_copy(layout->ndims, sub_size, size_m, sub_offset_m,
- (void*)buf, layout->dim, offset_wrt_chunk, chunk);
- H5_CHECK_OVERFLOW(naccessed,hsize_t,size_t);
- if (H5F_istore_unlock(f, dxpl_id, layout, &pline, FALSE,
- chunk_offset, &idx_hint, chunk, (size_t)naccessed)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk");
- } /* end else */
-
- /* Increment indices */
- for (i=(int)(layout->ndims-1), carry=1; i>=0 && carry; --i) {
- if (++idx_cur[i]>=idx_max[i])
- idx_cur[i] = idx_min[i];
- else
- carry = 0;
- }
- }
+ H5_CHECK_OVERFLOW(naccessed,ssize_t,size_t);
+ if (H5F_istore_unlock(f, dxpl_id, layout, &pline, FALSE,
+ chunk_coords_in_elmts, &idx_hint, chunk, (size_t)naccessed)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk");
+ /* Set return value */
+ ret_value=naccessed;
+ } /* end else */
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* H5F_istore_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_istore_write
+ * Function: H5F_istore_writevv
*
* Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
* storage array.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Wednesday, October 15, 1997
+ * Programmer: Quincey Koziol
+ * Friday, May 2, 2003
*
* Modifications:
- * Robb Matzke, 1999-08-02
- * The data transfer property list is passed as an object ID
- * since that's how the virtual file layer wants it.
*
- * Quincey Koziol, 2002-04-02
- * Enable hyperslab I/O into memory buffer
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const hsize_t size_m[], const hssize_t offset_m[],
- const hssize_t offset_f[], const hsize_t size[],
- const void *buf)
+ssize_t
+H5F_istore_writevv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+ H5P_genplist_t *dc_plist, hssize_t chunk_coords[],
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf)
{
- int i, carry;
- unsigned u;
- hsize_t idx_cur[H5O_LAYOUT_NDIMS];
- hsize_t idx_min[H5O_LAYOUT_NDIMS];
- hsize_t idx_max[H5O_LAYOUT_NDIMS];
- hsize_t sub_size[H5O_LAYOUT_NDIMS];
- hssize_t chunk_offset[H5O_LAYOUT_NDIMS];
- hssize_t offset_wrt_chunk[H5O_LAYOUT_NDIMS];
- hssize_t sub_offset_m[H5O_LAYOUT_NDIMS];
- uint8_t *chunk=NULL;
- unsigned idx_hint=0;
- hsize_t chunk_size, naccessed;
+ hsize_t chunk_size; /* Chunk size, in bytes */
haddr_t chunk_addr; /* Chunk address on disk */
+ hssize_t chunk_coords_in_elmts[H5O_LAYOUT_NDIMS];
H5O_pline_t pline; /* I/O pipeline information */
- H5O_fill_t fill; /* Fill value information */
- herr_t ret_value = SUCCEED; /* Return value */
+ size_t u; /* Local index variables */
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_istore_write, FAIL);
+ FUNC_ENTER_NOAPI(H5F_istore_writevv, FAIL);
/* Check args */
assert(f);
assert(layout && H5D_CHUNKED==layout->type);
assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS);
- assert(H5F_addr_defined(layout->addr));
- assert(size_m);
- assert(offset_m);
- assert(offset_f);
- assert(size);
+ assert(chunk_len_arr);
+ assert(chunk_offset_arr);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
assert(buf);
/* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline");
@@ -1933,118 +1841,79 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_size *= layout->dim[u];
#ifndef NDEBUG
- for (u=0; u<layout->ndims; u++) {
- assert(offset_f[u]>=0); /*negative offsets not supported*/
- assert(offset_m[u]>=0); /*negative offsets not supported*/
- assert(size[u]<SIZET_MAX);
- assert(offset_m[u]+(hssize_t)size[u]<=(hssize_t)size_m[u]);
- assert(layout->dim[u]>0);
- }
+ for (u=0; u<layout->ndims; u++)
+ assert(chunk_coords[u]>=0); /*negative coordinates not supported (yet) */
#endif
+
+ for (u=0; u<layout->ndims; u++)
+ chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
+
+ /* Get the address of this chunk on disk */
+ chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
/*
- * Set up multi-dimensional counters (idx_min, idx_max, and idx_cur) and
- * loop through the chunks copying each chunk from the application to the
- * chunk cache.
+ * If the chunk is too large to load into the cache and it has no
+ * filters in the pipeline (i.e. not compressed) and if the address
+ * for the chunk has been defined, then don't load the chunk into the
+ * cache, just write the data to it directly.
+ *
+ * If MPIO, MPIPOSIX, or FPHDF5 is used, must bypass the
+ * chunk-cache scheme because other MPI processes could be
+ * writing to other elements in the same chunk. Do a direct
+ * write-through of only the elements requested.
*/
- for (u=0; u<layout->ndims; u++) {
- idx_min[u] = offset_f[u] / layout->dim[u];
- idx_max[u] = (offset_f[u]+size[u]-1) / layout->dim[u] + 1;
- idx_cur[u] = idx_min[u];
- }
-
-
- /* Loop over all chunks */
- carry=0;
- while (carry==0) {
- for (u=0, naccessed=1; u<layout->ndims; u++) {
- /* The location and size of the chunk being accessed */
- assert(layout->dim[u] < HSSIZET_MAX);
- chunk_offset[u] = idx_cur[u] * (hssize_t)(layout->dim[u]);
-
- /* The offset and size wrt the chunk */
- offset_wrt_chunk[u] = MAX(offset_f[u], chunk_offset[u]) -
- chunk_offset[u];
- sub_size[u] = MIN((idx_cur[u]+1)*layout->dim[u],
- offset_f[u]+size[u]) -
- (chunk_offset[u] + offset_wrt_chunk[u]);
- naccessed *= sub_size[u];
-
- /* Offset into mem buffer */
- sub_offset_m[u] = chunk_offset[u] + offset_wrt_chunk[u] +
- offset_m[u] - offset_f[u];
- }
-
- /* Get the address of this chunk on disk */
- chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_offset);
+ if ((chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
+ chunk_addr!=HADDR_UNDEF)
+ || ((IS_H5FD_MPIO(f) ||IS_H5FD_MPIPOSIX(f) || IS_H5FD_FPHDF5(f)) &&
+ (H5F_ACC_RDWR & f->shared->flags))) {
+#ifdef H5_HAVE_PARALLEL
+ /* Additional sanity check when operating in parallel */
+ if (chunk_addr==HADDR_UNDEF || pline.nfilters>0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
+#endif /* H5_HAVE_PARALLEL */
+ if ((ret_value=H5F_contig_writevv(f, chunk_size, chunk_addr, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, dxpl_id, buf))<0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file");
+ } /* end if */
+ else {
+ uint8_t *chunk; /* Pointer to cached chunk in memory */
+ H5O_fill_t fill; /* Fill value information */
+ unsigned idx_hint=0; /* Cache index hint */
+ ssize_t naccessed; /* Number of bytes accessed in chunk */
+ hbool_t relax; /* Whether whole chunk is selected */
- /*
- * If the chunk is too large to load into the cache and it has no
- * filters in the pipeline (i.e. not compressed) and if the address
- * for the chunk has been defined, then don't load the chunk into the
- * cache, just write the data to it directly.
- */
- if ((chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
- chunk_addr!=HADDR_UNDEF)
+ /* Get necessary properties from property list */
+ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
/*
- * If MPIO, MPIPOSIX, or FPHDF5 is used, must bypass the
- * chunk-cache scheme because other MPI processes could be
- * writing to other elements in the same chunk. Do a direct
- * write-through of only the elements requested.
+ * Lock the chunk, copy from application to chunk, then unlock the
+ * chunk.
*/
- || ((IS_H5FD_MPIO(f) ||IS_H5FD_MPIPOSIX(f) || IS_H5FD_FPHDF5(f)) && (H5F_ACC_RDWR & f->shared->flags))
- ) {
- H5O_layout_t l; /* temporary layout */
-
-#ifdef H5_HAVE_PARALLEL
- /* Additional sanity check when operating in parallel */
- if (chunk_addr==HADDR_UNDEF || pline.nfilters>0) {
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
- }
-#endif /* H5_HAVE_PARALLEL */
-
- /*
- * use default transfer mode as we do not support collective
- * transfer mode since each data write could decompose into
- * multiple chunk writes and we are not doing the calculation yet.
- */
- l.type = H5D_CONTIGUOUS;
- l.ndims = layout->ndims;
- for (u=l.ndims; u-- > 0; /*void*/)
- l.dim[u] = layout->dim[u];
- l.addr = chunk_addr;
- if (H5F_arr_write(f, dxpl_id, &l, dc_plist, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file");
- } /* end if */
- else {
- /*
- * Lock the chunk, copy from application to chunk, then unlock the
- * chunk.
- */
- if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
- chunk_offset, (hbool_t)(naccessed==chunk_size), &idx_hint)))
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk");
- H5V_hyper_copy(layout->ndims, sub_size,
- layout->dim, offset_wrt_chunk, chunk, size_m, sub_offset_m, buf);
- H5_CHECK_OVERFLOW(naccessed,hsize_t,size_t);
- if (H5F_istore_unlock(f, dxpl_id, layout, &pline, TRUE,
- chunk_offset, &idx_hint, chunk, (size_t)naccessed)<0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk");
- } /* end else */
+ if(chunk_max_nseq==1 && chunk_len_arr[0] == chunk_size)
+ relax = TRUE;
+ else
+ relax = FALSE;
+
+ if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
+ chunk_coords_in_elmts, relax, &idx_hint)))
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk");
+
+ /* Use the vectorized memory copy routine to do actual work */
+ if((naccessed=H5V_memcpyvv(chunk,chunk_max_nseq,chunk_curr_seq,chunk_len_arr,chunk_offset_arr,buf,mem_max_nseq,mem_curr_seq,mem_len_arr,mem_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed");
+
+ H5_CHECK_OVERFLOW(naccessed,ssize_t,size_t);
+ if (H5F_istore_unlock(f, dxpl_id, layout, &pline, TRUE,
+ chunk_coords_in_elmts, &idx_hint, chunk, (size_t)naccessed)<0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk");
+
+ /* Set return value */
+ ret_value=naccessed;
+ } /* end else */
- /* Increment indices */
- for (i=layout->ndims-1, carry=1; i>=0 && carry; --i) {
- if (++idx_cur[i]>=idx_max[i])
- idx_cur[i] = idx_min[i];
- else
- carry = 0;
- }
- } /* end while */
-
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* H5F_istore_writevv() */
/*-------------------------------------------------------------------------
@@ -2808,7 +2677,8 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay
hsize_t size[H5O_LAYOUT_NDIMS]; /*current size of dimensions */
H5S_t *space_chunk = NULL; /*dataspace for a chunk */
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /*current dataspace dimensions */
- int rank; /*current # of dimensions */
+ int srank; /*current # of dimensions (signed) */
+ unsigned rank; /*current # of dimensions */
int i, carry; /*counters */
unsigned u;
int found = 0; /*initialize this entry */
@@ -2836,13 +2706,14 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay
HDmemset(count, 0, sizeof(count));
/* Go get the rank & dimensions */
- if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
+ if((srank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions");
+ rank=srank;
/* Copy current dimensions */
- for(i = 0; i < rank; i++)
- size[i] = curr_dims[i];
- size[i] = layout->dim[i];
+ for(u = 0; u < rank; u++)
+ size[u] = curr_dims[u];
+ size[u] = layout->dim[u];
/* Create a data space for a chunk & set the extent */
if(NULL == (space_chunk = H5S_create_simple(rank,layout->dim,NULL)))
@@ -2891,8 +2762,8 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay
if(H5S_select_all(space_chunk,1) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to select space");
- for(i = 0; i < rank; i++)
- count[i] = MIN((idx_cur[i] + 1) * layout->dim[i], size[i] - chunk_offset[i]);
+ for(u = 0; u < rank; u++)
+ count[u] = MIN((idx_cur[u] + 1) * layout->dim[u], size[u] - chunk_offset[u]);
#if defined (H5F_ISTORE_DEBUG)
HDfputs("cache:initialize:offset:[", stdout);
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
new file mode 100644
index 0000000..093360b
--- /dev/null
+++ b/src/H5Dpkg.h
@@ -0,0 +1,76 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Monday, April 14, 2003
+ *
+ * Purpose: This file contains declarations which are visible only within
+ * the H5D package. Source files outside the H5D package should
+ * include H5Dprivate.h instead.
+ */
+#ifndef H5D_PACKAGE
+#error "Do not include this file outside the H5D package!"
+#endif
+
+#ifndef _H5Dpkg_H
+#define _H5Dpkg_H
+
+/* Get package's private header */
+#include "H5Dprivate.h"
+
+/* Other private headers needed by this file */
+#include "H5Gprivate.h" /* Group headers */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Sprivate.h" /* Dataspace functions */
+#include "H5Tprivate.h" /* Datatype functions */
+
+/* The number of reserved IDs in dataset ID group */
+#define H5D_RESERVED_ATOMS 0
+
+/* Set the minimum object header size to create objects with */
+#define H5D_MINHDR_SIZE 256
+
+/****************************/
+/* Package Private Typedefs */
+/****************************/
+
+/*
+ * A dataset is the following struct.
+ */
+struct H5D_t {
+ H5G_entry_t ent; /* cached object header stuff */
+ H5T_t *type; /* datatype of this dataset */
+ H5S_t *space; /* dataspace of this dataset */
+ hid_t dcpl_id; /* dataset creation property id */
+ H5O_layout_t layout; /* data layout */
+ /* Cache some frequently accessed values from the DCPL */
+ H5O_efl_t efl; /* External file list information */
+ H5D_alloc_time_t alloc_time; /* Dataset allocation time */
+ H5D_fill_time_t fill_time; /* Dataset fill value writing time */
+ H5O_fill_t fill; /* Dataset fill value information */
+};
+
+/* Enumerated type for allocating dataset's storage */
+typedef enum {
+ H5D_ALLOC_CREATE, /* Dataset is being created */
+ H5D_ALLOC_OPEN, /* Dataset is being opened */
+ H5D_ALLOC_EXTEND, /* Dataset's dataspace is being extended */
+ H5D_ALLOC_WRITE /* Dataset is being extended */
+} H5D_time_alloc_t;
+
+/* Package-private functions defined in H5D package */
+H5_DLL herr_t H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset, H5D_time_alloc_t time_alloc,
+ hbool_t update_time, hbool_t full_overwrite);
+#endif /*_H5Dpkg_H*/
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index e69b0ad..38c13b7 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -21,13 +21,7 @@
#include "H5Dpublic.h"
/* Private headers needed by this file */
-#include "H5private.h"
-#include "H5Fprivate.h" /*for the H5F_t type */
-#include "H5Gprivate.h" /*symbol tables */
-#include "H5MMpublic.h" /*for H5MM_allocate_t and H5MM_free_t types */
-#include "H5Oprivate.h" /*object Headers */
-#include "H5Sprivate.h" /*for the H5S_t type */
-#include "H5Tprivate.h" /*for the H5T_t type */
+#include "H5Oprivate.h" /* Object headers */
/*
* Feature: Define H5D_DEBUG on the compiler command line if you want to
@@ -38,11 +32,6 @@
# undef H5D_DEBUG
#endif
-#define H5D_RESERVED_ATOMS 0
-
-/* Set the minimum object header size to create objects with */
-#define H5D_MINHDR_SIZE 256
-
/* ======== Dataset creation properties ======== */
/* Definitions for storage layout property */
#define H5D_CRT_LAYOUT_NAME "layout"
@@ -50,7 +39,7 @@
#define H5D_CRT_LAYOUT_DEF H5D_CONTIGUOUS
/* Definitions for chunk dimensionality property */
#define H5D_CRT_CHUNK_DIM_NAME "chunk_ndims"
-#define H5D_CRT_CHUNK_DIM_SIZE sizeof(int)
+#define H5D_CRT_CHUNK_DIM_SIZE sizeof(unsigned)
#define H5D_CRT_CHUNK_DIM_DEF 1
/* Definitions for chunk size */
#define H5D_CRT_CHUNK_SIZE_NAME "chunk_size"
@@ -155,23 +144,20 @@
#define H5D_XFER_FILTER_CB_SIZE sizeof(H5Z_cb_t)
#define H5D_XFER_FILTER_CB_DEF {NULL,NULL}
-/*
- * A dataset is the following struct.
- */
-typedef struct H5D_t {
- H5G_entry_t ent; /* cached object header stuff */
- H5T_t *type; /* datatype of this dataset */
- H5S_t *space; /* dataspace of this dataset */
- hid_t dcpl_id; /* dataset creation property id */
- H5O_layout_t layout; /* data layout */
- /* Cache some frequently accessed values from the DCPL */
- H5O_efl_t efl; /* External file list information */
- H5D_alloc_time_t alloc_time; /* Dataset allocation time */
- H5D_fill_time_t fill_time; /* Dataset fill value writing time */
- H5O_fill_t fill; /* Dataset fill value information */
-} H5D_t;
-
-/* Functions defined in H5D.c */
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Typedef for reference counted string (defined in H5Dpkg.h) */
+typedef struct H5D_t H5D_t;
+
+/* Typedef for dataset storage information */
+typedef union H5D_storage_t {
+ H5O_efl_t efl; /* External file list information for dataset */
+ hssize_t *chunk_coords; /* chunk's coordinates in file chunks */
+} H5D_storage_t;
+
+/* Library-private functions defined in H5D package */
H5_DLL herr_t H5D_init(void);
H5_DLL hid_t H5D_open(H5G_entry_t *ent, hid_t dxpl_id);
H5_DLL htri_t H5D_isa(H5G_entry_t *ent, hid_t dxpl_id);
diff --git a/src/H5Dseq.c b/src/H5Dseq.c
index 113a8d5..5248b0a 100644
--- a/src/H5Dseq.c
+++ b/src/H5Dseq.c
@@ -70,22 +70,24 @@ static int interface_initialize_g = 0;
*/
herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t mem_len=seq_len; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_read, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
done:
@@ -116,22 +118,24 @@ done:
*/
herr_t
H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, const void *buf)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t mem_len=seq_len; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_write, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -140,7 +144,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_seq_readv
+ * Function: H5F_seq_readvv
*
* Purpose: Reads in a vector of byte sequences from a file dataset into a
* buffer in in memory. The data is read from file F and the array's size
@@ -152,53 +156,61 @@ done:
* Bytes read into BUF are sequentially stored in the buffer, each sequence
* from the vector stored directly after the previous. The number of
* sequences is NSEQ.
+ * Purpose: Reads a vector of byte sequences from a vector of byte
+ * sequences in a file dataset into a buffer in memory. The data is
+ * read from file F and the array's size and storage information is in
+ * LAYOUT. External files and chunks are described according to the
+ * storage information, STORE. The vector of byte sequences offsets for
+ * the file is in the DSET_OFFSET_ARR array into the dataset (offsets are
+ * in terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
+ * array. The vector of byte sequences offsets for memory is in the
+ * MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
+ * and the size of each sequence is in the MEM_LEN_ARR array. The total
+ * size of the file array is implied in the LAYOUT argument. The maximum
+ * number of sequences in the file dataset and the memory buffer are
+ * DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
+ * operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
+ * & MEM_CURR_SEQ respectively. The current sequence being operated on
+ * will be updated as a result of the operation, as will the offsets and
+ * lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Wednesday, May 1, 2001
+ * Wednesday, May 7, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
- size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
- void *_buf/*out*/)
+ssize_t
+H5F_seq_readvv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf/*out*/)
{
- unsigned char *real_buf=(unsigned char *)_buf; /* Local pointer to buffer to fill */
- unsigned char *buf; /* Local pointer to buffer to fill */
- hsize_t dset_offset; /* Offset in dataset */
- hsize_t seq_len; /* Number of bytes to read */
- hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */
- hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */
- hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/
- hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */
- hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
- int ndims;
- hsize_t max_data; /*bytes in dataset */
- haddr_t addr=0; /*address in file */
- unsigned u; /*counters */
- size_t v; /*counters */
- int i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5F_seq_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_seq_readvv, FAIL);
/* Check args */
assert(f);
+ assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
- assert(efl);
- assert(real_buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+ assert(dc_plist);
+ assert(dset_curr_seq);
+ assert(*dset_curr_seq<dset_max_nseq);
+ assert(dset_len_arr);
+ assert(dset_offset_arr);
+ assert(mem_curr_seq);
+ assert(*mem_curr_seq<mem_max_nseq);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
+ assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
@@ -229,285 +241,52 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Read directly from file if the dataset is in an external file */
- if (efl->nused>0) {
- /* Iterate through the sequence vectors */
- for(v=0; v<nseq; v++) {
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- temp = seq_len_arr[v];
- assert(temp==seq_len_arr[v]); /* verify no overflow */
- MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
- H5FD_mpio_communicator(f->shared->lf));
- MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("seq_len=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL,
- "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_read(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
-
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
+ if (store && store->efl.nused>0) {
+ /* Note: We can't use data sieve buffers for datasets in external files
+ * because the 'addr' of all external files is set to 0 (above) and
+ * all datasets in external files would alias to the same set of
+ * file offsets, totally mixing up the data sieve buffer information. -QAK
+ */
+ if((ret_value=H5O_efl_readvv(&(store->efl),
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
} else {
+ hsize_t max_data; /*bytes in dataset */
+ unsigned u; /*counters */
+
/* Compute the size of the dataset in bytes */
for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
max_data *= layout->dim[u];
/* Pass along the vector of sequences to read */
- if (H5F_contig_readv(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
+ if((ret_value=H5F_contig_readvv(f, max_data, layout->addr,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
} /* end else */
break;
case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl->nused>0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
-
- /* Compute the file offset coordinates and hyperslab size */
- if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
- /* Build the array of cumulative hyperslab sizes */
- /* (And set the memory offset to zero) */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- mem_offset[i]=0;
- down_size[i]=acc;
- acc*=dset_dims[i];
- } /* end for */
- mem_offset[ndims]=0;
-
- /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
- for(v=0; v<nseq; v++) {
- dset_offset=dset_offset_arr[v];
- seq_len=seq_len_arr[v];
- buf=real_buf;
-
- {
- /* Set location in dataset from the dset_offset */
- addr=dset_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* Compute the hyperslab offset from the address given */
- for(i=ndims-1; i>=0; i--) {
- coords[i]=addr%dset_dims[i];
- addr/=dset_dims[i];
- } /* end for */
- coords[ndims]=0; /* No offset for element info */
-
- /*
- * Peel off initial partial hyperslabs until we've got a hyperslab which starts
- * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
- * zero for all dimensions except the slowest changing one
- */
- for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /* Check if we have a partial hyperslab in this lower dimension */
- if(coords[i]>0) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(i==j)
- hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
- else
- if(j>i)
- hslab_size[j]=dset_dims[j];
- else
- hslab_size[j]=1;
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size,
- buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
-
- /* Carry the coord array correction up the array, if the dimension is finished */
- while(i>0 && coords[i-1]==(hssize_t)dset_dims[i-1]) {
- i--;
- coords[i]=0;
- if(i>0) {
- coords[i-1]++;
- assert(coords[i-1]<=(hssize_t)dset_dims[i-1]);
- } /* end if */
- } /* end while */
- } /* end if */
- } /* end for */
-
- /* Check if there is more than just a partial hyperslab to read */
- if(seq_len>=down_size[0]) {
- hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
- hsize_t full_size; /* Size of the full hyperslab in bytes */
-
- /* Get the sequence length for computing the hyperslab sizes */
- tmp_seq_len=seq_len;
-
- /* Reset the size of the hyperslab read in */
- full_size=1;
-
- /* Compute the hyperslab size from the length given */
- for(i=ndims-1; i>=0; i--) {
- /* Check if the hyperslab is wider than the width of the dimension */
- if(tmp_seq_len>dset_dims[i]) {
- assert(0==coords[i]);
- hslab_size[i]=dset_dims[i];
- } /* end if */
- else
- hslab_size[i]=tmp_seq_len;
-
- /* compute the number of elements read in */
- full_size*=hslab_size[i];
-
- /* Fold the length into the length in the next highest dimension */
- tmp_seq_len/=dset_dims[i];
-
- /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
- assert(tmp_seq_len>=1 || i==0);
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read the full hyperslab in */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(full_size*elmt_size);
-
- /* Decrement the sequence length left */
- seq_len-=full_size;
-
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
-
- } /* end if */
-
- /*
- * Peel off final partial hyperslabs until we've finished reading all the data
- */
- if(seq_len>0) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /*
- * Peel off remaining partial hyperslabs, from the next-slowest dimension
- * on down to the next-to-fastest changing dimension
- */
- for(i=1; i<(ndims-1); i++) {
- /* Check if there are enough elements to read in a row in this dimension */
- if(seq_len>=down_size[i]) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j<i)
- hslab_size[j]=1;
- else
- if(j==i)
- hslab_size[j]=seq_len/down_size[j];
- else
- hslab_size[j]=dset_dims[j];
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=hslab_size[i];
- } /* end if */
- } /* end for */
-
- /* Handle fastest changing dimension if there are any elements left */
- if(seq_len>0) {
- assert(seq_len<dset_dims[ndims-1]);
-
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j==(ndims-1))
- hslab_size[j]=seq_len;
- else
- hslab_size[j]=1;
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Double-check the amount read in */
- assert(seq_len==partial_size);
- } /* end if */
- } /* end if */
- }
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
-
+ assert(store);
+ if((ret_value=H5F_istore_readvv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "istore read failed");
break;
case H5D_COMPACT:
-
/* Pass along the vector of sequences to read */
- if (H5F_compact_readv(f, layout, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
-
+ if((ret_value=H5F_compact_readvv(f, layout,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "compact read failed");
break;
+
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
@@ -515,69 +294,67 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* H5F_seq_readv() */
+} /* H5F_seq_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_seq_writev
+ * Function: H5F_seq_writevv
*
* Purpose: Writes a vector of byte sequences from a buffer in memory into
- * a file dataset. The data is written to file F and the array's size
- * and storage information is in LAYOUT. External files are described
- * according to the external file list, EFL. The vector of byte sequences
- * offsets is in the DSET_OFFSET array into the dataset (offsets are in
- * terms of bytes) and the size of each sequence is in the SEQ_LEN array.
- * The total size of the file array is implied in the LAYOUT argument.
- * Bytes written from BUF are sequentially stored in the buffer, each sequence
- * from the vector stored directly after the previous. The number of
- * sequences is NSEQ.
+ * a vector of byte sequences in a file dataset. The data is written to
+ * file F and the array's size and storage information is in LAYOUT.
+ * External files and chunks are described according to the storage
+ * information, STORE. The vector of byte sequences offsets for the file
+ * is in the DSET_OFFSET_ARR array into the dataset (offsets are in
+ * terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
+ * array. The vector of byte sequences offsets for memory is in the
+ * MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
+ * and the size of each sequence is in the MEM_LEN_ARR array. The total
+ * size of the file array is implied in the LAYOUT argument. The maximum
+ * number of sequences in the file dataset and the memory buffer are
+ * DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
+ * operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
+ * & MEM_CURR_SEQ respectively. The current sequence being operated on
+ * will be updated as a result of the operation, as will the offsets and
+ * lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Friday, July 6, 2001
+ * Friday, May 2, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
- size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
- const void *_buf)
+ssize_t
+H5F_seq_writevv(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf)
{
- const unsigned char *real_buf=(const unsigned char *)_buf; /* Local pointer to buffer to fill */
- const unsigned char *buf; /* Local pointer to buffer to fill */
- hsize_t dset_offset; /* Offset in dataset */
- hsize_t seq_len; /* Number of bytes to read */
- hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */
- hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */
- hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/
- hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */
- hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
- int ndims;
- hsize_t max_data; /*bytes in dataset */
- haddr_t addr; /*address in file */
- unsigned u; /*counters */
- size_t v; /*counters */
- int i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
- herr_t ret_value = SUCCEED; /* Return value */
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_seq_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_seq_writevv, FAIL);
/* Check args */
assert(f);
+ assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
- assert(efl);
- assert(real_buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+ assert(dc_plist);
+ assert(dset_curr_seq);
+ assert(*dset_curr_seq<dset_max_nseq);
+ assert(dset_len_arr);
+ assert(dset_offset_arr);
+ assert(mem_curr_seq);
+ assert(*mem_curr_seq<mem_max_nseq);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
+ assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
@@ -608,282 +385,50 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Write directly to file if the dataset is in an external file */
- if (efl->nused>0) {
- /* Iterate through the sequence vectors */
- for(v=0; v<nseq; v++) {
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- temp = seq_len_arr[v];
- assert(temp==seq_len_arr[v]); /* verify no overflow */
- MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
- H5FD_mpio_communicator(f->shared->lf));
- MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("seq_len=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_write(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
-
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
+ if (store && store->efl.nused>0) {
+ /* Note: We can't use data sieve buffers for datasets in external files
+ * because the 'addr' of all external files is set to 0 (above) and
+ * all datasets in external files would alias to the same set of
+ * file offsets, totally mixing up the data sieve buffer information. -QAK
+ */
+ if ((ret_value=H5O_efl_writevv(&(store->efl),
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
} else {
+ hsize_t max_data; /* Bytes in dataset */
+ unsigned u; /* Local index variable */
+
/* Compute the size of the dataset in bytes */
for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
max_data *= layout->dim[u];
/* Pass along the vector of sequences to write */
- if (H5F_contig_writev(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
+ if ((ret_value=H5F_contig_writevv(f, max_data, layout->addr,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
} /* end else */
break;
case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl->nused>0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
-
- /* Compute the file offset coordinates and hyperslab size */
- if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
- /* Build the array of cumulative hyperslab sizes */
- /* (And set the memory offset to zero) */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- mem_offset[i]=0;
- down_size[i]=acc;
- acc*=dset_dims[i];
- } /* end for */
- mem_offset[ndims]=0;
-
- /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
- for(v=0; v<nseq; v++) {
- dset_offset=dset_offset_arr[v];
- seq_len=seq_len_arr[v];
- buf=real_buf;
-
- {
- /* Set location in dataset from the dset_offset */
- addr=dset_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* Compute the hyperslab offset from the address given */
- for(i=ndims-1; i>=0; i--) {
- coords[i]=addr%dset_dims[i];
- addr/=dset_dims[i];
- } /* end for */
- coords[ndims]=0; /* No offset for element info */
-
- /*
- * Peel off initial partial hyperslabs until we've got a hyperslab which starts
- * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
- * zero for all dimensions except the slowest changing one
- */
- for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /* Check if we have a partial hyperslab in this lower dimension */
- if(coords[i]>0) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(i==j)
- hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
- else
- if(j>i)
- hslab_size[j]=dset_dims[j];
- else
- hslab_size[j]=1;
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write out the partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset,coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
-
- /* Carry the coord array correction up the array, if the dimension is finished */
- while(i>0 && coords[i-1]==(hssize_t)dset_dims[i-1]) {
- i--;
- coords[i]=0;
- if(i>0) {
- coords[i-1]++;
- assert(coords[i-1]<=(hssize_t)dset_dims[i-1]);
- } /* end if */
- } /* end while */
- } /* end if */
- } /* end for */
-
- /* Check if there is more than just a partial hyperslab to read */
- if(seq_len>=down_size[0]) {
- hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
- hsize_t full_size; /* Size of the full hyperslab in bytes */
-
- /* Get the sequence length for computing the hyperslab sizes */
- tmp_seq_len=seq_len;
-
- /* Reset the size of the hyperslab read in */
- full_size=1;
-
- /* Compute the hyperslab size from the length given */
- for(i=ndims-1; i>=0; i--) {
- /* Check if the hyperslab is wider than the width of the dimension */
- if(tmp_seq_len>dset_dims[i]) {
- assert(0==coords[i]);
- hslab_size[i]=dset_dims[i];
- } /* end if */
- else
- hslab_size[i]=tmp_seq_len;
-
- /* compute the number of elements read in */
- full_size*=hslab_size[i];
-
- /* Fold the length into the length in the next highest dimension */
- tmp_seq_len/=dset_dims[i];
-
- /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
- assert(tmp_seq_len>=1 || i==0);
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write the full hyperslab in */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(full_size*elmt_size);
-
- /* Decrement the sequence length left */
- seq_len-=full_size;
-
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
-
- } /* end if */
-
- /*
- * Peel off final partial hyperslabs until we've finished reading all the data
- */
- if(seq_len>0) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /*
- * Peel off remaining partial hyperslabs, from the next-slowest dimension
- * on down to the next-to-fastest changing dimension
- */
- for(i=1; i<(ndims-1); i++) {
- /* Check if there are enough elements to read in a row in this dimension */
- if(seq_len>=down_size[i]) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j<i)
- hslab_size[j]=1;
- else
- if(j==i)
- hslab_size[j]=seq_len/down_size[j];
- else
- hslab_size[j]=dset_dims[j];
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write out the partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=hslab_size[i];
- } /* end if */
- } /* end for */
-
- /* Handle fastest changing dimension if there are any elements left */
- if(seq_len>0) {
- assert(seq_len<dset_dims[ndims-1]);
-
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j==(ndims-1))
- hslab_size[j]=seq_len;
- else
- hslab_size[j]=1;
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write out the final partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Double-check the amount read in */
- assert(seq_len==partial_size);
- } /* end if */
- } /* end if */
- }
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
-
+ assert(store);
+ if((ret_value=H5F_istore_writevv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "istore write failed");
break;
case H5D_COMPACT:
-
/* Pass along the vector of sequences to write */
- if (H5F_compact_writev(f, layout, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
+ if((ret_value=H5F_compact_writevv(f, layout,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "compact write failed");
break;
default:
@@ -893,5 +438,4 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* H5F_seq_writev() */
-
+} /* H5F_seq_writevv() */
diff --git a/src/H5E.c b/src/H5E.c
index 96019af..084b143 100644
--- a/src/H5E.c
+++ b/src/H5E.c
@@ -162,6 +162,9 @@ static const H5E_minor_mesg_t H5E_minor_mesg_g[] = {
/* Dataspace errors */
{H5E_CANTCLIP, "Can't clip hyperslab region"},
{H5E_CANTCOUNT, "Can't count elements"},
+ {H5E_CANTSELECT, "Can't select hyperslab"},
+ {H5E_CANTNEXT, "Can't move to next iterator location"},
+ {H5E_BADSELECT, "Invalid selection"},
/* Property list errors */
{H5E_CANTGET, "Can't get value"},
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index d390f22..d970ab9 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -193,6 +193,9 @@ typedef enum H5E_minor_t {
/* Dataspace errors */
H5E_CANTCLIP, /*Can't clip hyperslab region */
H5E_CANTCOUNT, /*Can't count elements */
+ H5E_CANTSELECT, /*Can't select hyperslab */
+ H5E_CANTNEXT, /*Can't move to next iterator location */
+ H5E_BADSELECT, /*Invalid selection */
/* Property list errors */
H5E_CANTGET, /*Can't get value */
diff --git a/src/H5Farray.c b/src/H5Farray.c
deleted file mode 100644
index 1965a59..0000000
--- a/src/H5Farray.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by the Board of Trustees of the University of Illinois. *
- * All rights reserved. *
- * *
- * This file is part of HDF5. The full HDF5 copyright notice, including *
- * terms governing use, modification, and redistribution, is contained in *
- * the files COPYING and Copyright.html. COPYING can be found at the root *
- * of the source code distribution tree; Copyright.html can be found at the *
- * root level of an installed copy of the electronic HDF5 document set and *
- * is linked from the top-level documents page. It can also be found at *
- * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
- * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/*
- * Programmer: Robb Matzke <matzke@llnl.gov>
- * Thursday, January 15, 1998
- *
- * Purpose: Provides I/O facilities for multi-dimensional arrays of bytes
- * stored with various layout policies. If the caller is
- * interested in arrays of elements >1 byte then add an extra
- * dimension. For example, a 10x20 array of int would
- * translate to a 10x20x4 array of bytes at this level.
- */
-
-#define H5F_PACKAGE /*suppress error about including H5Fpkg */
-
-#include "H5private.h"
-#include "H5Dprivate.h"
-#include "H5Eprivate.h"
-#include "H5Fpkg.h"
-#include "H5FDprivate.h" /*file driver */
-#include "H5Iprivate.h"
-#include "H5MMprivate.h" /*memory management */
-#include "H5Oprivate.h"
-#include "H5Pprivate.h"
-#include "H5Vprivate.h"
-
-/* MPIO driver functions are needed for some special checks */
-#include "H5FDmpio.h"
-
-/* Interface initialization */
-#define PABLO_MASK H5Farray_mask
-#define INTERFACE_INIT NULL
-static int interface_initialize_g = 0;
-
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_arr_read
- *
- * Purpose: Reads a hyperslab of a file byte array into a hyperslab of
- * a byte array in memory. The data is read from file F and the
- * array's size and storage information is in LAYOUT. External
- * files are described according to the external file list, EFL.
- * The hyperslab offset is FILE_OFFSET[] in the file and
- * MEM_OFFSET[] in memory (offsets are relative to the origin of
- * the array) and the size of the hyperslab is HSLAB_SIZE[]. The
- * total size of the file array is implied in the LAYOUT
- * argument and the total size of the memory array is
- * MEM_SIZE[]. The dimensionality of these vectors is implied by
- * the LAYOUT argument.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Friday, January 16, 1998
- *
- * Modifications:
- * Albert Cheng, 1998-06-02
- * Added xfer_mode argument
- *
- * Robb Matzke, 1998-09-28
- * Added the `xfer' argument and removed the `xfer_mode'
- * argument since it's a field of `xfer'.
- *
- * Robb Matzke, 1999-08-02
- * Data transfer properties are passed by ID since that's how
- * the virtual file layer wants them.
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_arr_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const hsize_t _hslab_size[],
- const hsize_t mem_size[], const hssize_t mem_offset[],
- const hssize_t file_offset[], void *_buf/*out*/)
-{
- uint8_t *buf = (uint8_t*)_buf; /*cast for arithmetic */
- hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */
- hssize_t mem_stride[H5O_LAYOUT_NDIMS]; /*strides through memory*/
- hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /*hyperslab size */
- hsize_t idx[H5O_LAYOUT_NDIMS]; /*multi-dim counter */
- size_t mem_start; /*byte offset to start */
- hsize_t file_start; /*byte offset to start */
- hsize_t max_data = 0; /*bytes in dataset */
- hsize_t elmt_size = 1; /*bytes per element */
- hsize_t nelmts, z; /*number of elements */
- unsigned ndims; /*stride dimensionality */
- haddr_t addr; /*address in file */
- int j; /*counters */
- unsigned u; /*counters */
- hbool_t carray; /*carry for subtraction */
- struct H5O_efl_t efl; /* External File List info */
-#ifdef H5_HAVE_PARALLEL
- H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
-#endif /* H5_HAVE_PARALLEL */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_arr_read, FAIL);
-
- /* Check args */
- assert(f);
- assert(layout);
- assert(_hslab_size);
- assert(file_offset);
- assert(mem_offset);
- assert(mem_size);
- assert(buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
-
- /* Make a local copy of size so we can modify it */
- H5V_vector_cpy(layout->ndims, hslab_size, _hslab_size);
-
-#ifdef H5_HAVE_PARALLEL
- /* Get the transfer mode for MPIO transfers */
- if(IS_H5FD_MPIO(f)) {
- hid_t driver_id; /* VFL driver ID */
- H5P_genplist_t *plist; /* Property list */
-
- /* Get the plist structure */
- if(NULL == (plist = H5I_object(dxpl_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
-
- /* Get the driver ID */
- if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve VFL driver ID");
-
- /* Check if we are using the MPIO driver (for the DXPL) */
- if(H5FD_MPIO==driver_id) {
- /* Get the transfer mode */
- xfer_mode=H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME);
- } /* end if */
- } /* end if */
-
- /* Collective MPIO access is unsupported for non-contiguous datasets */
- if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
- HGOTO_ERROR (H5E_DATASET, H5E_READERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
-#endif /* H5_HAVE_PARALLEL */
-
- /* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get EFL value");
-
- switch (layout->type) {
- case H5D_CONTIGUOUS:
- ndims = layout->ndims;
- /*
- * Offsets must not be negative for this type of storage.
- */
- for (u=0; u<ndims; u++) {
- if (mem_offset[u]<0 || file_offset[u]<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "negative offsets are not valid");
- }
-
- /*
- * Calculate the strides needed to walk through the array on disk
- * and memory. Optimize the strides to result in the fewest number of
- * I/O requests.
- */
- H5_ASSIGN_OVERFLOW(mem_start,H5V_hyper_stride(ndims, hslab_size, mem_size, mem_offset, mem_stride/*out*/),hsize_t,size_t);
- file_start = H5V_hyper_stride(ndims, hslab_size, layout->dim,
- file_offset, file_stride/*out*/);
- H5V_stride_optimize2(&ndims, &elmt_size, hslab_size,
- mem_stride, file_stride);
-
- /*
- * Initialize loop variables. The loop is a multi-dimensional loop
- * that counts from SIZE down to zero and IDX is the counter. Each
- * element of IDX is treated as a digit with IDX[0] being the least
- * significant digit.
- */
- H5V_vector_cpy(ndims, idx, hslab_size);
- nelmts = H5V_vector_reduce_product(ndims, hslab_size);
- if (efl.nused>0) {
- addr = 0;
- } else {
- addr = layout->addr;
-
- /* Compute the size of the dataset in bytes */
- for(u=0, max_data=1; u<layout->ndims; u++)
- max_data *= layout->dim[u];
-
- /* Adjust the maximum size of the data by the offset into it */
- max_data -= file_start;
- }
- addr += file_start;
- buf += mem_start;
-
- /*
- * Now begin to walk through the array, copying data from disk to
- * memory.
- */
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- H5_ASSIGN_OVERFLOW(temp,nelmts,hsize_t,unsigned long);
- MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
- H5FD_mpio_communicator(f->shared->lf));
- MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("nelmts=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
-
- for (z=0; z<nelmts; z++) {
- /* Read directly from file if the dataset is in an external file */
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- if (efl.nused>0) {
- H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t);
- if (H5O_efl_read(f, &efl, addr, (size_t)elmt_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
- } else {
- H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t);
- if (H5F_contig_read(f, max_data, H5FD_MEM_DRAW, addr, (size_t)elmt_size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end else */
-
- /* Decrement indices and advance pointers */
- for (j=ndims-1, carray=TRUE; j>=0 && carray; --j) {
- addr += file_stride[j];
- buf += mem_stride[j];
-
- /* Adjust the maximum size of the data by the offset into it */
- max_data -= file_stride[j];
-
- if (--idx[j])
- carray = FALSE;
- else
- idx[j] = hslab_size[j];
- }
- }
- break;
-
- case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl.nused>0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
-
- /* Go get the data from the chunks */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist, mem_size,
- mem_offset, file_offset, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
- break;
-
- default:
- assert("not implemented yet" && 0);
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_arr_write
- *
- * Purpose: Copies a hyperslab of a memory array to a hyperslab of a
- * file array. The data is written to file F and the file
- * array's size and storage information is implied by LAYOUT.
- * The data is stored in external files according to the
- * external file list, EFL. The hyperslab offset is
- * FILE_OFFSET[] in the file and MEM_OFFSET[] in memory (offsets
- * are relative to the origin of the array) and the size of the
- * hyperslab is HSLAB_SIZE[]. The total size of the file array
- * is implied by the LAYOUT argument and the total size of the
- * memory array is MEM_SIZE[]. The dimensionality of these
- * vectors is implied by the LAYOUT argument.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Friday, January 16, 1998
- *
- * Modifications:
- * Albert Cheng, 1998-06-02
- * Added xfer_mode argument
- *
- * Robb Matzke, 1998-09-28
- * Added `xfer' argument, removed `xfer_mode' argument since it
- * is a member of H5D_xfer_t.
- *
- * Robb Matzke, 1999-08-02
- * Data transfer properties are passed by ID since that's how
- * the virtual file layer wants them.
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_arr_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const hsize_t _hslab_size[], const hsize_t mem_size[],
- const hssize_t mem_offset[], const hssize_t file_offset[],
- const void *_buf)
-{
- const uint8_t *buf = (const uint8_t *)_buf; /*cast for arithmetic */
- hssize_t file_stride[H5O_LAYOUT_NDIMS]; /*strides through file */
- hssize_t mem_stride[H5O_LAYOUT_NDIMS]; /*strides through memory*/
- hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /*hyperslab size */
- hsize_t idx[H5O_LAYOUT_NDIMS]; /*multi-dim counter */
- hsize_t mem_start; /*byte offset to start */
- hsize_t file_start; /*byte offset to start */
- hsize_t max_data = 0; /*bytes in dataset */
- hsize_t elmt_size = 1; /*bytes per element */
- hsize_t nelmts, z; /*number of elements */
- unsigned ndims; /*dimensionality */
- haddr_t addr; /*address in file */
- int j; /*counters */
- unsigned u; /*counters */
- hbool_t carray; /*carry for subtraction */
- struct H5O_efl_t efl; /* External File List info */
-#ifdef H5_HAVE_PARALLEL
- H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
-#endif /* H5_HAVE_PARALLEL */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_arr_write, FAIL);
-
- /* Check args */
- assert(f);
- assert(layout);
- assert(_hslab_size);
- assert(file_offset);
- assert(mem_offset);
- assert(mem_size);
- assert(buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
-
- /* Make a local copy of _size so we can modify it */
- H5V_vector_cpy(layout->ndims, hslab_size, _hslab_size);
-
-#ifdef H5_HAVE_PARALLEL
- /* Get the transfer mode for MPIO transfers */
- if(IS_H5FD_MPIO(f)) {
- hid_t driver_id; /* VFL driver ID */
- H5P_genplist_t *plist; /* Property list */
-
- /* Get the plist structure */
- if(NULL == (plist = H5I_object(dxpl_id)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
-
- /* Get the driver ID */
- if(H5P_get(plist, H5D_XFER_VFL_ID_NAME, &driver_id)<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve VFL driver ID");
-
- /* Check if we are using the MPIO driver (for the DXPL) */
- if(H5FD_MPIO==driver_id) {
- /* Get the transfer mode */
- xfer_mode=H5P_peek_unsigned(plist, H5D_XFER_IO_XFER_MODE_NAME);
- } /* end if */
- } /* end if */
-
- if (H5D_CONTIGUOUS!=layout->type && H5FD_MPIO_COLLECTIVE==xfer_mode)
- HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access on non-contiguous datasets not supported yet");
-#endif /* H5_HAVE_PARALLEL */
-
- /* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_EXT_FILE_LIST_NAME, &efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get EFL value");
-
- switch (layout->type) {
- case H5D_CONTIGUOUS:
- ndims = layout->ndims;
- /*
- * Offsets must not be negative for this type of storage.
- */
- for (u=0; u<ndims; u++) {
- if (mem_offset[u]<0 || file_offset[u]<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "negative offsets are not valid");
- }
-
- /*
- * Calculate the strides needed to walk through the array on disk.
- * Optimize the strides to result in the fewest number of I/O
- * requests.
- */
- mem_start = H5V_hyper_stride(ndims, hslab_size, mem_size,
- mem_offset, mem_stride/*out*/);
- file_start = H5V_hyper_stride(ndims, hslab_size, layout->dim,
- file_offset, file_stride/*out*/);
- H5V_stride_optimize2(&ndims, &elmt_size, hslab_size,
- mem_stride, file_stride);
-
- /*
- * Initialize loop variables. The loop is a multi-dimensional loop
- * that counts from SIZE down to zero and IDX is the counter. Each
- * element of IDX is treated as a digit with IDX[0] being the least
- * significant digit.
- */
- H5V_vector_cpy(ndims, idx, hslab_size);
- nelmts = H5V_vector_reduce_product(ndims, hslab_size);
-
- if (efl.nused>0) {
- addr = 0;
- } else {
- addr = layout->addr;
-
- /* Compute the size of the dataset in bytes */
- for(u=0, max_data=1; u<layout->ndims; u++)
- max_data *= layout->dim[u];
-
- /* Adjust the maximum size of the data by the offset into it */
- max_data -= file_start;
- }
- addr += file_start;
- buf += mem_start;
-
- /*
- * Now begin to walk through the array, copying data from memory to
- * disk.
- */
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode){
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all writes into one collective
- * MPIO call.
- */
- unsigned long max, min, temp;
-
- H5_ASSIGN_OVERFLOW(temp,nelmts,hsize_t,unsigned long);
- MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
- H5FD_mpio_communicator(f->shared->lf));
- MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("nelmts=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
-
- for (z=0; z<nelmts; z++) {
-
- /* Write to file */
- if (efl.nused>0) {
- H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t);
- if (H5O_efl_write(f, &efl, addr, (size_t)elmt_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data write failed");
- } else {
- H5_CHECK_OVERFLOW(elmt_size,hsize_t,size_t);
- if (H5F_contig_write(f, max_data, H5FD_MEM_DRAW, addr, (size_t)elmt_size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- } /* end else */
-
- /* Decrement indices and advance pointers */
- for (j=ndims-1, carray=TRUE; j>=0 && carray; --j) {
- addr += file_stride[j];
- buf += mem_stride[j];
-
- /* Adjust the maximum size of the data by the offset into it */
- max_data -= file_stride[j];
-
- if (--idx[j])
- carray = FALSE;
- else
- idx[j] = hslab_size[j];
- }
-
- }
- break;
-
- case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl.nused>0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
-
- /* Write the read to the chunks */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist, mem_size,
- mem_offset, file_offset, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
- break;
-
- default:
- assert("not implemented yet" && 0);
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
diff --git a/src/H5Fcompact.c b/src/H5Fcompact.c
index 1f77d92..829ba63 100644
--- a/src/H5Fcompact.c
+++ b/src/H5Fcompact.c
@@ -28,60 +28,55 @@
#include "H5Oprivate.h"
#include "H5FDprivate.h" /*file driver */
#include "H5FLprivate.h" /*Free Lists */
+#include "H5Vprivate.h" /* Vector and array functions */
/* Interface initialization */
#define PABLO_MASK H5Fcompact_mask
static int interface_initialize_g = 0;
#define INTERFACE_INIT NULL
+
/*-------------------------------------------------------------------------
- * Function: H5F_compact_readv
- *
+ * Function: H5F_compact_readvv
+ *
* Purpose: Reads some data vectors from a dataset into a buffer.
* The data is in compact dataset. The address is relative
* to the beginning address of the dataset. The offsets and
* sequence lengths are in bytes.
- *
+ *
* Return: Non-negative on success/Negative on failure
- *
- * Programmer: Raymond Lu
- * August 5, 2002
- *
- * Notes:
- * Offsets in the sequences must be monotonically increasing
*
+ * Programmer: Quincey Koziol
+ * May 7, 2003
+ *
+ * Notes:
+ * Offsets in the sequences must be monotonically increasing
+ *
* Modifications:
- *
+ *
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_compact_readv(H5F_t UNUSED *f, const H5O_layout_t *layout, size_t nseq,
- size_t size_arr[], hsize_t offset_arr[],
- hid_t UNUSED dxpl_id, void *_buf/*out*/)
+ssize_t
+H5F_compact_readvv(H5F_t UNUSED *f, const H5O_layout_t *layout,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[],
+ hid_t UNUSED dxpl_id, void *buf)
{
- unsigned char *buf=(unsigned char *)_buf;
- size_t size;
- haddr_t offset;
- unsigned u;
- herr_t ret_value=SUCCEED;
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_compact_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_compact_readvv, FAIL);
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- offset=offset_arr[u];
- if(size > 0) {
- HDmemcpy(buf, (unsigned char*)layout->buf+offset, size);
- buf +=size;
- }
- }
+ /* Use the vectorized memory copy routine to do actual work */
+ if((ret_value=H5V_memcpyvv(buf,mem_max_nseq,mem_curr_seq,mem_size_arr,mem_offset_arr,layout->buf,dset_max_nseq,dset_curr_seq,dset_size_arr,dset_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed");
-done:
+done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_compact_readv() */
+} /* end H5F_compact_readvv() */
+
/*-------------------------------------------------------------------------
- * Function: H5F_compact_writev
+ * Function: H5F_compact_writevv
*
* Purpose: Writes some data vectors from a dataset into a buffer.
* The data is in compact dataset. The address is relative
@@ -93,8 +88,8 @@ done:
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Raymond Lu
- * August 5, 2002
+ * Programmer: Quincey Koziol
+ * May 2, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
@@ -103,30 +98,23 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_compact_writev(H5F_t UNUSED *f, H5O_layout_t *layout, size_t nseq,
- size_t size_arr[], hsize_t offset_arr[],
- hid_t UNUSED dxpl_id, const void *_buf)
+ssize_t
+H5F_compact_writevv(H5F_t UNUSED *f, H5O_layout_t *layout,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[],
+ hid_t UNUSED dxpl_id, const void *buf)
{
- const unsigned char *buf=(const unsigned char *)_buf;
- size_t size;
- haddr_t offset;
- unsigned u;
- herr_t ret_value=SUCCEED;
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_compact_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_compact_writevv, FAIL);
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- offset=offset_arr[u];
- if(size > 0) {
- HDmemcpy((unsigned char*)layout->buf+offset, buf, size);
- buf += size;
- }
- }
+ /* Use the vectorized memory copy routine to do actual work */
+ if((ret_value=H5V_memcpyvv(layout->buf,dset_max_nseq,dset_curr_seq,dset_size_arr,dset_offset_arr,buf,mem_max_nseq,mem_curr_seq,mem_size_arr,mem_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed");
layout->dirty = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_compact_writev */
+} /* end H5F_compact_writevv() */
+
diff --git a/src/H5Fcontig.c b/src/H5Fcontig.c
index 2593d83..3a14175 100644
--- a/src/H5Fcontig.c
+++ b/src/H5Fcontig.c
@@ -18,9 +18,8 @@
*
* Purpose:
* Contiguous dataset I/O functions. These routines are similar to
- * the H5F_istore_* routines and really only abstract away dealing
- * with the data sieve buffer from the H5F_arr_read/write and
- * H5F_seg_read/write.
+ * the H5F_istore_* routines and really only an abstract way of dealing
+ * with the data sieve buffer from H5F_seg_read/write.
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
@@ -34,6 +33,7 @@
#include "H5MFprivate.h" /*file memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspace functions */
#include "H5Vprivate.h" /* Vector and array functions */
/* MPIO, MPIPOSIX, & FPHDF5 drivers needed for special checks */
@@ -41,6 +41,11 @@
#include "H5FDmpio.h"
#include "H5FDmpiposix.h"
+/* Private prototypes */
+static herr_t
+H5F_contig_write(H5F_t *f, hsize_t max_data, haddr_t addr,
+ const size_t size, hid_t dxpl_id, const void *buf);
+
/* Interface initialization */
#define PABLO_MASK H5Fcontig_mask
static int interface_initialize_g = 0;
@@ -57,6 +62,48 @@ H5FL_BLK_DEFINE_STATIC(zero_fill);
/*-------------------------------------------------------------------------
+ * Function: H5F_contig_create
+ *
+ * Purpose: Allocate file space for a contiguously stored dataset
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * April 19, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_contig_create(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout)
+{
+ hsize_t size; /* Size of contiguous block of data */
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_contig_create, FAIL);
+
+ /* check args */
+ assert(f);
+ assert(layout);
+
+ /* Compute size */
+ size=layout->dim[0];
+ for (u = 1; u < layout->ndims; u++)
+ size *= layout->dim[u];
+ assert (size>0);
+
+ /* Allocate space for the contiguous data */
+ if (HADDR_UNDEF==(layout->addr=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, size)))
+ HGOTO_ERROR (H5E_IO, H5E_NOSPACE, FAIL, "unable to reserve file space");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5F_contig_create */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_contig_fill
*
* Purpose: Write fill values to a contiguously stored dataset.
@@ -75,8 +122,7 @@ H5FL_BLK_DEFINE_STATIC(zero_fill);
*/
herr_t
H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *space,
+ struct H5P_genplist_t *dc_plist, const struct H5S_t *space,
const struct H5O_fill_t *fill, size_t elmt_size)
{
hssize_t snpoints; /* Number of points in space (for error checking) */
@@ -84,7 +130,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
size_t ptsperbuf; /* Maximum # of points which fit in the buffer */
size_t bufsize=64*1024; /* Size of buffer to write */
size_t size; /* Current # of points to write */
- hsize_t addr; /* Offset in dataset */
+ haddr_t addr; /* Offset of dataset */
void *buf = NULL; /* Buffer for fill value writing */
#ifdef H5_HAVE_PARALLEL
MPI_Comm mpi_comm=MPI_COMM_NULL; /* MPI communicator for file */
@@ -173,8 +219,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
* this quite efficiently by making sure we copy the fill value
* in relatively large pieces.
*/
- ptsperbuf = MAX(1, bufsize/elmt_size);
- bufsize = ptsperbuf*elmt_size;
+ ptsperbuf = MAX(1, bufsize/elmt_size);
+ bufsize = ptsperbuf*elmt_size;
/* Fill the buffer with the user's fill value */
if(fill->buf) {
@@ -207,7 +253,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end else */
/* Start at the beginning of the dataset */
- addr = 0;
+ addr = layout->addr;
/* Loop through writing the fill value to the dataset */
while (npoints>0) {
@@ -218,8 +264,7 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
if(using_mpi) {
/* Round-robin write the chunks out from only one process */
if(mpi_round==mpi_rank) {
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
- elmt_size, size, addr, buf)<0)
+ if (H5F_contig_write(f, size, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
} /* end if */
++mpi_round;
@@ -230,8 +275,8 @@ H5F_contig_fill(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, space,
- elmt_size, size, addr, buf)<0)
+ H5_CHECK_OVERFLOW(size,size_t,hsize_t);
+ if (H5F_contig_write(f, (hsize_t)size, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to write fill value to dataset");
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -314,44 +359,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_contig_read
- *
- * Purpose: Reads some data from a dataset into a buffer.
- * The data is contiguous. The address is relative to the base
- * address for the file.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Thursday, September 28, 2000
- *
- * Modifications:
- * Re-written in terms of the new readv call, QAK, 7/7/01
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
- size_t size, hid_t dxpl_id, void *buf/*out*/)
-{
- hsize_t offset=0; /* Offset for vector call */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_contig_read, FAIL);
-
- /* Check args */
- assert(f);
- assert(buf);
-
- if (H5F_contig_readv(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_read() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5F_contig_write
*
* Purpose: Writes some data from a dataset into a buffer.
@@ -364,23 +371,28 @@ done:
* Thursday, September 28, 2000
*
* Modifications:
- * Re-written in terms of the new readv call, QAK, 7/7/01
+ * Re-written in terms of the new writevv call, QAK, 5/7/03
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr, size_t size,
- hid_t dxpl_id, const void *buf)
+static herr_t
+H5F_contig_write(H5F_t *f, hsize_t max_data, haddr_t addr,
+ const size_t size, hid_t dxpl_id, const void *buf)
{
- hsize_t offset=0; /* Offset for vector call */
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t dset_off=0; /* Offset in dataset */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t dset_len=size; /* Length in dataset */
+ size_t mem_len=size; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_contig_write, FAIL);
assert (f);
assert (buf);
- if (H5F_contig_writev(f, max_data, type, addr, 1, &size, &offset, dxpl_id, buf)<0)
+ if (H5F_contig_writevv(f, max_data, addr, 1, &dset_curr_seq, &dset_len, &dset_off, 1, &mem_curr_seq, &mem_len, &mem_off, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -389,7 +401,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_contig_readv
+ * Function: H5F_contig_readvv
*
* Purpose: Reads some data vectors from a dataset into a buffer.
* The data is contiguous. The address is the start of the dataset,
@@ -409,9 +421,10 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
- size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id,
- void *_buf/*out*/)
+H5F_contig_readvv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, void *_buf)
{
unsigned char *buf=(unsigned char *)_buf; /* Pointer to buffer to fill */
haddr_t abs_eoa; /* Absolute end of file address */
@@ -420,18 +433,10 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
hsize_t max_data; /* Actual maximum size of data to cache */
size_t size; /* Size of sequence in bytes */
size_t u; /* Counting variable */
-#ifndef SLOW_WAY
- size_t max_seq; /* Maximum sequence to copy */
- haddr_t temp_end; /* Temporary end of buffer variable */
- size_t max_search; /* Maximum number of sequences to search */
- size_t mask; /* Bit mask */
- int bit_loc; /* Bit location of the leftmost '1' in max_search */
- size_t *size_arr_p; /* Pointer into the size array */
- hsize_t *offset_arr_p; /* Pointer into the offset array */
-#endif /* SLOW_WAY */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
- FUNC_ENTER_NOAPI(H5F_contig_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_contig_readvv, FAIL);
/* Check args */
assert(f);
@@ -439,325 +444,143 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
+ haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
+ haddr_t contig_end; /* End locations of block to write */
+ size_t sieve_size; /* size of sieve buffer */
+
+ /* Set offsets in sequence lists */
+ u=*dset_curr_seq;
+ v=*mem_curr_seq;
+
+ /* No data sieve buffer yet, go allocate one */
+ if(f->shared->sieve_buf==NULL) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Set up the buffer parameters */
+ max_data=_max_data-dset_offset_arr[u];
+
+ /* Check if we can actually hold the I/O request in the sieve buffer */
+ if(size>f->shared->sieve_buf_size) {
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
+ else {
+ /* Allocate room for the data sieve buffer */
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- /* Outer loop, guarantees working through all the sequences */
- for(u=0; u<nseq; ) {
-
- /* Try reading from the data sieve buffer */
- if(f->shared->sieve_buf) {
- haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
- haddr_t contig_end; /* End locations of block to write */
- size_t sieve_size; /* size of sieve buffer */
-
- /* Stash local copies of these value */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- /* Next-outer loop works through sequences as fast as possible */
- for(; u<nseq; ) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
-
- /* Compute end of sequence to retrieve */
- contig_end=addr+size-1;
-
- /* If entire read is within the sieve buffer, read it from the buffer */
- if(addr>=sieve_start && contig_end<sieve_end) {
- unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start);
- unsigned char *temp_sieve_buf;
- haddr_t temp_addr=_addr-1; /* Temporary address */
-
-#ifdef SLOW_WAY
- /* Retrieve all the sequences out of the current sieve buffer */
- while(contig_end<sieve_end) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+offset_arr[u];
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,size_arr[u]);
-
- /* Increment offset in buffer */
- buf += size_arr[u];
-
- /* Increment sequence number, check for finished with sequences */
- if((++u) >= nseq)
- break;
-
- /* Re-compute end of sequence to retrieve */
- contig_end=temp_addr+offset_arr[u]+size_arr[u];
- } /* end while */
-#else /* SLOW_WAY */
- /* Find log2(n) where n is the number of elements to search */
-
- /* Set initial parameters */
- mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */
- max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */
- assert(max_search>0); /* Sanity check */
- bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */
-
- /* Search for the first byte with a bit set */
- while((max_search & mask)==0) {
- mask>>=8;
- bit_loc-=8;
- } /* end while */
-
- /* Switch to searching for a bit */
- mask=1<<bit_loc;
- while((max_search & mask)==0) {
- mask>>=1;
- bit_loc--;
- } /* end while */
-
- /* location of the leftmost bit, plus 1, is log2(n) */
- max_seq=bit_loc+1;
-
- /* Don't walk off the array */
- max_seq=MIN(u+max_seq,nseq-1);
-
- /* Determine if a linear search is faster than a binary search */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- if(temp_end>=sieve_end) {
- /* Linear search is faster */
-
- /* Set the initial search values */
- max_seq=u;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Search for the first sequence ending greater than the sieve buffer end */
- while(temp_end<sieve_end) {
- if(++max_seq>=nseq)
- break;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- } /* end while */
-
- /* Adjust back one element */
- max_seq--;
-
- } /* end if */
- else {
- size_t lo,hi; /* Low and high bounds for binary search */
- unsigned found=0; /* Flag to indicate bounds have been found */
-
- /* Binary search is faster */
-
- /* Find the value 'u' which will be beyond the end of the sieve buffer */
- lo=u;
- hi=nseq-1;
- max_seq=(lo+hi)/2;
- while(!found) {
- /* Get the address of the end of sequence for the 'max_seq' position */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Current high bound is too large */
- if(temp_end>=sieve_end) {
- if((lo+1)<hi) {
- hi=max_seq;
- max_seq=(lo+hi)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end if */
- /* Current low bound is too small */
- else {
- if((lo+1)<hi) {
- lo=max_seq;
- max_seq=(lo+hi+1)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end else */
- } /* end while */
-
- /* Check for non-exact match */
- if(lo!=hi) {
- temp_end=temp_addr+offset_arr[hi]+size_arr[hi];
- if(temp_end<sieve_end)
- max_seq=hi;
- else
- max_seq=lo;
- } /* end if */
- } /* end else */
-
- /* Set the pointers to the correct locations in the offset & size arrays */
- size_arr_p=&size_arr[u];
- offset_arr_p=&offset_arr[u];
-
-#ifdef NO_DUFFS_DEVICE
- /* Retrieve all the sequences out of the current sieve buffer */
- while(u<=max_seq) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
- } /* end while */
-#else /* NO_DUFFS_DEVICE */
-{
- size_t seq_count;
-
- seq_count=(max_seq-u)+1;
- switch (seq_count % 4) {
- case 0:
- do
- {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- case 3:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- case 2:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- case 1:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
-
- /* Grab the data out of the buffer */
- HDmemcpy(buf,temp_sieve_buf,*size_arr_p);
-
- /* Increment offset in buffer */
- buf += *size_arr_p++;
-
- /* Increment the offset in the array */
- u++;
-
- } while (u<=max_seq);
- } /* end switch */
-
-}
-#endif /* NO_DUFFS_DEVICE */
-#endif /* SLOW_WAY */
- } /* end if */
- /* Entire request is not within this data sieve buffer */
- else {
- /* Check if we can actually hold the I/O request in the sieve buffer */
- if(size>f->shared->sieve_buf_size) {
- /* Check for any overlap with the current sieve buffer */
- if((sieve_start>=addr && sieve_start<(contig_end+1))
- || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
- /* Flush the sieve buffer, if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
- } /* end if */
-
- /* Read directly into the user's buffer */
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
- /* Element size fits within the buffer size */
- else {
- /* Flush the sieve buffer if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
-
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Only need this when resizing sieve buffer */
- max_data=_max_data-offset_arr[u];
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Compute the size of the sieve buffer */
- /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Compute the size of the sieve buffer */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- /* Update local copies of sieve information */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
+ /* Read the new sieve buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- /* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(buf,f->shared->sieve_buf,size);
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end else */
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(buf,f->shared->sieve_buf,size);
- } /* end else */
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
- /* Increment sequence number */
- u++;
- } /* end else */
- } /* end for */
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end if */
+
+ /* Stash local copies of these value */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
+
+ /* Works through sequences as fast as possible */
+ for(; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Compute end of sequence to retrieve */
+ contig_end=addr+size-1;
+
+ /* If entire read is within the sieve buffer, read it from the buffer */
+ if(addr>=sieve_start && contig_end<sieve_end) {
+ unsigned char *base_sieve_buf=f->shared->sieve_buf+(addr-sieve_start);
+
+ /* Grab the data out of the buffer */
+ HDmemcpy(buf,base_sieve_buf,size);
} /* end if */
- /* No data sieve buffer yet, go allocate one */
+ /* Entire request is not within this data sieve buffer */
else {
- /* Set up the buffer parameters */
- size=size_arr[u];
- addr=_addr+offset_arr[u];
- max_data=_max_data-offset_arr[u];
-
/* Check if we can actually hold the I/O request in the sieve buffer */
if(size>f->shared->sieve_buf_size) {
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
+ /* Check for any overlap with the current sieve buffer */
+ if((sieve_start>=addr && sieve_start<(contig_end+1))
+ || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
+ /* Flush the sieve buffer, if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
+ } /* end if */
+
+ /* Read directly into the user's buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
} /* end if */
+ /* Element size fits within the buffer size */
else {
- /* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* Flush the sieve buffer if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
/* Determine the new sieve buffer size & location */
f->shared->sieve_loc=addr;
@@ -769,59 +592,103 @@ H5F_contig_readv(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Adjust absolute EOA address to relative EOA address */
rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Only need this when resizing sieve buffer */
+ max_data=_max_data-dset_offset_arr[u];
+
/* Compute the size of the sieve buffer */
+ /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
+
/* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
-
/* Grab the data out of the buffer (must be first piece of data in buffer ) */
HDmemcpy(buf,f->shared->sieve_buf,size);
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
} /* end else */
+ } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment sequence number */
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
u++;
- } /* end else */
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end if */
else {
/* Work through all the sequences */
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
+ for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
- if (H5F_block_read(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
+
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end else */
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_readv() */
+} /* end H5F_contig_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_contig_writev
+ * Function: H5F_contig_writevv
*
- * Purpose: Writes some data vectors into a dataset from a buffer.
- * The data is contiguous. The address is the start of the dataset,
+ * Purpose: Writes some data vectors into a dataset from vectors into a
+ * buffer. The address is the start of the dataset,
* relative to the base address for the file and the offsets and
* sequence lengths are in bytes.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Thursday, July 5, 2001
+ * Friday, May 2, 2003
*
* Notes:
* Offsets in the sequences must be monotonically increasing
@@ -830,10 +697,11 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
- size_t nseq, size_t size_arr[], hsize_t offset_arr[], hid_t dxpl_id,
- const void *_buf)
+ssize_t
+H5F_contig_writevv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, const void *_buf)
{
const unsigned char *buf=_buf; /* Pointer to buffer to fill */
haddr_t abs_eoa; /* Absolute end of file address */
@@ -842,18 +710,10 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
hsize_t max_data; /* Actual maximum size of data to cache */
size_t size; /* Size of sequence in bytes */
size_t u; /* Counting variable */
-#ifndef SLOW_WAY
- size_t max_seq; /* Maximum sequence to copy */
- haddr_t temp_end; /* Temporary end of buffer variable */
- size_t max_search; /* Maximum number of sequences to search */
- size_t mask; /* Bit mask */
- int bit_loc; /* Bit location of the leftmost '1' in max_search */
- size_t *size_arr_p; /* Pointer into the size array */
- hsize_t *offset_arr_p; /* Pointer into the offset array */
-#endif /* SLOW_WAY */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
- FUNC_ENTER_NOAPI(H5F_contig_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_contig_writevv, FAIL);
/* Check args */
assert(f);
@@ -861,421 +721,284 @@ H5F_contig_writev(H5F_t *f, hsize_t _max_data, H5FD_mem_t type, haddr_t _addr,
/* Check if data sieving is enabled */
if(f->shared->lf->feature_flags&H5FD_FEAT_DATA_SIEVE) {
+ haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
+ haddr_t contig_end; /* End locations of block to write */
+ size_t sieve_size; /* size of sieve buffer */
+
+ /* Set offsets in sequence lists */
+ u=*dset_curr_seq;
+ v=*mem_curr_seq;
+
+ /* No data sieve buffer yet, go allocate one */
+ if(f->shared->sieve_buf==NULL) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Set up the buffer parameters */
+ max_data=_max_data-dset_offset_arr[u];
+
+ /* Check if we can actually hold the I/O request in the sieve buffer */
+ if(size>f->shared->sieve_buf_size) {
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+ } /* end if */
+ else {
+ /* Allocate room for the data sieve buffer */
+ if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- /* Outer loop, guarantees working through all the sequences */
- for(u=0; u<nseq; ) {
-
- /* Try writing into the data sieve buffer */
- if(f->shared->sieve_buf) {
- haddr_t sieve_start, sieve_end; /* Start & end locations of sieve buffer */
- haddr_t contig_end; /* End locations of block to write */
- size_t sieve_size; /* size of sieve buffer */
-
- /* Stash local copies of these value */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- /* Next-outer loop works through sequences as fast as possible */
- for(; u<nseq; ) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
-
- /* Compute end of sequence to retrieve */
- contig_end=addr+size-1;
-
- /* If entire write is within the sieve buffer, write it to the buffer */
- if(addr>=sieve_start && contig_end<sieve_end) {
- unsigned char *base_sieve_buf=f->shared->sieve_buf+(_addr-sieve_start);
- unsigned char *temp_sieve_buf;
- haddr_t temp_addr=_addr-1; /* Temporary address */
-
-#ifdef SLOW_WAY
- /* Retrieve all the sequences out of the current sieve buffer */
- while(contig_end<sieve_end) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+offset_arr[u];
-
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,size_arr[u]);
-
- /* Increment offset in buffer */
- buf += size_arr[u];
-
- /* Increment sequence number, check for finished with sequences */
- if((++u) >= nseq)
- break;
-
- /* Re-compute end of sequence to retrieve */
- contig_end=temp_addr+offset_arr[u]+size_arr[u];
- } /* end while */
-#else /* SLOW_WAY */
- /* Find log2(n) where n is the number of elements to search */
-
- /* Set initial parameters */
- mask=(size_t)0xff<<((sizeof(size_t)-1)*8); /* Get a mask for the leftmost byte */
- max_search=((nseq-1)-u)+1; /* Compute 'n' for the log2 */
- assert(max_search>0); /* Sanity check */
- bit_loc=(sizeof(size_t)*8)-1; /* Initial bit location */
-
- /* Search for the first byte with a bit set */
- while((max_search & mask)==0) {
- mask>>=8;
- bit_loc-=8;
- } /* end while */
-
- /* Switch to searching for a bit */
- mask=1<<bit_loc;
- while((max_search & mask)==0) {
- mask>>=1;
- bit_loc--;
- } /* end while */
-
- /* location of the leftmost bit, plus 1, is log2(n) */
- max_seq=bit_loc+1;
-
- /* Don't walk off the array */
- max_seq=MIN(u+max_seq,nseq-1);
-
- /* Determine if a linear search is faster than a binary search */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- if(temp_end>=sieve_end) {
- /* Linear search is faster */
-
- /* Set the initial search values */
- max_seq=u;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Search for the first sequence ending greater than the sieve buffer end */
- while(temp_end<sieve_end) {
- if(++max_seq>=nseq)
- break;
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
- } /* end while */
-
- /* Adjust back one element */
- max_seq--;
-
- } /* end if */
- else {
- size_t lo,hi; /* Low and high bounds for binary search */
- unsigned found=0; /* Flag to indicate bounds have been found */
-
- /* Binary search is faster */
-
- /* Find the value 'u' which will be beyond the end of the sieve buffer */
- lo=u;
- hi=nseq-1;
- max_seq=(lo+hi)/2;
- while(!found) {
- /* Get the address of the end of sequence for the 'max_seq' position */
- temp_end=temp_addr+offset_arr[max_seq]+size_arr[max_seq];
-
- /* Current high bound is too large */
- if(temp_end>=sieve_end) {
- if((lo+1)<hi) {
- hi=max_seq;
- max_seq=(lo+hi)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end if */
- /* Current low bound is too small */
- else {
- if((lo+1)<hi) {
- lo=max_seq;
- max_seq=(lo+hi+1)/2;
- } /* end if */
- else {
- found=1;
- } /* end else */
- } /* end else */
- } /* end while */
-
- /* Check for non-exact match */
- if(lo!=hi) {
- temp_end=temp_addr+offset_arr[hi]+size_arr[hi];
- if(temp_end<sieve_end)
- max_seq=hi;
- else
- max_seq=lo;
- } /* end if */
- } /* end else */
-
- /* Set the pointers to the correct locations in the offset & size arrays */
- size_arr_p=&size_arr[u];
- offset_arr_p=&offset_arr[u];
-
-#ifdef NO_DUFFS_DEVICE
- /* Retrieve all the sequences out of the current sieve buffer */
- while(u<=max_seq) {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Increment the offset in the array */
- u++;
- } /* end while */
-#else /* NO_DUFFS_DEVICE */
-{
- size_t seq_count;
+ /* Compute the size of the sieve buffer */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- seq_count=(max_seq-u)+1;
- switch (seq_count % 4) {
- case 0:
- do
- {
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Check if there is any point in reading the data from the file */
+ if(f->shared->sieve_size>size) {
+ /* Read the new sieve buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
+ } /* end else */
- /* Increment the offset in the array */
- u++;
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- case 3:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end if */
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Stash local copies of these value */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
+
+ /* Works through sequences as fast as possible */
+ for(; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
- /* Increment the offset in the array */
- u++;
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
- case 2:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ /* Compute end of sequence to retrieve */
+ contig_end=addr+size-1;
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* If entire write is within the sieve buffer, write it to the buffer */
+ if(addr>=sieve_start && contig_end<sieve_end) {
+ unsigned char *base_sieve_buf=f->shared->sieve_buf+(addr-sieve_start);
- /* Increment the offset in the array */
- u++;
+ /* Put the data into the sieve buffer */
+ HDmemcpy(base_sieve_buf,buf,size);
- case 1:
- /* Set the location within the sieve buffer to the correct offset */
- temp_sieve_buf=base_sieve_buf+*offset_arr_p++;
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
- /* Grab the data out of the buffer */
- HDmemcpy(temp_sieve_buf,buf,*size_arr_p);
+ } /* end if */
+ /* Entire request is not within this data sieve buffer */
+ else {
+ /* Check if we can actually hold the I/O request in the sieve buffer */
+ if(size>f->shared->sieve_buf_size) {
+ /* Check for any overlap with the current sieve buffer */
+ if((sieve_start>=addr && sieve_start<(contig_end+1))
+ || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
+ /* Flush the sieve buffer, if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += *size_arr_p++;
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
+ } /* end if */
- /* Increment the offset in the array */
- u++;
+ /* Force the sieve buffer to be re-read the next time */
+ f->shared->sieve_loc=HADDR_UNDEF;
+ f->shared->sieve_size=0;
+ } /* end if */
- } while (u<=max_seq);
- } /* end switch */
+ /* Write directly from the user's buffer */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+ } /* end if */
+ /* Element size fits within the buffer size */
+ else {
+ /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */
+ if(((addr+size)==sieve_start || addr==sieve_end) &&
+ (size+sieve_size)<=f->shared->sieve_buf_size &&
+ f->shared->sieve_dirty) {
+ /* Prepend to existing sieve buffer */
+ if((addr+size)==sieve_start) {
+ /* Move existing sieve information to correct location */
+ HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,sieve_size);
+
+ /* Copy in new information (must be first in sieve buffer) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
+
+ /* Adjust sieve location */
+ f->shared->sieve_loc=addr;
+
+ } /* end if */
+ /* Append to existing sieve buffer */
+ else {
+ /* Copy in new information */
+ HDmemcpy(f->shared->sieve_buf+sieve_size,buf,size);
+ } /* end else */
-}
-#endif /* NO_DUFFS_DEVICE */
-#endif /* SLOW_WAY */
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
+ /* Adjust sieve size */
+ f->shared->sieve_size += size;
+
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
} /* end if */
- /* Entire request is not within this data sieve buffer */
+ /* Can't add the new data onto the existing sieve buffer */
else {
- /* Check if we can actually hold the I/O request in the sieve buffer */
- if(size>f->shared->sieve_buf_size) {
- /* Check for any overlap with the current sieve buffer */
- if((sieve_start>=addr && sieve_start<(contig_end+1))
- || ((sieve_end-1)>=addr && (sieve_end-1)<(contig_end+1))) {
- /* Flush the sieve buffer, if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Force the sieve buffer to be re-read the next time */
- f->shared->sieve_loc=HADDR_UNDEF;
- f->shared->sieve_size=0;
- } /* end if */
-
- /* Write directly from the user's buffer */
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
+ /* Flush the sieve buffer if it's dirty */
+ if(f->shared->sieve_dirty) {
+ /* Write to file */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Reset sieve buffer dirty flag */
+ f->shared->sieve_dirty=0;
} /* end if */
- /* Element size fits within the buffer size */
- else {
- /* Check if it is possible to (exactly) prepend or append to existing (dirty) sieve buffer */
- if(((addr+size)==sieve_start || addr==sieve_end) &&
- (size+sieve_size)<=f->shared->sieve_buf_size &&
- f->shared->sieve_dirty) {
- /* Prepend to existing sieve buffer */
- if((addr+size)==sieve_start) {
- /* Move existing sieve information to correct location */
- HDmemmove(f->shared->sieve_buf+size,f->shared->sieve_buf,sieve_size);
-
- /* Copy in new information (must be first in sieve buffer) */
- HDmemcpy(f->shared->sieve_buf,buf,size);
-
- /* Adjust sieve location */
- f->shared->sieve_loc=addr;
-
- } /* end if */
- /* Append to existing sieve buffer */
- else {
- /* Copy in new information */
- HDmemcpy(f->shared->sieve_buf+sieve_size,buf,size);
- } /* end else */
-
- /* Adjust sieve size */
- f->shared->sieve_size += size;
-
- /* Update local copies of sieve information */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- } /* end if */
- /* Can't add the new data onto the existing sieve buffer */
- else {
- /* Flush the sieve buffer if it's dirty */
- if(f->shared->sieve_dirty) {
- /* Write to file */
- if (H5F_block_write(f, H5FD_MEM_DRAW, sieve_start, sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
- /* Reset sieve buffer dirty flag */
- f->shared->sieve_dirty=0;
- } /* end if */
-
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
-
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
-
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
-
- /* Only need this when resizing sieve buffer */
- max_data=_max_data-offset_arr[u];
-
- /* Compute the size of the sieve buffer */
- /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
-
- /* Update local copies of sieve information */
- sieve_start=f->shared->sieve_loc;
- sieve_size=f->shared->sieve_size;
- sieve_end=sieve_start+sieve_size;
-
- /* Check if there is any point in reading the data from the file */
- if(f->shared->sieve_size>size) {
- /* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
-
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(f->shared->sieve_buf,buf,size);
-
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
-
- } /* end else */
- } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Determine the new sieve buffer size & location */
+ f->shared->sieve_loc=addr;
- /* Increment sequence number */
- u++;
- } /* end else */
- } /* end for */
- } /* end if */
- /* No data sieve buffer yet, go allocate one */
- else {
- /* Set up the buffer parameters */
- size=size_arr[u];
- addr=_addr+offset_arr[u];
- max_data=_max_data-offset_arr[u];
+ /* Make certain we don't read off the end of the file */
+ if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
- /* Check if we can actually hold the I/O request in the sieve buffer */
- if(size>f->shared->sieve_buf_size) {
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- } /* end if */
- else {
- /* Allocate room for the data sieve buffer */
- if (NULL==(f->shared->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,f->shared->sieve_buf_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ /* Adjust absolute EOA address to relative EOA address */
+ rel_eoa=abs_eoa-f->shared->base_addr;
- /* Determine the new sieve buffer size & location */
- f->shared->sieve_loc=addr;
+ /* Only need this when resizing sieve buffer */
+ max_data=_max_data-dset_offset_arr[u];
- /* Make certain we don't read off the end of the file */
- if (HADDR_UNDEF==(abs_eoa=H5FD_get_eoa(f->shared->lf)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to determine file size");
+ /* Compute the size of the sieve buffer */
+ /* Don't read off the end of the file, don't read past the end of the data element and don't read more than the buffer size */
+ H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
- /* Adjust absolute EOA address to relative EOA address */
- rel_eoa=abs_eoa-f->shared->base_addr;
+ /* Update local copies of sieve information */
+ sieve_start=f->shared->sieve_loc;
+ sieve_size=f->shared->sieve_size;
+ sieve_end=sieve_start+sieve_size;
- /* Compute the size of the sieve buffer */
- H5_ASSIGN_OVERFLOW(f->shared->sieve_size,MIN(rel_eoa-f->shared->sieve_loc,MIN(max_data,f->shared->sieve_buf_size)),hsize_t,size_t);
+ /* Check if there is any point in reading the data from the file */
+ if(f->shared->sieve_size>size) {
+ /* Read the new sieve buffer */
+ if (H5F_block_read(f, H5FD_MEM_DRAW, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
+ } /* end if */
- /* Check if there is any point in reading the data from the file */
- if(f->shared->sieve_size>size) {
- /* Read the new sieve buffer */
- if (H5F_block_read(f, type, f->shared->sieve_loc, f->shared->sieve_size, dxpl_id, f->shared->sieve_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
- } /* end if */
+ /* Grab the data out of the buffer (must be first piece of data in buffer ) */
+ HDmemcpy(f->shared->sieve_buf,buf,size);
- /* Grab the data out of the buffer (must be first piece of data in buffer ) */
- HDmemcpy(f->shared->sieve_buf,buf,size);
+ /* Set sieve buffer dirty flag */
+ f->shared->sieve_dirty=1;
- /* Set sieve buffer dirty flag */
- f->shared->sieve_dirty=1;
+ } /* end else */
} /* end else */
+ } /* end else */
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
- /* Increment sequence number */
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
u++;
- } /* end else */
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end if */
else {
/* Work through all the sequences */
- for(u=0; u<nseq; u++) {
- size=size_arr[u];
- addr=_addr+offset_arr[u];
+ for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
- if (H5F_block_write(f, type, addr, size, dxpl_id, buf)<0)
+ /* Compute offset on disk */
+ addr=_addr+dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5F_block_write(f, H5FD_MEM_DRAW, addr, size, dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
- /* Increment offset in buffer */
- buf += size_arr[u];
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
+
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
} /* end for */
} /* end else */
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5F_contig_writev() */
+} /* end H5F_contig_writevv() */
diff --git a/src/H5Fistore.c b/src/H5Fistore.c
index 7f8d7e1..9629963 100644
--- a/src/H5Fistore.c
+++ b/src/H5Fistore.c
@@ -1685,246 +1685,154 @@ H5F_istore_unlock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
/*-------------------------------------------------------------------------
- * Function: H5F_istore_read
+ * Function: H5F_istore_readvv
*
* Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
* storage array.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Wednesday, October 15, 1997
+ * Programmer: Quincey Koziol
+ * Wednesday, May 7, 2003
*
* Modifications:
- * Robb Matzke, 1999-08-02
- * The data transfer property list is passed as an object ID
- * since that's how the virtual file layer wants it.
*
- * Quincey Koziol, 2002-04-02
- * Enable hyperslab I/O into memory buffer
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_istore_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const hsize_t size_m[], const hssize_t offset_m[],
- const hssize_t offset_f[], const hsize_t size[], void *buf)
+ssize_t
+H5F_istore_readvv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+ H5P_genplist_t *dc_plist, hssize_t chunk_coords[],
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf)
{
- hsize_t idx_cur[H5O_LAYOUT_NDIMS];
- hsize_t idx_min[H5O_LAYOUT_NDIMS];
- hsize_t idx_max[H5O_LAYOUT_NDIMS];
- hsize_t sub_size[H5O_LAYOUT_NDIMS];
- hssize_t offset_wrt_chunk[H5O_LAYOUT_NDIMS];
- hssize_t sub_offset_m[H5O_LAYOUT_NDIMS];
- hssize_t chunk_offset[H5O_LAYOUT_NDIMS];
- int i, carry;
- unsigned u;
- hsize_t naccessed; /*bytes accessed in chnk*/
- uint8_t *chunk=NULL; /*ptr to a chunk buffer */
- unsigned idx_hint=0; /*cache index hint */
- hsize_t chunk_size; /* Bytes in chunk */
+ hsize_t chunk_size; /* Chunk size, in bytes */
haddr_t chunk_addr; /* Chunk address on disk */
+ hssize_t chunk_coords_in_elmts[H5O_LAYOUT_NDIMS];
H5O_pline_t pline; /* I/O pipeline information */
- H5O_fill_t fill; /* Fill value information */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_istore_read, FAIL);
+ size_t u; /* Local index variables */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5F_istore_readvv, FAIL);
/* Check args */
assert(f);
assert(layout && H5D_CHUNKED==layout->type);
assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS);
- assert(H5F_addr_defined(layout->addr));
- assert(size_m);
- assert(offset_m);
- assert(offset_f);
- assert(size);
+ assert(chunk_len_arr);
+ assert(chunk_offset_arr);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
assert(buf);
/* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline");
/* Compute chunk size */
for (u=0, chunk_size=1; u<layout->ndims; u++)
chunk_size *= layout->dim[u];
-
+
#ifndef NDEBUG
- for (u=0; u<layout->ndims; u++) {
- assert(offset_f[u]>=0); /*negative offsets not supported*/
- assert(offset_m[u]>=0); /*negative offsets not supported*/
- assert(size[u]<SIZET_MAX);
- assert(offset_m[u]+(hssize_t)size[u]<=(hssize_t)size_m[u]);
- assert(layout->dim[u]>0);
- }
+ for (u=0; u<layout->ndims; u++)
+ assert(chunk_coords[u]>=0); /*negative coordinates not supported (yet) */
#endif
+
+ for (u=0; u<layout->ndims; u++)
+ chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
+
+ /* Get the address of this chunk on disk */
+ chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
/*
- * Set up multi-dimensional counters (idx_min, idx_max, and idx_cur) and
- * loop through the chunks copying each to its final destination in the
- * application buffer.
+ * If the chunk is too large to load into the cache and it has no
+ * filters in the pipeline (i.e. not compressed) and if the address
+ * for the chunk has been defined, then don't load the chunk into the
+ * cache, just write the data to it directly.
*/
- for (u=0; u<layout->ndims; u++) {
- idx_min[u] = offset_f[u] / layout->dim[u];
- idx_max[u] = (offset_f[u]+size[u]-1) / layout->dim[u] + 1;
- idx_cur[u] = idx_min[u];
- }
-
- /* Loop over all chunks */
- carry=0;
- while (carry==0) {
- for (u=0, naccessed=1; u<layout->ndims; u++) {
- /* The location and size of the chunk being accessed */
- assert(layout->dim[u] < HSSIZET_MAX);
- chunk_offset[u] = idx_cur[u] * (hssize_t)(layout->dim[u]);
-
- /* The offset and size wrt the chunk */
- offset_wrt_chunk[u] = MAX(offset_f[u], chunk_offset[u]) -
- chunk_offset[u];
- sub_size[u] = MIN((idx_cur[u]+1)*layout->dim[u],
- offset_f[u]+size[u]) -
- (chunk_offset[u] + offset_wrt_chunk[u]);
- naccessed *= sub_size[u];
-
- /* Offset into mem buffer */
- sub_offset_m[u] = chunk_offset[u] + offset_wrt_chunk[u] +
- offset_m[u] - offset_f[u];
- }
+ if (chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
+ chunk_addr!=HADDR_UNDEF) {
+ if ((ret_value=H5F_contig_readvv(f, chunk_size, chunk_addr, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, dxpl_id, buf))<0)
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data to file");
+ } /* end if */
+ else {
+ uint8_t *chunk; /* Pointer to cached chunk in memory */
+ H5O_fill_t fill; /* Fill value information */
+ unsigned idx_hint=0; /* Cache index hint */
+ ssize_t naccessed; /* Number of bytes accessed in chunk */
- /* Get the address of this chunk on disk */
- chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_offset);
+ /* Get necessary properties from property list */
+ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
/*
- * If the chunk is too large to load into the cache and it has no
- * filters in the pipeline (i.e. not compressed) and if the address
- * for the chunk has been defined, then don't load the chunk into the
- * cache, just read the data from it directly.
+ * Lock the chunk, copy from application to chunk, then unlock the
+ * chunk.
*/
- if ((chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
- chunk_addr!=HADDR_UNDEF)
+ if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
+ chunk_coords_in_elmts, FALSE, &idx_hint)))
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk");
- /*
- * If MPIO, MPIPOSIX, or FPHDF5 is used and file can be written
- * to, we must bypass the chunk-cache scheme because other MPI
- * processes could be writing to other elements in the same
- * chunk. Do a direct write-through of only the elements
- * requested.
- */
- || ((IS_H5FD_MPIO(f) ||IS_H5FD_MPIPOSIX(f) || IS_H5FD_FPHDF5(f)) && (H5F_ACC_RDWR & f->shared->flags))
- ) {
- H5O_layout_t l; /* temporary layout */
+ /* Use the vectorized memory copy routine to do actual work */
+ if((naccessed=H5V_memcpyvv(buf,mem_max_nseq,mem_curr_seq,mem_len_arr,mem_offset_arr,chunk,chunk_max_nseq,chunk_curr_seq,chunk_len_arr,chunk_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vectorized memcpy failed");
-#ifdef H5_HAVE_PARALLEL
- /* Additional sanity checks when operating in parallel */
- if (chunk_addr==HADDR_UNDEF || pline.nfilters>0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
-#endif /* H5_HAVE_PARALLEL */
-
- /*
- * use default transfer mode as we do not support collective
- * transfer mode since each data write could decompose into
- * multiple chunk writes and we are not doing the calculation yet.
- */
- l.type = H5D_CONTIGUOUS;
- l.ndims = layout->ndims;
- for (u=l.ndims; u-- > 0; /*void*/)
- l.dim[u] = layout->dim[u];
- l.addr = chunk_addr;
- if (H5F_arr_read(f, dxpl_id, &l, dc_plist, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0)
- HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, "unable to read raw data from file");
- } /* end if */
- else {
- /*
- * Lock the chunk, transfer data to the application, then unlock
- * the chunk.
- */
- if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
- chunk_offset, FALSE, &idx_hint)))
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk");
- H5V_hyper_copy(layout->ndims, sub_size, size_m, sub_offset_m,
- (void*)buf, layout->dim, offset_wrt_chunk, chunk);
- H5_CHECK_OVERFLOW(naccessed,hsize_t,size_t);
- if (H5F_istore_unlock(f, dxpl_id, layout, &pline, FALSE,
- chunk_offset, &idx_hint, chunk, (size_t)naccessed)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk");
- } /* end else */
-
- /* Increment indices */
- for (i=(int)(layout->ndims-1), carry=1; i>=0 && carry; --i) {
- if (++idx_cur[i]>=idx_max[i])
- idx_cur[i] = idx_min[i];
- else
- carry = 0;
- }
- }
+ H5_CHECK_OVERFLOW(naccessed,ssize_t,size_t);
+ if (H5F_istore_unlock(f, dxpl_id, layout, &pline, FALSE,
+ chunk_coords_in_elmts, &idx_hint, chunk, (size_t)naccessed)<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk");
+ /* Set return value */
+ ret_value=naccessed;
+ } /* end else */
+
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* H5F_istore_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_istore_write
+ * Function: H5F_istore_writevv
*
* Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
* storage array.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * Wednesday, October 15, 1997
+ * Programmer: Quincey Koziol
+ * Friday, May 2, 2003
*
* Modifications:
- * Robb Matzke, 1999-08-02
- * The data transfer property list is passed as an object ID
- * since that's how the virtual file layer wants it.
*
- * Quincey Koziol, 2002-04-02
- * Enable hyperslab I/O into memory buffer
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- const hsize_t size_m[], const hssize_t offset_m[],
- const hssize_t offset_f[], const hsize_t size[],
- const void *buf)
+ssize_t
+H5F_istore_writevv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
+ H5P_genplist_t *dc_plist, hssize_t chunk_coords[],
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf)
{
- int i, carry;
- unsigned u;
- hsize_t idx_cur[H5O_LAYOUT_NDIMS];
- hsize_t idx_min[H5O_LAYOUT_NDIMS];
- hsize_t idx_max[H5O_LAYOUT_NDIMS];
- hsize_t sub_size[H5O_LAYOUT_NDIMS];
- hssize_t chunk_offset[H5O_LAYOUT_NDIMS];
- hssize_t offset_wrt_chunk[H5O_LAYOUT_NDIMS];
- hssize_t sub_offset_m[H5O_LAYOUT_NDIMS];
- uint8_t *chunk=NULL;
- unsigned idx_hint=0;
- hsize_t chunk_size, naccessed;
+ hsize_t chunk_size; /* Chunk size, in bytes */
haddr_t chunk_addr; /* Chunk address on disk */
+ hssize_t chunk_coords_in_elmts[H5O_LAYOUT_NDIMS];
H5O_pline_t pline; /* I/O pipeline information */
- H5O_fill_t fill; /* Fill value information */
- herr_t ret_value = SUCCEED; /* Return value */
+ size_t u; /* Local index variables */
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_istore_write, FAIL);
+ FUNC_ENTER_NOAPI(H5F_istore_writevv, FAIL);
/* Check args */
assert(f);
assert(layout && H5D_CHUNKED==layout->type);
assert(layout->ndims>0 && layout->ndims<=H5O_LAYOUT_NDIMS);
- assert(H5F_addr_defined(layout->addr));
- assert(size_m);
- assert(offset_m);
- assert(offset_f);
- assert(size);
+ assert(chunk_len_arr);
+ assert(chunk_offset_arr);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
assert(buf);
/* Get necessary properties from property list */
- if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline");
@@ -1933,118 +1841,79 @@ H5F_istore_write(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
chunk_size *= layout->dim[u];
#ifndef NDEBUG
- for (u=0; u<layout->ndims; u++) {
- assert(offset_f[u]>=0); /*negative offsets not supported*/
- assert(offset_m[u]>=0); /*negative offsets not supported*/
- assert(size[u]<SIZET_MAX);
- assert(offset_m[u]+(hssize_t)size[u]<=(hssize_t)size_m[u]);
- assert(layout->dim[u]>0);
- }
+ for (u=0; u<layout->ndims; u++)
+ assert(chunk_coords[u]>=0); /*negative coordinates not supported (yet) */
#endif
+
+ for (u=0; u<layout->ndims; u++)
+ chunk_coords_in_elmts[u] = chunk_coords[u] * (hssize_t)(layout->dim[u]);
+
+ /* Get the address of this chunk on disk */
+ chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_coords_in_elmts);
/*
- * Set up multi-dimensional counters (idx_min, idx_max, and idx_cur) and
- * loop through the chunks copying each chunk from the application to the
- * chunk cache.
+ * If the chunk is too large to load into the cache and it has no
+ * filters in the pipeline (i.e. not compressed) and if the address
+ * for the chunk has been defined, then don't load the chunk into the
+ * cache, just write the data to it directly.
+ *
+ * If MPIO, MPIPOSIX, or FPHDF5 is used, must bypass the
+ * chunk-cache scheme because other MPI processes could be
+ * writing to other elements in the same chunk. Do a direct
+ * write-through of only the elements requested.
*/
- for (u=0; u<layout->ndims; u++) {
- idx_min[u] = offset_f[u] / layout->dim[u];
- idx_max[u] = (offset_f[u]+size[u]-1) / layout->dim[u] + 1;
- idx_cur[u] = idx_min[u];
- }
-
-
- /* Loop over all chunks */
- carry=0;
- while (carry==0) {
- for (u=0, naccessed=1; u<layout->ndims; u++) {
- /* The location and size of the chunk being accessed */
- assert(layout->dim[u] < HSSIZET_MAX);
- chunk_offset[u] = idx_cur[u] * (hssize_t)(layout->dim[u]);
-
- /* The offset and size wrt the chunk */
- offset_wrt_chunk[u] = MAX(offset_f[u], chunk_offset[u]) -
- chunk_offset[u];
- sub_size[u] = MIN((idx_cur[u]+1)*layout->dim[u],
- offset_f[u]+size[u]) -
- (chunk_offset[u] + offset_wrt_chunk[u]);
- naccessed *= sub_size[u];
-
- /* Offset into mem buffer */
- sub_offset_m[u] = chunk_offset[u] + offset_wrt_chunk[u] +
- offset_m[u] - offset_f[u];
- }
-
- /* Get the address of this chunk on disk */
- chunk_addr=H5F_istore_get_addr(f, dxpl_id, layout, chunk_offset);
+ if ((chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
+ chunk_addr!=HADDR_UNDEF)
+ || ((IS_H5FD_MPIO(f) ||IS_H5FD_MPIPOSIX(f) || IS_H5FD_FPHDF5(f)) &&
+ (H5F_ACC_RDWR & f->shared->flags))) {
+#ifdef H5_HAVE_PARALLEL
+ /* Additional sanity check when operating in parallel */
+ if (chunk_addr==HADDR_UNDEF || pline.nfilters>0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
+#endif /* H5_HAVE_PARALLEL */
+ if ((ret_value=H5F_contig_writevv(f, chunk_size, chunk_addr, chunk_max_nseq, chunk_curr_seq, chunk_len_arr, chunk_offset_arr, mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr, dxpl_id, buf))<0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file");
+ } /* end if */
+ else {
+ uint8_t *chunk; /* Pointer to cached chunk in memory */
+ H5O_fill_t fill; /* Fill value information */
+ unsigned idx_hint=0; /* Cache index hint */
+ ssize_t naccessed; /* Number of bytes accessed in chunk */
+ hbool_t relax; /* Whether whole chunk is selected */
- /*
- * If the chunk is too large to load into the cache and it has no
- * filters in the pipeline (i.e. not compressed) and if the address
- * for the chunk has been defined, then don't load the chunk into the
- * cache, just write the data to it directly.
- */
- if ((chunk_size>f->shared->rdcc_nbytes && pline.nfilters==0 &&
- chunk_addr!=HADDR_UNDEF)
+ /* Get necessary properties from property list */
+ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value");
/*
- * If MPIO, MPIPOSIX, or FPHDF5 is used, must bypass the
- * chunk-cache scheme because other MPI processes could be
- * writing to other elements in the same chunk. Do a direct
- * write-through of only the elements requested.
+ * Lock the chunk, copy from application to chunk, then unlock the
+ * chunk.
*/
- || ((IS_H5FD_MPIO(f) ||IS_H5FD_MPIPOSIX(f) || IS_H5FD_FPHDF5(f)) && (H5F_ACC_RDWR & f->shared->flags))
- ) {
- H5O_layout_t l; /* temporary layout */
-
-#ifdef H5_HAVE_PARALLEL
- /* Additional sanity check when operating in parallel */
- if (chunk_addr==HADDR_UNDEF || pline.nfilters>0) {
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk");
- }
-#endif /* H5_HAVE_PARALLEL */
-
- /*
- * use default transfer mode as we do not support collective
- * transfer mode since each data write could decompose into
- * multiple chunk writes and we are not doing the calculation yet.
- */
- l.type = H5D_CONTIGUOUS;
- l.ndims = layout->ndims;
- for (u=l.ndims; u-- > 0; /*void*/)
- l.dim[u] = layout->dim[u];
- l.addr = chunk_addr;
- if (H5F_arr_write(f, dxpl_id, &l, dc_plist, sub_size, size_m, sub_offset_m, offset_wrt_chunk, buf)<0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file");
- } /* end if */
- else {
- /*
- * Lock the chunk, copy from application to chunk, then unlock the
- * chunk.
- */
- if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
- chunk_offset, (hbool_t)(naccessed==chunk_size), &idx_hint)))
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk");
- H5V_hyper_copy(layout->ndims, sub_size,
- layout->dim, offset_wrt_chunk, chunk, size_m, sub_offset_m, buf);
- H5_CHECK_OVERFLOW(naccessed,hsize_t,size_t);
- if (H5F_istore_unlock(f, dxpl_id, layout, &pline, TRUE,
- chunk_offset, &idx_hint, chunk, (size_t)naccessed)<0)
- HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk");
- } /* end else */
+ if(chunk_max_nseq==1 && chunk_len_arr[0] == chunk_size)
+ relax = TRUE;
+ else
+ relax = FALSE;
+
+ if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill,
+ chunk_coords_in_elmts, relax, &idx_hint)))
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk");
+
+ /* Use the vectorized memory copy routine to do actual work */
+ if((naccessed=H5V_memcpyvv(chunk,chunk_max_nseq,chunk_curr_seq,chunk_len_arr,chunk_offset_arr,buf,mem_max_nseq,mem_curr_seq,mem_len_arr,mem_offset_arr))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vectorized memcpy failed");
+
+ H5_CHECK_OVERFLOW(naccessed,ssize_t,size_t);
+ if (H5F_istore_unlock(f, dxpl_id, layout, &pline, TRUE,
+ chunk_coords_in_elmts, &idx_hint, chunk, (size_t)naccessed)<0)
+ HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "uanble to unlock raw data chunk");
+
+ /* Set return value */
+ ret_value=naccessed;
+ } /* end else */
- /* Increment indices */
- for (i=layout->ndims-1, carry=1; i>=0 && carry; --i) {
- if (++idx_cur[i]>=idx_max[i])
- idx_cur[i] = idx_min[i];
- else
- carry = 0;
- }
- } /* end while */
-
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* H5F_istore_writevv() */
/*-------------------------------------------------------------------------
@@ -2808,7 +2677,8 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay
hsize_t size[H5O_LAYOUT_NDIMS]; /*current size of dimensions */
H5S_t *space_chunk = NULL; /*dataspace for a chunk */
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /*current dataspace dimensions */
- int rank; /*current # of dimensions */
+ int srank; /*current # of dimensions (signed) */
+ unsigned rank; /*current # of dimensions */
int i, carry; /*counters */
unsigned u;
int found = 0; /*initialize this entry */
@@ -2836,13 +2706,14 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay
HDmemset(count, 0, sizeof(count));
/* Go get the rank & dimensions */
- if((rank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
+ if((srank = H5S_get_simple_extent_dims(space, curr_dims, NULL)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions");
+ rank=srank;
/* Copy current dimensions */
- for(i = 0; i < rank; i++)
- size[i] = curr_dims[i];
- size[i] = layout->dim[i];
+ for(u = 0; u < rank; u++)
+ size[u] = curr_dims[u];
+ size[u] = layout->dim[u];
/* Create a data space for a chunk & set the extent */
if(NULL == (space_chunk = H5S_create_simple(rank,layout->dim,NULL)))
@@ -2891,8 +2762,8 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay
if(H5S_select_all(space_chunk,1) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to select space");
- for(i = 0; i < rank; i++)
- count[i] = MIN((idx_cur[i] + 1) * layout->dim[i], size[i] - chunk_offset[i]);
+ for(u = 0; u < rank; u++)
+ count[u] = MIN((idx_cur[u] + 1) * layout->dim[u], size[u] - chunk_offset[u]);
#if defined (H5F_ISTORE_DEBUG)
HDfputs("cache:initialize:offset:[", stdout);
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 1b7e49c..0b875b7 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -81,7 +81,7 @@
#else
# define H5F_OVERFLOW_HSIZET2OFFT(X) 0
#endif
-
+
/* The raw data chunk cache */
typedef struct H5F_rdcc_t {
unsigned ninits; /* Number of chunk creations */
@@ -198,40 +198,38 @@ H5_DLL herr_t H5F_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
H5_DLL herr_t H5F_istore_init (H5F_t *f);
H5_DLL herr_t H5F_istore_flush (H5F_t *f, hid_t dxpl_id, unsigned flags);
H5_DLL herr_t H5F_istore_dest (H5F_t *f, hid_t dxpl_id);
-H5_DLL herr_t H5F_istore_read(H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
- const hsize_t size_m[], const hssize_t offset_m[],
- const hssize_t offset_f[], const hsize_t size[],
- void *buf/*out*/);
-H5_DLL herr_t H5F_istore_write(H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
- const hsize_t size_m[], const hssize_t offset_m[],
- const hssize_t offset[], const hsize_t size[],
- const void *buf);
+H5_DLL ssize_t H5F_istore_readvv(H5F_t *f, hid_t dxpl_id,
+ const struct H5O_layout_t *layout, struct H5P_genplist_t *dc_plist, hssize_t chunk_coords[],
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf);
+H5_DLL ssize_t H5F_istore_writevv(H5F_t *f, hid_t dxpl_id,
+ const struct H5O_layout_t *layout, struct H5P_genplist_t *dc_plist, hssize_t chunk_coords[],
+ size_t chunk_max_nseq, size_t *chunk_curr_seq, size_t chunk_len_arr[], hsize_t chunk_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf);
H5_DLL herr_t H5F_istore_stats (H5F_t *f, hbool_t headers);
H5_DLL herr_t H5F_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, int ndims);
/* Functions that operate on contiguous storage wrt boot block */
-H5_DLL herr_t H5F_contig_read(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
- size_t size, hid_t dxpl_id, void *_buf/*out*/);
-H5_DLL herr_t H5F_contig_write(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
- size_t size, hid_t dxpl_id, const void *buf);
-H5_DLL herr_t H5F_contig_readv(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
- size_t nseq, size_t size[], hsize_t offset[], hid_t dxpl_id, void *_buf/*out*/);
-H5_DLL herr_t H5F_contig_writev(H5F_t *f, hsize_t max_data, H5FD_mem_t type, haddr_t addr,
- size_t nseq, size_t size[], hsize_t offset[], hid_t dxpl_id, const void *buf);
+H5_DLL herr_t H5F_contig_readvv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, void *buf);
+H5_DLL ssize_t H5F_contig_writevv(H5F_t *f, hsize_t _max_data, haddr_t _addr,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ hid_t dxpl_id, const void *buf);
/* Functions that operate on compact dataset storage */
-H5_DLL herr_t H5F_compact_readv(H5F_t *f, const struct H5O_layout_t *layout, size_t nseq,
- size_t size_arr[], hsize_t offset_arr[],
- hid_t dxpl_id, void *_buf/*out*/);
-H5_DLL herr_t H5F_compact_writev(H5F_t *f, struct H5O_layout_t *layout, size_t nseq,
- size_t size_arr[], hsize_t offset_arr[],
- hid_t dxpl_id, const void *_buf);
-
-
+H5_DLL ssize_t H5F_compact_readvv(H5F_t UNUSED *f, const struct H5O_layout_t *layout,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[],
+ hid_t UNUSED dxpl_id, void *buf);
+H5_DLL ssize_t H5F_compact_writevv(H5F_t UNUSED *f, struct H5O_layout_t *layout,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_size_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_size_arr[], hsize_t mem_offset_arr[],
+ hid_t UNUSED dxpl_id, const void *buf);
#endif
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 6276422..26bd833 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -369,6 +369,7 @@ struct H5O_fill_t;
struct H5P_genplist_t;
struct H5S_t;
struct H5B_class_t;
+union H5D_storage_t;
/* Private functions, not part of the publicly documented API */
H5_DLL herr_t H5F_init(void);
@@ -392,23 +393,6 @@ H5_DLL size_t H5F_sizeof_size(const H5F_t *f);
H5_DLL unsigned H5F_sym_leaf_k(const H5F_t *f);
H5_DLL int H5F_Kvalue(const H5F_t *f, const struct H5B_class_t *type);
-
-/* Functions that operate on array storage */
-H5_DLL herr_t H5F_arr_read (H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
- const hsize_t _hslab_size[],
- const hsize_t mem_size[],
- const hssize_t mem_offset[],
- const hssize_t file_offset[], void *_buf/*out*/);
-H5_DLL herr_t H5F_arr_write (H5F_t *f, hid_t dxpl_id,
- struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist,
- const hsize_t _hslab_size[],
- const hsize_t mem_size[],
- const hssize_t mem_offset[],
- const hssize_t file_offset[], const void *_buf);
-
/* Functions that operate on blocks of bytes wrt boot block */
H5_DLL herr_t H5F_block_read(H5F_t *f, H5FD_mem_t type, haddr_t addr,
size_t size, hid_t dxpl_id, void *buf/*out*/);
@@ -418,32 +402,33 @@ H5_DLL herr_t H5F_block_write(H5F_t *f, H5FD_mem_t type, haddr_t addr,
/* Functions that operate on byte sequences */
H5_DLL herr_t H5F_seq_read(H5F_t *f, hid_t dxpl_id,
const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *file_space, size_t elmt_size, size_t seq_len,
+ struct H5P_genplist_t *dc_plist, const union H5D_storage_t *store,
+ size_t seq_len,
hsize_t file_offset, void *_buf/*out*/);
H5_DLL herr_t H5F_seq_write (H5F_t *f, hid_t dxpl_id,
struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *file_space, size_t elmt_size, size_t seq_len,
+ struct H5P_genplist_t *dc_plist, const union H5D_storage_t *store,
+ size_t seq_len,
hsize_t file_offset, const void *_buf);
-/* Functions that operate on vectors of byte sequences */
-H5_DLL herr_t H5F_seq_readv(H5F_t *f, hid_t dxpl_id,
- const struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *file_space, size_t elmt_size, size_t nseq,
- size_t seq_len[], hsize_t file_offset[], void *_buf/*out*/);
-H5_DLL herr_t H5F_seq_writev(H5F_t *f, hid_t dxpl_id,
- struct H5O_layout_t *layout,
- struct H5P_genplist_t *dc_plist, const struct H5O_efl_t *efl,
- const struct H5S_t *file_space, size_t elmt_size, size_t nseq,
- size_t seq_len[], hsize_t file_offset[], const void *_buf);
-
+/* Functions that operate on byte sequences in memory and on disk */
+H5_DLL ssize_t H5F_seq_readvv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const union H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf);
+H5_DLL ssize_t H5F_seq_writevv(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const union H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf);
/* Functions that operate on contiguous storage */
+H5_DLL herr_t H5F_contig_create(H5F_t *f, hid_t dxpl_id,
+ struct H5O_layout_t *layout);
H5_DLL herr_t H5F_contig_fill(H5F_t *f, hid_t dxpl_id,
struct H5O_layout_t *layout, struct H5P_genplist_t *dc_plist,
- const struct H5O_efl_t *efl, const struct H5S_t *space,
+ const struct H5S_t *space,
const struct H5O_fill_t *fill, size_t elmt_size);
H5_DLL herr_t H5F_contig_delete(H5F_t *f, hid_t dxpl_id,
const struct H5O_layout_t *layout);
diff --git a/src/H5Fseq.c b/src/H5Fseq.c
index 113a8d5..5248b0a 100644
--- a/src/H5Fseq.c
+++ b/src/H5Fseq.c
@@ -70,22 +70,24 @@ static int interface_initialize_g = 0;
*/
herr_t
H5F_seq_read(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, void *buf/*out*/)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t mem_len=seq_len; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_read, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "vector read failed");
done:
@@ -116,22 +118,24 @@ done:
*/
herr_t
H5F_seq_write(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
size_t seq_len, hsize_t dset_offset, const void *buf)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ hsize_t mem_off=0; /* Offset in memory */
+ size_t mem_len=seq_len; /* Length in memory */
+ size_t mem_curr_seq=0; /* "Current sequence" in memory */
+ size_t dset_curr_seq=0; /* "Current sequence" in dataset */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5F_seq_write, FAIL);
/* Check args */
assert(f);
assert(layout);
- assert(efl);
assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, 1, &seq_len, &dset_offset, buf)<0)
+ if (H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store, 1, &dset_curr_seq, &seq_len, &dset_offset, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "vector write failed");
done:
@@ -140,7 +144,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_seq_readv
+ * Function: H5F_seq_readvv
*
* Purpose: Reads in a vector of byte sequences from a file dataset into a
* buffer in in memory. The data is read from file F and the array's size
@@ -152,53 +156,61 @@ done:
* Bytes read into BUF are sequentially stored in the buffer, each sequence
* from the vector stored directly after the previous. The number of
* sequences is NSEQ.
+ * Purpose: Reads a vector of byte sequences from a vector of byte
+ * sequences in a file dataset into a buffer in memory. The data is
+ * read from file F and the array's size and storage information is in
+ * LAYOUT. External files and chunks are described according to the
+ * storage information, STORE. The vector of byte sequences offsets for
+ * the file is in the DSET_OFFSET_ARR array into the dataset (offsets are
+ * in terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
+ * array. The vector of byte sequences offsets for memory is in the
+ * MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
+ * and the size of each sequence is in the MEM_LEN_ARR array. The total
+ * size of the file array is implied in the LAYOUT argument. The maximum
+ * number of sequences in the file dataset and the memory buffer are
+ * DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
+ * operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
+ * & MEM_CURR_SEQ respectively. The current sequence being operated on
+ * will be updated as a result of the operation, as will the offsets and
+ * lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Wednesday, May 1, 2001
+ * Wednesday, May 7, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
- size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
- void *_buf/*out*/)
+ssize_t
+H5F_seq_readvv(H5F_t *f, hid_t dxpl_id, const struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf/*out*/)
{
- unsigned char *real_buf=(unsigned char *)_buf; /* Local pointer to buffer to fill */
- unsigned char *buf; /* Local pointer to buffer to fill */
- hsize_t dset_offset; /* Offset in dataset */
- hsize_t seq_len; /* Number of bytes to read */
- hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */
- hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */
- hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/
- hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative yperslab sizes (in elements) */
- hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
- int ndims;
- hsize_t max_data; /*bytes in dataset */
- haddr_t addr=0; /*address in file */
- unsigned u; /*counters */
- size_t v; /*counters */
- int i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5F_seq_readv, FAIL);
+ FUNC_ENTER_NOAPI(H5F_seq_readvv, FAIL);
/* Check args */
assert(f);
+ assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
- assert(efl);
- assert(real_buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+ assert(dc_plist);
+ assert(dset_curr_seq);
+ assert(*dset_curr_seq<dset_max_nseq);
+ assert(dset_len_arr);
+ assert(dset_offset_arr);
+ assert(mem_curr_seq);
+ assert(*mem_curr_seq<mem_max_nseq);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
+ assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
@@ -229,285 +241,52 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Read directly from file if the dataset is in an external file */
- if (efl->nused>0) {
- /* Iterate through the sequence vectors */
- for(v=0; v<nseq; v++) {
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- temp = seq_len_arr[v];
- assert(temp==seq_len_arr[v]); /* verify no overflow */
- MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
- H5FD_mpio_communicator(f->shared->lf));
- MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("seq_len=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL,
- "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_read(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
-
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
+ if (store && store->efl.nused>0) {
+ /* Note: We can't use data sieve buffers for datasets in external files
+ * because the 'addr' of all external files is set to 0 (above) and
+ * all datasets in external files would alias to the same set of
+ * file offsets, totally mixing up the data sieve buffer information. -QAK
+ */
+ if((ret_value=H5O_efl_readvv(&(store->efl),
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "external data read failed");
} else {
+ hsize_t max_data; /*bytes in dataset */
+ unsigned u; /*counters */
+
/* Compute the size of the dataset in bytes */
for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
max_data *= layout->dim[u];
/* Pass along the vector of sequences to read */
- if (H5F_contig_readv(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
+ if((ret_value=H5F_contig_readvv(f, max_data, layout->addr,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
} /* end else */
break;
case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl->nused>0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
-
- /* Compute the file offset coordinates and hyperslab size */
- if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
- /* Build the array of cumulative hyperslab sizes */
- /* (And set the memory offset to zero) */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- mem_offset[i]=0;
- down_size[i]=acc;
- acc*=dset_dims[i];
- } /* end for */
- mem_offset[ndims]=0;
-
- /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
- for(v=0; v<nseq; v++) {
- dset_offset=dset_offset_arr[v];
- seq_len=seq_len_arr[v];
- buf=real_buf;
-
- {
- /* Set location in dataset from the dset_offset */
- addr=dset_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* Compute the hyperslab offset from the address given */
- for(i=ndims-1; i>=0; i--) {
- coords[i]=addr%dset_dims[i];
- addr/=dset_dims[i];
- } /* end for */
- coords[ndims]=0; /* No offset for element info */
-
- /*
- * Peel off initial partial hyperslabs until we've got a hyperslab which starts
- * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
- * zero for all dimensions except the slowest changing one
- */
- for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /* Check if we have a partial hyperslab in this lower dimension */
- if(coords[i]>0) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(i==j)
- hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
- else
- if(j>i)
- hslab_size[j]=dset_dims[j];
- else
- hslab_size[j]=1;
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size,
- buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
-
- /* Carry the coord array correction up the array, if the dimension is finished */
- while(i>0 && coords[i-1]==(hssize_t)dset_dims[i-1]) {
- i--;
- coords[i]=0;
- if(i>0) {
- coords[i-1]++;
- assert(coords[i-1]<=(hssize_t)dset_dims[i-1]);
- } /* end if */
- } /* end while */
- } /* end if */
- } /* end for */
-
- /* Check if there is more than just a partial hyperslab to read */
- if(seq_len>=down_size[0]) {
- hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
- hsize_t full_size; /* Size of the full hyperslab in bytes */
-
- /* Get the sequence length for computing the hyperslab sizes */
- tmp_seq_len=seq_len;
-
- /* Reset the size of the hyperslab read in */
- full_size=1;
-
- /* Compute the hyperslab size from the length given */
- for(i=ndims-1; i>=0; i--) {
- /* Check if the hyperslab is wider than the width of the dimension */
- if(tmp_seq_len>dset_dims[i]) {
- assert(0==coords[i]);
- hslab_size[i]=dset_dims[i];
- } /* end if */
- else
- hslab_size[i]=tmp_seq_len;
-
- /* compute the number of elements read in */
- full_size*=hslab_size[i];
-
- /* Fold the length into the length in the next highest dimension */
- tmp_seq_len/=dset_dims[i];
-
- /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
- assert(tmp_seq_len>=1 || i==0);
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read the full hyperslab in */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(full_size*elmt_size);
-
- /* Decrement the sequence length left */
- seq_len-=full_size;
-
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
-
- } /* end if */
-
- /*
- * Peel off final partial hyperslabs until we've finished reading all the data
- */
- if(seq_len>0) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /*
- * Peel off remaining partial hyperslabs, from the next-slowest dimension
- * on down to the next-to-fastest changing dimension
- */
- for(i=1; i<(ndims-1); i++) {
- /* Check if there are enough elements to read in a row in this dimension */
- if(seq_len>=down_size[i]) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j<i)
- hslab_size[j]=1;
- else
- if(j==i)
- hslab_size[j]=seq_len/down_size[j];
- else
- hslab_size[j]=dset_dims[j];
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Increment the buffer offset */
- buf=(unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=hslab_size[i];
- } /* end if */
- } /* end for */
-
- /* Handle fastest changing dimension if there are any elements left */
- if(seq_len>0) {
- assert(seq_len<dset_dims[ndims-1]);
-
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j==(ndims-1))
- hslab_size[j]=seq_len;
- else
- hslab_size[j]=1;
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Read in the partial hyperslab */
- if (H5F_istore_read(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "chunked read failed");
-
- /* Double-check the amount read in */
- assert(seq_len==partial_size);
- } /* end if */
- } /* end if */
- }
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
-
+ assert(store);
+ if((ret_value=H5F_istore_readvv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "istore read failed");
break;
case H5D_COMPACT:
-
/* Pass along the vector of sequences to read */
- if (H5F_compact_readv(f, layout, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "block read failed");
-
+ if((ret_value=H5F_compact_readvv(f, layout,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "compact read failed");
break;
+
default:
assert("not implemented yet" && 0);
HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout");
@@ -515,69 +294,67 @@ H5F_seq_readv(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout,
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* H5F_seq_readv() */
+} /* H5F_seq_readvv() */
/*-------------------------------------------------------------------------
- * Function: H5F_seq_writev
+ * Function: H5F_seq_writevv
*
* Purpose: Writes a vector of byte sequences from a buffer in memory into
- * a file dataset. The data is written to file F and the array's size
- * and storage information is in LAYOUT. External files are described
- * according to the external file list, EFL. The vector of byte sequences
- * offsets is in the DSET_OFFSET array into the dataset (offsets are in
- * terms of bytes) and the size of each sequence is in the SEQ_LEN array.
- * The total size of the file array is implied in the LAYOUT argument.
- * Bytes written from BUF are sequentially stored in the buffer, each sequence
- * from the vector stored directly after the previous. The number of
- * sequences is NSEQ.
+ * a vector of byte sequences in a file dataset. The data is written to
+ * file F and the array's size and storage information is in LAYOUT.
+ * External files and chunks are described according to the storage
+ * information, STORE. The vector of byte sequences offsets for the file
+ * is in the DSET_OFFSET_ARR array into the dataset (offsets are in
+ * terms of bytes) and the size of each sequence is in the DSET_LEN_ARR
+ * array. The vector of byte sequences offsets for memory is in the
+ * MEM_OFFSET_ARR array into the dataset (offsets are in terms of bytes)
+ * and the size of each sequence is in the MEM_LEN_ARR array. The total
+ * size of the file array is implied in the LAYOUT argument. The maximum
+ * number of sequences in the file dataset and the memory buffer are
+ * DSET_MAX_NSEQ & MEM_MAX_NSEQ respectively. The current sequence being
+ * operated on in the file dataset and the memory buffer are DSET_CURR_SEQ
+ * & MEM_CURR_SEQ respectively. The current sequence being operated on
+ * will be updated as a result of the operation, as will the offsets and
+ * lengths of the file dataset and memory buffer sequences.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
- * Friday, July 6, 2001
+ * Friday, May 2, 2003
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
- const H5S_t *file_space, size_t elmt_size,
- size_t nseq, size_t seq_len_arr[], hsize_t dset_offset_arr[],
- const void *_buf)
+ssize_t
+H5F_seq_writevv(H5F_t *f, hid_t dxpl_id, struct H5O_layout_t *layout,
+ struct H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf)
{
- const unsigned char *real_buf=(const unsigned char *)_buf; /* Local pointer to buffer to fill */
- const unsigned char *buf; /* Local pointer to buffer to fill */
- hsize_t dset_offset; /* Offset in dataset */
- hsize_t seq_len; /* Number of bytes to read */
- hsize_t dset_dims[H5O_LAYOUT_NDIMS]; /* dataspace dimensions */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in memory buffer */
- hssize_t coords[H5O_LAYOUT_NDIMS]; /* offset of hyperslab in dataspace */
- hsize_t hslab_size[H5O_LAYOUT_NDIMS]; /* hyperslab size in dataspace*/
- hsize_t down_size[H5O_LAYOUT_NDIMS]; /* Cumulative hyperslab sizes (in elements) */
- hsize_t acc; /* Accumulator for hyperslab sizes (in elements) */
- int ndims;
- hsize_t max_data; /*bytes in dataset */
- haddr_t addr; /*address in file */
- unsigned u; /*counters */
- size_t v; /*counters */
- int i,j; /*counters */
#ifdef H5_HAVE_PARALLEL
H5FD_mpio_xfer_t xfer_mode=H5FD_MPIO_INDEPENDENT;
#endif /* H5_HAVE_PARALLEL */
- herr_t ret_value = SUCCEED; /* Return value */
+ ssize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_seq_writev, FAIL);
+ FUNC_ENTER_NOAPI(H5F_seq_writevv, FAIL);
/* Check args */
assert(f);
+ assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); /* Make certain we have the correct type of property list */
assert(layout);
- assert(efl);
- assert(real_buf);
- /* Make certain we have the correct type of property list */
- assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+ assert(dc_plist);
+ assert(dset_curr_seq);
+ assert(*dset_curr_seq<dset_max_nseq);
+ assert(dset_len_arr);
+ assert(dset_offset_arr);
+ assert(mem_curr_seq);
+ assert(*mem_curr_seq<mem_max_nseq);
+ assert(mem_len_arr);
+ assert(mem_offset_arr);
+ assert(buf);
#ifdef H5_HAVE_PARALLEL
/* Get the transfer mode for MPIO transfers */
@@ -608,282 +385,50 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
switch (layout->type) {
case H5D_CONTIGUOUS:
/* Write directly to file if the dataset is in an external file */
- if (efl->nused>0) {
- /* Iterate through the sequence vectors */
- for(v=0; v<nseq; v++) {
-#ifdef H5_HAVE_PARALLEL
- if (H5FD_MPIO_COLLECTIVE==xfer_mode) {
- /*
- * Currently supports same number of collective access. Need to
- * be changed LATER to combine all reads into one collective MPIO
- * call.
- */
- unsigned long max, min, temp;
-
- temp = seq_len_arr[v];
- assert(temp==seq_len_arr[v]); /* verify no overflow */
- MPI_Allreduce(&temp, &max, 1, MPI_UNSIGNED_LONG, MPI_MAX,
- H5FD_mpio_communicator(f->shared->lf));
- MPI_Allreduce(&temp, &min, 1, MPI_UNSIGNED_LONG, MPI_MIN,
- H5FD_mpio_communicator(f->shared->lf));
-#ifdef AKC
- printf("seq_len=%lu, min=%lu, max=%lu\n", temp, min, max);
-#endif
- if (max != min)
- HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "collective access with unequal number of blocks not supported yet");
- }
-#endif /* H5_HAVE_PARALLEL */
- /* Note: We can't use data sieve buffers for datasets in external files
- * because the 'addr' of all external files is set to 0 (above) and
- * all datasets in external files would alias to the same set of
- * file offsets, totally mixing up the data sieve buffer information. -QAK
- */
- H5_CHECK_OVERFLOW(dset_offset_arr[v],hsize_t,haddr_t);
- if (H5O_efl_write(f, efl, (haddr_t)dset_offset_arr[v], seq_len_arr[v], real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
-
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
+ if (store && store->efl.nused>0) {
+ /* Note: We can't use data sieve buffers for datasets in external files
+ * because the 'addr' of all external files is set to 0 (above) and
+ * all datasets in external files would alias to the same set of
+ * file offsets, totally mixing up the data sieve buffer information. -QAK
+ */
+ if ((ret_value=H5O_efl_writevv(&(store->efl),
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "external data write failed");
} else {
+ hsize_t max_data; /* Bytes in dataset */
+ unsigned u; /* Local index variable */
+
/* Compute the size of the dataset in bytes */
for(u=1, max_data=layout->dim[0]; u<layout->ndims; u++)
max_data *= layout->dim[u];
/* Pass along the vector of sequences to write */
- if (H5F_contig_writev(f, max_data, H5FD_MEM_DRAW, layout->addr, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
+ if ((ret_value=H5F_contig_writevv(f, max_data, layout->addr,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
} /* end else */
break;
case H5D_CHUNKED:
- /*
- * This method is unable to access external raw data files
- */
- if (efl->nused>0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "chunking and external files are mutually exclusive");
-
- /* Compute the file offset coordinates and hyperslab size */
- if((ndims=H5S_get_simple_extent_dims(file_space,dset_dims,NULL))<0)
- HGOTO_ERROR(H5E_IO, H5E_UNSUPPORTED, FAIL, "unable to retrieve dataspace dimensions");
-
- /* Build the array of cumulative hyperslab sizes */
- /* (And set the memory offset to zero) */
- for(acc=1, i=(ndims-1); i>=0; i--) {
- mem_offset[i]=0;
- down_size[i]=acc;
- acc*=dset_dims[i];
- } /* end for */
- mem_offset[ndims]=0;
-
- /* Brute-force, stupid way to implement the vectors, but too complex to do other ways... */
- for(v=0; v<nseq; v++) {
- dset_offset=dset_offset_arr[v];
- seq_len=seq_len_arr[v];
- buf=real_buf;
-
- {
- /* Set location in dataset from the dset_offset */
- addr=dset_offset;
-
- /* Convert the bytes into elements */
- seq_len/=elmt_size;
- addr/=elmt_size;
-
- /* Compute the hyperslab offset from the address given */
- for(i=ndims-1; i>=0; i--) {
- coords[i]=addr%dset_dims[i];
- addr/=dset_dims[i];
- } /* end for */
- coords[ndims]=0; /* No offset for element info */
-
- /*
- * Peel off initial partial hyperslabs until we've got a hyperslab which starts
- * at coord[n]==0 for dimensions 1->(ndims-1) (i.e. starting at coordinate
- * zero for all dimensions except the slowest changing one
- */
- for(i=ndims-1; i>0 && seq_len>=down_size[i]; i--) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /* Check if we have a partial hyperslab in this lower dimension */
- if(coords[i]>0) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(i==j)
- hslab_size[j]=MIN(seq_len/down_size[i],dset_dims[i]-coords[i]);
- else
- if(j>i)
- hslab_size[j]=dset_dims[j];
- else
- hslab_size[j]=1;
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write out the partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset,coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=0;
- coords[i-1]++;
-
- /* Carry the coord array correction up the array, if the dimension is finished */
- while(i>0 && coords[i-1]==(hssize_t)dset_dims[i-1]) {
- i--;
- coords[i]=0;
- if(i>0) {
- coords[i-1]++;
- assert(coords[i-1]<=(hssize_t)dset_dims[i-1]);
- } /* end if */
- } /* end while */
- } /* end if */
- } /* end for */
-
- /* Check if there is more than just a partial hyperslab to read */
- if(seq_len>=down_size[0]) {
- hsize_t tmp_seq_len; /* Temp. size of the sequence in elements */
- hsize_t full_size; /* Size of the full hyperslab in bytes */
-
- /* Get the sequence length for computing the hyperslab sizes */
- tmp_seq_len=seq_len;
-
- /* Reset the size of the hyperslab read in */
- full_size=1;
-
- /* Compute the hyperslab size from the length given */
- for(i=ndims-1; i>=0; i--) {
- /* Check if the hyperslab is wider than the width of the dimension */
- if(tmp_seq_len>dset_dims[i]) {
- assert(0==coords[i]);
- hslab_size[i]=dset_dims[i];
- } /* end if */
- else
- hslab_size[i]=tmp_seq_len;
-
- /* compute the number of elements read in */
- full_size*=hslab_size[i];
-
- /* Fold the length into the length in the next highest dimension */
- tmp_seq_len/=dset_dims[i];
-
- /* Make certain the hyperslab sizes don't go less than 1 for dimensions less than 0*/
- assert(tmp_seq_len>=1 || i==0);
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write the full hyperslab in */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(full_size*elmt_size);
-
- /* Decrement the sequence length left */
- seq_len-=full_size;
-
- /* Increment coordinate of slowest changing dimension */
- coords[0]+=hslab_size[0];
-
- } /* end if */
-
- /*
- * Peel off final partial hyperslabs until we've finished reading all the data
- */
- if(seq_len>0) {
- hsize_t partial_size; /* Size of the partial hyperslab in bytes */
-
- /*
- * Peel off remaining partial hyperslabs, from the next-slowest dimension
- * on down to the next-to-fastest changing dimension
- */
- for(i=1; i<(ndims-1); i++) {
- /* Check if there are enough elements to read in a row in this dimension */
- if(seq_len>=down_size[i]) {
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j<i)
- hslab_size[j]=1;
- else
- if(j==i)
- hslab_size[j]=seq_len/down_size[j];
- else
- hslab_size[j]=dset_dims[j];
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write out the partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Increment the buffer offset */
- buf=(const unsigned char *)buf+(partial_size*elmt_size);
-
- /* Decrement the length of the sequence to read */
- seq_len-=partial_size;
-
- /* Correct the coords array */
- coords[i]=hslab_size[i];
- } /* end if */
- } /* end for */
-
- /* Handle fastest changing dimension if there are any elements left */
- if(seq_len>0) {
- assert(seq_len<dset_dims[ndims-1]);
-
- /* Reset the partial hyperslab size */
- partial_size=1;
-
- /* Build the partial hyperslab information */
- for(j=0; j<ndims; j++) {
- if(j==(ndims-1))
- hslab_size[j]=seq_len;
- else
- hslab_size[j]=1;
-
- partial_size*=hslab_size[j];
- } /* end for */
- hslab_size[ndims]=elmt_size; /* basic hyperslab size is the element */
-
- /* Write out the final partial hyperslab */
- if (H5F_istore_write(f, dxpl_id, layout, dc_plist,
- hslab_size, mem_offset, coords, hslab_size, buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "chunked write failed");
-
- /* Double-check the amount read in */
- assert(seq_len==partial_size);
- } /* end if */
- } /* end if */
- }
- /* Increment offset in buffer */
- real_buf += seq_len_arr[v];
- } /* end for */
-
+ assert(store);
+ if((ret_value=H5F_istore_writevv(f, dxpl_id, layout, dc_plist, store->chunk_coords,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "istore write failed");
break;
case H5D_COMPACT:
-
/* Pass along the vector of sequences to write */
- if (H5F_compact_writev(f, layout, nseq, seq_len_arr, dset_offset_arr, dxpl_id, real_buf)<0)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
-
+ if((ret_value=H5F_compact_writevv(f, layout,
+ dset_max_nseq, dset_curr_seq, dset_len_arr, dset_offset_arr,
+ mem_max_nseq, mem_curr_seq, mem_len_arr, mem_offset_arr,
+ dxpl_id, buf))<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "compact write failed");
break;
default:
@@ -893,5 +438,4 @@ H5F_seq_writev(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout,
done:
FUNC_LEAVE_NOAPI(ret_value);
-} /* H5F_seq_writev() */
-
+} /* H5F_seq_writevv() */
diff --git a/src/H5G.c b/src/H5G.c
index 0b71257..6b5e9ae 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -560,7 +560,7 @@ H5Gget_objtype_by_idx(hid_t group_id, hsize_t idx)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound");
/*call private function*/
- ret_value = (H5G_obj_t)H5G_get_objtype_by_idx(group, idx, H5AC_ind_dxpl_id);
+ ret_value = H5G_get_objtype_by_idx(group, idx, H5AC_ind_dxpl_id);
done:
FUNC_LEAVE_API(ret_value);
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 898da7f..3c80f95 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -37,6 +37,10 @@ static size_t H5O_efl_size(H5F_t *f, const void *_mesg);
static herr_t H5O_efl_reset(void *_mesg);
static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
+static herr_t H5O_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size,
+ uint8_t *buf);
+static herr_t H5O_efl_write(const H5O_efl_t *efl, haddr_t addr, size_t size,
+ const uint8_t *buf);
/* This message derives from H5O */
const H5O_class_t H5O_EFL[1] = {{
@@ -422,9 +426,8 @@ done:
* The ADDR argument is passed by value.
*-------------------------------------------------------------------------
*/
-herr_t
-H5O_efl_read (H5F_t UNUSED *f, const H5O_efl_t *efl, haddr_t addr,
- size_t size, uint8_t *buf)
+static herr_t
+H5O_efl_read (const H5O_efl_t *efl, haddr_t addr, size_t size, uint8_t *buf)
{
int i, fd=-1;
size_t to_read;
@@ -510,9 +513,8 @@ done:
* The ADDR argument is passed by value.
*-------------------------------------------------------------------------
*/
-herr_t
-H5O_efl_write (H5F_t UNUSED *f, const H5O_efl_t *efl, haddr_t addr,
- size_t size, const uint8_t *buf)
+static herr_t
+H5O_efl_write (const H5O_efl_t *efl, haddr_t addr, size_t size, const uint8_t *buf)
{
int i, fd=-1;
size_t to_write;
@@ -582,6 +584,164 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_efl_readvv
+ *
+ * Purpose: Reads data from an external file list. It is an error to
+ * read past the logical end of file, but reading past the end
+ * of any particular member of the external file list results in
+ * zeros.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 7, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5O_efl_readvv(const H5O_efl_t *efl,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *_buf)
+{
+ unsigned char *buf; /* Pointer to buffer to write */
+ haddr_t addr; /* Actual address to read */
+ size_t size; /* Size of sequence in bytes */
+ size_t u; /* Counting variable */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_efl_readvv, FAIL);
+
+ /* Check args */
+ assert (efl && efl->nused>0);
+ assert (buf);
+
+ /* Work through all the sequences */
+ for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Read data */
+ if (H5O_efl_read(efl, addr, size, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
+
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end for */
+
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_efl_readvv() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_efl_writevv
+ *
+ * Purpose: Writes data to an external file list. It is an error to
+ * write past the logical end of file, but writing past the end
+ * of any particular member of the external file list just
+ * extends that file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, May 2, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5O_efl_writevv(const H5O_efl_t *efl,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *_buf)
+{
+ const unsigned char *buf; /* Pointer to buffer to write */
+ haddr_t addr; /* Actual address to read */
+ size_t size; /* Size of sequence in bytes */
+ size_t u; /* Counting variable */
+ size_t v; /* Counting variable */
+ ssize_t ret_value=0; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_efl_writevv, FAIL);
+
+ /* Check args */
+ assert (efl && efl->nused>0);
+ assert (buf);
+
+ /* Work through all the sequences */
+ for(u=*dset_curr_seq, v=*mem_curr_seq; u<dset_max_nseq && v<mem_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(mem_len_arr[v]<dset_len_arr[u])
+ size=mem_len_arr[v];
+ else
+ size=dset_len_arr[u];
+
+ /* Compute offset on disk */
+ addr=dset_offset_arr[u];
+
+ /* Compute offset in memory */
+ buf = (const unsigned char *)_buf + mem_offset_arr[v];
+
+ /* Write data */
+ if (H5O_efl_write(efl, addr, size, buf)<0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed");
+
+ /* Update memory information */
+ mem_len_arr[v]-=size;
+ mem_offset_arr[v]+=size;
+ if(mem_len_arr[v]==0)
+ v++;
+
+ /* Update file information */
+ dset_len_arr[u]-=size;
+ dset_offset_arr[u]+=size;
+ if(dset_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end for */
+
+ /* Update current sequence vectors */
+ *dset_curr_seq=u;
+ *mem_curr_seq=v;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_efl_writevv() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_efl_debug
*
* Purpose: Prints debugging info for a message.
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 9b40eeb..6f08ca4 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -239,10 +239,14 @@ H5_DLL size_t H5O_layout_meta_size(H5F_t *f, const void *_mesg);
/* EFL operators */
H5_DLL hsize_t H5O_efl_total_size(H5O_efl_t *efl);
-H5_DLL herr_t H5O_efl_read(H5F_t *f, const H5O_efl_t *efl, haddr_t addr,
- size_t size, uint8_t *buf);
-H5_DLL herr_t H5O_efl_write(H5F_t *f, const H5O_efl_t *efl, haddr_t addr,
- size_t size, const uint8_t *buf);
+H5_DLL ssize_t H5O_efl_readvv(const H5O_efl_t *efl,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ void *buf);
+H5_DLL ssize_t H5O_efl_writevv(const H5O_efl_t *efl,
+ size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[],
+ size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
+ const void *buf);
/* Fill value operators */
H5_DLL herr_t H5O_fill_convert(void *_fill, H5T_t *type, hid_t dxpl_id);
diff --git a/src/H5S.c b/src/H5S.c
index d5eb588..08212c4 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -56,7 +56,7 @@ H5FL_DEFINE(H5S_simple_t);
H5FL_DEFINE(H5S_t);
/* Declare a free list to manage the array's of hsize_t's */
-H5FL_ARR_DEFINE(hsize_t,H5S_MAX_RANK);
+H5FL_ARR_DEFINE(hsize_t,-1);
/* Declare a free list to manage the array's of hssize_t's */
H5FL_ARR_DEFINE(hssize_t,H5S_MAX_RANK);
@@ -1548,7 +1548,11 @@ done:
*-------------------------------------------------------------------------
*/
H5S_conv_t *
-H5S_find (const H5S_t *mem_space, const H5S_t *file_space, unsigned flags)
+H5S_find (const H5S_t *mem_space, const H5S_t *file_space, unsigned
+#ifndef H5_HAVE_PARALLEL
+UNUSED
+#endif /* H5_HAVE_PARALLEL */
+flags)
{
H5S_conv_t *path=NULL; /* Space conversion path */
#ifdef H5_HAVE_PARALLEL
@@ -1780,7 +1784,7 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/],
}
/* Create the space and set the extent */
- if(NULL==(space=H5S_create_simple(rank,dims,maxdims)))
+ if(NULL==(space=H5S_create_simple((unsigned)rank,dims,maxdims)))
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
/* Atomize */
@@ -1817,7 +1821,7 @@ done:
*-------------------------------------------------------------------------
*/
H5S_t *
-H5S_create_simple(int rank, const hsize_t dims[/*rank*/],
+H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/],
const hsize_t maxdims[/*rank*/])
{
H5S_t *ret_value; /* Return value */
@@ -1825,12 +1829,12 @@ H5S_create_simple(int rank, const hsize_t dims[/*rank*/],
FUNC_ENTER_NOAPI(H5S_create_simple, NULL);
/* Check arguments */
- assert(rank>=0 && rank <=H5S_MAX_RANK);
+ assert(rank <=H5S_MAX_RANK);
/* Create the space and set the extent */
if(NULL==(ret_value=H5S_create(H5S_SIMPLE)))
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace");
- if(H5S_set_extent_simple(ret_value,(unsigned)rank,dims,maxdims)<0)
+ if(H5S_set_extent_simple(ret_value,rank,dims,maxdims)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, NULL, "can't set dimensions");
done:
diff --git a/src/H5Sall.c b/src/H5Sall.c
index f5b92b7..08dc8d3 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -21,11 +21,11 @@
#define H5S_PACKAGE /*suppress error about including H5Spkg */
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Iprivate.h" /* ID Functions */
-#include "H5Spkg.h" /* Dataspace functions */
-#include "H5Vprivate.h" /* Vector functions */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* ID Functions */
+#include "H5Spkg.h" /* Dataspace functions */
+#include "H5Vprivate.h" /* Vector functions */
/* Interface initialization */
#define PABLO_MASK H5Sall_mask
@@ -48,7 +48,7 @@ static int interface_initialize_g = 0;
*-------------------------------------------------------------------------
*/
herr_t
-H5S_all_iter_init (const H5S_t *space, size_t UNUSED elmt_size, H5S_sel_iter_t *sel_iter)
+H5S_all_iter_init (H5S_sel_iter_t *iter, const H5S_t *space, size_t UNUSED elmt_size)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -56,13 +56,19 @@ H5S_all_iter_init (const H5S_t *space, size_t UNUSED elmt_size, H5S_sel_iter_t *
/* Check args */
assert (space && H5S_SEL_ALL==space->select.type);
- assert (sel_iter);
+ assert (iter);
/* Initialize the number of elements to iterate over */
- sel_iter->all.elmt_left=H5S_get_simple_extent_npoints(space);
+ iter->elmt_left=H5S_get_simple_extent_npoints(space);
/* Start at the upper left location */
- sel_iter->all.offset=0;
+ iter->u.all.offset=0;
+
+ /* Initialize methods for selection iterator */
+ iter->iter_coords=H5S_all_iter_coords;
+ iter->iter_nelmts=H5S_all_iter_nelmts;
+ iter->iter_next=H5S_all_iter_next;
+ iter->iter_release=H5S_all_iter_release;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -70,6 +76,41 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5S_all_iter_coords
+ *
+ * Purpose: Retrieve the current coordinates of iterator for current
+ * selection
+ *
+ * Return: non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 22, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_all_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_all_iter_coords, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (coords);
+
+ /* Calculate the coordinates for the current iterator offset */
+ if(H5V_array_calc(iter->u.all.offset,iter->rank,iter->dims,coords)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve coordinates");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_all_iter_coords() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_all_iter_nelmts
*
* Purpose: Return number of elements left to process in iterator
@@ -84,17 +125,17 @@ done:
*-------------------------------------------------------------------------
*/
hsize_t
-H5S_all_iter_nelmts (const H5S_sel_iter_t *sel_iter)
+H5S_all_iter_nelmts (const H5S_sel_iter_t *iter)
{
hsize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5S_all_iter_nelmts, 0);
/* Check args */
- assert (sel_iter);
+ assert (iter);
/* Set return value */
- ret_value=sel_iter->all.elmt_left;
+ ret_value=iter->elmt_left;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -103,12 +144,49 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_all_iter_next
+ PURPOSE
+ Increment selection iterator
+ USAGE
+ herr_t H5S_all_iter_next(iter, nelem)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
+ size_t nelem; IN: Number of elements to advance by
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Advance selection iterator to the NELEM'th next element in the selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_all_iter_next(H5S_sel_iter_t *iter, size_t nelem)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_all_iter_next, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (nelem>0);
+
+ /* Increment the iterator */
+ iter->u.all.offset+=nelem;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_all_iter_next() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_all_iter_release
PURPOSE
Release "all" selection iterator information for a dataspace
USAGE
- herr_t H5S_all_iter_release(sel_iter)
- H5S_sel_iter_t *sel_iter; IN: Pointer to selection iterator
+ herr_t H5S_all_iter_release(iter)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -119,14 +197,14 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_all_iter_release (H5S_sel_iter_t UNUSED * sel_iter)
+H5S_all_iter_release (H5S_sel_iter_t UNUSED * iter)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_all_iter_release, FAIL);
/* Check args */
- assert (sel_iter);
+ assert (iter);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -542,9 +620,6 @@ H5S_select_all (H5S_t *space, unsigned rel_prev)
space->select.get_seq_list=H5S_all_get_seq_list;
space->select.get_npoints=H5S_all_npoints;
space->select.release=H5S_all_release;
- space->select.iter_init=H5S_all_iter_init;
- space->select.iter_nelmts=H5S_all_iter_nelmts;
- space->select.iter_release=H5S_all_iter_release;
space->select.is_valid=H5S_all_is_valid;
space->select.serial_size=H5S_all_serial_size;
space->select.serialize=H5S_all_serialize;
@@ -552,6 +627,7 @@ H5S_select_all (H5S_t *space, unsigned rel_prev)
space->select.is_contiguous=H5S_all_is_contiguous;
space->select.is_single=H5S_all_is_single;
space->select.is_regular=H5S_all_is_regular;
+ space->select.iter_init=H5S_all_iter_init;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -650,13 +726,13 @@ H5S_all_get_seq_list(const H5S_t UNUSED *space, unsigned UNUSED flags, H5S_sel_i
assert(len);
/* Calculate the number of bytes left in the selection */
- bytes_left=iter->all.elmt_left*elem_size;
+ bytes_left=iter->elmt_left*elem_size;
/* "round" off the maxbytes allowed to a multiple of the element size */
maxbytes=(maxbytes/elem_size)*elem_size;
/* Compute the offset in the dataset */
- off[0]=iter->all.offset*elem_size;
+ off[0]=iter->u.all.offset*elem_size;
H5_CHECK_OVERFLOW(bytes_left,hsize_t,size_t);
len[0]=MIN(maxbytes,(size_t)bytes_left);
@@ -668,8 +744,8 @@ H5S_all_get_seq_list(const H5S_t UNUSED *space, unsigned UNUSED flags, H5S_sel_i
/* Update the iterator */
elem_used=len[0]/elem_size;
- iter->all.elmt_left-=elem_used;
- iter->all.offset+=elem_used;
+ iter->elmt_left-=elem_used;
+ iter->u.all.offset+=elem_used;
done:
FUNC_LEAVE_NOAPI(ret_value);
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 17ea8d3..2fe79aa 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -55,11 +55,12 @@ H5FL_DEFINE_STATIC(H5S_hyper_span_info_t);
H5FL_ARR_EXTERN(hssize_t);
/* Declare a free list to manage arrays of hsize_t */
-H5FL_ARR_DEFINE_STATIC(hsize_t,-1);
+H5FL_ARR_EXTERN(hsize_t);
/* Declare a free list to manage arrays of H5S_hyper_dim_t */
H5FL_ARR_DEFINE_STATIC(H5S_hyper_dim_t,H5S_MAX_RANK);
+/* #define H5S_HYPER_DEBUG */
#ifdef H5S_HYPER_DEBUG
static herr_t
H5S_hyper_print_spans_helper(struct H5S_hyper_span_t *span,unsigned depth)
@@ -70,9 +71,9 @@ H5S_hyper_print_spans_helper(struct H5S_hyper_span_t *span,unsigned depth)
tmp_span=span;
while(tmp_span) {
- printf("%s: depth=%u, span=%p, (%d, %d), nelem=%u, pstride=%u\n",FUNC,depth,tmp_span,(int)tmp_span->low,(int)tmp_span->high,(unsigned)tmp_span->nelem,(unsigned)tmp_span->pstride);
+ HDfprintf(stderr,"%s: depth=%u, span=%p, (%d, %d), nelem=%u, pstride=%u\n",FUNC,depth,tmp_span,(int)tmp_span->low,(int)tmp_span->high,(unsigned)tmp_span->nelem,(unsigned)tmp_span->pstride);
if(tmp_span->down && tmp_span->down->head) {
- printf("%s: spans=%p, count=%u, scratch=%p, head=%p\n",FUNC,tmp_span->down,tmp_span->down->count,tmp_span->down->scratch,tmp_span->down->head);
+ HDfprintf(stderr,"%s: spans=%p, count=%u, scratch=%p, head=%p\n",FUNC,tmp_span->down,tmp_span->down->count,tmp_span->down->scratch,tmp_span->down->head);
H5S_hyper_print_spans_helper(tmp_span->down->head,depth+1);
} /* end if */
tmp_span=tmp_span->next;
@@ -87,7 +88,7 @@ H5S_hyper_print_spans(const struct H5S_hyper_span_info_t *span_lst)
FUNC_ENTER_NOINIT(H5S_hyper_print_spans);
if(span_lst!=NULL) {
- printf("%s: spans=%p, count=%u, scratch=%p, head=%p\n",FUNC,span_lst,span_lst->count,span_lst->scratch,span_lst->head);
+ HDfprintf(stderr,"%s: spans=%p, count=%u, scratch=%p, head=%p\n",FUNC,span_lst,span_lst->count,span_lst->scratch,span_lst->head);
H5S_hyper_print_spans_helper(span_lst->head,0);
} /* end if */
@@ -111,11 +112,11 @@ H5S_hyper_print_spans(const struct H5S_hyper_span_info_t *span_lst)
*-------------------------------------------------------------------------
*/
herr_t
-H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_iter)
+H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size)
{
- unsigned cont_dim; /* Maximum contiguous dimension */
const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */
H5S_hyper_span_info_t *spans; /* Pointer to hyperslab span info node */
+ unsigned rank; /* Dataspace's dimension rank */
unsigned u; /* Index variable */
int i; /* Index variable */
herr_t ret_value=SUCCEED; /* Return value */
@@ -124,12 +125,15 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
/* Check args */
assert(space && H5S_SEL_HYPERSLABS==space->select.type);
- assert(sel_iter);
+ assert(iter);
assert(space->select.sel_info.hslab.span_lst);
/* Initialize the number of points to iterate over */
- sel_iter->hyp.elmt_left=space->select.num_elem;
- sel_iter->hyp.iter_rank=0;
+ iter->elmt_left=space->select.num_elem;
+ iter->u.hyp.iter_rank=0;
+
+ /* Get the rank of the dataspace */
+ rank=space->extent.u.simple.rank;
/* Set the temporary pointer to the dimension information */
tdiminfo=space->select.sel_info.hslab.diminfo;
@@ -139,6 +143,7 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
/* Initialize the information needed for regular hyperslab I/O */
const hsize_t *mem_size; /* Temporary pointer to dataspace extent's dimension sizes */
hsize_t acc; /* Accumulator for "flattened" dimension's sizes */
+ unsigned cont_dim; /* Maximum contiguous dimension */
/* Set the temporary pointer to the dataspace extent's dimension sizes */
mem_size=space->extent.u.simple.size;
@@ -151,10 +156,10 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
*/
/* Initialize the number of contiguous dimensions to be the same as the dataspace's rank */
- cont_dim=space->extent.u.simple.rank;
+ cont_dim=rank;
/* Check for a "contiguous" block */
- for(u=space->extent.u.simple.rank-1; u>0; u--) {
+ for(u=rank-1; u>0; u--) {
if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u])
cont_dim=u;
else
@@ -162,114 +167,189 @@ H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_i
} /* end for */
/* Check if the regular selection can be "flattened" */
- if(cont_dim<space->extent.u.simple.rank) {
+ if(cont_dim<rank) {
/* Set the iterator's rank to the contiguous dimensions */
- sel_iter->hyp.iter_rank=cont_dim;
+ iter->u.hyp.iter_rank=cont_dim;
/* Allocate the position & initialize to initial location */
- sel_iter->hyp.off = H5FL_ARR_MALLOC(hsize_t,cont_dim);
- assert(sel_iter->hyp.off);
- sel_iter->hyp.diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,cont_dim);
- assert(sel_iter->hyp.diminfo);
- sel_iter->hyp.size = H5FL_ARR_MALLOC(hsize_t,cont_dim);
- assert(sel_iter->hyp.size);
- sel_iter->hyp.sel_off = H5FL_ARR_MALLOC(hssize_t,cont_dim);
- assert(sel_iter->hyp.sel_off);
+ iter->u.hyp.off = H5FL_ARR_MALLOC(hsize_t,cont_dim);
+ assert(iter->u.hyp.off);
+ iter->u.hyp.diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,cont_dim);
+ assert(iter->u.hyp.diminfo);
+ iter->u.hyp.size = H5FL_ARR_MALLOC(hsize_t,cont_dim);
+ assert(iter->u.hyp.size);
+ iter->u.hyp.sel_off = H5FL_ARR_MALLOC(hssize_t,cont_dim);
+ assert(iter->u.hyp.sel_off);
/* "Flatten" dataspace extent and selection information */
- for(i=space->extent.u.simple.rank-1, acc=1; i>=0; i--) {
+ for(i=rank-1, acc=1; i>=0; i--) {
if(tdiminfo[i].block==mem_size[i] && i>0) {
assert(tdiminfo[i].start==0);
acc *= mem_size[i];
} /* end if */
else {
if((unsigned)i==(cont_dim-1)) {
- sel_iter->hyp.diminfo[i].start = tdiminfo[i].start*acc;
+ iter->u.hyp.diminfo[i].start = tdiminfo[i].start*acc;
/* Special case for stride==1 regular selections */
if(tdiminfo[i].stride==1)
- sel_iter->hyp.diminfo[i].stride = 1;
+ iter->u.hyp.diminfo[i].stride = 1;
else
- sel_iter->hyp.diminfo[i].stride = tdiminfo[i].stride*acc;
- sel_iter->hyp.diminfo[i].count = tdiminfo[i].count;
- sel_iter->hyp.diminfo[i].block = tdiminfo[i].block*acc;
- sel_iter->hyp.size[i] = mem_size[i]*acc;
- sel_iter->hyp.sel_off[i] = space->select.offset[i]*acc;
+ iter->u.hyp.diminfo[i].stride = tdiminfo[i].stride*acc;
+ iter->u.hyp.diminfo[i].count = tdiminfo[i].count;
+ iter->u.hyp.diminfo[i].block = tdiminfo[i].block*acc;
+ iter->u.hyp.size[i] = mem_size[i]*acc;
+ iter->u.hyp.sel_off[i] = space->select.offset[i]*acc;
} /* end if */
else {
- sel_iter->hyp.diminfo[i].start = tdiminfo[i].start;
- sel_iter->hyp.diminfo[i].stride = tdiminfo[i].stride;
- sel_iter->hyp.diminfo[i].count = tdiminfo[i].count;
- sel_iter->hyp.diminfo[i].block = tdiminfo[i].block;
- sel_iter->hyp.size[i] = mem_size[i];
- sel_iter->hyp.sel_off[i] = space->select.offset[i];
+ iter->u.hyp.diminfo[i].start = tdiminfo[i].start;
+ iter->u.hyp.diminfo[i].stride = tdiminfo[i].stride;
+ iter->u.hyp.diminfo[i].count = tdiminfo[i].count;
+ iter->u.hyp.diminfo[i].block = tdiminfo[i].block;
+ iter->u.hyp.size[i] = mem_size[i];
+ iter->u.hyp.sel_off[i] = space->select.offset[i];
} /* end else */
} /* end if */
} /* end for */
/* Initialize "flattened" iterator offset to initial location and dataspace extent and selection information to correct values */
for(u=0; u<cont_dim; u++)
- sel_iter->hyp.off[u]=sel_iter->hyp.diminfo[u].start;
+ iter->u.hyp.off[u]=iter->u.hyp.diminfo[u].start;
} /* end if */
else {
/* Allocate the position & initialize to initial location */
- sel_iter->hyp.off = H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank);
- assert(sel_iter->hyp.off);
- for(u=0; u<space->extent.u.simple.rank; u++)
- sel_iter->hyp.off[u]=tdiminfo[u].start;
+ iter->u.hyp.off = H5FL_ARR_MALLOC(hsize_t,rank);
+ assert(iter->u.hyp.off);
+
+ /* Allocate the storage for the regular selection information */
+ iter->u.hyp.diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,rank);
+ assert(iter->u.hyp.diminfo);
+
+ /* Initialize position to initial location */
+ /* Also make local copy of the regular selection information */
+ for(u=0; u<rank; u++) {
+ /* Regular selection information */
+ iter->u.hyp.diminfo[u].start = tdiminfo[u].start;
+ iter->u.hyp.diminfo[u].stride = tdiminfo[u].stride;
+ iter->u.hyp.diminfo[u].count = tdiminfo[u].count;
+ iter->u.hyp.diminfo[u].block = tdiminfo[u].block;
+
+ /* Position information */
+ iter->u.hyp.off[u]=tdiminfo[u].start;
+ } /* end if */
/* Initialize other regular region information also (for release) */
- sel_iter->hyp.diminfo = NULL;
- sel_iter->hyp.size = NULL;
- sel_iter->hyp.sel_off = NULL;
+ iter->u.hyp.size = NULL;
+ iter->u.hyp.sel_off = NULL;
} /* end else */
/* Initialize irregular region information also (for release) */
- sel_iter->hyp.spans=NULL;
- sel_iter->hyp.span=NULL;
+ iter->u.hyp.spans=NULL;
+ iter->u.hyp.span=NULL;
} /* end if */
else {
/* Initialize the information needed for non-regular hyperslab I/O */
/* Make a copy of the span tree to iterate over */
- sel_iter->hyp.spans=H5S_hyper_copy_span(space->select.sel_info.hslab.span_lst);
+ iter->u.hyp.spans=H5S_hyper_copy_span(space->select.sel_info.hslab.span_lst);
/* Set the nelem & pstride values according to the element size */
- H5S_hyper_span_precompute(sel_iter->hyp.spans,elmt_size);
+ H5S_hyper_span_precompute(iter->u.hyp.spans,elmt_size);
/* Allocate the span tree pointers, span pointers and positions */
- sel_iter->hyp.span = H5FL_ARR_MALLOC(H5S_hyper_span_t,space->extent.u.simple.rank);
- assert(sel_iter->hyp.span);
- sel_iter->hyp.off = H5FL_ARR_MALLOC(hsize_t,space->extent.u.simple.rank);
- assert(sel_iter->hyp.off);
+ iter->u.hyp.span = H5FL_ARR_MALLOC(H5S_hyper_span_t,rank);
+ assert(iter->u.hyp.span);
+ iter->u.hyp.off = H5FL_ARR_MALLOC(hsize_t,rank);
+ assert(iter->u.hyp.off);
/* Initialize the starting span_info's and spans */
- spans=sel_iter->hyp.spans;
- for(u=0; u<space->extent.u.simple.rank; u++) {
+ spans=iter->u.hyp.spans;
+ for(u=0; u<rank; u++) {
/* Set the pointers to the initial span in each dimension */
assert(spans);
assert(spans->head);
/* Set the pointer to the first span in the list for this node */
- sel_iter->hyp.span[u] = spans->head;
+ iter->u.hyp.span[u] = spans->head;
/* Set the initial offset to low bound of span */
- sel_iter->hyp.off[u]=sel_iter->hyp.span[u]->low;
+ iter->u.hyp.off[u]=iter->u.hyp.span[u]->low;
/* Get the pointer to the next level down */
spans=spans->head->down;
} /* end for */
/* Initialize regular region information also (for release) */
- sel_iter->hyp.diminfo = NULL;
- sel_iter->hyp.size = NULL;
- sel_iter->hyp.sel_off = NULL;
+ iter->u.hyp.diminfo = NULL;
+ iter->u.hyp.size = NULL;
+ iter->u.hyp.sel_off = NULL;
} /* end else */
+ /* Initialize methods for selection iterator */
+ iter->iter_coords=H5S_hyper_iter_coords;
+ iter->iter_nelmts=H5S_hyper_iter_nelmts;
+ iter->iter_next=H5S_hyper_iter_next;
+ iter->iter_release=H5S_hyper_iter_release;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_hyper_iter_init() */
/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_iter_coords
+ *
+ * Purpose: Retrieve the current coordinates of iterator for current
+ * selection
+ *
+ * Return: non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 22, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_hyper_iter_coords, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (coords);
+
+ /* Copy the offset of the current point */
+
+ /* Check for a single "regular" hyperslab */
+ if(iter->u.hyp.diminfo!=NULL) {
+ /* Check if this is a "flattened" regular hyperslab selection */
+ if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) {
+ unsigned flat_dim; /* The rank of the flattened dimension */
+
+ /* Get the rank of the flattened dimension */
+ flat_dim=iter->u.hyp.iter_rank-1;
+
+ /* Copy the coordinates up to where things got flattened */
+ HDmemcpy(coords,iter->u.hyp.off,sizeof(hssize_t)*flat_dim);
+
+ /* Compute the coordinates for the flattened dimensions */
+ H5_CHECK_OVERFLOW(iter->u.hyp.off[flat_dim],hssize_t,hsize_t);
+ H5V_array_calc((hsize_t)iter->u.hyp.off[flat_dim],iter->rank-flat_dim,&(iter->dims[flat_dim]),&(coords[flat_dim]));
+ } /* end if */
+ else
+ HDmemcpy(coords,iter->u.hyp.off,sizeof(hssize_t)*iter->rank);
+ } /* end if */
+ else
+ HDmemcpy(coords,iter->u.hyp.off,sizeof(hssize_t)*iter->rank);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_iter_coords() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_hyper_iter_nelmts
*
* Purpose: Return number of elements left to process in iterator
@@ -284,31 +364,248 @@ done:
*-------------------------------------------------------------------------
*/
hsize_t
-H5S_hyper_iter_nelmts (const H5S_sel_iter_t *sel_iter)
+H5S_hyper_iter_nelmts (const H5S_sel_iter_t *iter)
{
hsize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5S_hyper_iter_nelmts, 0);
/* Check args */
- assert (sel_iter);
+ assert (iter);
/* Set return value */
- ret_value=sel_iter->hyp.elmt_left;
+ ret_value=iter->elmt_left;
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_hyper_iter_nelmts() */
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_iter_next
+ *
+ * Purpose: Moves a hyperslab iterator to the beginning of the next sequence
+ * of elements to read. Handles walking off the end in all dimensions.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, September 8, 2000
+ *
+ * Modifications:
+ * Modified for both general and optimized hyperslab I/O
+ * Quincey Koziol, April 17, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem)
+{
+ unsigned ndims; /* Number of dimensions of dataset */
+ int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ unsigned i; /* Counters */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_iter_next);
+
+ /* Check for the special case of just one H5Sselect_hyperslab call made */
+ /* (i.e. a regular hyperslab selection */
+ if(iter->u.hyp.diminfo!=NULL) {
+ const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */
+ hsize_t iter_offset[H5O_LAYOUT_NDIMS];
+ hsize_t iter_count[H5O_LAYOUT_NDIMS];
+ int temp_dim; /* Temporary rank holder */
+
+ /* Check if this is a "flattened" regular hyperslab selection */
+ if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) {
+ /* Set the aliases for the dimension rank */
+ ndims=iter->u.hyp.iter_rank;
+ } /* end if */
+ else {
+ /* Set the aliases for the dimension rank */
+ ndims=iter->rank;
+ } /* end else */
+
+ /* Set the fastest dimension rank */
+ fast_dim=ndims-1;
+
+ /* Set the local copy of the diminfo pointer */
+ tdiminfo=iter->u.hyp.diminfo;
+
+ /* Calculate the offset and block count for each dimension */
+ for(i=0; i<ndims; i++) {
+ if(tdiminfo[i].stride==1) {
+ iter_offset[i]=iter->u.hyp.off[i]-tdiminfo[i].start;
+ iter_count[i]=0;
+ } /* end if */
+ else {
+ iter_offset[i]=(iter->u.hyp.off[i]-tdiminfo[i].start)%tdiminfo[i].stride;
+ iter_count[i]=(iter->u.hyp.off[i]-tdiminfo[i].start)/tdiminfo[i].stride;
+ } /* end else */
+ } /* end for */
+
+ /* Loop through, advancing the offset & counts, until all the nelements are accounted for */
+ while(nelem>0) {
+ /* Start with the fastest changing dimension */
+ temp_dim=fast_dim;
+ while(temp_dim>=0) {
+ if(temp_dim==fast_dim) {
+ size_t actual_elem; /* Actual # of elements advanced on each iteration through loop */
+ size_t block_elem; /* Number of elements left in a block */
+
+ /* Compute the number of elements left in block */
+ block_elem=tdiminfo[temp_dim].block-iter_offset[temp_dim];
+
+ /* Compute the number of actual elements to advance */
+ actual_elem=MIN(nelem,block_elem);
+
+ /* Move the iterator over as many elements as possible */
+ iter_offset[temp_dim]+=actual_elem;
+
+ /* Decrement the number of elements advanced */
+ nelem-=actual_elem;
+ } /* end if */
+ else {
+ /* Move to the next row in the current dimension */
+ iter_offset[temp_dim]++;
+ } /* end else */
+
+ /* If this block is still in the range of blocks to output for the dimension, break out of loop */
+ if(iter_offset[temp_dim]<tdiminfo[temp_dim].block)
+ break;
+ else {
+ /* Move to the next block in the current dimension */
+ iter_offset[temp_dim]=0;
+ iter_count[temp_dim]++;
+
+ /* If this block is still in the range of blocks to output for the dimension, break out of loop */
+ if(iter_count[temp_dim]<tdiminfo[temp_dim].count)
+ break;
+ else
+ iter_count[temp_dim]=0; /* reset back to the beginning of the line */
+ } /* end else */
+
+ /* Decrement dimension count */
+ temp_dim--;
+ } /* end while */
+ } /* end while */
+
+ /* Translate current iter_offset and iter_count into iterator position */
+ for(i=0; i<ndims; i++)
+ iter->u.hyp.off[i]=tdiminfo[i].start+(tdiminfo[i].stride*iter_count[i])+iter_offset[i];
+ } /* end if */
+ /* Must be an irregular hyperslab selection */
+ else {
+ H5S_hyper_span_t *curr_span; /* Current hyperslab span node */
+ H5S_hyper_span_t **ispan; /* Iterator's hyperslab span nodes */
+ hssize_t *abs_arr; /* Absolute hyperslab span position */
+ int curr_dim; /* Temporary rank holder */
+
+ /* Set the rank of the fastest changing dimension */
+ ndims=iter->rank;
+ fast_dim=(ndims-1);
+
+ /* Get the pointers to the current span info and span nodes */
+ abs_arr=iter->u.hyp.off;
+ ispan=iter->u.hyp.span;
+
+ /* Loop through, advancing the span information, until all the nelements are accounted for */
+ while(nelem>0) {
+ /* Start at the fastest dim */
+ curr_dim=fast_dim;
+
+ /* Work back up through the dimensions */
+ while(curr_dim>=0) {
+ /* Reset the current span */
+ curr_span=ispan[curr_dim];
+
+ /* Increment absolute position */
+ if(curr_dim==fast_dim) {
+ size_t actual_elem; /* Actual # of elements advanced on each iteration through loop */
+ size_t span_elem; /* Number of elements left in a span */
+
+ /* Compute the number of elements left in block */
+ span_elem=(curr_span->high-abs_arr[curr_dim])+1;
+
+ /* Compute the number of actual elements to advance */
+ actual_elem=MIN(nelem,span_elem);
+
+ /* Move the iterator over as many elements as possible */
+ abs_arr[curr_dim]+=actual_elem;
+
+ /* Decrement the number of elements advanced */
+ nelem-=actual_elem;
+ } /* end if */
+ else {
+ /* Move to the next row in the current dimension */
+ abs_arr[curr_dim]++;
+ } /* end else */
+
+ /* Check if we are still within the span */
+ if(abs_arr[curr_dim]<=curr_span->high) {
+ break;
+ } /* end if */
+ /* If we walked off that span, advance to the next span */
+ else {
+ /* Advance span in this dimension */
+ curr_span=curr_span->next;
+
+ /* Check if we have a valid span in this dimension still */
+ if(curr_span!=NULL) {
+ /* Reset the span in the current dimension */
+ ispan[curr_dim]=curr_span;
+
+ /* Reset absolute position */
+ abs_arr[curr_dim]=curr_span->low;
+
+ break;
+ } /* end if */
+ else {
+ /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */
+ curr_dim--;
+ } /* end else */
+ } /* end else */
+ } /* end while */
+
+ /* Check if we are finished with the spans in the tree */
+ if(curr_dim>=0) {
+ /* Walk back down the iterator positions, reseting them */
+ while(curr_dim<fast_dim) {
+ assert(curr_span);
+ assert(curr_span->down);
+ assert(curr_span->down->head);
+
+ /* Increment current dimension */
+ curr_dim++;
+
+ /* Set the new span_info & span for this dimension */
+ ispan[curr_dim]=curr_span->down->head;
+
+ /* Advance span down the tree */
+ curr_span=curr_span->down->head;
+
+ /* Reset the absolute offset for the dim */
+ abs_arr[curr_dim]=curr_span->low;
+ } /* end while */
+
+ /* Verify that the curr_span points to the fastest dim */
+ assert(curr_span==ispan[fast_dim]);
+ } /* end if */
+ } /* end while */
+ } /* end else */
+
+ FUNC_LEAVE_NOAPI(SUCCEED);
+} /* H5S_hyper_iter_next() */
+
+
/*--------------------------------------------------------------------------
NAME
H5S_hyper_iter_release
PURPOSE
Release hyperslab selection iterator information for a dataspace
USAGE
- herr_t H5S_hyper_iter_release(sel_iter)
- H5S_sel_iter_t *sel_iter; IN: Pointer to selection iterator
+ herr_t H5S_hyper_iter_release(iter)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -319,154 +616,46 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_iter_release (H5S_sel_iter_t *sel_iter)
+H5S_hyper_iter_release (H5S_sel_iter_t *iter)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_hyper_iter_release, FAIL);
/* Check args */
- assert (sel_iter);
+ assert (iter);
/* Release the common array of offsets/positions */
- if(sel_iter->hyp.off!=NULL)
- H5FL_ARR_FREE(hsize_t,sel_iter->hyp.off);
+ if(iter->u.hyp.off!=NULL)
+ H5FL_ARR_FREE(hsize_t,iter->u.hyp.off);
/* Release the information needed for "flattened" regular hyperslab I/O */
/* Free the "flattened" dataspace extent */
- if(sel_iter->hyp.size!=NULL)
- H5FL_ARR_FREE(hsize_t,sel_iter->hyp.size);
+ if(iter->u.hyp.size!=NULL)
+ H5FL_ARR_FREE(hsize_t,iter->u.hyp.size);
/* Free the "flattened" regular hyperslab selection */
- if(sel_iter->hyp.diminfo!=NULL)
- H5FL_ARR_FREE(H5S_hyper_dim_t,sel_iter->hyp.diminfo);
+ if(iter->u.hyp.diminfo!=NULL)
+ H5FL_ARR_FREE(H5S_hyper_dim_t,iter->u.hyp.diminfo);
/* Free the "flattened" selection offset */
- if(sel_iter->hyp.sel_off!=NULL)
- H5FL_ARR_FREE(hssize_t,sel_iter->hyp.sel_off);
+ if(iter->u.hyp.sel_off!=NULL)
+ H5FL_ARR_FREE(hssize_t,iter->u.hyp.sel_off);
/* Release the information needed for non-regular hyperslab I/O */
/* Free the copy of the selections span tree */
- if(sel_iter->hyp.spans!=NULL)
- H5S_hyper_free_span_info(sel_iter->hyp.spans);
+ if(iter->u.hyp.spans!=NULL)
+ H5S_hyper_free_span_info(iter->u.hyp.spans);
/* Release the array of pointers to span nodes */
- if(sel_iter->hyp.span!=NULL)
- H5FL_ARR_FREE(H5S_hyper_span_t,sel_iter->hyp.span);
+ if(iter->u.hyp.span!=NULL)
+ H5FL_ARR_FREE(H5S_hyper_span_t,iter->u.hyp.span);
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_hyper_iter_release() */
-/*-------------------------------------------------------------------------
- * Function: H5S_hyper_iter_next
- *
- * Purpose: Moves a hyperslab iterator to the beginning of the next sequence
- * of elements to read. Handles walking off the end in all dimensions.
- *
- * Return: Success: non-negative
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Friday, September 8, 2000
- *
- * Notes:
- * Only used for the optimized hyperslab I/O routines
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5S_hyper_iter_next (const H5S_t *space, H5S_sel_iter_t *iter)
-{
- const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */
- hsize_t iter_offset[H5O_LAYOUT_NDIMS];
- hsize_t iter_count[H5O_LAYOUT_NDIMS];
- int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
- int temp_dim; /* Temporary rank holder */
- unsigned i; /* Counters */
- unsigned ndims; /* Number of dimensions of dataset */
-
- FUNC_ENTER_NOINIT(H5S_hyper_iter_next);
-
- /* Check if this is a "flattened" regular hyperslab selection */
- if(iter->hyp.iter_rank!=0 && iter->hyp.iter_rank<space->extent.u.simple.rank) {
- /* Set the aliases for a few important dimension ranks */
- ndims=iter->hyp.iter_rank;
- fast_dim=ndims-1;
-
- /* Set the local copy of the diminfo pointer */
- tdiminfo=iter->hyp.diminfo;
- } /* end if */
- else {
- /* Set the aliases for a few important dimension ranks */
- ndims=space->extent.u.simple.rank;
- fast_dim=ndims-1;
-
- /* Set the local copy of the diminfo pointer */
- tdiminfo=space->select.sel_info.hslab.diminfo;
- } /* end else */
-
- /* Calculate the offset and block count for each dimension */
- for(i=0; i<ndims; i++) {
- if(tdiminfo[i].stride==1) {
- iter_offset[i]=iter->hyp.off[i]-tdiminfo[i].start;
- iter_count[i]=0;
- } /* end if */
- else {
- iter_offset[i]=(iter->hyp.off[i]-tdiminfo[i].start)%tdiminfo[i].stride;
- iter_count[i]=(iter->hyp.off[i]-tdiminfo[i].start)/tdiminfo[i].stride;
- } /* end else */
- } /* end for */
-
- /* Start with the fastest changing dimension */
- temp_dim=fast_dim;
- while(temp_dim>=0) {
- if(temp_dim==fast_dim) {
- /* Move to the next block in the current dimension */
- iter_offset[temp_dim]=0; /* reset the offset in the fastest dimension */
- iter_count[temp_dim]++;
-
- /* If this block is still in the range of blocks to output for the dimension, break out of loop */
- if(iter_count[temp_dim]<tdiminfo[temp_dim].count)
- break;
- else
- iter_count[temp_dim]=0; /* reset back to the beginning of the line */
- } /* end if */
- else {
- /* Move to the next row in the curent dimension */
- iter_offset[temp_dim]++;
-
- /* If this block is still in the range of blocks to output for the dimension, break out of loop */
- if(iter_offset[temp_dim]<tdiminfo[temp_dim].block)
- break;
- else {
- /* Move to the next block in the current dimension */
- iter_offset[temp_dim]=0;
- iter_count[temp_dim]++;
-
- /* If this block is still in the range of blocks to output for the dimension, break out of loop */
- if(iter_count[temp_dim]<tdiminfo[temp_dim].count)
- break;
- else
- iter_count[temp_dim]=0; /* reset back to the beginning of the line */
- } /* end else */
- } /* end else */
-
- /* Decrement dimension count */
- temp_dim--;
- } /* end while */
-
- /* Translate current iter_offset and iter_count into iterator position */
- for(i=0; i<ndims; i++)
- iter->hyp.off[i]=tdiminfo[i].start+(tdiminfo[i].stride*iter_count[i])+iter_offset[i];
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* H5S_hyper_iter_next() */
-
-
/*--------------------------------------------------------------------------
NAME
H5S_hyper_npoints
@@ -2592,6 +2781,395 @@ H5S_hyper_recover_span (unsigned *recover, H5S_hyper_span_t **curr_span, H5S_hyp
/*--------------------------------------------------------------------------
NAME
+ H5S_hyper_coord_to_span
+ PURPOSE
+ Create a span tree for a single element
+ USAGE
+ H5S_hyper_span_t *H5S_hyper_coord_to_span(rank, coords)
+ unsigned rank; IN: Number of dimensions of coordinate
+ hssize_t *coords; IN: Location of element
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Create a span tree for a single element
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static H5S_hyper_span_t *
+H5S_hyper_coord_to_span(unsigned rank, hssize_t *coords)
+{
+ H5S_hyper_span_t *new_span; /* Pointer to new span tree for coordinate */
+ H5S_hyper_span_info_t *down=NULL; /* Pointer to new span tree for next level down */
+ H5S_hyper_span_t *ret_value=NULL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_coord_to_span);
+
+ assert(rank>0);
+ assert(coords);
+
+ /* Search for location to insert new element in tree */
+ if(rank>1) {
+ /* Allocate a span info node */
+ if((down = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
+
+ /* Set the reference count */
+ down->count=0;
+
+ /* Reset the scratch pad space */
+ down->scratch=0;
+
+ /* Build span tree for coordinates below this one */
+ if((down->head=H5S_hyper_coord_to_span(rank-1,&coords[1]))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
+ } /* end if */
+
+ /* Build span for this coordinate */
+ if((new_span = H5S_hyper_new_span(coords[0],coords[0],down,NULL))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span");
+
+ /* Set return value */
+ ret_value=new_span;
+
+done:
+ if(ret_value==NULL) {
+ if(down!=NULL)
+ H5S_hyper_free_span_info(down);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_coord_to_span() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_add_span_element_helper
+ PURPOSE
+ Add a single elment to a span tree
+ USAGE
+ herr_t H5S_hyper_add_span_element_helper(prev_span, span_tree, rank, coords)
+ H5S_hyper_span_info_t *span_tree; IN/OUT: Pointer to span tree to append to
+ unsigned rank; IN: Number of dimensions of coordinates
+ hssize_t *coords; IN: Location of element to add to span tree
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Add a single element to an existing span tree.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Assumes that the element is not already covered by the span tree
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, unsigned rank, hssize_t *coords)
+{
+ H5S_hyper_span_info_t *tspan_info; /* Temporary pointer to span info */
+ H5S_hyper_span_info_t *prev_span_info; /* Pointer to span info for level above current position */
+ H5S_hyper_span_t *tmp_span; /* Temporary pointer to a span */
+ H5S_hyper_span_t *tmp2_span; /* Another temporary pointer to a span */
+ H5S_hyper_span_t *new_span; /* New span created for element */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_add_span_element_helper);
+
+ assert(span_tree);
+ assert(rank>0);
+ assert(coords);
+
+ /* Get pointer to last span in span tree */
+ tspan_info=span_tree;
+ if(span_tree->scratch)
+ tmp_span=(H5S_hyper_span_t *)span_tree->scratch;
+ else {
+ tmp_span=span_tree->head;
+ assert(tmp_span);
+ span_tree->scratch=(H5S_hyper_span_info_t *)tmp_span;
+ } /* end else */
+
+ /* Find last span tree which includes a portion of the coordinate */
+ prev_span_info=NULL;
+ while(coords[0]>=tmp_span->low && coords[0]<=tmp_span->high) {
+ /* Move rank & coordinate offset down a dimension */
+ rank--;
+ coords++;
+
+ /* Remember the span tree we are descending into */
+ prev_span_info=tspan_info;
+ tspan_info=tmp_span->down;
+
+ /* Get the last span in this span's 'down' tree */
+ if(tspan_info->scratch)
+ tmp_span=(H5S_hyper_span_t *)tspan_info->scratch;
+ else {
+ tmp_span=tspan_info->head;
+ assert(tmp_span);
+ tspan_info->scratch=(H5S_hyper_span_info_t *)tmp_span;
+ } /* end else */
+ } /* end while */
+
+ /* Check if we made it all the way to the bottom span in the tree */
+ if(rank>1) {
+ /* Before we create another span at this level in the tree, check if
+ * the last span's "down tree" was equal to any other spans in this
+ * list of spans in the span tree.
+ *
+ * If so, release last span information and make last span merge into
+ * previous span (if possible), or at least share their "down tree"
+ * information.
+ */
+ tmp2_span=tspan_info->head;
+ while(tmp2_span!=tmp_span) {
+ if(H5S_hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) {
+ /* Check for merging into previous span */
+ if(tmp2_span->high+1==tmp_span->low) {
+ /* Release last span created */
+ H5S_hyper_free_span(tmp_span);
+
+ /* Increase size of previous span */
+ tmp2_span->high++;
+
+ /* Reset the 'tmp_span' for the rest of this block's algorithm */
+ tmp_span=tmp2_span;
+ } /* end if */
+ /* Span is disjoint, but has the same "down tree" selection */
+ else {
+ /* Release "down tree" information */
+ H5S_hyper_free_span_info(tmp_span->down);
+
+ /* Point at earlier span's "down tree" */
+ tmp_span->down=tmp2_span->down;
+
+ /* Increment reference count on shared "down tree" */
+ tmp_span->down->count++;
+ } /* end else */
+
+ /* Found span to merge into, break out now */
+ break;
+ } /* end if */
+
+ /* Advance to next span to check */
+ tmp2_span=tmp2_span->next;
+ } /* end while */
+
+ /* Make span tree for current coordinates */
+ if((new_span=H5S_hyper_coord_to_span(rank,coords))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+
+ /* Add new span tree as span */
+ assert(tmp_span);
+ tmp_span->next=new_span;
+
+ /* Make scratch pointer point to last span in list */
+ assert(tspan_info);
+ tspan_info->scratch=(H5S_hyper_span_info_t *)new_span;
+
+ /* Set the proper 'pstride' for new span */
+ new_span->pstride=new_span->low-tmp_span->low;
+ } /* end if */
+ else {
+ /* Does new node adjoin existing node? */
+ if(tmp_span->high+1==coords[0]) {
+ tmp_span->high++;
+
+ /* Check if this span tree should now be merged with a level higher in the tree */
+ if(prev_span_info!=NULL) {
+ /* Before we create another span at this level in the tree, check if
+ * the last span's "down tree" was equal to any other spans in this
+ * list of spans in the span tree.
+ *
+ * If so, release last span information and make last span merge into
+ * previous span (if possible), or at least share their "down tree"
+ * information.
+ */
+ tmp2_span=prev_span_info->head;
+ tmp_span=(H5S_hyper_span_t *)prev_span_info->scratch;
+ while(tmp2_span!=tmp_span) {
+ if(H5S_hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) {
+ /* Check for merging into previous span */
+ if(tmp2_span->high+1==tmp_span->low) {
+ /* Release last span created */
+ H5S_hyper_free_span(tmp_span);
+
+ /* Increase size of previous span */
+ tmp2_span->high++;
+
+ /* Update pointers */
+ tmp2_span->next=NULL;
+ prev_span_info->scratch=(H5S_hyper_span_info_t *)tmp2_span;
+ } /* end if */
+ /* Span is disjoint, but has the same "down tree" selection */
+ else {
+ /* Release "down tree" information */
+ H5S_hyper_free_span_info(tmp_span->down);
+
+ /* Point at earlier span's "down tree" */
+ tmp_span->down=tmp2_span->down;
+
+ /* Increment reference count on shared "down tree" */
+ tmp_span->down->count++;
+ } /* end else */
+
+ /* Found span to merge into, break out now */
+ break;
+ } /* end if */
+
+ /* Advance to next span to check */
+ tmp2_span=tmp2_span->next;
+ } /* end while */
+ } /* end if */
+ } /* end if */
+ else {
+ if((new_span = H5S_hyper_new_span(coords[0],coords[0],NULL,NULL))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+
+ /* Add new span tree as span */
+ assert(tmp_span);
+ tmp_span->next=new_span;
+
+ /* Make scratch pointer point to last span in list */
+ tspan_info->scratch=(H5S_hyper_span_info_t *)new_span;
+
+ /* Set the proper 'pstride' for new span */
+ new_span->pstride=new_span->low-tmp_span->low;
+ } /* end else */
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_add_span_element_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_add_span_element
+ PURPOSE
+ Add a single elment to a span tree
+ USAGE
+ herr_t H5S_hyper_add_span_element(space, span_tree, rank, coords)
+ H5S_t *space; IN/OUT: Pointer to dataspace to add coordinate to
+ unsigned rank; IN: Number of dimensions of coordinates
+ hssize_t *coords; IN: Location of element to add to span tree
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Add a single element to an existing span tree.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Assumes that the element is not already in the dataspace's selection
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_add_span_element(H5S_t *space, unsigned rank, hssize_t *coords)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_add_span_element);
+
+ assert(space);
+ assert(rank>0);
+ assert(coords);
+
+ /* Check if this is the first element in the selection */
+ if(space->select.sel_info.hslab.span_lst==NULL) {
+ H5S_hyper_span_info_t *head; /* Pointer to new head of span tree */
+
+ /* Allocate a span info node */
+ if((head = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+
+ /* Set the reference count */
+ head->count=0;
+
+ /* Reset the scratch pad space */
+ head->scratch=0;
+
+ /* Build span tree for this coordinate */
+ if((head->head=H5S_hyper_coord_to_span(rank,coords))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+
+ /* Set the selection to the new span tree */
+ space->select.sel_info.hslab.span_lst=head;
+
+ /* Set selection type */
+ space->select.type=H5S_SEL_HYPERSLABS;
+
+ /* Reset "regular" hyperslab fields */
+ space->select.sel_info.hslab.diminfo = NULL;
+ space->select.sel_info.hslab.app_diminfo = NULL;
+
+ /* Set selection methods */
+ space->select.get_seq_list=H5S_hyper_get_seq_list;
+ space->select.get_npoints=H5S_hyper_npoints;
+ space->select.release=H5S_hyper_release;
+ space->select.is_valid=H5S_hyper_is_valid;
+ space->select.serial_size=H5S_hyper_serial_size;
+ space->select.serialize=H5S_hyper_serialize;
+ space->select.bounds=H5S_hyper_bounds;
+ space->select.is_contiguous=H5S_hyper_is_contiguous;
+ space->select.is_single=H5S_hyper_is_single;
+ space->select.is_regular=H5S_hyper_is_regular;
+ space->select.iter_init=H5S_hyper_iter_init;
+
+ /* Set # of elements in selection */
+ space->select.num_elem=1;
+ } /* end if */
+ else {
+ if(H5S_hyper_add_span_element_helper(space->select.sel_info.hslab.span_lst,rank,coords)<0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span");
+
+ /* Increment # of elements in selection */
+ space->select.num_elem++;
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_add_span_element() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_reset_scratch
+ PURPOSE
+ Reset the scratch information for span tree
+ USAGE
+ herr_t H5S_hyper_reset_scratch(space)
+ H5S_t *space; IN/OUT: Pointer to dataspace to reset scratch pointers
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Resets the "scratch" pointers used for various tasks in computing hyperslab
+ spans.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_reset_scratch(H5S_t *space)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5S_hyper_reset_scratch);
+
+ assert(space);
+
+ /* Check if there are spans in the span tree */
+ if(space->select.sel_info.hslab.span_lst!=NULL)
+ /* Reset the scratch pointers for the next routine which needs them */
+ if(H5S_hyper_span_scratch(space->select.sel_info.hslab.span_lst,NULL)==FAIL)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "can't reset span tree scratch pointers");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_reset_scratch() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_hyper_append_span
PURPOSE
Create a new span and append to span list
@@ -4145,9 +4723,6 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
space->select.get_seq_list=H5S_hyper_get_seq_list;
space->select.get_npoints=H5S_hyper_npoints;
space->select.release=H5S_hyper_release;
- space->select.iter_init=H5S_hyper_iter_init;
- space->select.iter_nelmts=H5S_hyper_iter_nelmts;
- space->select.iter_release=H5S_hyper_iter_release;
space->select.is_valid=H5S_hyper_is_valid;
space->select.serial_size=H5S_hyper_serial_size;
space->select.serialize=H5S_hyper_serialize;
@@ -4155,6 +4730,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
space->select.is_contiguous=H5S_hyper_is_contiguous;
space->select.is_single=H5S_hyper_is_single;
space->select.is_regular=H5S_hyper_is_regular;
+ space->select.iter_init=H5S_hyper_iter_init;
done:
if(_stride!=NULL)
@@ -4375,18 +4951,17 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper
result->select.type=H5S_SEL_HYPERSLABS;
/* Set selection methods */
- space->select.get_seq_list=H5S_hyper_get_seq_list;
- space->select.get_npoints=H5S_hyper_npoints;
- space->select.release=H5S_hyper_release;
- space->select.iter_init=H5S_hyper_iter_init;
- space->select.iter_nelmts=H5S_hyper_iter_nelmts;
- space->select.iter_release=H5S_hyper_iter_release;
- space->select.is_valid=H5S_hyper_is_valid;
- space->select.serial_size=H5S_hyper_serial_size;
- space->select.serialize=H5S_hyper_serialize;
- space->select.bounds=H5S_hyper_bounds;
- space->select.is_contiguous=H5S_hyper_is_contiguous;
- space->select.is_single=H5S_hyper_is_single;
+ result->select.get_seq_list=H5S_hyper_get_seq_list;
+ result->select.get_npoints=H5S_hyper_npoints;
+ result->select.release=H5S_hyper_release;
+ result->select.is_valid=H5S_hyper_is_valid;
+ result->select.serial_size=H5S_hyper_serial_size;
+ result->select.serialize=H5S_hyper_serialize;
+ result->select.bounds=H5S_hyper_bounds;
+ result->select.is_contiguous=H5S_hyper_is_contiguous;
+ result->select.is_single=H5S_hyper_is_single;
+ result->select.is_regular=H5S_hyper_is_regular;
+ result->select.iter_init=H5S_hyper_iter_init;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -4487,8 +5062,8 @@ done:
*/
herr_t
H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
- const hssize_t start,
- const hsize_t *stride[],
+ const hssize_t start[],
+ const hsize_t *stride,
const hsize_t count[],
const hsize_t *block)
{
@@ -4943,7 +5518,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2)
{
H5S_hyper_span_info_t *tmp_spans=NULL; /* Temporary copy of selection */
@@ -5071,6 +5646,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
hsize_t slab[H5O_LAYOUT_NDIMS]; /* Cumulative size of each dimension in bytes */
hsize_t acc; /* Accumulator for computing cumulative sizes */
hsize_t loc_off; /* Element offset in the dataspace */
+ hsize_t last_span_end=0; /* The offset of the end of the last span */
hssize_t *abs_arr; /* Absolute hyperslab span position */
hssize_t *off_arr; /* Offset within the dataspace extent */
size_t span_size=0; /* Number of bytes in current span to actually process */
@@ -5104,14 +5680,14 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
fast_dim=(ndims-1);
/* Get the pointers to the current span info and span nodes */
- curr_span=iter->hyp.span[fast_dim];
- abs_arr=iter->hyp.off;
+ curr_span=iter->u.hyp.span[fast_dim];
+ abs_arr=iter->u.hyp.off;
off_arr=space->select.offset;
- ispan=iter->hyp.span;
+ ispan=iter->u.hyp.span;
/* Set the amount of elements to perform I/O on, etc. */
- H5_CHECK_OVERFLOW( (iter->hyp.elmt_left*elem_size) ,hsize_t,size_t);
- start_io_bytes_left=io_bytes_left=MIN(maxbytes,(size_t)(iter->hyp.elmt_left*elem_size));
+ H5_CHECK_OVERFLOW( (iter->elmt_left*elem_size) ,hsize_t,size_t);
+ start_io_bytes_left=io_bytes_left=MIN(maxbytes,(size_t)(iter->elmt_left*elem_size));
nelem=io_bytes_left/elem_size;
/* Compute the cumulative size of dataspace dimensions */
@@ -5126,7 +5702,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
loc_off+=(abs_arr[i]+off_arr[i])*slab[i];
/* Range check against number of elements left in selection */
- assert(io_bytes_left<=(iter->hyp.elmt_left*elem_size));
+ assert(io_bytes_left<=(iter->elmt_left*elem_size));
/* Take care of any partial spans leftover from previous I/Os */
if(abs_arr[fast_dim]!=curr_span->low) {
@@ -5147,6 +5723,9 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
/* Increment sequence count */
curr_seq++;
+ /* Set the location of the last span's end */
+ last_span_end=loc_off+span_size;
+
/* Decrement I/O left to perform */
io_bytes_left-=span_size;
@@ -5169,7 +5748,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
/* Check if we are still within the span */
if(abs_arr[fast_dim]<=curr_span->high) {
- iter->hyp.span[fast_dim]=curr_span;
+ iter->u.hyp.span[fast_dim]=curr_span;
goto partial_done; /* finished with partial span */
} /* end if */
@@ -5182,7 +5761,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
if(curr_span!=NULL) {
/* Reset absolute position */
abs_arr[fast_dim]=curr_span->low;
- iter->hyp.span[fast_dim]=curr_span;
+ iter->u.hyp.span[fast_dim]=curr_span;
goto partial_done; /* finished with partial span */
} /* end if */
@@ -5199,7 +5778,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
/* Work back up through the dimensions */
while(curr_dim>=0) {
/* Reset the current span */
- curr_span=iter->hyp.span[curr_dim];
+ curr_span=iter->u.hyp.span[curr_dim];
/* Increment absolute position */
abs_arr[curr_dim]++;
@@ -5248,7 +5827,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
curr_dim++;
/* Set the new span_info & span for this dimension */
- iter->hyp.span[curr_dim]=curr_span->down->head;
+ iter->u.hyp.span[curr_dim]=curr_span->down->head;
/* Advance span down the tree */
curr_span=curr_span->down->head;
@@ -5258,7 +5837,7 @@ H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
} /* end while */
/* Verify that the curr_span points to the fastest dim */
- assert(curr_span==iter->hyp.span[fast_dim]);
+ assert(curr_span==iter->u.hyp.span[fast_dim]);
} /* end else */
/* Reset the buffer offset */
@@ -5290,11 +5869,20 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
/* COMMON */
/* Store the I/O information for the span */
- off[curr_seq]=loc_off;
- len[curr_seq]=span_size;
-
- /* Increment the number of sequences in arrays */
- curr_seq++;
+
+ /* Check if this is appending onto previous sequence */
+ if(curr_seq>0 && last_span_end==loc_off)
+ len[curr_seq-1]+=span_size;
+ else {
+ off[curr_seq]=loc_off;
+ len[curr_seq]=span_size;
+
+ /* Increment the number of sequences in arrays */
+ curr_seq++;
+ } /* end else */
+
+ /* Set the location of the last span's end */
+ last_span_end=loc_off+span_size;
/* If the sequence & offset arrays are full, do what? */
if(curr_seq>=maxseq) {
@@ -5313,11 +5901,20 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
/* COMMON */
/* Store the I/O information for the span */
- off[curr_seq]=loc_off;
- len[curr_seq]=span_size;
-
- /* Increment the number of sequences in arrays */
- curr_seq++;
+
+ /* Check if this is appending onto previous sequence */
+ if(curr_seq>0 && last_span_end==loc_off)
+ len[curr_seq-1]+=span_size;
+ else {
+ off[curr_seq]=loc_off;
+ len[curr_seq]=span_size;
+
+ /* Increment the number of sequences in arrays */
+ curr_seq++;
+ } /* end else */
+
+ /* Set the location of the last span's end */
+ last_span_end=loc_off+span_size;
/* If the sequence & offset arrays are full, do what? */
if(curr_seq>=maxseq) {
@@ -5337,7 +5934,7 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
/* Check if we are still within the span */
if(abs_arr[fast_dim]<=curr_span->high) {
- iter->hyp.span[fast_dim]=curr_span;
+ iter->u.hyp.span[fast_dim]=curr_span;
break;
} /* end if */
/* If we walked off that span, advance to the next span */
@@ -5349,7 +5946,7 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
if(curr_span!=NULL) {
/* Reset absolute position */
abs_arr[fast_dim]=curr_span->low;
- iter->hyp.span[fast_dim]=curr_span;
+ iter->u.hyp.span[fast_dim]=curr_span;
break;
} /* end if */
} /* end else */
@@ -5363,7 +5960,7 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
/* Work back up through the dimensions */
while(curr_dim>=0) {
/* Reset the current span */
- curr_span=iter->hyp.span[curr_dim];
+ curr_span=iter->u.hyp.span[curr_dim];
/* Increment absolute position */
abs_arr[curr_dim]++;
@@ -5411,7 +6008,7 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
curr_dim++;
/* Set the new span for the next dimension down */
- iter->hyp.span[curr_dim]=curr_span->down->head;
+ iter->u.hyp.span[curr_dim]=curr_span->down->head;
/* Advance span down the tree */
curr_span=curr_span->down->head;
@@ -5421,7 +6018,7 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
} /* end while */
/* Verify that the curr_span points to the fastest dim */
- assert(curr_span==iter->hyp.span[fast_dim]);
+ assert(curr_span==iter->u.hyp.span[fast_dim]);
} /* end else */
/* Reset the buffer offset */
@@ -5430,7 +6027,7 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
} /* end while */
/* Decrement number of elements left in iterator */
- iter->hyp.elmt_left-=(nelem-(io_bytes_left/elem_size));
+ iter->elmt_left-=(nelem-(io_bytes_left/elem_size));
/* Set the number of sequences generated */
*nseq=curr_seq;
@@ -5526,29 +6123,26 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
assert(off);
assert(len);
+ /* Set the local copy of the diminfo pointer */
+ tdiminfo=iter->u.hyp.diminfo;
+
/* Check if this is a "flattened" regular hyperslab selection */
- if(iter->hyp.iter_rank!=0 && iter->hyp.iter_rank<space->extent.u.simple.rank) {
+ if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<space->extent.u.simple.rank) {
/* Set the aliases for a few important dimension ranks */
- ndims=iter->hyp.iter_rank;
+ ndims=iter->u.hyp.iter_rank;
fast_dim=ndims-1;
- /* Set the local copy of the diminfo pointer */
- tdiminfo=iter->hyp.diminfo;
-
/* Set the local copy of the selection offset */
- sel_off=iter->hyp.sel_off;
+ sel_off=iter->u.hyp.sel_off;
/* Set up the size of the memory space */
- HDmemcpy(mem_size, iter->hyp.size, ndims*sizeof(hsize_t));
+ HDmemcpy(mem_size, iter->u.hyp.size, ndims*sizeof(hsize_t));
} /* end if */
else {
/* Set the aliases for a few important dimension ranks */
ndims=space->extent.u.simple.rank;
fast_dim=ndims-1;
- /* Set the local copy of the diminfo pointer */
- tdiminfo=space->select.sel_info.hslab.diminfo;
-
/* Set the local copy of the selection offset */
sel_off=space->select.offset;
@@ -5564,22 +6158,22 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
} /* end for */
/* Get the number of elements left in the selection */
- H5_ASSIGN_OVERFLOW(io_left,iter->hyp.elmt_left,hsize_t,size_t);
+ H5_ASSIGN_OVERFLOW(io_left,iter->elmt_left,hsize_t,size_t);
/* Calculate the number of elements to sequence through */
start_io_left=io_left=MIN(io_left,(maxbytes/elmt_size));
/* Check if we stopped in the middle of a sequence of elements */
- if((iter->hyp.off[fast_dim]-tdiminfo[fast_dim].start)%tdiminfo[fast_dim].stride!=0 ||
- ((iter->hyp.off[fast_dim]!=tdiminfo[fast_dim].start) && tdiminfo[fast_dim].stride==1)) {
+ if((iter->u.hyp.off[fast_dim]-tdiminfo[fast_dim].start)%tdiminfo[fast_dim].stride!=0 ||
+ ((iter->u.hyp.off[fast_dim]!=tdiminfo[fast_dim].start) && tdiminfo[fast_dim].stride==1)) {
size_t leftover; /* The number of elements left over from the last sequence */
/* Calculate the number of elements left in the sequence */
if(tdiminfo[fast_dim].stride==1) {
- H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block-(iter->hyp.off[fast_dim]-tdiminfo[fast_dim].start) ,hsize_t,size_t);
+ H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block-(iter->u.hyp.off[fast_dim]-tdiminfo[fast_dim].start) ,hsize_t,size_t);
} /* end if */
else {
- H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block-((iter->hyp.off[fast_dim]-tdiminfo[fast_dim].start)%tdiminfo[fast_dim].stride) ,hsize_t,size_t);
+ H5_ASSIGN_OVERFLOW(leftover, tdiminfo[fast_dim].block-((iter->u.hyp.off[fast_dim]-tdiminfo[fast_dim].start)%tdiminfo[fast_dim].stride) ,hsize_t,size_t);
} /* end else */
/* Make certain that we don't write too many */
@@ -5587,7 +6181,7 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
/* Compute the initial buffer offset */
for(i=0,loc=0; i<ndims; i++)
- loc+=(iter->hyp.off[i]+sel_off[i])*slab[i];
+ loc+=(iter->u.hyp.off[i]+sel_off[i])*slab[i];
/* Add a new sequence */
off[curr_seq]=loc;
@@ -5600,22 +6194,10 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
io_left -= actual_elem;
/* Advance the hyperslab iterator */
-
- /* If we had enough room to count the rest of the sequence
- * in the fastest changing dimension, move the iterator offset to
- * the beginning of the next block to write. Otherwise, just advance
- * the iterator in the fastest changing dimension.
- */
- if(actual_elem==leftover) {
- /* Move iterator offset to beginning of next sequence in the fastest changing dimension */
- H5S_hyper_iter_next(space,iter);
- } /* end if */
- else {
- iter->hyp.off[fast_dim]+=actual_elem; /* whole sequence not written out, just advance fastest dimension offset */
- } /* end else */
+ H5S_hyper_iter_next(iter,actual_elem);
/* Decrement the number of elements left in selection */
- iter->hyp.elmt_left-=actual_elem;
+ iter->elmt_left-=actual_elem;
} /* end if */
/* Now that we've cleared the "remainder" of the previous fastest dimension
@@ -5629,7 +6211,7 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
/* Compute the arrays to perform I/O on */
/* Copy the location of the point to get */
- HDmemcpy(offset, iter->hyp.off,ndims*sizeof(hssize_t));
+ HDmemcpy(offset, iter->u.hyp.off,ndims*sizeof(hssize_t));
/* Add in the selection offset */
for(i=0; i<ndims; i++)
@@ -5639,11 +6221,11 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
for(i=0; i<ndims; i++) {
if(tdiminfo[i].stride==1) {
tmp_count[i] = 0;
- tmp_block[i] = iter->hyp.off[i]-tdiminfo[i].start;
+ tmp_block[i] = iter->u.hyp.off[i]-tdiminfo[i].start;
} /* end if */
else {
- tmp_count[i] = (iter->hyp.off[i]-tdiminfo[i].start)/tdiminfo[i].stride;
- tmp_block[i] = (iter->hyp.off[i]-tdiminfo[i].start)%tdiminfo[i].stride;
+ tmp_count[i] = (iter->u.hyp.off[i]-tdiminfo[i].start)/tdiminfo[i].stride;
+ tmp_block[i] = (iter->u.hyp.off[i]-tdiminfo[i].start)%tdiminfo[i].stride;
} /* end else */
} /* end for */
@@ -5983,7 +6565,6 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
assert(io_left==0 || curr_seq==maxseq);
} /* end if */
-
/* Update the iterator */
/* Subtract out the selection offset */
@@ -5991,10 +6572,10 @@ H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
offset[i] -= sel_off[i];
/* Update the iterator with the location we stopped */
- HDmemcpy(iter->hyp.off, offset, ndims*sizeof(hssize_t));
+ HDmemcpy(iter->u.hyp.off, offset, ndims*sizeof(hssize_t));
/* Decrement the number of elements left in selection */
- iter->hyp.elmt_left-=(nelmts-io_left);
+ iter->elmt_left-=(nelmts-io_left);
} /* end if */
/* Set the number of sequences generated */
diff --git a/src/H5Snone.c b/src/H5Snone.c
index 20f03be..a1d6127 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -49,7 +49,7 @@ static int interface_initialize_g = 0;
*-------------------------------------------------------------------------
*/
herr_t
-H5S_none_iter_init (const H5S_t UNUSED *space, size_t UNUSED elmt_size, H5S_sel_iter_t UNUSED *sel_iter)
+H5S_none_iter_init (H5S_sel_iter_t *iter, const H5S_t UNUSED *space, size_t UNUSED elmt_size)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -57,7 +57,13 @@ H5S_none_iter_init (const H5S_t UNUSED *space, size_t UNUSED elmt_size, H5S_sel_
/* Check args */
assert (space && H5S_SEL_NONE==space->select.type);
- assert (sel_iter);
+ assert (iter);
+
+ /* Initialize methods for selection iterator */
+ iter->iter_coords=H5S_none_iter_coords;
+ iter->iter_nelmts=H5S_none_iter_nelmts;
+ iter->iter_next=H5S_none_iter_next;
+ iter->iter_release=H5S_none_iter_release;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -65,6 +71,37 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5S_none_iter_coords
+ *
+ * Purpose: Retrieve the current coordinates of iterator for current
+ * selection
+ *
+ * Return: non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 22, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_none_iter_coords (const H5S_sel_iter_t UNUSED *iter, hssize_t UNUSED *coords)
+{
+ herr_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_none_iter_coords, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (coords);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_none_iter_coords() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_none_iter_nelmts
*
* Purpose: Return number of elements left to process in iterator
@@ -79,14 +116,14 @@ done:
*-------------------------------------------------------------------------
*/
hsize_t
-H5S_none_iter_nelmts (const H5S_sel_iter_t UNUSED *sel_iter)
+H5S_none_iter_nelmts (const H5S_sel_iter_t UNUSED *iter)
{
hsize_t ret_value=0; /* Return value */
FUNC_ENTER_NOAPI(H5S_none_iter_nelmts, 0);
/* Check args */
- assert (sel_iter);
+ assert (iter);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -95,12 +132,46 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_none_iter_next
+ PURPOSE
+ Increment selection iterator
+ USAGE
+ herr_t H5S_none_iter_next(iter, nelem)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
+ size_t nelem; IN: Number of elements to advance by
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Advance selection iterator to the NELEM'th next element in the selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_none_iter_next(H5S_sel_iter_t UNUSED *iter, size_t UNUSED nelem)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_none_iter_next, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (nelem>0);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_none_iter_next() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_none_iter_release
PURPOSE
Release "none" selection iterator information for a dataspace
USAGE
- herr_t H5S_none_iter_release(sel_iter)
- H5S_sel_iter_t *sel_iter; IN: Pointer to selection iterator
+ herr_t H5S_none_iter_release(iter)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -111,14 +182,14 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_none_iter_release (H5S_sel_iter_t UNUSED * sel_iter)
+H5S_none_iter_release (H5S_sel_iter_t UNUSED * iter)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_none_iter_release, FAIL);
/* Check args */
- assert (sel_iter);
+ assert (iter);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -515,9 +586,6 @@ herr_t H5S_select_none (H5S_t *space)
space->select.get_seq_list=H5S_none_get_seq_list;
space->select.get_npoints=H5S_none_npoints;
space->select.release=H5S_none_release;
- space->select.iter_init=H5S_none_iter_init;
- space->select.iter_nelmts=H5S_none_iter_nelmts;
- space->select.iter_release=H5S_none_iter_release;
space->select.is_valid=H5S_none_is_valid;
space->select.serial_size=H5S_none_serial_size;
space->select.serialize=H5S_none_serialize;
@@ -525,6 +593,7 @@ herr_t H5S_select_none (H5S_t *space)
space->select.is_contiguous=H5S_none_is_contiguous;
space->select.is_single=H5S_none_is_single;
space->select.is_regular=H5S_none_is_regular;
+ space->select.iter_init=H5S_none_iter_init;
done:
FUNC_LEAVE_NOAPI(ret_value);
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 8079d77..7844d14 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -79,7 +79,12 @@ struct H5S_hyper_span_t {
/* Information about a list of hyperslab spans */
struct H5S_hyper_span_info_t {
unsigned count; /* Ref. count of number of spans which share this span */
- struct H5S_hyper_span_info_t *scratch; /* Scratch pointer (used during copies & as mark during precomputes for I/O) */
+ struct H5S_hyper_span_info_t *scratch; /* Scratch pointer
+ * (used during copies, as mark
+ * during precomputes for I/O &
+ * to point to the last span in a
+ * list during single element adds)
+ */
struct H5S_hyper_span_t *head; /* Pointer to list of spans in next dimension down */
};
@@ -117,12 +122,6 @@ typedef herr_t (*H5S_sel_get_seq_list_func_t)(const H5S_t *space, unsigned flags
typedef hsize_t (*H5S_sel_get_npoints_func_t)(const H5S_t *space);
/* Method to release current selection */
typedef herr_t (*H5S_sel_release_func_t)(H5S_t *space);
-/* Method to initialize iterator for current selection */
-typedef herr_t (*H5S_sel_iter_init_func_t)(const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_iter);
-/* Method to determine number of elements left in iterator for current selection */
-typedef hsize_t (*H5S_sel_iter_nelmts_func_t)(const H5S_sel_iter_t *iter);
-/* Method to release iterator for current selection */
-typedef herr_t (*H5S_sel_iter_release_func_t)(H5S_sel_iter_t *iter);
/* Method to determine if current selection is valid for dataspace */
typedef htri_t (*H5S_sel_is_valid_func_t)(const H5S_t *space);
/* Method to determine number of bytes required to store current selection */
@@ -137,6 +136,8 @@ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space);
typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space);
/* Method to determine if current selection is "regular" */
typedef htri_t (*H5S_sel_is_regular_func_t)(const H5S_t *space);
+/* Method to initialize iterator for current selection */
+typedef herr_t (*H5S_sel_iter_init_func_t)(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size);
/* Selection information object */
typedef struct {
@@ -151,9 +152,6 @@ typedef struct {
H5S_sel_get_seq_list_func_t get_seq_list; /* Method to retrieve a list of offset/length sequences for selection */
H5S_sel_get_npoints_func_t get_npoints; /* Method to compute number of elements in current selection */
H5S_sel_release_func_t release; /* Method to release current selection */
- H5S_sel_iter_init_func_t iter_init; /* Method to initialize iterator for current selection */
- H5S_sel_iter_nelmts_func_t iter_nelmts; /* Method to determine number of elements left in iterator for current selection */
- H5S_sel_iter_release_func_t iter_release; /* Method to release iterator for current selection */
H5S_sel_is_valid_func_t is_valid; /* Method to determine if current selection is valid for dataspace */
H5S_sel_serial_size_func_t serial_size; /* Method to determine number of bytes required to store current selection */
H5S_sel_serialize_func_t serialize; /* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */
@@ -161,6 +159,7 @@ typedef struct {
H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */
H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */
H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */
+ H5S_sel_iter_init_func_t iter_init; /* Method to initialize iterator for current selection */
} H5S_select_t;
/* Main dataspace structure (typedef'd in H5Sprivate.h) */
@@ -174,11 +173,14 @@ H5_DLL herr_t H5S_close_simple(H5S_simple_t *simple);
H5_DLL herr_t H5S_release_simple(H5S_simple_t *simple);
H5_DLL herr_t H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src);
-/* Point select functions */
-H5_DLL herr_t H5S_point_iter_init (const H5S_t *space, size_t elmt_size,
- H5S_sel_iter_t *iter);
-H5_DLL hsize_t H5S_point_iter_nelmts (const H5S_sel_iter_t *iter);
+/* Point selection iterator functions */
+H5_DLL herr_t H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);
+H5_DLL herr_t H5S_point_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords);
+H5_DLL hsize_t H5S_point_iter_nelmts(const H5S_sel_iter_t *iter);
+H5_DLL herr_t H5S_point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
H5_DLL herr_t H5S_point_iter_release(H5S_sel_iter_t *sel_iter);
+
+/* Point selection functions */
H5_DLL herr_t H5S_point_release(H5S_t *space);
H5_DLL hsize_t H5S_point_npoints(const H5S_t *space);
H5_DLL herr_t H5S_point_copy(H5S_t *dst, const H5S_t *src);
@@ -194,11 +196,14 @@ H5_DLL herr_t H5S_point_get_seq_list(const H5S_t *space, unsigned flags,
H5S_sel_iter_t *iter, size_t elem_size, size_t maxseq, size_t maxbytes,
size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);
-/* "All" select functions */
-H5_DLL herr_t H5S_all_iter_init (const H5S_t *space, size_t elmt_size,
- H5S_sel_iter_t *iter);
-H5_DLL hsize_t H5S_all_iter_nelmts (const H5S_sel_iter_t *iter);
+/* "All" selection iterator functions */
+H5_DLL herr_t H5S_all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);
+H5_DLL herr_t H5S_all_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords);
+H5_DLL hsize_t H5S_all_iter_nelmts(const H5S_sel_iter_t *iter);
+H5_DLL herr_t H5S_all_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
H5_DLL herr_t H5S_all_iter_release(H5S_sel_iter_t *sel_iter);
+
+/* "All" selection functions */
H5_DLL herr_t H5S_all_release(H5S_t *space);
H5_DLL hsize_t H5S_all_npoints(const H5S_t *space);
H5_DLL htri_t H5S_all_is_valid(const H5S_t *space);
@@ -213,11 +218,14 @@ H5_DLL herr_t H5S_all_get_seq_list(const H5S_t *space, unsigned flags,
H5S_sel_iter_t *iter, size_t elem_size, size_t maxseq, size_t maxbytes,
size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);
-/* Hyperslab selection functions */
-H5_DLL herr_t H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size,
- H5S_sel_iter_t *iter);
-H5_DLL hsize_t H5S_hyper_iter_nelmts (const H5S_sel_iter_t *iter);
+/* Hyperslab selection iterator functions */
+H5_DLL herr_t H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);
+H5_DLL herr_t H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords);
+H5_DLL hsize_t H5S_hyper_iter_nelmts(const H5S_sel_iter_t *iter);
+H5_DLL herr_t H5S_hyper_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
H5_DLL herr_t H5S_hyper_iter_release(H5S_sel_iter_t *sel_iter);
+
+/* Hyperslab selection functions */
H5_DLL herr_t H5S_hyper_release(H5S_t *space);
H5_DLL hsize_t H5S_hyper_npoints(const H5S_t *space);
H5_DLL herr_t H5S_hyper_copy(H5S_t *dst, const H5S_t *src);
@@ -233,11 +241,14 @@ H5_DLL herr_t H5S_hyper_get_seq_list(const H5S_t *space, unsigned flags,
H5S_sel_iter_t *iter, size_t elem_size, size_t maxseq, size_t maxbytes,
size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);
-/* "None" selection functions */
-H5_DLL herr_t H5S_none_iter_init (const H5S_t *space, size_t elmt_size,
- H5S_sel_iter_t *iter);
-H5_DLL hsize_t H5S_none_iter_nelmts (const H5S_sel_iter_t *iter);
+/* "None" selection iterator functions */
+H5_DLL herr_t H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);
+H5_DLL herr_t H5S_none_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords);
+H5_DLL hsize_t H5S_none_iter_nelmts(const H5S_sel_iter_t *iter);
+H5_DLL herr_t H5S_none_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
H5_DLL herr_t H5S_none_iter_release(H5S_sel_iter_t *sel_iter);
+
+/* "None" selection functions */
H5_DLL herr_t H5S_none_release(H5S_t *space);
H5_DLL hsize_t H5S_none_npoints(const H5S_t *space);
H5_DLL htri_t H5S_none_is_valid(const H5S_t *space);
@@ -252,6 +263,8 @@ H5_DLL herr_t H5S_none_get_seq_list(const H5S_t *space, unsigned flags,
H5S_sel_iter_t *iter, size_t elem_size, size_t maxseq, size_t maxbytes,
size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);
/* Needed for use in hyperslab code (H5Shyper.c) */
-H5_DLL herr_t H5S_select_none(H5S_t *space);
+#ifdef NEW_HYPERSLAB_API
+H5_DLL herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
+#endif /*NEW_HYPERSLAB_API*/
-#endif
+#endif /*_H5Spkg_H*/
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 18b81b5..eefd599 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -56,7 +56,7 @@ H5FL_DEFINE_STATIC(H5S_pnt_list_t);
*-------------------------------------------------------------------------
*/
herr_t
-H5S_point_iter_init(const H5S_t *space, size_t UNUSED elmt_size, H5S_sel_iter_t *sel_iter)
+H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t UNUSED elmt_size)
{
herr_t ret_value=SUCCEED; /* Return value */
@@ -64,20 +64,60 @@ H5S_point_iter_init(const H5S_t *space, size_t UNUSED elmt_size, H5S_sel_iter_t
/* Check args */
assert (space && H5S_SEL_POINTS==space->select.type);
- assert (sel_iter);
+ assert (iter);
/* Initialize the number of points to iterate over */
- sel_iter->pnt.elmt_left=space->select.num_elem;
+ iter->elmt_left=space->select.num_elem;
/* Start at the head of the list of points */
- sel_iter->pnt.curr=space->select.sel_info.pnt_lst->head;
+ iter->u.pnt.curr=space->select.sel_info.pnt_lst->head;
+ /* Initialize methods for selection iterator */
+ iter->iter_coords=H5S_point_iter_coords;
+ iter->iter_nelmts=H5S_point_iter_nelmts;
+ iter->iter_next=H5S_point_iter_next;
+ iter->iter_release=H5S_point_iter_release;
+
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_point_iter_init() */
/*-------------------------------------------------------------------------
+ * Function: H5S_point_iter_coords
+ *
+ * Purpose: Retrieve the current coordinates of iterator for current
+ * selection
+ *
+ * Return: non-negative on success, negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 22, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_point_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_point_iter_coords, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (coords);
+
+ /* Copy the offset of the current point */
+ HDmemcpy(coords,iter->u.pnt.curr->pnt,sizeof(hssize_t)*iter->rank);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_point_iter_coords() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_point_iter_nelmts
*
* Purpose: Return number of elements left to process in iterator
@@ -92,17 +132,17 @@ done:
*-------------------------------------------------------------------------
*/
hsize_t
-H5S_point_iter_nelmts (const H5S_sel_iter_t *sel_iter)
+H5S_point_iter_nelmts (const H5S_sel_iter_t *iter)
{
hsize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5S_point_iter_nelmts, 0);
/* Check args */
- assert (sel_iter);
+ assert (iter);
/* Set return value */
- ret_value=sel_iter->pnt.elmt_left;
+ ret_value=iter->elmt_left;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -111,12 +151,52 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_point_iter_next
+ PURPOSE
+ Increment selection iterator
+ USAGE
+ herr_t H5S_point_iter_next(iter, nelem)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
+ size_t nelem; IN: Number of elements to advance by
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Advance selection iterator to the NELEM'th next element in the selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_point_iter_next(H5S_sel_iter_t *iter, size_t nelem)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_point_iter_next, FAIL);
+
+ /* Check args */
+ assert (iter);
+ assert (nelem>0);
+
+ /* Increment the iterator */
+ while(nelem>0) {
+ iter->u.pnt.curr=iter->u.pnt.curr->next;
+ nelem--;
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_point_iter_next() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_point_iter_release
PURPOSE
Release point selection iterator information for a dataspace
USAGE
- herr_t H5S_point_iter_release(sel_iter)
- H5S_sel_iter_t *sel_iter; IN: Pointer to selection iterator
+ herr_t H5S_point_iter_release(iter)
+ H5S_sel_iter_t *iter; IN: Pointer to selection iterator
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
@@ -127,14 +207,14 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_point_iter_release (H5S_sel_iter_t UNUSED * sel_iter)
+H5S_point_iter_release (H5S_sel_iter_t UNUSED * iter)
{
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_point_iter_release, FAIL);
/* Check args */
- assert (sel_iter);
+ assert (iter);
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -339,7 +419,7 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static herr_t
+herr_t
H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
const hssize_t **coord)
{
@@ -376,9 +456,6 @@ H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
space->select.get_seq_list=H5S_point_get_seq_list;
space->select.get_npoints=H5S_point_npoints;
space->select.release=H5S_point_release;
- space->select.iter_init=H5S_point_iter_init;
- space->select.iter_nelmts=H5S_point_iter_nelmts;
- space->select.iter_release=H5S_point_iter_release;
space->select.is_valid=H5S_point_is_valid;
space->select.serial_size=H5S_point_serial_size;
space->select.serialize=H5S_point_serialize;
@@ -386,6 +463,7 @@ H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
space->select.is_contiguous=H5S_point_is_contiguous;
space->select.is_single=H5S_point_is_single;
space->select.is_regular=H5S_point_is_regular;
+ space->select.iter_init=H5S_point_iter_init;
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -811,7 +889,7 @@ H5S_get_select_elem_pointlist(H5S_t *space, hsize_t startpoint, hsize_t numpoint
/* Iterate through the node, copying each hyperslab's information */
while(node!=NULL && numpoints>0) {
- HDmemcpy(buf,node->pnt,sizeof(hsize_t)*rank);
+ HDmemcpy(buf,node->pnt,sizeof(hssize_t)*rank);
buf+=rank;
numpoints--;
node=node->next;
@@ -1183,7 +1261,7 @@ H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter,
maxbytes=(maxbytes/elem_size)*elem_size;
/* Choose the minimum number of bytes to sequence through */
- start_bytes_left=bytes_left=MIN(iter->pnt.elmt_left*elem_size,maxbytes);
+ start_bytes_left=bytes_left=MIN(iter->elmt_left*elem_size,maxbytes);
/* Get the dataspace dimensions */
if ((ndims=H5S_get_simple_extent_dims (space, dims, NULL))<0)
@@ -1191,7 +1269,7 @@ H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter,
/* Walk through the points in the selection, starting at the current */
/* location in the iterator */
- node=iter->pnt.curr;
+ node=iter->u.pnt.curr;
curr_seq=0;
while(node!=NULL) {
/* Compute the offset of each selected point in the buffer */
@@ -1234,8 +1312,8 @@ H5S_point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter,
bytes_left-=elem_size;
/* Move the iterator */
- iter->pnt.curr=node->next;
- iter->pnt.elmt_left--;
+ iter->u.pnt.curr=node->next;
+ iter->elmt_left--;
/* Check if we're finished with all sequences */
if(curr_seq==maxseq)
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index e6619a4..6ca9802 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -51,17 +51,16 @@ typedef struct H5S_pnt_node_t H5S_pnt_node_t;
typedef struct H5S_hyper_span_t H5S_hyper_span_t;
typedef struct H5S_hyper_span_info_t H5S_hyper_span_info_t;
typedef struct H5S_hyper_dim_t H5S_hyper_dim_t;
+union H5D_storage_t;
/* Point selection iteration container */
typedef struct {
- hsize_t elmt_left; /* Number of elements left to iterate over */
H5S_pnt_node_t *curr; /* Pointer to next node to output */
} H5S_point_iter_t;
-/* New Hyperslab selection iteration container */
+/* Hyperslab selection iteration container */
typedef struct {
/* Common fields for all hyperslab selections */
- hsize_t elmt_left; /* Number of elements left to iterate over */
hssize_t *off; /* Offset in span node (used as position for regular hyperslabs) */
unsigned iter_rank; /* Rank of iterator information */
/* (This should always be the same as the dataspace
@@ -82,16 +81,40 @@ typedef struct {
/* "All" selection iteration container */
typedef struct {
- hsize_t elmt_left; /* Number of elements left to iterate over */
hsize_t offset; /* Next element to output */
} H5S_all_iter_t;
+typedef struct H5S_sel_iter_t H5S_sel_iter_t;
+
+/* Method to retrieve the current coordinates of iterator for current selection */
+typedef herr_t (*H5S_sel_iter_coords_func_t)(const H5S_sel_iter_t *iter, hssize_t *coords);
+/* Method to determine number of elements left in iterator for current selection */
+typedef hsize_t (*H5S_sel_iter_nelmts_func_t)(const H5S_sel_iter_t *iter);
+/* Method to move selection iterator to the next element in the selection */
+typedef herr_t (*H5S_sel_iter_next_func_t)(H5S_sel_iter_t *iter, size_t nelem);
+/* Method to release iterator for current selection */
+typedef herr_t (*H5S_sel_iter_release_func_t)(H5S_sel_iter_t *iter);
+
/* Selection iteration container */
-typedef union {
- H5S_point_iter_t pnt; /* Point selection iteration information */
- H5S_hyper_iter_t hyp; /* New Hyperslab selection iteration information */
- H5S_all_iter_t all; /* "All" selection iteration information */
-} H5S_sel_iter_t;
+struct H5S_sel_iter_t {
+ /* Information common to all iterators */
+ unsigned rank; /* Rank of dataspace the selection iterator is operating on */
+ hsize_t *dims; /* Dimensions of dataspace the selection is operating on */
+ hsize_t elmt_left; /* Number of elements left to iterate over */
+
+ /* Information specific to each type of iterator */
+ union {
+ H5S_point_iter_t pnt; /* Point selection iteration information */
+ H5S_hyper_iter_t hyp; /* New Hyperslab selection iteration information */
+ H5S_all_iter_t all; /* "All" selection iteration information */
+ } u;
+
+ /* Methods on selections */
+ H5S_sel_iter_coords_func_t iter_coords; /* Method to retrieve the current coordinates of iterator for current selection */
+ H5S_sel_iter_nelmts_func_t iter_nelmts; /* Method to determine number of elements left in iterator for current selection */
+ H5S_sel_iter_next_func_t iter_next; /* Method to move selection iterator to the next element in the selection */
+ H5S_sel_iter_release_func_t iter_release; /* Method to release iterator for current selection */
+};
typedef struct H5S_conv_t {
H5S_sel_type ftype;
@@ -105,14 +128,14 @@ typedef struct H5S_conv_t {
/* Read from file to application w/o intermediate scratch buffer */
herr_t (*read)(H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ H5P_genplist_t *dc_plist, const union H5D_storage_t *store,
size_t elmt_size, const H5S_t *file_space,
const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/);
/* Write directly from app buffer to file */
herr_t (*write)(H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl,
+ H5P_genplist_t *dc_plist, const union H5D_storage_t *store,
size_t elmt_size, const H5S_t *file_space,
const H5S_t *mem_space, hid_t dxpl_id, const void *buf);
@@ -161,7 +184,7 @@ H5_DLL htri_t H5S_is_simple(const H5S_t *sdim);
H5_DLL herr_t H5S_extent_release(H5S_t *space);
H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size);
H5_DLL int H5S_set_extent(H5S_t *space, const hsize_t *size);
-H5_DLL H5S_t *H5S_create_simple(int rank, const hsize_t dims[/*rank*/],
+H5_DLL H5S_t *H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/],
const hsize_t maxdims[/*rank*/]);
H5_DLL herr_t H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream,
int indent, int fwidth);
@@ -169,17 +192,18 @@ H5_DLL herr_t H5S_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream
/* Operations on selections */
H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src);
H5_DLL herr_t H5S_select_deserialize(H5S_t *space, const uint8_t *buf);
+H5_DLL H5S_sel_type H5S_get_select_type(const H5S_t *space);
H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2);
-H5_DLL herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space,
+H5_DLL herr_t H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space,
H5D_operator_t op, void *operator_data);
H5_DLL herr_t H5S_select_fill(void *fill, size_t fill_size,
const H5S_t *space, void *buf);
H5_DLL herr_t H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const union H5D_storage_t *store, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts,
hid_t dxpl_id, const void *_buf);
H5_DLL hsize_t H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const union H5D_storage_t *store, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter, hsize_t nelmts,
hid_t dxpl_id, void *buf);
H5_DLL herr_t H5S_select_mscat (const void *_tscat_buf, size_t elmt_size,
@@ -189,19 +213,35 @@ H5_DLL hsize_t H5S_select_mgath (const void *_buf, size_t elmt_size,
const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
hid_t dxpl_id, void *_tgath_buf/*out*/);
H5_DLL herr_t H5S_select_read(H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const union H5D_storage_t *store, size_t elmt_size,
const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id,
void *buf/*out*/);
H5_DLL herr_t H5S_select_write(H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
+ H5P_genplist_t *dc_plist, const union H5D_storage_t *store, size_t elmt_size,
const H5S_t *file_space, const H5S_t *mem_space, hid_t dxpl_id,
const void *buf/*out*/);
-
-/* Needed for internal use of selections in H5Fistore code */
+H5_DLL herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op,
+ size_t num_elem, const hssize_t **coord);
+#ifdef NEW_HYPERSLAB_API
+H5_DLL herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
+#endif /*NEW_HYPERSLAB_API */
+H5_DLL htri_t H5S_select_valid(const H5S_t *space);
+H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space);
H5_DLL herr_t H5S_select_all(H5S_t *space, unsigned rel_prev);
+H5_DLL herr_t H5S_select_none(H5S_t *space);
H5_DLL herr_t H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hssize_t start[],
const hsize_t *stride, const hsize_t count[],
const hsize_t *block);
+H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank,
+ hssize_t *coords);
+H5_DLL herr_t H5S_hyper_reset_scratch(H5S_t *space);
+
+/* Operations on selection iterators */
+H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);
+H5_DLL herr_t H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hssize_t *coords);
+H5_DLL hsize_t H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter);
+H5_DLL herr_t H5S_select_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
+H5_DLL herr_t H5S_select_iter_release(H5S_sel_iter_t *sel_iter);
#ifdef H5_HAVE_PARALLEL
/* MPI-IO function to read directly from app buffer to file rky980813 */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 5d921d8..5551412 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -40,7 +40,7 @@ H5FL_ARR_EXTERN(hssize_t);
H5FL_ARR_DEFINE_STATIC(size_t,-1);
/* Declare a free list to manage arrays of hsize_t */
-H5FL_ARR_DEFINE_STATIC(hsize_t,-1);
+H5FL_ARR_EXTERN(hsize_t);
/* Declare a free list to manage blocks of single datatype element data */
H5FL_BLK_EXTERN(type_elem);
@@ -182,7 +182,7 @@ done:
hssize_t H5Sget_select_npoints(dsid)
hid_t dsid; IN: Dataspace ID of selection to query
RETURNS
- The number of elements in selection on success, 0 on failure
+ Non-negative on success/Negative on failure
DESCRIPTION
Returns the number of elements in current selection for dataspace.
GLOBAL VARIABLES
@@ -196,14 +196,14 @@ H5Sget_select_npoints(hid_t spaceid)
H5S_t *space = NULL; /* Dataspace to modify selection of */
hssize_t ret_value; /* return value */
- FUNC_ENTER_API(H5Sget_select_npoints, 0);
+ FUNC_ENTER_API(H5Sget_select_npoints, FAIL);
H5TRACE1("Hs","i",spaceid);
/* Check args */
if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data space");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
- ret_value = (*space->select.get_npoints)(space);
+ ret_value = H5S_get_select_npoints(space);
done:
FUNC_LEAVE_API(ret_value);
@@ -212,6 +212,40 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_get_select_npoints
+ PURPOSE
+ Get the number of elements in current selection
+ USAGE
+ hssize_t H5Sget_select_npoints(space)
+ H5S_t *space; IN: Dataspace of selection to query
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Returns the number of elements in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hssize_t
+H5S_get_select_npoints(const H5S_t *space)
+{
+ hssize_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_get_select_npoints, 0);
+
+ /* Check args */
+ assert(space);
+
+ ret_value = (*space->select.get_npoints)(space);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_get_select_npoints() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5Sselect_valid
PURPOSE
Check whether the selection fits within the extent, with the current
@@ -243,7 +277,7 @@ H5Sselect_valid(hid_t spaceid)
if (NULL == (space=H5I_object_verify(spaceid, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a data space");
- ret_value = (*space->select.is_valid)(space);
+ ret_value = H5S_select_valid(space);
done:
FUNC_LEAVE_API(ret_value);
@@ -252,6 +286,42 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_select_valid
+ PURPOSE
+ Check whether the selection fits within the extent, with the current
+ offset defined.
+ USAGE
+ htri_t H5S_select_void(space)
+ H5S_t *space; IN: Dataspace to query
+ RETURNS
+ TRUE if the selection fits within the extent, FALSE if it does not and
+ Negative on an error.
+ DESCRIPTION
+ Determines if the current selection at the current offet fits within the
+ extent for the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5S_select_valid(const H5S_t *space)
+{
+ htri_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_valid, 0);
+
+ assert(space);
+
+ ret_value = (*space->select.is_valid)(space);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_valid() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_deserialize
PURPOSE
Deserialize the current selection from a user-provided buffer into a real
@@ -362,6 +432,207 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_select_iter_init
+ PURPOSE
+ Initializes iteration information for a selection.
+ USAGE
+ herr_t H5S_select_iter_init(sel_iter, space, elmt_size)
+ H5S_sel_iter_t *sel_iter; OUT: Selection iterator to initialize.
+ H5S_t *space; IN: Dataspace object containing selection to
+ iterate over
+ size_t elmt_size; IN: Size of elements in the selection
+ RETURNS
+ Non-negative on success, negative on failure.
+ DESCRIPTION
+ Initialize the selection iterator object to point to the first element
+ in the dataspace's selection.
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_iter_init, FAIL);
+
+ /* Check args */
+ assert(sel_iter);
+ assert(space);
+ assert(elmt_size>0);
+
+ /* Initialize common information */
+
+ /* Save the dataspace's rank */
+ sel_iter->rank=space->extent.u.simple.rank;
+
+ /* Allocate room for the dataspace dimensions */
+ sel_iter->dims = H5FL_ARR_MALLOC(hsize_t,sel_iter->rank);
+ assert(sel_iter->dims);
+
+ /* Keep a copy of the dataspace dimensions */
+ HDmemcpy(sel_iter->dims,space->extent.u.simple.size,sel_iter->rank*sizeof(hsize_t));
+
+ /* Call initialization routine for selection type */
+ ret_value= (*space->select.iter_init)(sel_iter, space, elmt_size);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_iter_init() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_iter_coords
+ PURPOSE
+ Get the coordinates of the current iterator position
+ USAGE
+ herr_t H5S_select_iter_coords(sel_iter,coords)
+ H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
+ hssize_t *coords; OUT: Array to place iterator coordinates in
+ RETURNS
+ Non-negative on success, negative on failure.
+ DESCRIPTION
+ The current location of the iterator within the selection is placed in
+ the COORDS array.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_iter_coords (const H5S_sel_iter_t *sel_iter, hssize_t *coords)
+{
+ herr_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_iter_coords, FAIL);
+
+ /* Check args */
+ assert(sel_iter);
+ assert(coords);
+
+ /* Call iter_coords routine for selection type */
+ ret_value = (*sel_iter->iter_coords)(sel_iter,coords);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_iter_coords() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_iter_nelmts
+ PURPOSE
+ Get the number of elements left to iterate over in selection
+ USAGE
+ hssize_t H5S_select_iter_nelmts(sel_iter)
+ H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Returns the number of elements in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hsize_t
+H5S_select_iter_nelmts (const H5S_sel_iter_t *sel_iter)
+{
+ hsize_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_iter_nelmts, 0);
+
+ /* Check args */
+ assert(sel_iter);
+
+ /* Call iter_nelmts routine for selection type */
+ ret_value = (*sel_iter->iter_nelmts)(sel_iter);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_iter_nelmts() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_iter_next
+ PURPOSE
+ Advance seletion iterator
+ USAGE
+ herr_t H5S_select_iter_next(iter, nelem)
+ H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change
+ size_t nelem; IN: Number of elements to advance by
+ RETURNS
+ Non-negative on success, negative on failure.
+ DESCRIPTION
+ Move the current element for the selection iterator to the NELEM'th next
+ element in the selection.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
+{
+ herr_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_iter_next, FAIL);
+
+ /* Check args */
+ assert(iter);
+ assert(nelem>0);
+
+ /* Call iter_coords routine for selection type */
+ ret_value = (*iter->iter_next)(iter,nelem);
+
+ /* Decrement the number of elements left in selection */
+ iter->elmt_left-=nelem;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_iter_next() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_select_iter_release
+ PURPOSE
+ Release a selection iterator's resources.
+ USAGE
+ hssize_t H5S_select_iter_release(sel_iter)
+ H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
+ RETURNS
+ The number of elements in selection on success, 0 on failure
+ DESCRIPTION
+ Returns the number of elements in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
+{
+ herr_t ret_value; /* return value */
+
+ FUNC_ENTER_NOAPI(H5S_select_iter_release, FAIL);
+
+ /* Check args */
+ assert(sel_iter);
+
+ /* Release the array of dimensions common to all iterators */
+ H5FL_ARR_FREE(hsize_t,sel_iter->dims);
+
+ /* Call selection type-specific release routine */
+ ret_value = (*sel_iter->iter_release)(sel_iter);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_select_iter_release() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_iterate
PURPOSE
Iterate over the selected elements in a memory buffer.
@@ -389,7 +660,7 @@ done:
the selection is not modified.
--------------------------------------------------------------------------*/
herr_t
-H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
+H5S_select_iterate(void *buf, hid_t type_id, const H5S_t *space, H5D_operator_t op,
void *operator_data)
{
H5T_t *dt; /* Datatype structure */
@@ -441,7 +712,7 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid");
/* Initialize iterator */
- if ((*space->select.iter_init)(space, elmt_size, &iter)<0)
+ if (H5S_select_iter_init(&iter, space, elmt_size)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
iter_init=1; /* Selection iteration info has been initialized */
@@ -509,7 +780,7 @@ H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
done:
/* Release selection iterator */
if(iter_init) {
- if ((*space->select.iter_release)(&iter)<0)
+ if (H5S_select_iter_release(&iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
@@ -530,7 +801,7 @@ done:
Retrieve the type of selection in a dataspace
USAGE
H5S_sel_type H5Sget_select_type(space_id)
- hid_t space_id; IN: Dataspace object to reset
+ hid_t space_id; IN: Dataspace object to query
RETURNS
Non-negative on success/Negative on failure. Return value is from the
set of values in the H5S_sel_type enumerated type.
@@ -552,7 +823,7 @@ H5Sget_select_type(hid_t space_id)
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a data space");
/* Set return value */
- ret_value=space->select.type;
+ ret_value=H5S_get_select_type(space);
done:
FUNC_LEAVE_API(ret_value);
@@ -561,6 +832,39 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_get_select_type
+ PURPOSE
+ Retrieve the type of selection in a dataspace
+ USAGE
+ H5S_sel_type H5Sget_select_type(space)
+ const H5S_t *space; IN: Dataspace object to query
+ RETURNS
+ Non-negative on success/Negative on failure. Return value is from the
+ set of values in the H5S_sel_type enumerated type.
+ DESCRIPTION
+ This function retrieves the type of selection currently defined for
+ a dataspace.
+--------------------------------------------------------------------------*/
+H5S_sel_type
+H5S_get_select_type(const H5S_t *space)
+{
+ H5S_sel_type ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_get_select_type, H5S_SEL_ERROR);
+
+ /* Check args */
+ assert(space);
+
+ /* Set return value */
+ ret_value=space->select.type;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5S_get_select_type() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_select_shape_same
PURPOSE
Check if two selections are the same shape
@@ -745,7 +1049,7 @@ H5S_select_fill(void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
/* Initialize iterator */
- if ((*space->select.iter_init)(space, fill_size, &iter)<0)
+ if (H5S_select_iter_init(&iter, space, fill_size)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
iter_init=1; /* Selection iteration info has been initialized */
@@ -780,7 +1084,7 @@ H5S_select_fill(void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
done:
/* Release selection iterator */
if(iter_init) {
- if ((*space->select.iter_release)(&iter)<0)
+ if (H5S_select_iter_release(&iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
@@ -818,13 +1122,17 @@ done:
*/
herr_t
H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
- hid_t dxpl_id, const void *_buf)
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t elmt_size, const H5S_t *space, H5S_sel_iter_t *iter,
+ hsize_t nelmts, hid_t dxpl_id, const void *_buf)
{
const uint8_t *buf=_buf; /* Alias for pointer arithmetic */
hsize_t *off=NULL; /* Array to store sequence offsets */
+ hsize_t mem_off; /* Offset in memory */
+ size_t mem_curr_seq; /* "Current sequence" in memory */
+ size_t dset_curr_seq; /* "Current sequence" in dataset */
size_t *len=NULL; /* Array to store sequence lengths */
+ size_t mem_len; /* Length of sequence in memory */
ssize_t vector_size; /* Value for vector size */
size_t maxbytes; /* Number of bytes in the buffer */
size_t nseq; /* Number of sequences generated */
@@ -837,7 +1145,7 @@ H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
assert (f);
assert (layout);
assert (elmt_size>0);
- assert (efl);
+ assert (store);
assert (space);
assert (iter);
assert (nelmts>0);
@@ -863,8 +1171,13 @@ H5S_select_fscat (H5F_t *f, struct H5O_layout_t *layout,
if((*space->select.get_seq_list)(space,H5S_GET_SEQ_LIST_SORTED,iter,elmt_size,(size_t)vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed");
+ /* Reset the current sequence information */
+ mem_curr_seq=dset_curr_seq=0;
+ mem_len=nbytes;
+ mem_off=0;
+
/* Write sequence list out */
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, space, elmt_size, nseq, len, off, buf)<0)
+ if (H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store, nseq, &dset_curr_seq, len, off, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
/* Update buffer */
@@ -909,13 +1222,17 @@ done:
*/
hsize_t
H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist, const H5O_efl_t *efl, size_t elmt_size,
- const H5S_t *space, H5S_sel_iter_t *iter, hsize_t nelmts,
- hid_t dxpl_id, void *_buf/*out*/)
+ H5P_genplist_t *dc_plist, const H5D_storage_t *store,
+ size_t elmt_size, const H5S_t *space, H5S_sel_iter_t *iter,
+ hsize_t nelmts, hid_t dxpl_id, void *_buf/*out*/)
{
uint8_t *buf=_buf; /* Alias for pointer arithmetic */
hsize_t *off=NULL; /* Array to store sequence offsets */
+ hsize_t mem_off; /* Offset in memory */
+ size_t mem_curr_seq; /* "Current sequence" in memory */
+ size_t dset_curr_seq; /* "Current sequence" in dataset */
size_t *len=NULL; /* Array to store sequence lengths */
+ size_t mem_len; /* Length of sequence in memory */
ssize_t vector_size; /* Value for vector size */
size_t maxbytes; /* Number of bytes in the buffer */
size_t nseq; /* Number of sequences generated */
@@ -928,7 +1245,7 @@ H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
assert (f);
assert (layout);
assert (elmt_size>0);
- assert (efl);
+ assert (store);
assert (space);
assert (iter);
assert (nelmts>0);
@@ -953,8 +1270,13 @@ H5S_select_fgath (H5F_t *f, const struct H5O_layout_t *layout,
if((*space->select.get_seq_list)(space,H5S_GET_SEQ_LIST_SORTED,iter,elmt_size,(size_t)vector_size,maxbytes,&nseq,&nbytes,off,len)<0)
HGOTO_ERROR (H5E_INTERNAL, H5E_UNSUPPORTED, 0, "sequence length generation failed");
+ /* Reset the current sequence information */
+ mem_curr_seq=dset_curr_seq=0;
+ mem_len=nbytes;
+ mem_off=0;
+
/* Read sequence list in */
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, space, elmt_size, nseq, len, off, buf)<0)
+ if (H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store, nseq, &dset_curr_seq, len, off, 1, &mem_curr_seq, &mem_len, &mem_off, buf)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error");
/* Update buffer */
@@ -1166,14 +1488,13 @@ done:
*/
herr_t
H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
- const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space,
- const H5S_t *mem_space, hid_t dxpl_id, void *_buf/*out*/)
+ const H5D_storage_t *store, size_t elmt_size, const H5S_t *file_space,
+ const H5S_t *mem_space, hid_t dxpl_id, void *buf/*out*/)
{
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
H5S_sel_iter_t file_iter; /* File selection iteration info */
hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
- uint8_t *buf=NULL; /* Local buffer pointer, for address arithmetic */
hsize_t *mem_off=NULL; /* Array to store sequence offsets in memory */
hsize_t *file_off=NULL; /* Array to store sequence offsets in the file */
ssize_t vector_size; /* Value for vector size */
@@ -1186,20 +1507,26 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
size_t file_nbytes; /* Number of bytes used in file sequences */
size_t curr_mem_seq; /* Current memory sequence to operate on */
size_t curr_file_seq; /* Current file sequence to operate on */
- size_t tmp_file_len; /* Temporary number of bytes in file sequence */
- unsigned partial_file; /* Whether a partial file sequence was accessed */
- size_t orig_file_len=0; /* Original file sequence length for partial file access */
- size_t orig_file_seq; /* Original file sequence to operate on */
- size_t tot_file_seq; /* Number of file sequences to access */
+ ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_read, FAIL);
/* Check args */
assert(f);
- assert(efl);
- assert(_buf);
+ assert(store);
+ assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
+
+ /* Initialize file iterator */
+ if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ file_iter_init=1; /* File selection iteration info has been initialized */
+
+ /* Initialize memory iterator */
+ if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0)
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
+ mem_iter_init=1; /* Memory selection iteration info has been initialized */
/* Get the hyperslab vector size */
if((vector_size=H5S_get_vector_size(dxpl_id))<0)
@@ -1215,16 +1542,6 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
if((file_off = H5FL_ARR_MALLOC(hsize_t,(size_t)vector_size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
- /* Initialize file iterator */
- if ((*file_space->select.iter_init)(file_space, elmt_size, &file_iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- file_iter_init=1; /* File selection iteration info has been initialized */
-
- /* Initialize memory iterator */
- if ((*mem_space->select.iter_init)(mem_space, elmt_size, &mem_iter)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
- mem_iter_init=1; /* Memory selection iteration info has been initialized */
-
/* Get number of bytes in selection */
#ifndef NDEBUG
{
@@ -1259,115 +1576,29 @@ H5S_select_read(H5F_t *f, const H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Start at the beginning of the sequences again */
curr_mem_seq=0;
-
- /* Set the buffer pointer using the first sequence */
- H5_CHECK_OVERFLOW(mem_off[0],hsize_t,size_t);
- buf=(uint8_t *)_buf+(size_t)mem_off[0];
} /* end if */
- /* Check if current file sequence will fit into current memory sequence */
- if(mem_len[curr_mem_seq]>=file_len[curr_file_seq]) {
- /* Save the current number file sequence */
- orig_file_seq=curr_file_seq;
-
- /* Determine how many file sequences will fit into current memory sequence */
- tmp_file_len=0;
- tot_file_seq=0;
- while( curr_file_seq<file_nseq && (tmp_file_len+file_len[curr_file_seq])<=mem_len[curr_mem_seq] ) {
- tmp_file_len+=file_len[curr_file_seq];
- curr_file_seq++;
- tot_file_seq++;
- } /* end while */
-
- /* Check for partial file sequence */
- if(tmp_file_len<mem_len[curr_mem_seq] && curr_file_seq<file_nseq) {
- /* Get the original file sequence length */
- orig_file_len=file_len[curr_file_seq];
-
- /* Make the last file sequence a partial access */
- file_len[curr_file_seq]=mem_len[curr_mem_seq]-tmp_file_len;
-
- /* Increase the number of bytes to access */
- tmp_file_len=mem_len[curr_mem_seq];
-
- /* Indicate that there is an extra sequence to include in the file access */
- tot_file_seq++;
-
- /* Indicate a partial file sequence */
- partial_file=1;
- } /* end if */
- else
- partial_file=0;
-
- /* Read file sequences into current memory sequence */
- if (H5F_seq_readv(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tot_file_seq, &file_len[orig_file_seq], &file_off[orig_file_seq], buf)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
-
- /* Update last file sequence, if it was partially accessed */
- if(partial_file) {
- file_off[curr_file_seq]+=orig_file_len-file_len[curr_file_seq];
- file_len[curr_file_seq]=orig_file_len-file_len[curr_file_seq];
- } /* end if */
-
- /* Check if the current memory sequence was only partially accessed */
- if(tmp_file_len<mem_len[curr_mem_seq]) {
- /* Adjust current memory sequence */
- mem_off[curr_mem_seq]+=tmp_file_len;
- mem_len[curr_mem_seq]-=tmp_file_len;
-
- /* Adjust memory buffer pointer */
- buf+=tmp_file_len;
- } /* end if */
- else {
- /* Must have used entire memory sequence, advance to next one */
- curr_mem_seq++;
-
- /* Check if it is valid to adjust buffer pointer */
- if(curr_mem_seq<mem_nseq) {
- H5_CHECK_OVERFLOW(mem_off[curr_mem_seq],hsize_t,size_t);
- buf=(uint8_t *)_buf+(size_t)mem_off[curr_mem_seq];
- } /* end if */
- } /* end else */
+ /* Read file sequences into current memory sequence */
+ if ((tmp_file_len=H5F_seq_readvv(f, dxpl_id, layout, dc_plist, store,
+ file_nseq, &curr_file_seq, file_len, file_off,
+ mem_nseq, &curr_mem_seq, mem_len, mem_off,
+ buf))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
- /* Decrement number of bytes left to process */
- maxbytes-=tmp_file_len;
- } /* end if */
- else {
- /* Save number of bytes to access */
- tmp_file_len=mem_len[curr_mem_seq];
-
- /* Read part of current file sequence into current memory sequence */
- if (H5F_seq_read(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tmp_file_len, file_off[curr_file_seq], buf)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
-
- /* Update current file sequence information */
- file_off[curr_file_seq]+=tmp_file_len;
- file_len[curr_file_seq]-=tmp_file_len;
-
- /* Increment memory sequence */
- curr_mem_seq++;
-
- /* Check if it is valid to adjust buffer pointer */
- if(curr_mem_seq<mem_nseq) {
- H5_CHECK_OVERFLOW(mem_off[curr_mem_seq],hsize_t,size_t);
- buf=(uint8_t *)_buf+(size_t)mem_off[curr_mem_seq];
- } /* end if */
-
- /* Decrement number of bytes left to process */
- maxbytes-=tmp_file_len;
- } /* end else */
+ /* Decrement number of bytes left to process */
+ maxbytes-=tmp_file_len;
} /* end while */
done:
/* Release file selection iterator */
if(file_iter_init) {
- if ((*file_space->select.iter_release)(&file_iter)<0)
+ if (H5S_select_iter_release(&file_iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release memory selection iterator */
if(mem_iter_init) {
- if ((*mem_space->select.iter_release)(&mem_iter)<0)
+ if (H5S_select_iter_release(&mem_iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
@@ -1400,14 +1631,13 @@ done:
*/
herr_t
H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
- const H5O_efl_t *efl, size_t elmt_size, const H5S_t *file_space,
- const H5S_t *mem_space, hid_t dxpl_id, const void *_buf/*out*/)
+ const H5D_storage_t *store, size_t elmt_size, const H5S_t *file_space,
+ const H5S_t *mem_space, hid_t dxpl_id, const void *buf/*out*/)
{
H5S_sel_iter_t mem_iter; /* Memory selection iteration info */
hbool_t mem_iter_init=0; /* Memory selection iteration info has been initialized */
H5S_sel_iter_t file_iter; /* File selection iteration info */
hbool_t file_iter_init=0; /* File selection iteration info has been initialized */
- const uint8_t *buf=NULL; /* Local buffer pointer, for address arithmetic */
hsize_t *mem_off=NULL; /* Array to store sequence offsets in memory */
hsize_t *file_off=NULL; /* Array to store sequence offsets in the file */
ssize_t vector_size; /* Value for vector size */
@@ -1420,21 +1650,17 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
size_t file_nbytes; /* Number of bytes used in file sequences */
size_t curr_mem_seq; /* Current memory sequence to operate on */
size_t curr_file_seq; /* Current file sequence to operate on */
- size_t tmp_file_len; /* Temporary number of bytes in file sequence */
- unsigned partial_file; /* Whether a partial file sequence was accessed */
- size_t orig_file_len=0; /* Original file sequence length for partial file access */
- size_t orig_file_seq; /* Original file sequence to operate on */
- size_t tot_file_seq; /* Number of file sequences to access */
+ ssize_t tmp_file_len; /* Temporary number of bytes in file sequence */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_select_write, FAIL);
/* Check args */
assert(f);
- assert(efl);
- assert(_buf);
+ assert(store);
+ assert(buf);
assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER));
-
+
/* Get the hyperslab vector size */
if((vector_size=H5S_get_vector_size(dxpl_id))<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get I/O vector size");
@@ -1450,15 +1676,15 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate I/O offset vector array");
/* Initialize file iterator */
- if ((*file_space->select.iter_init)(file_space, elmt_size, &file_iter)<0)
+ if (H5S_select_iter_init(&file_iter, file_space, elmt_size)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
file_iter_init=1; /* File selection iteration info has been initialized */
/* Initialize memory iterator */
- if ((*mem_space->select.iter_init)(mem_space, elmt_size, &mem_iter)<0)
+ if (H5S_select_iter_init(&mem_iter, mem_space, elmt_size)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator");
mem_iter_init=1; /* Memory selection iteration info has been initialized */
-
+
/* Get number of bytes in selection */
#ifndef NDEBUG
{
@@ -1493,115 +1719,29 @@ H5S_select_write(H5F_t *f, H5O_layout_t *layout, H5P_genplist_t *dc_plist,
/* Start at the beginning of the sequences again */
curr_mem_seq=0;
-
- /* Set the buffer pointer using the first sequence */
- H5_CHECK_OVERFLOW(mem_off[0],hsize_t,size_t);
- buf=(const uint8_t *)_buf+(size_t)mem_off[0];
} /* end if */
- /* Check if current file sequence will fit into current memory sequence */
- if(mem_len[curr_mem_seq]>=file_len[curr_file_seq]) {
- /* Save the current number file sequence */
- orig_file_seq=curr_file_seq;
-
- /* Determine how many file sequences will fit into current memory sequence */
- tmp_file_len=0;
- tot_file_seq=0;
- while( curr_file_seq<file_nseq && (tmp_file_len+file_len[curr_file_seq])<=mem_len[curr_mem_seq] ) {
- tmp_file_len+=file_len[curr_file_seq];
- curr_file_seq++;
- tot_file_seq++;
- } /* end while */
-
- /* Check for partial file sequence */
- if(tmp_file_len<mem_len[curr_mem_seq] && curr_file_seq<file_nseq) {
- /* Get the original file sequence length */
- orig_file_len=file_len[curr_file_seq];
-
- /* Make the last file sequence a partial access */
- file_len[curr_file_seq]=mem_len[curr_mem_seq]-tmp_file_len;
-
- /* Increase the number of bytes to access */
- tmp_file_len=mem_len[curr_mem_seq];
-
- /* Indicate that there is an extra sequence to include in the file access */
- tot_file_seq++;
-
- /* Indicate a partial file sequence */
- partial_file=1;
- } /* end if */
- else
- partial_file=0;
-
- /* Write current memory sequence into file sequences */
- if (H5F_seq_writev(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tot_file_seq, &file_len[orig_file_seq], &file_off[orig_file_seq], buf)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
-
- /* Update last file sequence, if it was partially accessed */
- if(partial_file) {
- file_off[curr_file_seq]+=orig_file_len-file_len[curr_file_seq];
- file_len[curr_file_seq]=orig_file_len-file_len[curr_file_seq];
- } /* end if */
-
- /* Check if the current memory sequence was only partially accessed */
- if(tmp_file_len<mem_len[curr_mem_seq]) {
- /* Adjust current memory sequence */
- mem_off[curr_mem_seq]+=tmp_file_len;
- mem_len[curr_mem_seq]-=tmp_file_len;
-
- /* Adjust memory buffer pointer */
- buf+=tmp_file_len;
- } /* end if */
- else {
- /* Must have used entire memory sequence, advance to next one */
- curr_mem_seq++;
-
- /* Check if it is valid to adjust buffer pointer */
- if(curr_mem_seq<mem_nseq) {
- H5_CHECK_OVERFLOW(mem_off[curr_mem_seq],hsize_t,size_t);
- buf=(const uint8_t *)_buf+(size_t)mem_off[curr_mem_seq];
- } /* end if */
- } /* end else */
+ /* Write memory sequences into file sequences */
+ if ((tmp_file_len=H5F_seq_writevv(f, dxpl_id, layout, dc_plist, store,
+ file_nseq, &curr_file_seq, file_len, file_off,
+ mem_nseq, &curr_mem_seq, mem_len, mem_off,
+ buf))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
- /* Decrement number of bytes left to process */
- maxbytes-=tmp_file_len;
- } /* end if */
- else {
- /* Save number of bytes to access */
- tmp_file_len=mem_len[curr_mem_seq];
-
- /* Write part of current memory sequence to current file sequence */
- if (H5F_seq_write(f, dxpl_id, layout, dc_plist, efl, file_space, elmt_size, tmp_file_len, file_off[curr_file_seq], buf)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
-
- /* Update current file sequence information */
- file_off[curr_file_seq]+=tmp_file_len;
- file_len[curr_file_seq]-=tmp_file_len;
-
- /* Increment memory sequence */
- curr_mem_seq++;
-
- /* Check if it is valid to adjust buffer pointer */
- if(curr_mem_seq<mem_nseq) {
- H5_CHECK_OVERFLOW(mem_off[curr_mem_seq],hsize_t,size_t);
- buf=(const uint8_t *)_buf+(size_t)mem_off[curr_mem_seq];
- } /* end if */
-
- /* Decrement number of bytes left to process */
- maxbytes-=tmp_file_len;
- } /* end else */
+ /* Decrement number of bytes left to process */
+ maxbytes-=tmp_file_len;
} /* end while */
done:
/* Release file selection iterator */
if(file_iter_init) {
- if ((*file_space->select.iter_release)(&file_iter)<0)
+ if (H5S_select_iter_release(&file_iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release memory selection iterator */
if(mem_iter_init) {
- if ((*mem_space->select.iter_release)(&mem_iter)<0)
+ if (H5S_select_iter_release(&mem_iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
diff --git a/src/H5V.c b/src/H5V.c
index abbff24..1d5fd0a 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -959,7 +959,49 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5V_array_offset
+ * Function: H5V_array_down
+ *
+ * Purpose: Given a set of dimension sizes, calculate the size of each
+ * "down" slice. This is the size of the dimensions for all the
+ * dimensions below the current one, which is used for indexing
+ * offsets in this dimension.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 28, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5V_array_down(unsigned n, const hsize_t *total_size, hsize_t *down)
+{
+ hsize_t acc; /*accumulator */
+ int i; /*counter */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5V_array_down, FAIL);
+
+ assert(n <= H5V_HYPER_NDIMS);
+ assert(total_size);
+ assert(down);
+
+ /* Build the sizes of each dimension in the array */
+ /* (From fastest to slowest) */
+ for(i=n-1,acc=1; i>=0; i--) {
+ down[i]=acc;
+ acc *= total_size[i];
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5V_array_down() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_array_offset_pre
*
* Purpose: Given a coordinate description of a location in an array, this
* function returns the byte offset of the coordinate.
@@ -975,33 +1017,293 @@ done:
* Tuesday, June 22, 1999
*
* Modifications:
+ * Use precomputed accumulator array
+ * Quincey Koziol
+ * Saturday, April 26, 2003
*
*-------------------------------------------------------------------------
*/
hsize_t
-H5V_array_offset(unsigned n, const hsize_t *total_size, const hssize_t *offset)
+H5V_array_offset_pre(unsigned n, const hsize_t *total_size, const hsize_t *acc, const hssize_t *offset)
{
hsize_t skip; /*starting point byte offset */
- hsize_t acc; /*accumulator */
- int i; /*counter */
+ int i; /*counter */
hsize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5V_array_offset, (HDabort(), 0));
+ FUNC_ENTER_NOAPI(H5V_array_offset_pre, (HDabort(), 0));
assert(n <= H5V_HYPER_NDIMS);
assert(total_size);
+ assert(acc);
assert(offset);
- /* others */
- for (i=(int)(n-1), acc=1, skip=0; i>=0; --i) {
- skip += acc * offset[i];
- acc *= total_size[i];
- } /* end for */
+ /* Compute offset in array */
+ for (i=(int)(n-1), skip=0; i>=0; --i)
+ skip += acc[i] * offset[i];
/* Set return value */
ret_value=skip;
done:
FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5V_array_offset_pre() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_array_offset
+ *
+ * Purpose: Given a coordinate description of a location in an array, this
+ * function returns the byte offset of the coordinate.
+ *
+ * The dimensionality of the whole array, and the offset is N.
+ * The whole array dimensions are TOTAL_SIZE and the coordinate
+ * is at offset OFFSET.
+ *
+ * Return: Success: Byte offset from beginning of array to element offset
+ * Failure: abort() -- should never fail
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 22, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5V_array_offset(unsigned n, const hsize_t *total_size, const hssize_t *offset)
+{
+ hsize_t acc_arr[H5V_HYPER_NDIMS]; /* Accumulated size of down dimensions */
+ hsize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5V_array_offset, (HDabort(), 0));
+
+ assert(n <= H5V_HYPER_NDIMS);
+ assert(total_size);
+ assert(offset);
+
+ /* Build the sizes of each dimension in the array */
+ if(H5V_array_down(n,total_size,acc_arr)<0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_BADVALUE, UFAIL, "can't compute down sizes");
+
+ /* Set return value */
+ ret_value=H5V_array_offset_pre(n,total_size,acc_arr,offset);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
} /* end H5V_array_offset() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_array_calc
+ *
+ * Purpose: Given a linear offset in an array and the dimensions of that
+ * array, this function computes the coordinates of that offset
+ * in the array.
+ *
+ * The dimensionality of the whole array, and the coordinates is N.
+ * The array dimensions are TOTAL_SIZE and the coordinates
+ * are returned in COORD. The linear offset is in OFFSET.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, April 16, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5V_array_calc(hsize_t offset, unsigned n, const hsize_t *total_size, hssize_t *coords)
+{
+ hsize_t idx[H5V_HYPER_NDIMS]; /* Size of each dimension in bytes */
+ hsize_t acc; /* Size accumulator */
+ unsigned u; /* Local index variable */
+ int i; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5V_array_calc, FAIL);
+
+ /* Sanity check */
+ assert(n <= H5V_HYPER_NDIMS);
+ assert(total_size);
+ assert(coords);
+
+ /* Build the sizes of each dimension in the array */
+ /* (From fastest to slowest) */
+ for(i=n-1,acc=1; i>=0; i--) {
+ idx[i]=acc;
+ acc *= total_size[i];
+ } /* end for */
+
+ /* Compute the coordinates from the offset */
+ for(u=0; u<n; u++) {
+ coords[u]=offset/idx[u];
+ offset %= idx[u];
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5V_array_calc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_chunk_index
+ *
+ * Purpose: Given a coordinate offset (COORD), the size of each chunk
+ * (CHUNK), the number of chunks in each dimension (NCHUNKS)
+ * and the number of dimensions of all of these (NDIMS), calculate
+ * a "chunk index" for the chunk that the coordinate offset is
+ * located in.
+ *
+ * The chunk index starts at 0 and increases according to the
+ * fastest changing dimension, then the next fastest, etc.
+ *
+ * For example, with a 3x5 chunk size and 6 chunks in the fastest
+ * changing dimension and 3 chunks in the slowest changing
+ * dimension, the chunk indices are as follows:
+ *
+ * +-----+-----+-----+-----+-----+-----+
+ * | | | | | | |
+ * | 0 | 1 | 2 | 3 | 4 | 5 |
+ * | | | | | | |
+ * +-----+-----+-----+-----+-----+-----+
+ * | | | | | | |
+ * | 6 | 7 | 8 | 9 | 10 | 11 |
+ * | | | | | | |
+ * +-----+-----+-----+-----+-----+-----+
+ * | | | | | | |
+ * | 12 | 13 | 14 | 15 | 16 | 17 |
+ * | | | | | | |
+ * +-----+-----+-----+-----+-----+-----+
+ *
+ * The chunk index is placed in the CHUNK_IDX location for return
+ * from this function
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, April 21, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5V_chunk_index(unsigned ndims, const hssize_t *coord, const hsize_t *chunk,
+ const hsize_t *nchunks, const hsize_t *down_nchunks, hsize_t *chunk_idx)
+{
+ hssize_t scaled_coord[H5V_HYPER_NDIMS]; /* Scaled, coordinates, in terms of chunks */
+ unsigned u; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5V_chunk_index, FAIL);
+
+ /* Sanity check */
+ assert(ndims <= H5V_HYPER_NDIMS);
+ assert(coord);
+ assert(chunk);
+ assert(nchunks);
+ assert(chunk_idx);
+
+ /* Compute the scaled coordinates for actual coordinates */
+ for(u=0; u<ndims; u++)
+ scaled_coord[u]=coord[u]/chunk[u];
+
+ /* Compute the chunk index */
+ *chunk_idx=H5V_array_offset_pre(ndims,nchunks,down_nchunks,scaled_coord);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5V_chunk_index() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_memcpyvv
+ *
+ * Purpose: Given source and destination buffers in memory (SRC & DST)
+ * copy sequences of from the source buffer into the destination
+ * buffer. Each set of sequnces has an array of lengths, an
+ * array of offsets, the maximum number of sequences and the
+ * current sequence to start at in the sequence.
+ *
+ * There may be different numbers of bytes in the source and
+ * destination sequences, data copying stops when either the
+ * source or destination buffer runs out of sequence information.
+ *
+ * Return: Non-negative # of bytes copied on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, May 2, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5V_memcpyvv(void *_dst,
+ size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[], hsize_t dst_off_arr[],
+ const void *_src,
+ size_t src_max_nseq, size_t *src_curr_seq, size_t src_len_arr[], hsize_t src_off_arr[])
+{
+ unsigned char *dst; /* Destination buffer pointer */
+ const unsigned char *src; /* Source buffer pointer */
+ size_t size; /* Size of sequence in bytes */
+ size_t u,v; /* Local index variables */
+ ssize_t ret_value=0; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5V_memcpyvv, FAIL);
+
+ /* Sanity check */
+ assert(_dst);
+ assert(dst_curr_seq);
+ assert(*dst_curr_seq<dst_max_nseq);
+ assert(dst_len_arr);
+ assert(dst_off_arr);
+ assert(_src);
+ assert(src_curr_seq);
+ assert(*src_curr_seq<src_max_nseq);
+ assert(src_len_arr);
+ assert(src_off_arr);
+
+ /* Work through all the sequences */
+ for(u=*dst_curr_seq, v=*src_curr_seq; u<dst_max_nseq && v<src_max_nseq; ) {
+ /* Choose smallest buffer to write */
+ if(src_len_arr[v]<dst_len_arr[u])
+ size=src_len_arr[v];
+ else
+ size=dst_len_arr[u];
+
+ /* Compute offset on disk */
+ dst=(unsigned char *)_dst+dst_off_arr[u];
+
+ /* Compute offset in memory */
+ src=(const unsigned char *)_src+src_off_arr[v];
+
+ /* Copy data */
+ HDmemcpy(dst,src,size);
+
+ /* Update source information */
+ src_len_arr[v]-=size;
+ src_off_arr[v]+=size;
+ if(src_len_arr[v]==0)
+ v++;
+
+ /* Update destination information */
+ dst_len_arr[u]-=size;
+ dst_off_arr[u]+=size;
+ if(dst_len_arr[u]==0)
+ u++;
+
+ /* Increment number of bytes copied */
+ ret_value+=size;
+ } /* end for */
+
+ /* Update current sequence vectors */
+ *dst_curr_seq=u;
+ *src_curr_seq=v;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5V_memcpyvv() */
+
diff --git a/src/H5Vprivate.h b/src/H5Vprivate.h
index a6f67ba..3840075 100644
--- a/src/H5Vprivate.h
+++ b/src/H5Vprivate.h
@@ -83,8 +83,21 @@ H5_DLL herr_t H5V_stride_optimize2(unsigned *np, hsize_t *elmt_size,
hssize_t *stride2);
H5_DLL herr_t H5V_array_fill(void *_dst, const void *src, size_t size,
size_t count);
+H5_DLL herr_t H5V_array_down(unsigned n, const hsize_t *total_size,
+ hsize_t *down);
+H5_DLL hsize_t H5V_array_offset_pre(unsigned n, const hsize_t *total_size,
+ const hsize_t *acc, const hssize_t *offset);
H5_DLL hsize_t H5V_array_offset(unsigned n, const hsize_t *total_size,
- const hssize_t *offset);
+ const hssize_t *offset);
+H5_DLL herr_t H5V_array_calc(hsize_t offset, unsigned n,
+ const hsize_t *total_size, hssize_t *coords);
+H5_DLL herr_t H5V_chunk_index(unsigned ndims, const hssize_t *coord,
+ const hsize_t *chunk, const hsize_t *nchunks, const hsize_t *down_nchunks,
+ hsize_t *chunk_idx);
+H5_DLL ssize_t H5V_memcpyvv(void *_dst,
+ size_t dst_max_nseq, size_t *dst_curr_seq, size_t dst_len_arr[], hsize_t dst_off_arr[],
+ const void *_src,
+ size_t src_max_nseq, size_t *src_curr_seq, size_t src_len_arr[], hsize_t src_off_arr[]);
/*-------------------------------------------------------------------------
diff --git a/src/H5Z.c b/src/H5Z.c
index f8265d3..b5e0e52 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -529,7 +529,7 @@ H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_ty
/* Check if the chunks have filters */
if(dcpl_pline.nfilters > 0) {
- int chunk_ndims; /* # of chunk dimensions */
+ unsigned chunk_ndims; /* # of chunk dimensions */
hsize_t chunk_size[H5O_LAYOUT_NDIMS]; /* Size of chunk dimensions */
H5S_t *space; /* Dataspace describing chunk */
hid_t space_id; /* ID for dataspace describing chunk */
diff --git a/src/Makefile.in b/src/Makefile.in
index 03f4cf8..b0e43e7 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -28,21 +28,21 @@ LIB=libhdf5.la
CLEAN=libhdf5.settings
## Source and object files for the library (lexicographically)...
-LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5E.c H5F.c H5Farray.c H5Fcontig.c \
- H5Fcompact.c H5Fistore.c H5Fseq.c H5FD.c H5FDcore.c H5FDfamily.c \
- H5FDfphdf5.c H5FDgass.c H5FDlog.c H5FDmpio.c H5FDmpiposix.c \
- H5FDmulti.c H5FDsec2.c H5FDsrb.c H5FDstdio.c H5FDstream.c H5FL.c \
- H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c H5G.c H5Gent.c \
- H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5HP.c H5I.c H5MF.c H5MM.c H5O.c \
- H5Oattr.c H5Obogus.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c \
- H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c \
- H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c \
- H5R.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c \
- H5Spoint.c H5Sselect.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \
- H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c H5Tfixed.c \
- H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c H5Torder.c \
- H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TB.c H5TS.c H5V.c H5Z.c \
- H5Zdeflate.c H5Zfletcher32.c H5Zshuffle.c H5Zszip.c
+LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5D.c H5Dio.c H5E.c H5F.c H5Fcontig.c \
+ H5Fcompact.c H5Fistore.c H5Fseq.c H5FD.c H5FDcore.c \
+ H5FDfamily.c H5FDfphdf5.c H5FDgass.c H5FDlog.c H5FDmpio.c \
+ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDsrb.c H5FDstdio.c \
+ H5FDstream.c H5FL.c H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c \
+ H5G.c H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5HP.c H5I.c H5MF.c \
+ H5MM.c H5O.c H5Oattr.c H5Obogus.c H5Ocont.c H5Odtype.c H5Oefl.c \
+ H5Ofill.c H5Olayout.c H5Omtime.c H5Oname.c H5Onull.c H5Opline.c \
+ H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5Pdcpl.c H5Pdxpl.c \
+ H5Pfapl.c H5Pfcpl.c H5R.c H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c \
+ H5Snone.c H5Spoint.c H5Sselect.c H5ST.c H5T.c H5Tarray.c H5Tbit.c \
+ H5Tcommit.c H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c \
+ H5Tfixed.c H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c \
+ H5Torder.c H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TB.c H5TS.c \
+ H5V.c H5Z.c H5Zdeflate.c H5Zfletcher32.c H5Zshuffle.c H5Zszip.c
LIB_OBJ=$(LIB_SRC:.c=.lo)
@@ -64,7 +64,7 @@ PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \
H5FOprivate.h H5FPprivate.h H5FSprivate.h H5Gprivate.h H5Gpkg.h \
H5HGprivate.h H5HLprivate.h H5HPprivate.h H5Iprivate.h H5MFprivate.h \
H5MMprivate.h H5Oprivate.h H5Opkg.h H5Pprivate.h H5Ppkg.h \
- H5Rprivate.h H5RSprivate.h H5Sprivate.h H5STprivate.h \
+ H5Rprivate.h H5RSprivate.h H5Sprivate.h H5STprivate.h \
H5Tprivate.h H5TBprivate.h H5Tpkg.h H5TSprivate.h H5Vprivate.h \
H5Zprivate.h H5Zpkg.h H5config.h