diff options
-rw-r--r-- | MANIFEST | 12 | ||||
-rw-r--r-- | doc/html/H5.format.html | 103 | ||||
-rw-r--r-- | src/.distdep | 599 | ||||
-rw-r--r-- | src/H5.c | 6 | ||||
-rw-r--r-- | src/H5D.c | 2 | ||||
-rw-r--r-- | src/H5Distore.c | 12 | ||||
-rw-r--r-- | src/H5F.c | 202 | ||||
-rw-r--r-- | src/H5FD.c | 145 | ||||
-rw-r--r-- | src/H5FDcore.c | 34 | ||||
-rw-r--r-- | src/H5FDfamily.c | 44 | ||||
-rw-r--r-- | src/H5FDmpio.c | 36 | ||||
-rw-r--r-- | src/H5FDmulti.c | 1393 | ||||
-rw-r--r-- | src/H5FDmulti.h | 31 | ||||
-rw-r--r-- | src/H5FDprivate.h | 4 | ||||
-rw-r--r-- | src/H5FDpublic.h | 25 | ||||
-rw-r--r-- | src/H5FDsec2.c | 4 | ||||
-rw-r--r-- | src/H5Fistore.c | 12 | ||||
-rw-r--r-- | src/H5Fprivate.h | 10 | ||||
-rw-r--r-- | src/H5R.c | 2 | ||||
-rw-r--r-- | src/H5Rpublic.h | 4 | ||||
-rw-r--r-- | src/H5T.c | 8 | ||||
-rw-r--r-- | src/H5Tpublic.h | 2 | ||||
-rw-r--r-- | src/H5private.h | 1 | ||||
-rw-r--r-- | src/Makefile.in | 18 | ||||
-rw-r--r-- | src/hdf5.h | 1 | ||||
-rw-r--r-- | test/.distdep | 337 | ||||
-rw-r--r-- | test/Makefile.in | 12 | ||||
-rw-r--r-- | test/big.c | 16 | ||||
-rw-r--r-- | test/cmpd_dset.c | 7 | ||||
-rw-r--r-- | test/dsets.c | 7 | ||||
-rw-r--r-- | test/dtypes.c | 10 | ||||
-rw-r--r-- | test/extend.c | 7 | ||||
-rw-r--r-- | test/external.c | 15 | ||||
-rw-r--r-- | test/h5test.c | 85 | ||||
-rw-r--r-- | test/tfile.c | 2 |
35 files changed, 3049 insertions, 159 deletions
@@ -244,14 +244,18 @@ ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5FD.c -./src/H5FDprivate.h -./src/H5FDpublic.h -./src/H5FDsec2.c -./src/H5FDsec2.h +./src/H5FDcore.c +./src/H5FDcore.h ./src/H5FDfamily.c ./src/H5FDfamily.h ./src/H5FDmpio.c ./src/H5FDmpio.h +./src/H5FDmulti.c +./src/H5FDmulti.h +./src/H5FDprivate.h +./src/H5FDpublic.h +./src/H5FDsec2.c +./src/H5FDsec2.h ./src/H5G.c ./src/H5Gent.c ./src/H5Gnode.c diff --git a/doc/html/H5.format.html b/doc/html/H5.format.html index 59bc28d..afcd444 100644 --- a/doc/html/H5.format.html +++ b/doc/html/H5.format.html @@ -266,7 +266,7 @@ each high-level object. </tr> <tr align=center> - <td colspan=4>Reserved Address</td> + <td colspan=4>Driver Information Block Address</td> </tr> <tr align=center> @@ -480,12 +480,14 @@ each high-level object. used.</td> </tr> - <tr valign=top> - <td>Reserved Address</td> - <td>This address field is present for alignment purposes and - is always set to the undefined address value (all bits - set).</td> - </tr> + <tr valign=top> + <td>Driver Information Block Address</td> + <td>This is the relative file address of the file driver + information block which contains driver-specific + information needed to reopen the file. If there is no + driver information block then this entry should be the + undefined address (all bits set).</td> + </tr> <tr valign=top> <td>Root Group Symbol Table Entry</td> @@ -497,6 +499,91 @@ each high-level object. </table> </center> + <p>The file driver information block is an optional region of the + file which contains information needed by the file driver in + order to reopen a file. The format of the driver information + block is: + + <p> + <center> + <table border align=center cellpadding=4 width="80%"> + <caption align=top> + <B>Driver Information Block</B> + </caption> + + <tr align=center> + <th width="25%">byte</th> + <th width="25%">byte</th> + <th width="25%">byte</th> + <th width="25%">byte</th> + </tr> + + <tr align=center> + <td>Version</td> + <td colspan=3>Reserved (zero)</td> + </tr> + + <tr align=center> + <td colspan=4>Driver Information Size (4 bytes)</td> + </tr> + + <tr align=center> + <td colspan=4><br>Driver Identification (8 bytes)<br><br></td> + </tr> + + <tr align=center> + <td colspan=4><br><br>Driver Information<br><br><br></td> + </tr> + </table> + </center> + + <p> + <center> + <table align=center width="80%"> + <tr> + <th width="30%">Field Name</th> + <th width="70%">Description</th> + </tr> + + <tr valign=top> + <td>Version</td> + <td>The version number of the driver information block. The + file format documented here is version zero.</td> + </tr> + + <tr valign=top> + <td>Driver Information Size</td> + <td>The size in bytes of the Driver Information part of this + structure.</td> + </tr> + + <tr valign=top> + <td>Driver Identification</td> + <td>This is an eight-byte ASCII string without null + termination which identifies the driver and version number + of the Driver Information block. The predefined drivers + supplied with the HDF5 library are identified by the + letters "NCSA" followed by the first four characters of + the driver name. If the Driver Information block is not + the original version then the last letter(s) of the + identification will be replaced by a version number in + ASCII. For example, the various versions of the "family" + driver will be identified by "NCSAfami", "NCSAfam0", + NCSAfam1", etc. Identification for user-defined drivers is + arbitrary but should be unique.</td> + </tr> + + <tr valign=top> + <td>Driver Information</td> + <td>Driver information is stored in a format defined by the + file driver and encoded/decoded by the driver callbacks + invoked from the <code>H5FD_sb_encode</code> and + <code>H5FD_sb_decode</code> functions.</td> + </tr> + </table> + </center> + + <h3><a name="Btrees">Disk Format: Level 1A - B-link Trees</a></h3> <p>B-link trees allow flexible storage for objects which tend to grow @@ -3584,7 +3671,7 @@ data-type. <address><a href="mailto:koziol@ncsa.uiuc.edu">Quincey Koziol</a></address> <address><a href="mailto:matzke@llnl.gov">Robb Matzke</a></address> <!-- hhmts start --> -Last modified: Fri Jun 11 14:11:57 EDT 1999 +Last modified: Tue Aug 17 10:57:50 EDT 1999 <!-- hhmts end --> </body> </html> diff --git a/src/.distdep b/src/.distdep index 458112d..4fef9a8 100644 --- a/src/.distdep +++ b/src/.distdep @@ -1490,3 +1490,602 @@ H5Z.lo: \ H5Dpublic.h \ H5Zprivate.h \ H5Zpublic.h +H5.lo: \ + H5.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5Ipublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5FDprivate.h \ + H5Iprivate.h \ + H5MMprivate.h \ + H5Pprivate.h \ + H5Ppublic.h \ + H5Dpublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h +H5D.lo: \ + H5D.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h \ + H5Ipublic.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5HLprivate.h \ + H5HLpublic.h \ + H5MMprivate.h \ + H5Pprivate.h \ + H5Ppublic.h +H5F.lo: \ + H5F.c \ + H5FDsec2.h \ + H5Ipublic.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDpublic.h \ + H5private.h \ + H5Aprivate.h \ + H5Apublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5MMpublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Iprivate.h \ + H5ACprivate.h \ + H5ACpublic.h \ + H5Eprivate.h \ + H5Epublic.h +H5Fistore.lo: \ + H5Fistore.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Iprivate.h \ + H5MFprivate.h \ + H5MMprivate.h +H5FD.lo: \ + H5FD.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5FDprivate.h \ + H5Iprivate.h \ + H5MMprivate.h \ + H5Pprivate.h \ + H5Ppublic.h \ + H5Dpublic.h +H5FDsec2.lo: \ + H5FDsec2.c \ + hdf5.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Ipublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ + H5Dpublic.h \ + H5Epublic.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5Gpublic.h \ + H5HGpublic.h \ + H5HLpublic.h \ + H5MMpublic.h \ + H5Opublic.h \ + H5Ppublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5RApublic.h \ + H5Spublic.h \ + H5Tpublic.h \ + H5FDcore.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDsec2.h \ + H5FDmulti.h +H5FDfamily.lo: \ + H5FDfamily.c \ + hdf5.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Ipublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ + H5Dpublic.h \ + H5Epublic.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5Gpublic.h \ + H5HGpublic.h \ + H5HLpublic.h \ + H5MMpublic.h \ + H5Opublic.h \ + H5Ppublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5RApublic.h \ + H5Spublic.h \ + H5Tpublic.h \ + H5FDcore.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDsec2.h \ + H5FDmulti.h +H5FDmpio.lo: \ + H5FDmpio.c \ + hdf5.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Ipublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ + H5Dpublic.h \ + H5Epublic.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5Gpublic.h \ + H5HGpublic.h \ + H5HLpublic.h \ + H5MMpublic.h \ + H5Opublic.h \ + H5Ppublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5RApublic.h \ + H5Spublic.h \ + H5Tpublic.h \ + H5FDcore.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDsec2.h \ + H5FDmulti.h +H5FDcore.lo: \ + H5FDcore.c \ + hdf5.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Ipublic.h \ + H5Apublic.h \ + H5ACpublic.h \ + H5Bpublic.h \ + H5Dpublic.h \ + H5Epublic.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5Gpublic.h \ + H5HGpublic.h \ + H5HLpublic.h \ + H5MMpublic.h \ + H5Opublic.h \ + H5Ppublic.h \ + H5Zpublic.h \ + H5Rpublic.h \ + H5RApublic.h \ + H5Spublic.h \ + H5Tpublic.h \ + H5FDcore.h \ + H5FDfamily.h \ + H5FDmpio.h \ + H5FDsec2.h \ + H5FDmulti.h +H5I.lo: \ + H5I.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h \ + H5Ipublic.h \ + H5Eprivate.h +H5Oattr.lo: \ + H5Oattr.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5MMprivate.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h +H5Odtype.lo: \ + H5Odtype.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5MMprivate.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h +H5P.lo: \ + H5P.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h \ + H5Ipublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5FDprivate.h \ + H5MMprivate.h +H5R.lo: \ + H5R.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Iprivate.h \ + H5Ipublic.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h +H5Sall.lo: \ + H5Sall.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Iprivate.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h +H5Shyper.lo: \ + H5Shyper.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Iprivate.h \ + H5MMprivate.h \ + H5Pprivate.h +H5Snone.lo: \ + H5Snone.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Iprivate.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h +H5Spoint.lo: \ + H5Spoint.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Iprivate.h \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h +H5Sselect.lo: \ + H5Sselect.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5Ipublic.h \ + H5Iprivate.h \ + H5MMprivate.h \ + H5MMpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Dpublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h +H5T.lo: \ + H5T.c \ + H5private.h \ + H5public.h \ + H5config.h \ + H5api_adpt.h \ + H5Dprivate.h \ + H5Dpublic.h \ + H5Ipublic.h \ + H5Fprivate.h \ + H5Fpublic.h \ + H5FDpublic.h \ + H5MMpublic.h \ + H5Gprivate.h \ + H5Gpublic.h \ + H5Bprivate.h \ + H5Bpublic.h \ + H5Oprivate.h \ + H5Opublic.h \ + H5HGprivate.h \ + H5HGpublic.h \ + H5Tprivate.h \ + H5Tpublic.h \ + H5Rprivate.h \ + H5Rpublic.h \ + H5Sprivate.h \ + H5Spublic.h \ + H5Zprivate.h \ + H5Zpublic.h \ + H5Iprivate.h \ + H5Eprivate.h \ + H5Epublic.h \ + H5MMprivate.h \ + H5Pprivate.h @@ -1871,12 +1871,6 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) case H5FD_MEM_DRAW: fprintf(out, "H5FD_MEM_DRAW"); break; - case H5FD_MEM_META: - fprintf(out, "H5FD_MEM_META"); - break; - case H5FD_MEM_GROUP: - fprintf(out, "H5FD_MEM_GROUP"); - break; case H5FD_MEM_GHEAP: fprintf(out, "H5FD_MEM_GHEAP"); break; @@ -2475,7 +2475,7 @@ H5D_init_storage(H5D_t *dset, const H5S_t *space) * If the dataset is accessed via parallel I/O, allocate file space * for all chunks now and initialize each chunk with the fill value. */ - if (H5FD_MPIO==dset->ent.file->shared->fapl->driver_id) { + if (H5FD_MPIO==dset->ent.file->shared->driver_id) { /* We only handle simple data spaces so far */ if ((ndims=H5S_get_simple_extent_dims(space, dim, NULL))<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, diff --git a/src/H5Distore.c b/src/H5Distore.c index 4849e98..eca1cd2 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -806,9 +806,8 @@ H5F_istore_init (H5F_t *f) FUNC_ENTER (H5F_istore_init, FAIL); HDmemset (rdcc, 0, sizeof(H5F_rdcc_t)); - if (f->shared->fapl->rdcc_nbytes>0 && - f->shared->fapl->rdcc_nelmts>0) { - rdcc->nslots = f->shared->fapl->rdcc_nelmts; + if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) { + rdcc->nslots = f->shared->rdcc_nelmts; rdcc->slot = H5MM_calloc (rdcc->nslots*sizeof(H5F_rdcc_ent_t*)); if (NULL==rdcc->slot) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -1111,7 +1110,7 @@ H5F_istore_prune (H5F_t *f, size_t size) { intn i, j, nerrors=0; H5F_rdcc_t *rdcc = &(f->shared->rdcc); - size_t total = f->shared->fapl->rdcc_nbytes; + size_t total = f->shared->rdcc_nbytes; const int nmeth=2; /*number of methods */ intn w[1]; /*weighting as an interval */ H5F_rdcc_ent_t *p[2], *cur; /*list pointers */ @@ -1129,7 +1128,7 @@ H5F_istore_prune (H5F_t *f, size_t size) * begins. The pointers participating in the list traversal are each * given a chance at preemption before any of the pointers are advanced. */ - w[0] = rdcc->nused * f->shared->fapl->rdcc_w0; + w[0] = rdcc->nused * f->shared->rdcc_w0; p[0] = rdcc->head; p[1] = NULL; @@ -1353,8 +1352,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, } assert (found || chunk_size>0); - if (!found && rdcc->nslots>0 && - chunk_size<=f->shared->fapl->rdcc_nbytes && + if (!found && rdcc->nslots>0 && chunk_size<=f->shared->rdcc_nbytes && (!ent || !ent->locked)) { /* * Add the chunk to the cache only if the slot is not already locked. @@ -57,7 +57,7 @@ const H5F_create_t H5F_create_dflt = { 0, /* unused */ 0, /* unused */ }, - sizeof(hsize_t), /* Default offset size */ + sizeof(haddr_t), /* Default offset size */ sizeof(hsize_t), /* Default length size */ HDF5_BOOTBLOCK_VERSION, /* Current Boot-Block version # */ HDF5_FREESPACE_VERSION, /* Current Free-Space info version # */ @@ -453,7 +453,7 @@ hid_t H5Fget_access_plist(hid_t file_id) { H5F_t *f = NULL; - H5F_access_t *plist = NULL; + H5F_access_t *fapl=NULL, _fapl; hid_t ret_value = FAIL; FUNC_ENTER(H5Fget_access_plist, FAIL); @@ -464,15 +464,30 @@ H5Fget_access_plist(hid_t file_id) HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file"); } - /* Create the property list object to return */ - if (NULL==(plist=H5P_copy(H5P_FILE_ACCESS, f->shared->fapl))) { + /* Initialize the property list */ + HDmemset(&_fapl, 0, sizeof _fapl); + _fapl.mdc_nelmts = f->shared->mdc_nelmts; + _fapl.rdcc_nelmts = f->shared->rdcc_nelmts; + _fapl.rdcc_nbytes = f->shared->rdcc_nbytes; + _fapl.rdcc_w0 = f->shared->rdcc_w0; + _fapl.threshold = f->shared->threshold; + _fapl.alignment = f->shared->alignment; + _fapl.gc_ref = f->shared->gc_ref; + _fapl.driver_id = f->shared->driver_id; + _fapl.driver_info = NULL; /*just for now */ + + /* Copy properties */ + if (NULL==(fapl=H5P_copy(H5P_FILE_ACCESS, &_fapl))) { HRETURN_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to copy file access properties"); } + /* Get the properties for the file driver */ + fapl->driver_info = H5FD_fapl_get(f->shared->lf); + /* Create an atom */ - if ((ret_value = H5P_create(H5P_FILE_ACCESS, plist))<0) { - H5P_close(H5P_FILE_ACCESS, plist); + if ((ret_value = H5P_create(H5P_FILE_ACCESS, fapl))<0) { + H5P_close(H5P_FILE_ACCESS, fapl); HRETURN_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register property list"); } @@ -675,9 +690,10 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id) f->shared->boot_addr = HADDR_UNDEF; f->shared->base_addr = HADDR_UNDEF; f->shared->freespace_addr = HADDR_UNDEF; + f->shared->driver_addr = HADDR_UNDEF; /* - * Deep-copy the file creation and file access property lists into the + * Copy the file creation and file access property lists into the * new file handle. We do this early because some values might need * to change as the file is being opened. */ @@ -688,10 +704,14 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id) } fapl = (H5P_DEFAULT==fapl_id)? &H5F_access_dflt : H5I_object(fapl_id); - if (NULL==(f->shared->fapl=H5P_copy(H5P_FILE_ACCESS, fapl))) { - HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, NULL, - "unable to copy file access property list"); - } + f->shared->mdc_nelmts = fapl->mdc_nelmts; + f->shared->rdcc_nelmts = fapl->rdcc_nelmts; + f->shared->rdcc_nbytes = fapl->rdcc_nbytes; + f->shared->rdcc_w0 = fapl->rdcc_w0; + f->shared->threshold = fapl->threshold; + f->shared->alignment = fapl->alignment; + f->shared->gc_ref = fapl->gc_ref; + f->shared->driver_id = H5I_inc_ref(fapl->driver_id); #ifdef HAVE_PARALLEL /* @@ -710,11 +730,11 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id) * The cache might be created with a different number of elements and * the access property list should be updated to reflect that. */ - if ((n=H5AC_create(f, f->shared->fapl->mdc_nelmts))<0) { + if ((n=H5AC_create(f, f->shared->mdc_nelmts))<0) { HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache"); } - f->shared->fapl->mdc_nelmts = n; + f->shared->mdc_nelmts = n; /* Create the chunk cache */ H5F_istore_init(f); @@ -784,9 +804,20 @@ H5F_dest(H5F_t *f) ret_value = FAIL; /*but keep going*/ } f->shared->cwfs = H5MM_xfree (f->shared->cwfs); + + /* Destroy file creation properties */ H5P_close(H5P_FILE_CREATE, f->shared->fcpl); - H5P_close(H5P_FILE_ACCESS, f->shared->fapl); + + /* Destroy file access properties (most don't need destruction) */ + H5I_dec_ref(f->shared->driver_id); + + /* Destroy shared file struct */ + if (H5FD_close(f->shared->lf)<0) { + HERROR(H5E_FILE, H5E_CANTINIT, "problems closing file"); + ret_value = FAIL; /*but keep going*/ + } f->shared = H5MM_xfree(f->shared); + } else if (f->shared->nrefs>0) { /* * There are other references to the shared part of the file. @@ -869,6 +900,11 @@ H5F_dest(H5F_t *f) * * Robb Matzke, 1999-08-02 * Rewritten to use the virtual file layer. + * + * Robb Matzke, 1999-08-16 + * Added decoding of file driver information block, which uses a + * formerly reserved address slot in the boot block in order to + * be compatible with previous versions of the file format. *------------------------------------------------------------------------- */ H5F_t * @@ -882,11 +918,12 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id) const uint8_t *p; /*ptr into temp I/O buffer */ size_t fixed_size=24; /*fixed sizeof superblock */ size_t variable_size; /*variable sizeof superblock */ + size_t driver_size; /*size of driver info block */ H5G_entry_t root_ent; /*root symbol table entry */ haddr_t eof; /*end of file address */ - haddr_t reserved_addr; /*unused */ haddr_t stored_eoa; /*relative end-of-addr in file */ uintn tent_flags; /*tentative flags */ + char driver_name[9]; /*file driver name/version */ FUNC_ENTER(H5F_open, NULL); @@ -1102,11 +1139,51 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id) H5F_addr_decode(file, &p, &(shared->base_addr)/*out*/); H5F_addr_decode(file, &p, &(shared->freespace_addr)/*out*/); H5F_addr_decode(file, &p, &stored_eoa/*out*/); - H5F_addr_decode(file, &p, &reserved_addr/*out*/); + H5F_addr_decode(file, &p, &(shared->driver_addr)/*out*/); if (H5G_ent_decode(file, &p, &root_ent/*out*/)<0) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root symbol entry"); } + + /* Decode the optional driver information block */ + if (H5F_addr_defined(shared->driver_addr)) { + haddr_t drv_addr = shared->base_addr + shared->driver_addr; + if (H5FD_set_eoa(lf, drv_addr+16)<0 || + H5FD_read(lf, H5P_DEFAULT, drv_addr, 16, buf)<0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to read driver information block"); + } + p = buf; + + /* Version number */ + if (HDF5_DRIVERINFO_VERSION!=*p++) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "bad driver information block version number"); + } + + /* Reserved */ + p += 3; + + /* Driver info size */ + UINT32DECODE(p, driver_size); + + /* Driver name and/or version */ + strncpy(driver_name, p, 8); + driver_name[8] = '\0'; + + /* Read driver information and decode */ + if (H5FD_set_eoa(lf, drv_addr+16+driver_size)<0 || + H5FD_read(lf, H5P_DEFAULT, drv_addr+16, driver_size, buf)<0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to read file driver information"); + } + if (H5FD_sb_decode(lf, driver_name, buf)<0) { + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, + "unable to decode driver information"); + } + } + + /* Make sure we can open the root group */ if (H5G_mkroot(file, &root_ent)<0) { HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group"); @@ -1118,7 +1195,6 @@ H5F_open(const char *name, uintn flags, hid_t fcpl_id, hid_t fapl_id) */ shared->fcpl->userblock_size = shared->base_addr; - /* * Make sure that the data is not truncated. One case where this is * possible is if the first file of a family of files was opened @@ -1472,18 +1548,24 @@ H5Fflush(hid_t object_id, H5F_scope_t scope) * H5F_SCOPE_DOWN means flush the specified file and all * children. * - * Robb Matzke, 1998-08-02 + * Robb Matzke, 1999-08-02 * If ALLOC_ONLY is non-zero then all this function does is * allocate space for the userblock and superblock. Also * rewritten to use the virtual file layer. + * + * Robb Matzke, 1999-08-16 + * The driver information block is encoded and either allocated + * or written to disk. *------------------------------------------------------------------------- */ static herr_t H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, hbool_t alloc_only) { - uint8_t buf[2048], *p = buf; + uint8_t sbuf[2048], dbuf[2048], *p=NULL; uintn nerrors=0, i; + hsize_t superblock_size, driver_size; + char driver_name[9]; FUNC_ENTER(H5F_flush, FAIL); @@ -1523,6 +1605,7 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, } /* encode the file boot block */ + p = sbuf; HDmemcpy(p, H5F_SIGNATURE, H5F_SIGNATURE_LEN); p += H5F_SIGNATURE_LEN; *p++ = f->shared->fcpl->bootblock_ver; @@ -1541,31 +1624,91 @@ H5F_flush(H5F_t *f, H5F_scope_t scope, hbool_t invalidate, H5F_addr_encode(f, &p, f->shared->base_addr); H5F_addr_encode(f, &p, f->shared->freespace_addr); H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf)); - H5F_addr_encode(f, &p, HADDR_UNDEF); + H5F_addr_encode(f, &p, f->shared->driver_addr); H5G_ent_encode(f, &p, H5G_entof(f->shared->root_grp)); + superblock_size = p-sbuf; /* - * Allocate space for the userblock and superblock if that hasn't been - * done yet, which is the case just after a new file is created. - * Otherwise write the superblock at the specified address. Since these - * addresses are absolute we must use the virtual file layer directly. + * Encode the driver information block. */ + if ((driver_size=H5FD_sb_size(f->shared->lf))) { + driver_size += 16; /*driver block header */ + assert(driver_size<=sizeof dbuf); + p = dbuf; + + /* Version */ + *p++ = HDF5_DRIVERINFO_VERSION; + + /* Reserved*/ + p += 3; + + /* Driver info size, excluding header */ + UINT32ENCODE(p, driver_size-16); + + /* Encode driver-specific data */ + if (H5FD_sb_encode(f->shared->lf, driver_name, dbuf+16)<0) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, + "unable to encode driver information"); + } + + /* Driver name */ + HDmemcpy(dbuf+8, driver_name, 8); + } + if (alloc_only) { - assert(0==H5FD_get_eoa(f->shared->lf)); - if (H5FD_set_eoa(f->shared->lf, f->shared->boot_addr+(p-buf))<0) { + /* + * Allocate space for the userblock, superblock, and driver info + * block. We do it with one allocation request because the userblock + * and superblock need to be at the beginning of the file and only + * the first allocation request is required to return memory at + * format address zero. + */ + haddr_t addr = H5FD_alloc(f->shared->lf, H5FD_MEM_SUPER, + (f->shared->base_addr + + superblock_size + + driver_size)); + if (HADDR_UNDEF==addr) { HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to allocate file space for userblock " "and/or superblock"); } + if (0!=addr) { + HRETURN_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, + "file driver failed to allocate userblock " + "and/or superblock at address zero"); + } + + /* + * The file driver information block begins immediately after the + * superblock. + */ + if (driver_size>0) { + f->shared->driver_addr = superblock_size; + } + } else { + /* Write superblock */ #ifdef HAVE_PARALLEL H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ #endif if (H5FD_write(f->shared->lf, H5P_DEFAULT, f->shared->boot_addr, - p-buf, buf)<0) { + superblock_size, sbuf)<0) { HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write superblock"); } + + /* Write driver information block */ + if (HADDR_UNDEF!=f->shared->driver_addr) { +#ifdef HAVE_PARALLLEL + H5FD_mpio_tas_allsame(f->shared->lf, TRUE); /*only p0 will write*/ +#endif + if (H5FD_write(f->shared->lf, H5P_DEFAULT, + f->shared->base_addr+superblock_size, driver_size, + dbuf)<0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to write driver information block"); + } + } } /* Flush file buffers to disk */ @@ -1692,9 +1835,6 @@ H5F_close(H5F_t *f) /* Dump debugging info */ H5AC_debug(f); H5F_istore_stats(f, FALSE); - - /* Close files and release resources */ - H5FD_close(f->shared->lf); } else { /* * Flush all caches but do not destroy. As long as all handles for @@ -2493,6 +2633,8 @@ H5F_debug(H5F_t *f, haddr_t UNUSED addr, FILE * stream, intn indent, "Base address:", f->shared->base_addr); HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth, "Free list address:", f->shared->freespace_addr); + HDfprintf(stream, "%*s%-*s %a (rel)\n", indent, "", fwidth, + "Driver information block:", f->shared->driver_addr); HDfprintf(stream, "%*s%-*s %lu bytes\n", indent, "", fwidth, "Size of user block:", (unsigned long) (f->shared->fcpl->userblock_size)); @@ -247,6 +247,151 @@ H5FDunregister(hid_t driver_id) /*------------------------------------------------------------------------- + * Function: H5FD_sb_size + * + * Purpose: Obtains the number of bytes required to store the driver file + * access data in the HDF5 superblock. + * + * Return: Success: Number of bytes required. + * + * Failure: 0 if an error occurs or if the driver has no + * data to store in the superblock. + * + * Programmer: Robb Matzke + * Monday, August 16, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hsize_t +H5FD_sb_size(H5FD_t *file) +{ + hsize_t ret_value=0; + + FUNC_ENTER(H5FD_sb_size, 0); + + assert(file && file->cls); + if (file->cls->sb_size) { + ret_value = (file->cls->sb_size)(file); + } + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sb_encode + * + * Purpose: Encode driver-specific data into the output arguments. The + * NAME is a nine-byte buffer which should get an + * eight-character driver name and/or version followed by a null + * terminator. The BUF argument is a buffer to receive the + * encoded driver-specific data. The size of the BUF array is + * the size returned by the H5FD_sb_size() call. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, August 16, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf) +{ + FUNC_ENTER(H5FD_sb_encode, FAIL); + + assert(file && file->cls); + if (file->cls->sb_encode && + (file->cls->sb_encode)(file, name/*out*/, buf/*out*/)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver sb_encode request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_sb_decode + * + * Purpose: Decodes the driver information block. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, August 16, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf) +{ + FUNC_ENTER(H5FD_sb_decode, FAIL); + + assert(file && file->cls); + if (file->cls->sb_decode && + (file->cls->sb_decode)(file, name, buf)<0) { + HRETURN_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, + "driver sb_decode request failed"); + } + + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_fapl_get + * + * Purpose: Gets the file access property list associated with a file. + * Usually the file will copy what it needs from the original + * file access property list when the file is created. The + * purpose of this function is to create a new file access + * property list based on the settings in the file, which may + * have been modified from the original file access property + * list. + * + * Return: Success: Pointer to a new file access property list + * with all members copied. If the file is + * closed then this property list lives on, and + * vice versa. + * + * Failure: NULL, including when the file has no + * properties. + * + * Programmer: Robb Matzke + * Friday, August 13, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void * +H5FD_fapl_get(H5FD_t *file) +{ + void *ret_value=NULL; + + FUNC_ENTER(H5FD_fapl_get, NULL); + assert(file); + + if (file->cls->fapl_get) { + ret_value = (file->cls->fapl_get)(file); + } + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- * Function: H5FD_fapl_copy * * Purpose: Copies the driver-specific part of the file access property diff --git a/src/H5FDcore.c b/src/H5FDcore.c index 4be868e..9920678 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -67,6 +67,7 @@ typedef struct H5FD_core_fapl_t { (size_t)((A)+(Z))<(size_t)(A)) /* Prototypes */ +static void *H5FD_core_fapl_get(H5FD_t *_file); static H5FD_t *H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD_core_close(H5FD_t *_file); @@ -82,7 +83,11 @@ static herr_t H5FD_core_write(H5FD_t *_file, hid_t fapl_id, haddr_t addr, static const H5FD_class_t H5FD_core_g = { "core", /*name */ MAXADDR, /*maxaddr */ + NULL, /*sb_size */ + NULL, /*sb_encode */ + NULL, /*sb_decode */ sizeof(H5FD_core_fapl_t), /*fapl_size */ + H5FD_core_fapl_get, /*fapl_get */ NULL, /*fapl_copy */ NULL, /*fapl_free */ 0, /*dxpl_size */ @@ -189,6 +194,33 @@ H5Pget_fapl_core(hid_t fapl_id, size_t *increment/*out*/) /*------------------------------------------------------------------------- + * Function: H5FD_core_fapl_get + * + * Purpose: Returns a copy of the file access properties. + * + * Return: Success: Ptr to new file access properties. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, August 13, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_core_fapl_get(H5FD_t *_file) +{ + H5FD_core_t *file = (H5FD_core_t*)_file; + H5FD_core_fapl_t *fa = calloc(1, sizeof(H5FD_core_fapl_t)); + + fa->increment = file->increment; + return fa; +} + + +/*------------------------------------------------------------------------- * Function: H5FD_core_open * * Purpose: Create memory as an HDF5 file. @@ -426,7 +458,7 @@ H5FD_core_read(H5FD_t *_file, hid_t dxpl_id/*unused*/, haddr_t addr, memcpy(buf, file->mem+addr, nbytes); size -= nbytes; addr += nbytes; - (char*)buf += nbytes; + buf = (char*)buf + nbytes; } /* Read zeros for the part which is after the EOF markers */ diff --git a/src/H5FDfamily.c b/src/H5FDfamily.c index bf46efc..4f0536c 100644 --- a/src/H5FDfamily.c +++ b/src/H5FDfamily.c @@ -58,6 +58,7 @@ typedef struct H5FD_family_dxpl_t { } H5FD_family_dxpl_t; /* Callback prototypes */ +static void *H5FD_family_fapl_get(H5FD_t *_file); static void *H5FD_family_fapl_copy(const void *_old_fa); static herr_t H5FD_family_fapl_free(void *_fa); static void *H5FD_family_dxpl_copy(const void *_old_dx); @@ -79,7 +80,11 @@ static herr_t H5FD_family_flush(H5FD_t *_file); static const H5FD_class_t H5FD_family_g = { "family", /*name */ HADDR_MAX, /*maxaddr */ + NULL, /*sb_size */ + NULL, /*sb_encode */ + NULL, /*sb_decode */ sizeof(H5FD_family_fapl_t), /*fapl_size */ + H5FD_family_fapl_get, /*fapl_get */ H5FD_family_fapl_copy, /*fapl_copy */ H5FD_family_fapl_free, /*fapl_free */ sizeof(H5FD_family_dxpl_t), /*dxpl_size */ @@ -159,7 +164,10 @@ H5Pset_fapl_family(hid_t fapl_id, hsize_t memb_size, hid_t memb_fapl_id) if (H5P_DEFAULT!=memb_fapl_id && H5P_FILE_ACCESS!=H5Pget_class(memb_fapl_id)) return -1; - /* Initialize driver specific information */ + /* + * Initialize driver specific information. No need to copy it into the FA + * struct since all members will be copied by H5Pset_driver(). + */ fa.memb_size = memb_size; fa.memb_fapl_id = memb_fapl_id; return H5Pset_driver(fapl_id, H5FD_FAMILY, &fa); @@ -201,6 +209,35 @@ H5Pget_fapl_family(hid_t fapl_id, hsize_t *memb_size/*out*/, /*------------------------------------------------------------------------- + * Function: H5FD_family_fapl_get + * + * Purpose: Gets a file access property list which could be used to + * create an identical file. + * + * Return: Success: Ptr to new file access property list. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, August 13, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_family_fapl_get(H5FD_t *_file) +{ + H5FD_family_t *file = (H5FD_family_t*)_file; + H5FD_family_fapl_t *fa = calloc(1, sizeof(H5FD_family_fapl_t*)); + + fa->memb_size = file->memb_size; + fa->memb_fapl_id = H5Pcopy(file->memb_fapl_id); + return fa; +} + + +/*------------------------------------------------------------------------- * Function: H5FD_family_fapl_copy * * Purpose: Copies the family-specific file access properties. @@ -348,7 +385,7 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id, file->memb_size = 1024*1024*1024; /*1GB*/ } else { H5FD_family_fapl_t *fa = H5Pget_driver_info(fapl_id); - file->memb_fapl_id = fa->memb_fapl_id; + file->memb_fapl_id = H5Pcopy(fa->memb_fapl_id); file->memb_size = fa->memb_size; } file->name = malloc(strlen(name)+1); @@ -408,6 +445,9 @@ H5FD_family_open(const char *name, unsigned flags, hid_t fapl_id, for (i=0; i<file->nmembs; i++) { if (file->memb[i]) H5FDclose(file->memb[i]); } + if (file->memb) free(file->memb); + H5Pclose(file->memb_fapl_id); + if (file->name) free(file->name); free(file); } return NULL; diff --git a/src/H5FDmpio.c b/src/H5FDmpio.c index ca9ce12..ac853c5 100644 --- a/src/H5FDmpio.c +++ b/src/H5FDmpio.c @@ -67,6 +67,7 @@ static haddr_t MPIOff_to_haddr(MPI_Offset mpi_off); static herr_t haddr_to_MPIOff(haddr_t addr, MPI_Offset *mpi_off/*out*/); /* Callbacks */ +static void *H5FD_mpio_fapl_get(H5FD_t *_file); static H5FD_t *H5FD_mpio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD_mpio_close(H5FD_t *_file); @@ -89,7 +90,11 @@ typedef struct H5FD_mpio_fapl_t { static const H5FD_class_t H5FD_mpio_g = { "mpio", /*name */ HADDR_MAX, /*maxaddr */ + NULL, /*sb_size */ + NULL, /*sb_encode */ + NULL, /*sb_decode */ sizeof(H5FD_mpio_fapl_t), /*fapl_size */ + H5FD_mpio_fapl_get, /*fapl_get */ NULL, /*fapl_copy */ NULL, /*fapl_free */ sizeof(H5FD_mpio_dxpl_t), /*dxpl_size */ @@ -564,6 +569,37 @@ H5FD_mpio_signal_right_neighbor(H5FD_t *_file) /*------------------------------------------------------------------------- + * Function: H5FD_mpio_fapl_get + * + * Purpose: Returns a file access property list which could be used to + * create another file the same as this one. + * + * Return: Success: Ptr to new file access property list with all + * fields copied from the file pointer. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, August 13, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_mpio_fapl_get(H5FD_t *_file) +{ + H5FD_mpio_t *file = (H5FD_mpio_t*)_file; + H5FD_mpio_fapl_t *fa = calloc(1, sizeof(H5FD_mpio_fapl_t)); + + /* These should both be copied. --rpm, 1999-08-13 */ + fa->comm = file->comm; + fa->info = file->info; + return fa; +} + + +/*------------------------------------------------------------------------- * Function: H5FD_mpio_open * * Purpose: Opens a file with name NAME. The FLAGS are a bit field with diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c new file mode 100644 index 0000000..a8c9325 --- /dev/null +++ b/src/H5FDmulti.c @@ -0,0 +1,1393 @@ +/* + * Copyright (C) 1997 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, November 10, 1997 + * + * Purpose: Implements a file driver which dispatches I/O requests to + * other file drivers depending on the purpose of the address + * region being accessed. For instance, all meta-data could be + * place in one file while all raw data goes to some other file. + */ +#include <assert.h> +#include <hdf5.h> +#include <stdlib.h> + +/* + * Define H5FD_MULTI_DEBUG if you want the ability to print debugging + * messages to the standard error stream. Messages are only printed if the + * file is opened with the H5F_ACC_DEBUG flag. + */ +#define H5FD_MULTI_DEBUG + +/* Our versions of MIN and MAX */ +#undef MAX +#define MAX(X,Y) ((X)>(Y)?(X):(Y)) +#undef MIN +#define MIN(X,Y) ((X)<(Y)?(X):(Y)) + +/* The driver identification number, initialized at runtime */ +static hid_t H5FD_MULTI_g = 0; + +/* + * The description of a file belonging to this driver. The file access + * properties and member names do not have to be copied into this struct + * since they will be held open by the file access property list which is + * copied into the parent file struct in H5F_open(). + */ +typedef struct H5FD_multi_t { + H5FD_t pub; /*public stuff, must be first */ + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /*map from usage to file */ + haddr_t memb_addr[H5FD_MEM_NTYPES];/*starting address per member*/ + haddr_t memb_next[H5FD_MEM_NTYPES];/*addr of next member */ + H5FD_t *memb[H5FD_MEM_NTYPES]; /*member pointers */ + hid_t memb_fapl[H5FD_MEM_NTYPES];/*member file access props */ + char *memb_name[H5FD_MEM_NTYPES];/*name generators */ + haddr_t eoa; /*end of allocated addresses */ + unsigned flags; /*file open flags saved for debugging */ +} H5FD_multi_t; + +/* Driver-specific file access properties */ +typedef struct H5FD_multi_fapl_t { + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; /*memory usage map */ + hid_t memb_fapl[H5FD_MEM_NTYPES];/*member access properties */ + char *memb_name[H5FD_MEM_NTYPES];/*name generators */ + haddr_t memb_addr[H5FD_MEM_NTYPES];/*starting addr per member */ +} H5FD_multi_fapl_t; + +/* Driver specific data transfer properties */ +typedef struct H5FD_multi_dxpl_t { + hid_t memb_dxpl[H5FD_MEM_NTYPES];/*member data xfer properties*/ +} H5FD_multi_dxpl_t; + +/* Private functions */ +static char *my_strdup(const char *s); + +/* Callback prototypes */ +static hsize_t H5FD_multi_sb_size(H5FD_t *file); +static herr_t H5FD_multi_sb_encode(H5FD_t *file, char *name/*out*/, + unsigned char *buf/*out*/); +static herr_t H5FD_multi_sb_decode(H5FD_t *file, const char *name, + const unsigned char *buf); +static void *H5FD_multi_fapl_get(H5FD_t *file); +static void *H5FD_multi_fapl_copy(const void *_old_fa); +static herr_t H5FD_multi_fapl_free(void *_fa); +static void *H5FD_multi_dxpl_copy(const void *_old_dx); +static herr_t H5FD_multi_dxpl_free(void *_dx); +static H5FD_t *H5FD_multi_open(const char *name, unsigned flags, + hid_t fapl_id, haddr_t maxaddr); +static herr_t H5FD_multi_close(H5FD_t *_file); +static int H5FD_multi_cmp(const H5FD_t *_f1, const H5FD_t *_f2); +static haddr_t H5FD_multi_get_eoa(H5FD_t *_file); +static herr_t H5FD_multi_set_eoa(H5FD_t *_file, haddr_t eoa); +static haddr_t H5FD_multi_get_eof(H5FD_t *_file); +static haddr_t H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hsize_t size); +static herr_t H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, haddr_t addr, + hsize_t size); +static herr_t H5FD_multi_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, + hsize_t size, void *_buf/*out*/); +static herr_t H5FD_multi_write(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, + hsize_t size, const void *_buf); +static herr_t H5FD_multi_flush(H5FD_t *_file); + +/* The class struct */ +static const H5FD_class_t H5FD_multi_g = { + "multi", /*name */ + HADDR_MAX, /*maxaddr */ + H5FD_multi_sb_size, /*sb_size */ + H5FD_multi_sb_encode, /*sb_encode */ + H5FD_multi_sb_decode, /*sb_decode */ + sizeof(H5FD_multi_fapl_t), /*fapl_size */ + H5FD_multi_fapl_get, /*fapl_get */ + H5FD_multi_fapl_copy, /*fapl_copy */ + H5FD_multi_fapl_free, /*fapl_free */ + sizeof(H5FD_multi_dxpl_t), /*dxpl_size */ + H5FD_multi_dxpl_copy, /*dxpl_copy */ + H5FD_multi_dxpl_free, /*dxpl_free */ + H5FD_multi_open, /*open */ + H5FD_multi_close, /*close */ + H5FD_multi_cmp, /*cmp */ + H5FD_multi_alloc, /*alloc */ + H5FD_multi_free, /*free */ + H5FD_multi_get_eoa, /*get_eoa */ + H5FD_multi_set_eoa, /*set_eoa */ + H5FD_multi_get_eof, /*get_eof */ + H5FD_multi_read, /*read */ + H5FD_multi_write, /*write */ + H5FD_multi_flush, /*flush */ + H5FD_FLMAP_DEFAULT, /*fl_map */ +}; + + +/*------------------------------------------------------------------------- + * Function: my_strdup + * + * Purpose: Private version of strdup() + * + * Return: Success: Ptr to new copy of string + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, August 13, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static char * +my_strdup(const char *s) +{ + char *x; + if (!s) return NULL; + if (NULL==(x=malloc(strlen(s)+1))) return NULL; + strcpy(x, s); + return x; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_init + * + * Purpose: Initialize this driver by registering the driver with the + * library. + * + * Return: Success: The driver ID for the multi driver. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t +H5FD_multi_init(void) +{ + if (!H5FD_MULTI_g) { + H5FD_MULTI_g = H5FDregister(&H5FD_multi_g); + } + return H5FD_MULTI_g; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_split + * + * Purpose: Compatability function. Makes the multi driver act like the + * old split driver which stored meta data in one file and raw + * data in another file. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 11, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_split(hid_t fapl, const char *meta_ext, hid_t meta_plist_id, + const char *raw_ext, hid_t raw_plist_id) +{ + H5FD_mem_t mt, memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + char meta_name[1024], raw_name[1024]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + + /*NO TRACE*/ + + /* Initialize */ + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + memb_map[mt] = (H5FD_MEM_DRAW==mt?mt:H5FD_MEM_SUPER); + memb_fapl[mt] = -1; + memb_name[mt] = NULL; + memb_addr[mt] = HADDR_UNDEF; + } + + /* The file access properties */ + memb_fapl[H5FD_MEM_SUPER] = meta_plist_id; + memb_fapl[H5FD_MEM_DRAW] = raw_plist_id; + + /* The names */ + sprintf(meta_name, "%%s%s", meta_ext?meta_ext:".meta"); + memb_name[H5FD_MEM_SUPER] = meta_name; + sprintf(raw_name, "%%s%s", raw_ext?raw_ext:".raw"); + memb_name[H5FD_MEM_DRAW] = raw_name; + + /* The sizes */ + memb_addr[H5FD_MEM_SUPER] = 0; + memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + + return H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, memb_addr); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_fapl_multi + * + * Purpose: Sets the file access property list FAPL_ID to use the multi + * driver. The MEMB_MAP array maps memory usage types to other + * memory usage types and is the mechanism which allows the + * caller to specify how many files are created. The array + * contains H5FD_MEM_NTYPES entries which are either the value + * H5FD_MEM_DEFAULT or a memory usage type and the number of + * unique values determines the number of files which are + * opened. For each memory usage type which will be associated + * with a file the MEMB_FAPL array should have a property list + * and the MEMB_NAME array should be a name generator (a + * printf-style format with a %s which will be replaced with the + * name passed to H5FDopen(), usually from H5Fcreate() or + * H5Fopen()). + * + * Example: To set up a multi file access property list which partitions + * data into meta and raw files each being 1/2 of the address + * space one would say: + * + * H5FD_mem_t mt, memb_map[H5FD_MEM_NTYPES]; + * hid_t memb_fapl[H5FD_MEM_NTYPES]; + * const char *memb[H5FD_MEM_NTYPES]; + * haddr_t memb_addr[H5FD_MEM_NTYPES]; + * + * // The mapping... + * for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + * memb_map[mt] = H5FD_MEM_SUPER; + * } + * memb_map[H5FD_MEM_DRAW] = H5FD_MEM_DRAW; + * + * // Member information + * memb_fapl[H5FD_MEM_SUPER] = H5P_DEFAULT; + * memb_name[H5FD_MEM_SUPER] = "%s.meta"; + * memb_addr[H5FD_MEM_SUPER] = 0; + * + * memb_fapl[H5FD_MEM_DRAW] = H5P_DEFAULT; + * memb_name[H5FD_MEM_DRAW] = "%s.raw"; + * memb_addr[H5FD_MEM_DRAW] = HADDR_MAX/2; + * + * hid_t fapl = H5Pcreate(H5P_FILE_ACCESS); + * H5Pset_fapl_multi(fapl, memb_map, memb_fapl, + * memb_name, memb_addr); + * + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, + const hid_t *memb_fapl, const char **memb_name, + const haddr_t *memb_addr) +{ + H5FD_multi_fapl_t fa; + H5FD_mem_t mt, mmt; + + /*NO TRACE*/ + + /* Check arguments */ + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + if (!memb_map) return -1; + if (!memb_fapl) return -1; + if (!memb_name) return -1; + if (!memb_addr) return -1; + + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + /* Map usage type */ + mmt = memb_map[mt]; + if (mmt<0 || mmt>=H5FD_MEM_NTYPES) return -1; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + + /* + * All members of MEMB_FAPL must be either defaults or actual file + * access property lists. + */ + if (H5P_DEFAULT!=memb_fapl[mmt] && + H5P_FILE_ACCESS!=H5Pget_class(memb_fapl[mmt])) return -1; + + /* All names must be defined */ + if (!memb_name[mmt] || !memb_name[mmt][0]) return -1; + } + + /* + * Initialize driver specific information. No need to copy it into the FA + * struct since all members will be copied by H5Pset_driver(). + */ + memcpy(fa.memb_map, memb_map, H5FD_MEM_NTYPES*sizeof(H5FD_mem_t)); + memcpy(fa.memb_fapl, memb_fapl, H5FD_MEM_NTYPES*sizeof(hid_t)); + memcpy(fa.memb_name, memb_name, H5FD_MEM_NTYPES*sizeof(char*)); + memcpy(fa.memb_addr, memb_addr, H5FD_MEM_NTYPES*sizeof(haddr_t)); + return H5Pset_driver(fapl_id, H5FD_MULTI, &fa); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_fapl_multi + * + * Purpose: Returns information about the multi file access property + * list though the function arguments which are the same as for + * H5Pset_fapl_multi() above. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/, + hid_t *memb_fapl/*out*/, char **memb_name/*out*/, + haddr_t *memb_addr/*out*/) +{ + H5FD_multi_fapl_t *fa; + H5FD_mem_t mt; + + /*NO TRACE*/ + + if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; + if (H5FD_MULTI!=H5Pget_driver(fapl_id)) return -1; + if (NULL==(fa=H5Pget_driver_info(fapl_id))) return -1; + + if (memb_map) { + memcpy(memb_map, fa->memb_map, H5FD_MEM_NTYPES*sizeof(H5FD_mem_t)); + } + if (memb_fapl) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (fa->memb_fapl[mt]>=0) { + memb_fapl[mt] = H5Pcopy(fa->memb_fapl[mt]); + } else { + memb_fapl[mt] = fa->memb_fapl[mt]; /*default or bad ID*/ + } + } + } + if (memb_name) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (fa->memb_name[mt]) { + memb_name[mt] = malloc(strlen(fa->memb_name[mt])+1); + strcpy(memb_name[mt], fa->memb_name[mt]); + } else { + memb_name[mt] = NULL; + } + } + } + if (memb_addr) { + memcpy(memb_addr, fa->memb_addr, H5FD_MEM_NTYPES*sizeof(haddr_t)); + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5Pset_dxpl_multi + * + * Purpose: Set the data transfer property list DXPL_ID to use the multi + * driver with the specified data transfer properties for each + * memory usage type MEMB_DXPL[] (after the usage map is + * applied). + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Tuesday, August 10, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_dxpl_multi(hid_t dxpl_id, const hid_t *memb_dxpl) +{ + H5FD_multi_dxpl_t dx; + H5FD_mem_t mt; + + /*NO TRACE*/ + + /* Check arguments */ + if (H5P_DATA_XFER!=H5Pget_class(dxpl_id)) return -1; + if (!memb_dxpl) return -1; + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (H5P_DEFAULT!=memb_dxpl[mt] && + H5P_DATA_XFER!=H5Pget_class(memb_dxpl[mt])) return -1; + } + + /* Initialize the data transfer property list */ + memcpy(dx.memb_dxpl, memb_dxpl, H5FD_MEM_NTYPES*sizeof(hid_t)); + return H5Pset_driver(dxpl_id, H5FD_MULTI, &dx); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_dxpl_multi + * + * Purpose: Returns information which was set with H5Pset_dxpl_multi() + * above. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Tuesday, August 10, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_dxpl_multi(hid_t dxpl_id, hid_t *memb_dxpl/*out*/) +{ + H5FD_multi_dxpl_t *dx; + H5FD_mem_t mt; + + /*NO TRACE*/ + + if (H5P_FILE_ACCESS!=H5Pget_class(dxpl_id)) return -1; + if (H5FD_MULTI!=H5Pget_driver(dxpl_id)) return -1; + if (NULL==(dx=H5Pget_driver_info(dxpl_id))) return -1; + + if (memb_dxpl) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (dx->memb_dxpl[mt]>=0) { + memb_dxpl[mt] = H5Pcopy(dx->memb_dxpl[mt]); + } else { + memb_dxpl[mt] = dx->memb_dxpl[mt]; /*default or bad ID */ + } + } + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_sb_size + * + * Purpose: Returns the size of the private information to be stored in + * the superblock. + * + * Return: Success: The super block driver data size. + * + * Failure: never fails + * + * Programmer: Robb Matzke + * Monday, August 16, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static hsize_t +H5FD_multi_sb_size(H5FD_t *_file/*unused*/) +{ + return H5FD_MEM_NTYPES * 8; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_sb_encode + * + * Purpose: Encode driver information for the superblock. The NAME + * argument is a nine-byte buffer which will be initialized with + * an eight-character name/version number and null termination. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Monday, August 16, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/, + unsigned char *buf/*out*/) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mt; + haddr_t memb_eoa; + + /* Name and version number */ + strcpy(name, "NCSAmulti"); + + /* Copy EOA values into buffer */ + assert(sizeof(haddr_t)<=8); + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (file->memb[mt]) { + memb_eoa = H5FDget_eoa(file->memb[mt]); + } else { + memb_eoa = HADDR_UNDEF; + } + memcpy(buf+mt*sizeof(memb_eoa), &memb_eoa, sizeof(memb_eoa)); + } + + /* Convert to destination type */ + if (H5Tconvert(H5T_NATIVE_HADDR, H5T_STD_U64LE, H5FD_MEM_NTYPES, + buf, NULL, H5P_DEFAULT)<0) return -1; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_sb_decode + * + * Purpose: Decodes the superblock information for this driver. The NAME + * argument is the eight-character (plus null termination) name + * stored in the file. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Monday, August 16, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_sb_decode(H5FD_t *_file, const char *name, const unsigned char *buf) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mt; + char x[H5FD_MEM_NTYPES*8]; + + /* Make sure the name/version number is correct */ + if (strcmp(name, "NCSAmult")) return -1; + + /* Decode EOA values */ + assert(sizeof(haddr_t)<=8); + memcpy(x, buf, H5FD_MEM_NTYPES*8); + if (H5Tconvert(H5T_STD_U64LE, H5T_NATIVE_HADDR, H5FD_MEM_NTYPES, + x, NULL, H5P_DEFAULT)<0) return -1; + + /* Set EOA values */ + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (file->memb[mt]) { + H5FDset_eoa(file->memb[mt], ((haddr_t*)x)[mt]); + } + } + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_fapl_get + * + * Purpose: Returns a file access property list which indicates how the + * specified file is being accessed. The return list could be + * used to access another file the same way. + * + * Return: Success: Ptr to new file access property list with all + * members copied from the file struct. + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Friday, August 13, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_multi_fapl_get(H5FD_t *_file) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_multi_fapl_t fa; + + memset(&fa, 0, sizeof fa); + memcpy(fa.memb_map, file->memb_map, sizeof(fa.memb_map)); + memcpy(fa.memb_fapl, file->memb_fapl, sizeof(fa.memb_fapl)); + memcpy(fa.memb_name, file->memb_name, sizeof(fa.memb_name)); + memcpy(fa.memb_addr, file->memb_addr, sizeof(fa.memb_addr)); + return H5FD_multi_fapl_copy(&fa); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_fapl_copy + * + * Purpose: Copies the multi-specific file access properties. + * + * Return: Success: Ptr to a new property list + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_multi_fapl_copy(const void *_old_fa) +{ + const H5FD_multi_fapl_t *old_fa = (const H5FD_multi_fapl_t*)_old_fa; + H5FD_multi_fapl_t *new_fa = malloc(sizeof(H5FD_multi_fapl_t)); + H5FD_mem_t mt; + int nerrors = 0; + + assert(new_fa); + + memcpy(new_fa, old_fa, sizeof(H5FD_multi_fapl_t)); + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (old_fa->memb_fapl[mt]>=0) { + new_fa->memb_fapl[mt] = H5Pcopy(old_fa->memb_fapl[mt]); + if (new_fa->memb_fapl[mt]<0) nerrors++; + } + if (old_fa->memb_name[mt]) { + new_fa->memb_name[mt] = malloc(strlen(old_fa->memb_name[mt])+1); + assert(new_fa->memb_name[mt]); + strcpy(new_fa->memb_name[mt], old_fa->memb_name[mt]); + } + } + + if (nerrors) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (new_fa->memb_fapl[mt]>=0) H5Pclose(new_fa->memb_fapl[mt]); + if (new_fa->memb_name[mt]) free(new_fa->memb_name[mt]); + } + free(new_fa); + return NULL; + } + return new_fa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_fapl_free + * + * Purpose: Frees the multi-specific file access properties. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_fapl_free(void *_fa) +{ + H5FD_multi_fapl_t *fa = (H5FD_multi_fapl_t*)_fa; + H5FD_mem_t mt; + + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (fa->memb_fapl[mt]>=0) H5Pclose(fa->memb_fapl[mt]); + if (fa->memb_name[mt]) free(fa->memb_name[mt]); + } + free(fa); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_dxpl_copy + * + * Purpose: Copes the multi-specific data transfer properties. + * + * Return: Success: Ptr to new property list + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_multi_dxpl_copy(const void *_old_dx) +{ + const H5FD_multi_dxpl_t *old_dx = (const H5FD_multi_dxpl_t*)_old_dx; + H5FD_multi_dxpl_t *new_dx = malloc(sizeof(H5FD_multi_dxpl_t)); + H5FD_mem_t mt; + int nerrors = 0; + + assert(new_dx); + + memcpy(new_dx, old_dx, sizeof(H5FD_multi_dxpl_t)); + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (old_dx->memb_dxpl[mt]>=0) { + new_dx->memb_dxpl[mt] = H5Pcopy(old_dx->memb_dxpl[mt]); + if (new_dx->memb_dxpl[mt]<0) nerrors++; + } + } + + if (nerrors) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + H5Pclose(new_dx->memb_dxpl[mt]); + } + free(new_dx); + return NULL; + } + return new_dx; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_dxpl_free + * + * Purpose: Frees the multi-specific data transfer properties. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_dxpl_free(void *_dx) +{ + H5FD_multi_dxpl_t *dx = (H5FD_multi_dxpl_t*)_dx; + H5FD_mem_t mt; + + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (dx->memb_dxpl[mt]>=0) H5Pclose(dx->memb_dxpl[mt]); + } + free(dx); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_open + * + * Purpose: Creates and/or opens a multi HDF5 file. + * + * Return: Success: A pointer to a new file data structure. The + * public fields will be initialized by the + * caller, which is always H5FD_open(). + * + * Failure: NULL + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static H5FD_t * +H5FD_multi_open(const char *name, unsigned flags, hid_t fapl_id, + haddr_t maxaddr) +{ + H5FD_multi_t *file=NULL; + H5FD_mem_t mt, mmt, mt2, mmt2; + char tmp[4096]; + int seen[H5FD_MEM_NTYPES]; + + /* Check arguments */ + if (!name || !*name) return NULL; + if (0==maxaddr || HADDR_UNDEF==maxaddr) return NULL; + + /* + * Initialize file from file access properties. The default mapping + * creates two files -- one for meta data and one for raw data. The + * default file extensions are ".meta" and ".raw" accessed by default + * file drivers. Half the address space is used for each. + */ + if (NULL==(file=calloc(1, sizeof(H5FD_multi_t)))) return NULL; + if (H5P_DEFAULT==fapl_id || H5FD_MULTI!=H5Pget_driver(fapl_id)) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + file->memb_map[mt] = H5FD_MEM_DRAW==mt?mt:H5FD_MEM_SUPER; + file->memb_addr[mt] = HADDR_UNDEF; + file->memb_fapl[mt] = H5P_DEFAULT; + } + file->memb_name[H5FD_MEM_SUPER] = my_strdup("%s.meta"); + file->memb_addr[H5FD_MEM_SUPER] = 0; + + file->memb_name[H5FD_MEM_DRAW] = my_strdup("%s.raw"); + file->memb_addr[H5FD_MEM_DRAW] = maxaddr/2; + } else { + H5FD_multi_fapl_t *fa = H5Pget_driver_info(fapl_id); + assert(fa); + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + file->memb_map[mt] = fa->memb_map[mt]; + file->memb_addr[mt] = fa->memb_addr[mt]; + if (fa->memb_fapl[mt]>=0) { + file->memb_fapl[mt] = H5Pcopy(fa->memb_fapl[mt]); + } else { + file->memb_fapl[mt] = fa->memb_fapl[mt]; + } + if (fa->memb_name[mt]) { + file->memb_name[mt] = my_strdup(fa->memb_name[mt]); + } else { + file->memb_name[mt] = NULL; + } + } + } + file->flags = flags; + + /* + * Figure out the memb_next[] values for each member. This is the + * beginning address of the next member. + */ + memset(seen, 0, sizeof seen); + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + assert(mmt>0 && mmt<H5FD_MEM_NTYPES); + if (seen[mmt]++) continue; + + file->memb_next[mmt] = HADDR_UNDEF; + for (mt2=1; mt2<H5FD_MEM_NTYPES; mt2++) { + mmt2 = file->memb_map[mt2]; + if (H5FD_MEM_DEFAULT==mmt2) mmt2 = mt2; + assert(mmt2>0 && mmt2<H5FD_MEM_NTYPES); + if (mmt==mmt2) continue; + + if (file->memb_addr[mmt]<file->memb_addr[mmt2] && + (HADDR_UNDEF==file->memb_next[mmt] || + file->memb_next[mmt]>file->memb_addr[mmt2])) { + file->memb_next[mmt] = file->memb_addr[mmt2]; + } + } + } + + /* + * Open all the multi members. + */ + memset(seen, 0, sizeof seen); + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + assert(mmt>0 && mmt<H5FD_MEM_NTYPES); + if (seen[mmt]++) continue; + assert(file->memb_name[mmt]); + sprintf(tmp, file->memb_name[mmt], name); + +#ifdef H5FD_MULTI_DEBUG + if (file->flags & H5F_ACC_DEBUG) { + fprintf(stderr, "H5FD_MULTI: opening \"%s\"\n", tmp); + } +#endif + H5E_BEGIN_TRY { + file->memb[mmt] = H5FDopen(tmp, flags, file->memb_fapl[mmt], + HADDR_UNDEF); + } H5E_END_TRY; + if (!file->memb[mmt]) { +#ifdef H5FD_MULTI_DEBUG + if (file->flags & H5F_ACC_DEBUG) { + fprintf(stderr, "H5FD_MULTI: open failed\n"); + } +#endif + goto error; + } + } + + /* Write index file */ + if ((flags & H5F_ACC_RDWR) && + H5FD_multi_flush((H5FD_t*)file)<0) goto error; + return (H5FD_t*)file; + + error: + /* Cleanup and fail */ + if (file) { + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (file->memb[mt]) H5FDclose(file->memb[mt]); + if (file->memb_fapl[mt]>=0) H5Pclose(file->memb_fapl[mt]); + if (file->memb_name[mt]) free(file->memb_name[mt]); + } + free(file); + } + return NULL; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_close + * + * Purpose: Closes a multi file. + * + * Return: Success: Non-negative + * + * Failure: Negative with as many members closed as + * possible. The only subsequent operation + * permitted on the file is a close operation. + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_close(H5FD_t *_file) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mt; + int nerrors=0; + + /* Flush our own data */ + if (H5FD_multi_flush(_file)<0) nerrors++; + + /* Close as many members as possible */ + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (file->memb[mt]) { +#ifdef H5FD_MULTI_DEBUG + if (file->flags & H5F_ACC_DEBUG) { + fprintf(stderr, "H5FD_MULTI: closing member %d\n", (int)mt); + } +#endif + if (H5FDclose(file->memb[mt])<0) { +#ifdef H5FD_MULTI_DEBUG + if (file->flags & H5F_ACC_DEBUG) { + fprintf(stderr, "H5FD_MULTI: close failed\n"); + } +#endif + nerrors++; + } else { + file->memb[mt] = NULL; + } + } + } + if (nerrors) return -1; + + /* Clean up other stuff */ + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (file->memb_fapl[mt]>=0) H5Pclose(file->memb_fapl[mt]); + if (file->memb_name[mt]) free(file->memb_name[mt]); + } + free(file); + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_cmp + * + * Purpose: Compares two file families to see if they are the same. It + * does this by comparing the first common member of the two + * families. If the families have no members in common then the + * file with the earliest member is smaller than the other file. + * We abort if neither file has any members. + * + * Return: Success: like strcmp() + * + * Failure: never fails (arguments were checked by the + * caller). + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static int +H5FD_multi_cmp(const H5FD_t *_f1, const H5FD_t *_f2) +{ + const H5FD_multi_t *f1 = (const H5FD_multi_t*)_f1; + const H5FD_multi_t *f2 = (const H5FD_multi_t*)_f2; + H5FD_mem_t mt; + int cmp=0; + + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + if (f1->memb[mt] && f2->memb[mt]) break; + if (!cmp) { + if (f1->memb[mt]) cmp = -1; + else if (f2->memb[mt]) cmp = 1; + } + } + assert(cmp || mt<H5FD_MEM_NTYPES); + if (mt>=H5FD_MEM_NTYPES) return cmp; + + return H5FDcmp(f1->memb[mt], f2->memb[mt]); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_get_eoa + * + * Purpose: Returns the end-of-address marker for the file. The EOA + * marker is the first address past the last byte allocated in + * the format address space. + * + * Return: Success: The end-of-address-marker + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_multi_get_eoa(H5FD_t *_file) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + return file->eoa; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_set_eoa + * + * Purpose: Set the end-of-address marker for the file by savig the new + * EOA value in the file struct. Also set the EOA marker for the + * subfile in which the new EOA value falls. We don't set the + * EOA values of any other subfiles. + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_set_eoa(H5FD_t *_file, haddr_t eoa) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mt, mmt; + herr_t status; + + /* Find the subfile in which the new EOA value falls */ + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + assert(mmt>0 && mmt<H5FD_MEM_NTYPES); + + if (eoa>=file->memb_addr[mmt] && eoa<file->memb_next[mmt]) { + break; + } + } + assert(mt<H5FD_MEM_NTYPES); + + /* Set subfile eoa */ + H5E_BEGIN_TRY { + status = H5FDset_eoa(file->memb[mmt], eoa-file->memb_addr[mmt]); + } H5E_END_TRY; + if (status<0) return -1; + + /* Save new eoa for return later */ + file->eoa = eoa; + return 0; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_get_eof + * + * Purpose: Returns the end-of-file marker, which is the greater of + * either the total multi size or the current EOA marker. + * + * Return: Success: End of file address, the first address past + * the end of the multi of files or the current + * EOA, whichever is larger. + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_multi_get_eof(H5FD_t *_file) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + haddr_t eof=0, tmp; + H5FD_mem_t mt, mmt; + int seen[H5FD_MEM_NTYPES]; + + memset(seen, 0, sizeof seen); + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + assert(mmt>0 && mmt<H5FD_MEM_NTYPES); + if (seen[mmt]++) continue; + + H5E_BEGIN_TRY { + tmp = H5FDget_eof(file->memb[mmt]); + } H5E_END_TRY; + if (HADDR_UNDEF==tmp) return HADDR_UNDEF; + if (tmp>0) tmp += file->memb_addr[mmt]; + if (tmp>eof) eof = tmp; + } + + return MAX(file->eoa, eof); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_alloc + * + * Purpose: Allocate file memory. + * + * Return: Success: Address of new memory + * + * Failure: HADDR_UNDEF + * + * Programmer: Robb Matzke + * Thursday, August 12, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static haddr_t +H5FD_multi_alloc(H5FD_t *_file, H5FD_mem_t type, hsize_t size) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mmt; + haddr_t addr; + + mmt = file->memb_map[type]; + if (H5FD_MEM_DEFAULT==mmt) mmt = type; + + if (HADDR_UNDEF==(addr=H5FDalloc(file->memb[mmt], type, size))) { + return HADDR_UNDEF; + } + addr += file->memb_addr[mmt]; + if (addr+size>file->eoa) file->eoa = addr+size; + return addr; +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_free + * + * Purpose: Frees memory + * + * Return: Success: 0 + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Thursday, August 12, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_free(H5FD_t *_file, H5FD_mem_t type, haddr_t addr, hsize_t size) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mmt; + + mmt = file->memb_map[type]; + if (H5FD_MEM_DEFAULT==mmt) mmt = type; + + assert(addr>=file->memb_addr[mmt]); + assert(addr+size<=file->memb_next[mmt]); + return H5FDfree(file->memb[mmt], type, addr-file->memb_addr[mmt], size); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_read + * + * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR + * into buffer BUF according to data transfer properties in + * DXPL_ID. + * + * Return: Success: Zero. Result is stored in caller-supplied + * buffer BUF. + * + * Failure: -1, contents of buffer BUF are undefined. + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_read(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size, + void *_buf/*out*/) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_multi_dxpl_t *dx=NULL; + H5FD_mem_t mt, mmt, hi=H5FD_MEM_DEFAULT; + haddr_t start_addr=0; + + /* Get the data transfer properties */ + if (H5P_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) { + dx = H5Pget_driver_info(dxpl_id); + } + + /* Find the file to which this address belongs */ + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + assert(mmt>0 && mmt<H5FD_MEM_NTYPES); + + if (file->memb_addr[mmt]>addr) continue; + if (file->memb_addr[mmt]>=start_addr) { + start_addr = file->memb_addr[mmt]; + hi = mmt; + } + } + assert(hi>0); + + /* Read from that member */ + return H5FDread(file->memb[hi], dx?dx->memb_dxpl[hi]:H5P_DEFAULT, + addr-start_addr, size, _buf); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_write + * + * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR + * from buffer BUF according to data transfer properties in + * DXPL_ID. + * + * Return: Success: Zero + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_write(H5FD_t *_file, hid_t dxpl_id, haddr_t addr, hsize_t size, + const void *_buf) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_multi_dxpl_t *dx=NULL; + H5FD_mem_t mt, mmt, hi=H5FD_MEM_DEFAULT; + haddr_t start_addr=0; + + /* Get the data transfer properties */ + if (H5P_DEFAULT!=dxpl_id && H5FD_MULTI==H5Pget_driver(dxpl_id)) { + dx = H5Pget_driver_info(dxpl_id); + } + + /* Find the file to which this address belongs */ + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + assert(mmt>0 && mmt<H5FD_MEM_NTYPES); + + if (file->memb_addr[mmt]>addr) continue; + if (file->memb_addr[mmt]>=start_addr) { + start_addr = file->memb_addr[mmt]; + hi = mmt; + } + } + assert(hi>0); + + /* Write to that member */ + return H5FDwrite(file->memb[hi], dx?dx->memb_dxpl[hi]:H5P_DEFAULT, + addr-start_addr, size, _buf); +} + + +/*------------------------------------------------------------------------- + * Function: H5FD_multi_flush + * + * Purpose: Flushes all multi members. + * + * Return: Success: 0 + * + * Failure: -1, as many files flushed as possible. + * + * Programmer: Robb Matzke + * Wednesday, August 4, 1999 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_multi_flush(H5FD_t *_file) +{ + H5FD_multi_t *file = (H5FD_multi_t*)_file; + H5FD_mem_t mt, mmt; + int nerrors=0; + +#if 0 + /* Debugging stuff... */ + fprintf(stderr, "multifile access information:\n"); + + /* print the map */ + fprintf(stderr, " map="); + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + mmt = file->memb_map[mt]; + if (H5FD_MEM_DEFAULT==mmt) mmt = mt; + fprintf(stderr, "%s%d", 1==mt?"":",", (int)mmt); + } + fprintf(stderr, "\n"); + + /* print info about each file */ + fprintf(stderr, " File Starting Allocated Next Member\n"); + fprintf(stderr, " Number Address Size Address Name\n"); + fprintf(stderr, " ------ -------------------- -------------------- -------------------- ------------------------------\n"); + + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + if (HADDR_UNDEF!=file->memb_addr[mt]) { + haddr_t eoa = H5FDget_eoa(file->memb[mt]); + fprintf(stderr, " %6d %20llu %20llu %20llu %s\n", + (int)mt, (unsigned long long)(file->memb_addr[mt]), + (unsigned long long)eoa, + (unsigned long long)(file->memb_next[mt]), + file->memb_name[mt]); + } + } +#endif + + /* Flush each file */ + for (mt=1; mt<H5FD_MEM_NTYPES; mt++) { + if (file->memb[mt]) { + H5E_BEGIN_TRY { + if (H5FDflush(file->memb[mt])<0) nerrors++; + } H5E_END_TRY; + } + } + + return nerrors ? -1 : 0; +} + diff --git a/src/H5FDmulti.h b/src/H5FDmulti.h new file mode 100644 index 0000000..dbe7c8e --- /dev/null +++ b/src/H5FDmulti.h @@ -0,0 +1,31 @@ +/* + * Copyright © 1999 NCSA + * All rights reserved. + * + * Programmer: Robb Matzke <matzke@llnl.gov> + * Monday, August 2, 1999 + * + * Purpose: The public header file for the "multi" driver. + */ +#ifndef H5FDmulti_H +#define H5FDmulti_H + +#include <H5Ipublic.h> + +#define H5FD_MULTI (H5FD_multi_init()) + +hid_t H5FD_multi_init(void); +herr_t H5Pset_fapl_multi(hid_t fapl_id, const H5FD_mem_t *memb_map, + const hid_t *memb_fapl, const char **memb_name, + const haddr_t *memb_addr); +herr_t H5Pget_fapl_multi(hid_t fapl_id, H5FD_mem_t *memb_map/*out*/, + hid_t *memb_fapl/*out*/, char **memb_name/*out*/, + haddr_t *memb_addr/*out*/); +herr_t H5Pset_dxpl_multi(hid_t dxpl_id, const hid_t *memb_dxpl); +herr_t H5Pget_dxpl_multi(hid_t dxpl_id, hid_t *memb_dxpl/*out*/); + +herr_t H5Pset_fapl_split(hid_t fapl, const char *meta_ext, + hid_t meta_plist_id, const char *raw_ext, + hid_t raw_plist_id); + +#endif diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index a987b60..93fa724 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -11,6 +11,10 @@ #include <H5FDpublic.h> intn H5FD_term_interface(void); +hsize_t H5FD_sb_size(H5FD_t *file); +herr_t H5FD_sb_encode(H5FD_t *file, char *name/*out*/, uint8_t *buf); +herr_t H5FD_sb_decode(H5FD_t *file, const char *name, const uint8_t *buf); +void *H5FD_fapl_get(H5FD_t *file); void *H5FD_fapl_copy(hid_t driver_id, const void *fapl); herr_t H5FD_fapl_free(hid_t driver_id, void *fapl); void *H5FD_dxpl_copy(hid_t driver_id, const void *dxpl); diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index 8af79d2..a63e982 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -15,8 +15,6 @@ typedef enum H5FD_mem_t { H5FD_MEM_SUPER, H5FD_MEM_BTREE, H5FD_MEM_DRAW, - H5FD_MEM_META, - H5FD_MEM_GROUP, H5FD_MEM_GHEAP, H5FD_MEM_LHEAP, H5FD_MEM_OHDR, @@ -35,8 +33,6 @@ typedef enum H5FD_mem_t { H5FD_MEM_SUPER, /*super*/ \ H5FD_MEM_SUPER, /*btree*/ \ H5FD_MEM_SUPER, /*draw*/ \ - H5FD_MEM_SUPER, /*meta*/ \ - H5FD_MEM_SUPER, /*group*/ \ H5FD_MEM_SUPER, /*gheap*/ \ H5FD_MEM_SUPER, /*lheap*/ \ H5FD_MEM_SUPER /*ohdr*/ \ @@ -47,15 +43,13 @@ typedef enum H5FD_mem_t { * pools. */ #define H5FD_FLMAP_DICHOTOMY { \ - H5FD_MEM_META, /*default*/ \ - H5FD_MEM_META, /*super*/ \ - H5FD_MEM_META, /*btree*/ \ + H5FD_MEM_SUPER, /*default*/ \ + H5FD_MEM_SUPER, /*super*/ \ + H5FD_MEM_SUPER, /*btree*/ \ H5FD_MEM_DRAW, /*draw*/ \ - H5FD_MEM_META, /*meta*/ \ - H5FD_MEM_META, /*group*/ \ - H5FD_MEM_META, /*gheap*/ \ - H5FD_MEM_META, /*lheap*/ \ - H5FD_MEM_META /*ohdr*/ \ + H5FD_MEM_SUPER, /*gheap*/ \ + H5FD_MEM_SUPER, /*lheap*/ \ + H5FD_MEM_SUPER /*ohdr*/ \ } /* @@ -67,8 +61,6 @@ typedef enum H5FD_mem_t { H5FD_MEM_DEFAULT, /*super*/ \ H5FD_MEM_DEFAULT, /*btree*/ \ H5FD_MEM_DEFAULT, /*draw*/ \ - H5FD_MEM_DEFAULT, /*meta*/ \ - H5FD_MEM_DEFAULT, /*group*/ \ H5FD_MEM_DEFAULT, /*gheap*/ \ H5FD_MEM_DEFAULT, /*lheap*/ \ H5FD_MEM_DEFAULT /*ohdr*/ \ @@ -83,7 +75,12 @@ typedef struct H5FD_t H5FD_t; typedef struct H5FD_class_t { const char *name; haddr_t maxaddr; + hsize_t (*sb_size)(H5FD_t *file); + herr_t (*sb_encode)(H5FD_t *file, char *name/*out*/, + unsigned char *p/*out*/); + herr_t (*sb_decode)(H5FD_t *f, const char *name, const unsigned char *p); size_t fapl_size; + void *(*fapl_get)(H5FD_t *file); void *(*fapl_copy)(const void *fapl); herr_t (*fapl_free)(void *fapl); size_t dxpl_size; diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index b383b92..e1ed9c3 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -133,7 +133,11 @@ static herr_t H5FD_sec2_flush(H5FD_t *_file); static const H5FD_class_t H5FD_sec2_g = { "sec2", /*name */ MAXADDR, /*maxaddr */ + NULL, /*sb_size */ + NULL, /*sb_encode */ + NULL, /*sb_decode */ 0, /*fapl_size */ + NULL, /*fapl_get */ NULL, /*fapl_copy */ NULL, /*fapl_free */ 0, /*dxpl_size */ diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 4849e98..eca1cd2 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -806,9 +806,8 @@ H5F_istore_init (H5F_t *f) FUNC_ENTER (H5F_istore_init, FAIL); HDmemset (rdcc, 0, sizeof(H5F_rdcc_t)); - if (f->shared->fapl->rdcc_nbytes>0 && - f->shared->fapl->rdcc_nelmts>0) { - rdcc->nslots = f->shared->fapl->rdcc_nelmts; + if (f->shared->rdcc_nbytes>0 && f->shared->rdcc_nelmts>0) { + rdcc->nslots = f->shared->rdcc_nelmts; rdcc->slot = H5MM_calloc (rdcc->nslots*sizeof(H5F_rdcc_ent_t*)); if (NULL==rdcc->slot) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, @@ -1111,7 +1110,7 @@ H5F_istore_prune (H5F_t *f, size_t size) { intn i, j, nerrors=0; H5F_rdcc_t *rdcc = &(f->shared->rdcc); - size_t total = f->shared->fapl->rdcc_nbytes; + size_t total = f->shared->rdcc_nbytes; const int nmeth=2; /*number of methods */ intn w[1]; /*weighting as an interval */ H5F_rdcc_ent_t *p[2], *cur; /*list pointers */ @@ -1129,7 +1128,7 @@ H5F_istore_prune (H5F_t *f, size_t size) * begins. The pointers participating in the list traversal are each * given a chance at preemption before any of the pointers are advanced. */ - w[0] = rdcc->nused * f->shared->fapl->rdcc_w0; + w[0] = rdcc->nused * f->shared->rdcc_w0; p[0] = rdcc->head; p[1] = NULL; @@ -1353,8 +1352,7 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, } assert (found || chunk_size>0); - if (!found && rdcc->nslots>0 && - chunk_size<=f->shared->fapl->rdcc_nbytes && + if (!found && rdcc->nslots>0 && chunk_size<=f->shared->rdcc_nbytes && (!ent || !ent->locked)) { /* * Add the chunk to the cache only if the slot is not already locked. diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index efe8bd9..d26f406 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -305,9 +305,17 @@ typedef struct H5F_file_t { haddr_t boot_addr; /* Absolute address of boot block */ haddr_t base_addr; /* Absolute base address for rel.addrs. */ haddr_t freespace_addr; /* Relative address of free-space info */ + haddr_t driver_addr; /* File driver information block address*/ struct H5AC_t *cache; /* The object cache */ H5F_create_t *fcpl; /* File-creation property list */ - H5F_access_t *fapl; /* File-access property list */ + intn mdc_nelmts; /* Size of meta data cache (elements) */ + intn rdcc_nelmts; /* Size of raw data chunk cache (elmts) */ + size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */ + double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/ + hsize_t threshold; /* Threshold for alignment */ + hsize_t alignment; /* Alignment */ + uintn gc_ref; /* Garbage-collect references? */ + hid_t driver_id; /* File driver ID */ struct H5G_t *root_grp; /* Open root group */ intn ncwfs; /* Num entries on cwfs list */ struct H5HG_heap_t **cwfs; /* Global heap cache */ @@ -177,7 +177,7 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type, /* Set up information for dataset region */ /* Return any previous heap block to the free list if we are garbage collecting */ - if(loc->file->shared->fapl->gc_ref) { + if(loc->file->shared->gc_ref) { /* Check for an existing heap ID in the reference */ for(u=0, heapid_found=0; u<H5R_DSET_REG_REF_BUF_SIZE; u++) if(ref->heapid[u]!=0) { diff --git a/src/H5Rpublic.h b/src/H5Rpublic.h index 61e96b7..fd97859 100644 --- a/src/H5Rpublic.h +++ b/src/H5Rpublic.h @@ -45,14 +45,14 @@ typedef struct { * to be defined at run-time, so we have to go with the worst case sizes for * them. -QAK */ -#define H5R_OBJ_REF_BUF_SIZE sizeof(hsize_t) +#define H5R_OBJ_REF_BUF_SIZE sizeof(haddr_t) /* Object reference structure for user's code */ typedef struct { unsigned char oid[H5R_OBJ_REF_BUF_SIZE]; /* Buffer to store OID of object referenced */ /* Needs to be large enough to store largest haddr_t in a worst case machine (ie. 8 bytes currently) */ } hobj_ref_t; -#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(hsize_t)+sizeof(int)) +#define H5R_DSET_REG_REF_BUF_SIZE (sizeof(haddr_t)+sizeof(int)) /* Dataset Region reference structure for user's code */ typedef struct { unsigned char heapid[H5R_DSET_REG_REF_BUF_SIZE]; /* Buffer to store heap ID and index */ @@ -94,6 +94,7 @@ hid_t H5T_NATIVE_B16_g = FAIL; hid_t H5T_NATIVE_B32_g = FAIL; hid_t H5T_NATIVE_B64_g = FAIL; hid_t H5T_NATIVE_OPAQUE_g = FAIL; +hid_t H5T_NATIVE_HADDR_g = FAIL; hid_t H5T_NATIVE_HSIZE_g = FAIL; hid_t H5T_NATIVE_HSSIZE_g = FAIL; hid_t H5T_NATIVE_HERR_g = FAIL; @@ -471,6 +472,13 @@ H5T_init_interface(void) "unable to initialize H5T layer"); } + /* haddr_t */ + dt = H5I_object(H5T_NATIVE_HADDR_g=H5Tcopy(H5T_NATIVE_UINT_g)); + dt->state = H5T_STATE_IMMUTABLE; + dt->size = sizeof(haddr_t); + dt->u.atomic.prec = 8*dt->size; + dt->u.atomic.offset = 0; + /* hsize_t */ dt = H5I_object (H5T_NATIVE_HSIZE_g = H5Tcopy (H5T_NATIVE_UINT_g)); dt->state = H5T_STATE_IMMUTABLE; diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index 12dd593..e595da6 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -357,6 +357,7 @@ __DLLVAR__ hid_t H5T_FORTRAN_S1_g; #define H5T_NATIVE_B32 (H5open(), H5T_NATIVE_B32_g) #define H5T_NATIVE_B64 (H5open(), H5T_NATIVE_B64_g) #define H5T_NATIVE_OPAQUE (H5open(), H5T_NATIVE_OPAQUE_g) +#define H5T_NATIVE_HADDR (H5open(), H5T_NATIVE_HADDR_g) #define H5T_NATIVE_HSIZE (H5open(), H5T_NATIVE_HSIZE_g) #define H5T_NATIVE_HSSIZE (H5open(), H5T_NATIVE_HSSIZE_g) #define H5T_NATIVE_HERR (H5open(), H5T_NATIVE_HERR_g) @@ -379,6 +380,7 @@ __DLLVAR__ hid_t H5T_NATIVE_B16_g; __DLLVAR__ hid_t H5T_NATIVE_B32_g; __DLLVAR__ hid_t H5T_NATIVE_B64_g; __DLLVAR__ hid_t H5T_NATIVE_OPAQUE_g; +__DLLVAR__ hid_t H5T_NATIVE_HADDR_g; __DLLVAR__ hid_t H5T_NATIVE_HSIZE_g; __DLLVAR__ hid_t H5T_NATIVE_HSSIZE_g; __DLLVAR__ hid_t H5T_NATIVE_HERR_g; diff --git a/src/H5private.h b/src/H5private.h index bd9e348..253fbad 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -177,6 +177,7 @@ #define HDF5_FREESPACE_VERSION 0 /* of the Free-Space Info */ #define HDF5_OBJECTDIR_VERSION 0 /* of the Object Directory format */ #define HDF5_SHAREDHEADER_VERSION 0 /* of the Shared-Header Info */ +#define HDF5_DRIVERINFO_VERSION 0 /* of the Driver Information Block*/ /* * Status return values for the `herr_t' type. diff --git a/src/Makefile.in b/src/Makefile.in index ec675a1..da03c0e 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -22,12 +22,12 @@ 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 H5Fistore.c \ - H5FD.c H5FDsec2.c H5FDfamily.c H5FDmpio.c H5FDcore.c H5G.c H5Gent.c \ - H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c H5Oattr.c \ - H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.c \ - H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c H5R.c H5RA.c \ - H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c H5Sselect.c \ - H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c + H5FD.c H5FDsec2.c H5FDfamily.c H5FDmpio.c H5FDcore.c H5FDmulti.c H5G.c \ + H5Gent.c H5Gnode.c H5Gstab.c H5HG.c H5HL.c H5I.c H5MF.c H5MM.c H5O.c \ + H5Oattr.c H5Ocomp.c H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c \ + H5Omtime.c H5Oname.c H5Onull.c H5Osdspace.c H5Oshared.c H5Ostab.c H5P.c \ + H5R.c H5RA.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \ + H5Sselect.c H5T.c H5Tbit.c H5Tconv.c H5Tinit.c H5Tvlen.c H5TB.c H5V.c H5Z.c LIB_OBJ=$(LIB_SRC:.c=.lo) @@ -37,9 +37,9 @@ MOSTLYCLEAN=H5detect.o H5detect H5Tinit.o H5Tinit.c ## Public header files (to be installed)... PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Dpublic.h \ H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDfamily.h H5FDmpio.h H5FDsec2.h \ - H5FDcore.h H5Gpublic.h H5HGpublic.h H5HLpublic.h H5Ipublic.h H5MMpublic.h \ - H5Opublic.h H5Ppublic.h H5Rpublic.h H5RApublic.h H5Spublic.h H5Tpublic.h \ - H5Zpublic.h H5config.h hdf5.h H5api_adpt.h + H5FDcore.h H5FDmulti.h H5Gpublic.h H5HGpublic.h H5HLpublic.h H5Ipublic.h \ + H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5RApublic.h H5Spublic.h \ + H5Tpublic.h H5Zpublic.h H5config.h hdf5.h H5api_adpt.h ## Other header files (not to be installed)... PRIVATE_HDR=H5private.h H5Aprivate.h H5Apkg.h H5ACprivate.h H5Bprivate.h \ @@ -44,5 +44,6 @@ #include <H5FDfamily.h> /* File families */ #include <H5FDmpio.h> /* Parallel files using MPI-2 I/O */ #include <H5FDsec2.h> /* POSIX unbuffered file I/O */ +#include <H5FDmulti.h> /* Usage-partitioned file family */ #endif diff --git a/test/.distdep b/test/.distdep index cd429b7..ebd0e84 100644 --- a/test/.distdep +++ b/test/.distdep @@ -1092,3 +1092,340 @@ enum.lo: \ ../src/H5Fprivate.h \ ../src/H5Rprivate.h \ ../src/H5Tprivate.h +h5test.lo: \ + h5test.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +big.lo: \ + big.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +cmpd_dset.lo: \ + cmpd_dset.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +dsets.lo: \ + dsets.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +dtypes.lo: \ + dtypes.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +extend.lo: \ + extend.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +external.lo: \ + external.c \ + h5test.h \ + ../src/hdf5.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Ipublic.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Epublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h \ + ../src/H5FDmpio.h \ + ../src/H5FDsec2.h \ + ../src/H5FDmulti.h \ + ../src/H5private.h \ + ../src/H5Tpkg.h \ + ../src/H5HGprivate.h \ + ../src/H5Fprivate.h \ + ../src/H5Rprivate.h \ + ../src/H5Tprivate.h +tfile.lo: \ + tfile.c \ + testhdf5.h \ + ../src/H5private.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Eprivate.h \ + ../src/H5Epublic.h \ + ../src/H5Ipublic.h \ + ../src/H5Bprivate.h \ + ../src/H5Bpublic.h \ + ../src/H5Fprivate.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Pprivate.h \ + ../src/H5Ppublic.h +tselect.lo: \ + tselect.c \ + testhdf5.h \ + ../src/H5private.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Eprivate.h \ + ../src/H5Epublic.h \ + ../src/H5Ipublic.h \ + ../src/hdf5.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h +tvltypes.lo: \ + tvltypes.c \ + testhdf5.h \ + ../src/H5private.h \ + ../src/H5public.h \ + ../src/H5config.h \ + ../src/H5api_adpt.h \ + ../src/H5Eprivate.h \ + ../src/H5Epublic.h \ + ../src/H5Ipublic.h \ + ../src/hdf5.h \ + ../src/H5Apublic.h \ + ../src/H5ACpublic.h \ + ../src/H5Bpublic.h \ + ../src/H5Dpublic.h \ + ../src/H5Fpublic.h \ + ../src/H5FDpublic.h \ + ../src/H5Gpublic.h \ + ../src/H5HGpublic.h \ + ../src/H5HLpublic.h \ + ../src/H5MMpublic.h \ + ../src/H5Opublic.h \ + ../src/H5Ppublic.h \ + ../src/H5Zpublic.h \ + ../src/H5Rpublic.h \ + ../src/H5RApublic.h \ + ../src/H5Spublic.h \ + ../src/H5Tpublic.h \ + ../src/H5FDcore.h \ + ../src/H5FDfamily.h diff --git a/test/Makefile.in b/test/Makefile.in index 7ad9478..2e602a4 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -45,18 +45,18 @@ MOSTLYCLEAN=cmpd_dset.h5 dataset.h5 extend.h5 istore.h5 tfile1.h5 tfile2.h5 \ extern_4a.raw extern_4b.raw iopipe.raw iopipe.h5 gheap0.h5 \ gheap1.h5 gheap2.h5 gheap3.h5 gheap4.h5 links.h5 chunk.h5 \ big.data big[0-9][0-9][0-9][0-9][0-9].h5 dtypes1.h5 dtypes2.h5 \ - tattr.h5 tselect.h5 mtime.h5 ragged.h5 unlink.h5 overhead.h5 \ - fillval_[0-9].h5 fillval.raw mount_[0-9].h5 trefer[12].h5 tvltypes.h5 \ - flush.h5 enum1.h5 + tattr.h5 tselect.h5 mtime.h5 ragged.h5 unlink.h5 overhead.h5 \ + fillval_[0-9].h5 fillval.raw mount_[0-9].h5 trefer[12].h5 \ + tvltypes.h5 flush.h5 enum1.h5 CLEAN=$(TIMINGS) ## Source and object files for programs... The TEST_SRC list contains all the ## source files and is used for things like dependencies, archiving, etc. The ## other source lists are for the individual tests, the files of which may ## overlap with other tests. -TEST_SRC=big.c bittests.c chunk.c cmpd_dset.c dsets.c dtypes.c extend.c \ - external.c fillval.c flush1.c flush2.c gheap.c h5test.c hyperslab.c \ - iopipe.c istore.c lheap.c links.c mount.c mtime.c ohdr.c overhead.c \ +TEST_SRC=big.c bittests.c chunk.c cmpd_dset.c dsets.c dtypes.c extend.c \ + external.c fillval.c flush1.c flush2.c gheap.c h5test.c hyperslab.c \ + iopipe.c istore.c lheap.c links.c mount.c mtime.c ohdr.c overhead.c \ ragged.c stab.c tattr.c testhdf5.c tfile.c th5s.c tmeta.c trefer.c \ tselect.c tvltypes.c unlink.c enum.c TEST_OBJ=$(TEST_SRC:.c=.lo) @@ -187,9 +187,10 @@ writer (hid_t fapl, int wrt_n) * which is a family of files. Each member of the family will be 1GB */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file=H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, H5P_DEFAULT, - fapl))<0) goto error; - + if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } + /* Create simple data spaces according to the size specified above. */ if ((space1 = H5Screate_simple (4, size1, size1))<0 || (space2 = H5Screate_simple (1, size2, size2))<0) { @@ -277,9 +278,7 @@ reader (hid_t fapl) /* Open HDF5 file */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file=H5Fopen(filename, H5F_ACC_RDONLY|H5F_ACC_DEBUG, fapl))<0) { - goto error; - } + if ((file=H5Fopen(filename, H5F_ACC_RDONLY, fapl))<0) goto error; /* Open the dataset */ if ((d2 = H5Dopen (file, "d2"))<0) goto error; @@ -387,19 +386,23 @@ main (void) if (sizeof(long_long)<8 || 0==GB8LL) { puts("Test skipped because sizeof(long_long) is too small. This"); puts("hardware apparently doesn't support 64-bit integer types."); + H5Pclose(fapl); exit(0); } if (!is_sparse()) { puts("Test skipped because file system does not support holes."); + H5Pclose(fapl); exit(0); } if (!enough_room(fapl)) { puts("Test skipped because of quota (file size or num open files)."); + H5Pclose(fapl); exit(0); } if (sizeof(hsize_t)<=4) { puts("Test skipped because the hdf5 library was configured with the"); puts("--disable-hsizet flag in order to work around a compiler bug."); + H5Pclose(fapl); exit(0); } @@ -411,6 +414,7 @@ main (void) return 0; error: + if (fapl>=0) H5Pclose(fapl); puts("*** TEST FAILED ***"); return 1; } diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index 714c810..4ccd060 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -148,9 +148,10 @@ main (int argc, char *argv[]) /* Create the file */ fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - if ((file = H5Fcreate (filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, - H5P_DEFAULT, fapl))<0) goto error; - + if ((file = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } + /* Create the data space */ if ((space = H5Screate_simple (2, dim, NULL))<0) goto error; diff --git a/test/dsets.c b/test/dsets.c index 5fe0b26..b98730f 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -834,9 +834,10 @@ main(void) #endif h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file=H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, - H5P_DEFAULT, fapl))<0) goto error; - + if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } + /* Cause the library to emit initial messages */ if ((grp = H5Gcreate (file, "emit diagnostics", 0))<0) goto error; if (H5Gset_comment(grp, ".", "Causes diagnostic messages to be emitted")<0) diff --git a/test/dtypes.c b/test/dtypes.c index 730dc0d..4328dad 100644 --- a/test/dtypes.c +++ b/test/dtypes.c @@ -778,8 +778,9 @@ test_transient (hid_t fapl) TESTING("transient data types"); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file=H5Fcreate (filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, - H5P_DEFAULT, fapl))<0) goto error; + if ((file=H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } if ((space = H5Screate_simple (2, ds_size, ds_size))<0) goto error; /* Predefined types cannot be modified or closed */ @@ -906,8 +907,9 @@ test_named (hid_t fapl) TESTING("named data types"); h5_fixname(FILENAME[1], fapl, filename, sizeof filename); - if ((file=H5Fcreate (filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, - H5P_DEFAULT, fapl))<0) goto error; + if ((file=H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } if ((space = H5Screate_simple (2, ds_size, ds_size))<0) goto error; /* Predefined types cannot be committed */ diff --git a/test/extend.c b/test/extend.c index cae6e0c..25f7ee7 100644 --- a/test/extend.c +++ b/test/extend.c @@ -64,9 +64,10 @@ main (void) /* Create the file */ h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file = H5Fcreate (filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, - H5P_DEFAULT, fapl))<0) goto error; - + if ((file = H5Fcreate (filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } + /* Create the dataset which is originally NX by NY */ if ((cparms = H5Pcreate (H5P_DATASET_CREATE))<0) goto error; if (H5Pset_chunk (cparms, 2, chunk_dims)<0) goto error; diff --git a/test/external.c b/test/external.c index 7e07554..902bc76 100644 --- a/test/external.c +++ b/test/external.c @@ -606,8 +606,9 @@ test_2 (hid_t fapl) * output looks like. */ h5_fixname(FILENAME[1], fapl, filename, sizeof filename); - if ((file=H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, - H5P_DEFAULT, fapl))<0) goto error; + if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } if ((grp=H5Gcreate(file, "emit-diagnostics", 8))<0) goto error; if (H5Gclose(grp)<0) goto error; @@ -710,8 +711,9 @@ test_3 (hid_t fapl) /* Create another file */ h5_fixname(FILENAME[2], fapl, filename, sizeof filename); - if ((file=H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, H5P_DEFAULT, - fapl))<0) goto error; + if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } /* Create the external file list */ if ((dcpl=H5Pcreate(H5P_DATASET_CREATE))<0) goto error; @@ -814,8 +816,9 @@ main (void) h5_reset(); fapl = h5_fileaccess(); h5_fixname(FILENAME[0], fapl, filename, sizeof filename); - if ((file=H5Fcreate(filename, H5F_ACC_TRUNC|H5F_ACC_DEBUG, H5P_DEFAULT, - fapl))<0) goto error; + if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl))<0) { + goto error; + } if ((grp=H5Gcreate(file, "emit-diagnostics", 8))<0) goto error; if (H5Gclose (grp)<0) goto error; diff --git a/test/h5test.c b/test/h5test.c index 88a45a9..b6e5551 100644 --- a/test/h5test.c +++ b/test/h5test.c @@ -32,6 +32,19 @@ * */ +/* + * These are the letters that are appended to the file name when generating + * names for the split and multi drivers. They are: + * + * m: All meta data when using the split driver. + * s: The userblock, superblock, and driver info block + * b: B-tree nodes + * r: Dataset raw data + * g: Global heap + * l: local heap (object names) + * o: object headers + */ +static const char *multi_letters = "msbrglo"; /*------------------------------------------------------------------------- @@ -100,22 +113,17 @@ h5_cleanup(hid_t fapl) } } else if (H5FD_CORE==driver) { /*void*/ + } else if (H5FD_MULTI==driver) { + H5FD_mem_t mt; + assert(strlen(multi_letters)==H5FD_MEM_NTYPES); + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + HDsnprintf(temp, sizeof temp, "%s-%c.h5", + filename, multi_letters[mt]); + remove(temp); /*don't care if it fails*/ + } } else { remove(filename); } - - -#ifndef ROBB_VFL -#warning "H5F_LOW_SPLIT not implemented" -#else - switch (H5Pget_driver(fapl)) { - case H5F_LOW_SPLIT: - HDsnprintf(temp, sizeof temp, "%s.raw", filename); - remove(temp); - HDsnprintf(temp, sizeof temp, "%s.meta", filename); - remove(temp); - break; -#endif } retval=1; } @@ -217,20 +225,12 @@ h5_fixname(const char *base_name, hid_t fapl, char *fullname, size_t size) if ((driver=H5Pget_driver(fapl))<0) return NULL; if (H5FD_FAMILY==driver) { suffix = "%05d.h5"; - } else if (H5FD_CORE==driver) { + } else if (H5FD_CORE==driver || H5FD_MULTI==driver) { suffix = NULL; } else { suffix = ".h5"; } -#ifndef RPM_VFL -#warning "H5FD_SPLIT not implemented" -#else - if (H5FD_SPLIT==driver) { - suffix = NULL; - } -#endif - if (suffix) { if (strlen(fullname)+strlen(suffix)>=size) return NULL; strcat(fullname, suffix); @@ -266,6 +266,7 @@ h5_fileaccess(void) char s[1024]; hid_t fapl = -1; hsize_t fam_size = 100*1024*1024; /*100 MB*/ + H5FD_mem_t mt; /* First use the environment variable, then the constant */ val = getenv("HDF5_DRIVER"); @@ -283,24 +284,40 @@ h5_fileaccess(void) if (!strcmp(name, "sec2")) { /* Unix read() and write() system calls */ if (H5Pset_fapl_sec2(fapl)<0) return -1; - } else if (!strcmp(name, "stdio")) { - /* C standard I/O library */ -#ifndef RPM_VFL -#warning "H5FD_STDIO not implemented" -#else - if (H5Pset_stdio(fapl)<0) return -1; -#endif } else if (!strcmp(name, "core")) { /* In-core temporary file with 1MB increment */ if (H5Pset_fapl_core(fapl, 1024*1024)<0) return -1; } else if (!strcmp(name, "split")) { /* Split meta data and raw data each using default driver */ -#ifndef RPM_VFL -#warning "H5FD_SPLIT not implemented" -#else - if (H5Pset_split(fapl, NULL, H5P_DEFAULT, NULL, H5P_DEFAULT)<0) + if (H5Pset_fapl_split(fapl, + "-m.h5", H5P_DEFAULT, + "-r.h5", H5P_DEFAULT)<0) return -1; -#endif + } else if (!strcmp(name, "multi")) { + /* Multi-file driver, general case of the split driver */ + H5FD_mem_t memb_map[H5FD_MEM_NTYPES]; + hid_t memb_fapl[H5FD_MEM_NTYPES]; + const char *memb_name[H5FD_MEM_NTYPES]; + char sv[H5FD_MEM_NTYPES][1024]; + haddr_t memb_addr[H5FD_MEM_NTYPES]; + + memset(memb_map, 0, sizeof memb_map); + memset(memb_fapl, 0, sizeof memb_fapl); + memset(memb_name, 0, sizeof memb_name); + memset(memb_addr, 0, sizeof memb_addr); + + assert(strlen(multi_letters)==H5FD_MEM_NTYPES); + for (mt=0; mt<H5FD_MEM_NTYPES; mt++) { + memb_fapl[mt] = H5P_DEFAULT; + sprintf(sv[mt], "%%s-%c.h5", multi_letters[mt]); + memb_name[mt] = sv[mt]; + memb_addr[mt] = MAX(mt-1,0)*(HADDR_MAX/10); + } + + if (H5Pset_fapl_multi(fapl, memb_map, memb_fapl, memb_name, + memb_addr)<0) { + return -1; + } } else if (!strcmp(name, "family")) { /* Family of files, each 1MB and using the default driver */ if ((val=strtok(NULL, " \t\n\r"))) { diff --git a/test/tfile.c b/test/tfile.c index f5ed1b2..2968b8e 100644 --- a/test/tfile.c +++ b/test/tfile.c @@ -31,7 +31,7 @@ static char RcsId[] = "$Revision$"; #include <H5Pprivate.h> #define F1_USERBLOCK_SIZE (hsize_t)0 -#define F1_OFFSET_SIZE sizeof(hsize_t) +#define F1_OFFSET_SIZE sizeof(haddr_t) #define F1_LENGTH_SIZE sizeof(hsize_t) #define F1_SYM_LEAF_K 4 #define F1_SYM_INTERN_K 16 |