summaryrefslogtreecommitdiffstats
path: root/src/H5Ffamily.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-02-19 18:19:48 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-02-19 18:19:48 (GMT)
commitb24130dcf051e6f569612c0a9b13d2168c6213c0 (patch)
tree607e5fc4db5da70f6584c9567f28ef9b88faeae1 /src/H5Ffamily.c
parent5b8d25d3c6db32d04213978500dca99dd1794d77 (diff)
downloadhdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.zip
hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.tar.gz
hdf5-b24130dcf051e6f569612c0a9b13d2168c6213c0.tar.bz2
[svn-r290] Changes since 19980206
---------------------- ./configure.in ./src/H5Fprivate.h ./src/H5Fsec2.c We now detect and use lseek64() on systems that have it (e.g., Irix64) and are able to generate >2GB files on Irix XFS file systems (and anything else that supports large files). This change also removed some warning messages from the Irix `-64' compiler. > $ ls -l istore.h5 > -rw-r--r-- 1 matzke meshtv 8605436856 Feb 17 14:03 istore.h5 ./configure.in ./src/H5Fprivate.h ./src/H5Fstdio.h We now detect and use fseek64() on systems that have it (e.g., Irix64) and are able to generate >2GB files on Irix XFS file systems (and anything else that supports large files). This change also removed some warning messages from the Iris `-64' compiler. ./src/H5E.c ./src/H5Epublic.h Added the H5E_OVERFLOW error to signal file address overflow. ./src/H5Fpublic.h ./examples/h5_chunk_read.c ./examples/h5_compound.c ./examples/h5_extend_write.c ./examples/h5_group.c ./examples/h5_read.c ./examples/h5_write.c ./html/Datasets.html ./html/Files.html ./html/H5.api.html ./html/H5.intro.html ./html/H5.sample_code.html ./html/ph5example.c ./html/review1.html ./test/cmpd_dset.c ./test/dsets.c ./test/extend.c ./test/tfile.c ./test/th5p.c ./test/theap.c ./test/tohdr.c ./test/tstab.c ./testpar/phdf5.c Renamed file access constants to follow the naming scheme. Also changed the base names a little to be more accurate as to what they do. The old names H5ACC_WRITE and H5ACC_OVERWRITE will temporarily work. H5ACC_DEFAULT --> H5F_ACC_RDONLY for H5Fopen() H5ACC_DEFAULT --> H5F_ACC_EXCL for H5Fcreate() H5ACC_WRITE --> H5F_ACC_RDWR H5ACC_OVERWRITE --> H5F_ACC_TRUNC Albert or Kim: The H5ACC_INDEPENDENT and H5ACC_COLLECTIVE macros in H5Fpublic.h should be an enum typedef and have names more like H5F_MPIO_INDEPENDENT and H5F_MPIO_COLLECTIVE. Also change the access_mode argument of H5Cset_mpio(). H5Fcreate() and H5Fopen() are more strict now about which flags are acceptable for the operation. ./src/H5Fprivate.h ./src/H5F.c ./src/H5C.c Changed the file access template to make it more general. A union contains a struct for each type of low-level driver and the default template is initialized at run-time. ./src/H5Fpublic.h ./src/H5F.c Added H5Fget_access_template() and cleaned up H5Fget_create_template(). ./src/H5C.c The H5Cset_mpi() no longer trashes the file access template when an error is detected. We check for errors and *then* update the file access template. Added H5C_close() so Albert and Kim have a place to release the MPI communicator and info from the file access property list. Kim or Albert: I notice in H5Cset_mpi() you copy the MPI communicator. Do you need to do something similar in H5C_copy()? ./src/H5F.c Added more error checking for the file creation and access property lists because it used to be possible to make the library dump core by swapping the creation and access property list ID numbers of H5Fcreate(). ./test/istore.c ./test/tfile.c ./test/th5p.c ./test/theap.c ./test/tohdr.c ./test/tstab.c ./testpar/testphdf5.c One must pass H5C_DEFAULT as the file creation or access property list in order to get the default property list. It is no longer possible to pass zero or any other arbitrary bad object ID. ./src/H5Fcore.c ./src/H5Ffamly.c ./src/H5Flow.c ./src/H5Fmpio.c ./src/H5Fsec2.c ./src/H5Fsplit.c ./src/H5Fstdio.c ./src/H5MF.c The file access property list is passed to all H5F_low_...() functions and to the drivers. ./src/H5Fcore.c The block size can be set at run time on a per-file basis instead of at compile time across all files. The "5000 items in a group test" now takes 1.6 seconds. ./src/H5private.h Removed inclusion of mpi.h and mpio.h since they're included from H5public.h. ./src/H5Cpublic.h ./src/H5C.c Added H5Cset_stdio(), H5Cset_sec2(), H5Cset_core(), H5Cset_split(), and H5Cset_family() in addition to the H5Cset_mpio() that Kim and Albert already wrote. We still need the H5Cget_driver() and an H5Cget...() counterpart for each of those functions. The split and family drivers still need a little work but I'm checking this in anyway.
Diffstat (limited to 'src/H5Ffamily.c')
-rw-r--r--src/H5Ffamily.c678
1 files changed, 371 insertions, 307 deletions
diff --git a/src/H5Ffamily.c b/src/H5Ffamily.c
index 025039c..dba22f1 100644
--- a/src/H5Ffamily.c
+++ b/src/H5Ffamily.c
@@ -1,25 +1,25 @@
/*
* Copyright (C) 1997 Spizella Software
- * All rights reserved.
+ * All rights reserved.
*
* Programmer: Robb Matzke <matzke@llnl.gov>
- * Monday, November 10, 1997
- *
- * Purpose: Implements a family of files that acts as a single hdf5
- * file. The purpose is to be able to split a huge file on a
- * 64-bit platform, transfer all the <2GB members to a 32-bit
- * platform, and then access the entire huge file on the 32-bit
- * platform.
- *
- * All family members are logically the same size although their
- * physical sizes may vary. The logical member size is
- * determined by looking at the physical size of the first
- * member and rounding that up to the next power of two. When
- * creating a file family, the first member is created with a
- * predefined physical size (actually, this happens when the
- * file family is flushed, and can be quite time consuming on
- * file systems that don't implement holes, like nfs).
- *
+ * Monday, November 10, 1997
+ *
+ * Purpose: Implements a family of files that acts as a single hdf5
+ * file. The purpose is to be able to split a huge file on a
+ * 64-bit platform, transfer all the <2GB members to a 32-bit
+ * platform, and then access the entire huge file on the 32-bit
+ * platform.
+ *
+ * All family members are logically the same size although their
+ * physical sizes may vary. The logical member size is
+ * determined by looking at the physical size of the first
+ * member and rounding that up to the next power of two. When
+ * creating a file family, the first member is created with a
+ * predefined physical size (actually, this happens when the
+ * file family is flushed, and can be quite time consuming on
+ * file systems that don't implement holes, like nfs).
+ *
*/
#include <H5private.h>
#include <H5Eprivate.h>
@@ -27,7 +27,7 @@
#include <H5MMprivate.h>
#define PABLO_MASK H5F_family
-static hbool_t interface_initialize_g = FALSE;
+static hbool_t interface_initialize_g = FALSE;
#define INTERFACE_INIT NULL
/*
@@ -38,81 +38,104 @@ static hbool_t interface_initialize_g = FALSE;
* Smaller values result in files of a more manageable size (from a human
* perspective) but also limit the total logical size of the hdf5 file.
*/
-#define H5F_FAM_DFLT_NBITS 26u /*64MB */
-
-#define H5F_FAM_MASK(N) (((uint64)1<<(N))-1)
-#define H5F_FAM_OFFSET(ADDR,N) ((off_t)((ADDR)->offset & H5F_FAM_MASK(N)))
-#define H5F_FAM_MEMBNO(ADDR,N) ((intn)((ADDR)->offset >> N))
-
-static hbool_t H5F_fam_access(const char *name, int mode, H5F_search_t *key);
-static H5F_low_t *H5F_fam_open(const char *name, uintn flags, H5F_search_t *);
-static herr_t H5F_fam_close(H5F_low_t *lf);
-static herr_t H5F_fam_read(H5F_low_t *lf, const haddr_t *addr, size_t size,
- uint8 *buf);
-static herr_t H5F_fam_write(H5F_low_t *lf, const haddr_t *addr, size_t size,
+#define H5F_FAM_DFLT_NBITS 26u /*64MB */
+
+#define H5F_FAM_MASK(N) (((uint64)1<<(N))-1)
+#define H5F_FAM_OFFSET(ADDR,N) ((off_t)((ADDR)->offset & H5F_FAM_MASK(N)))
+#define H5F_FAM_MEMBNO(ADDR,N) ((intn)((ADDR)->offset >> N))
+
+static hbool_t H5F_fam_access(const char *name,
+ const H5F_access_t *access_parms, int mode,
+ H5F_search_t *key/*out*/);
+static H5F_low_t *H5F_fam_open(const char *name,
+ const H5F_access_t *access_parms, uintn flags,
+ H5F_search_t *key/*out*/);
+static herr_t H5F_fam_close(H5F_low_t *lf, const H5F_access_t *access_parms);
+static herr_t H5F_fam_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, uint8 *buf);
+static herr_t H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size,
const uint8 *buf);
-static herr_t H5F_fam_flush(H5F_low_t *lf);
-
-const H5F_low_class_t H5F_LOW_FAM[1] = {{
- H5F_fam_access, /* access method */
- H5F_fam_open, /* open method */
- H5F_fam_close, /* close method */
- H5F_fam_read, /* read method */
- H5F_fam_write, /* write method */
- H5F_fam_flush, /* flush method */
- NULL, /* extend method */
+static herr_t H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms);
+
+const H5F_low_class_t H5F_LOW_FAMILY_g[1] = {{
+ H5F_fam_access, /* access method */
+ H5F_fam_open, /* open method */
+ H5F_fam_close, /* close method */
+ H5F_fam_read, /* read method */
+ H5F_fam_write, /* write method */
+ H5F_fam_flush, /* flush method */
+ NULL, /* extend method */
}};
/*-------------------------------------------------------------------------
- * Function: H5F_fam_open
+ * Function: H5F_fam_open
*
- * Purpose: Opens a file family with the specified base name. The name
- * should contain a printf-style "%d" field which will be
- * expanded with a zero-origin family member number.
+ * Purpose: Opens a file family with the specified base name. The name
+ * should contain a printf-style "%d" field which will be
+ * expanded with a zero-origin family member number.
*
- * Bugs: We don't check for overflow on the name, so keep it under
- * 4kb, please. Also, we don't actually check for the `%d'
- * field because we assume that the caller already did. Who
- * knows what happens when all the family member names are the
- * same!
+ * Bugs: We don't check for overflow on the name, so keep it under
+ * 4kb, please. Also, we don't actually check for the `%d'
+ * field because we assume that the caller already did. Who
+ * knows what happens when all the family member names are the
+ * same!
*
- * Return: Success: Low-level file pointer
+ * Return: Success: Low-level file pointer
*
- * Failure: NULL
+ * Failure: NULL
*
- * Programmer: Robb Matzke
- * Monday, November 10, 1997
+ * Programmer: Robb Matzke
+ * Monday, November 10, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
-static H5F_low_t *
-H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ )
+static H5F_low_t *
+H5F_fam_open(const char *name, const H5F_access_t *access_parms,
+ uintn flags, H5F_search_t *key/*out*/)
{
- H5F_low_t *ret_value = NULL, *lf = NULL;
- H5F_low_t *member = NULL; /*a family member */
- char member_name[4096]; /*name of family member */
- intn membno; /*member number (zero-origin) */
- size_t nbits = H5F_FAM_DFLT_NBITS; /*num bits in an offset */
- haddr_t tmp_addr; /*temporary address */
+ H5F_low_t *ret_value = NULL;
+ H5F_low_t *lf = NULL;
+ H5F_low_t *member = NULL; /*a family member */
+ char member_name[4096]; /*name of family member */
+ intn membno; /*member number (zero-origin) */
+ size_t nbits = H5F_FAM_DFLT_NBITS; /*num bits in an offset */
+ haddr_t tmp_addr; /*temporary address */
+ const H5F_low_class_t *memb_type; /*type of family member */
FUNC_ENTER(H5F_fam_open, NULL);
+ assert (access_parms);
+ assert (H5F_LOW_FAMILY==access_parms->driver);
+
+ /*
+ * Use the default file driver or the specified driver for each of the
+ * family members.
+ */
+ if (access_parms->u.fam.memb_access) {
+ memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
+ } else {
+ memb_type = H5F_low_class (H5F_LOW_DFLT);
+ }
+
/*
* If we're truncating the file then delete all but the first family
- * member. Use the default number of bits for the offset.
+ * member. Use the default number of bits for the offset.
*/
- if ((flags & H5F_ACC_WRITE) && (flags & H5F_ACC_TRUNC)) {
- for (membno = 1; /*void */ ; membno++) {
- sprintf(member_name, name, membno);
- if (!H5F_low_access(H5F_LOW_DFLT, member_name, F_OK, NULL)) {
- break;
- } else if (unlink(member_name) < 0) {
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "can't delete member");
- }
- }
+ if ((flags & H5F_ACC_RDWR) && (flags & H5F_ACC_TRUNC)) {
+ for (membno = 1; /*void*/; membno++) {
+ sprintf(member_name, name, membno);
+ if (!H5F_low_access(memb_type, member_name,
+ access_parms->u.fam.memb_access,
+ F_OK, NULL)) {
+ break;
+ } else if (unlink(member_name) < 0) {
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "can't delete member");
+ }
+ }
}
/* Create the file descriptor */
lf = H5MM_xcalloc(1, sizeof(H5F_low_t));
@@ -120,33 +143,34 @@ H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ )
lf->u.fam.flags = (flags & ~H5F_ACC_CREAT);
/* Open all existing members */
- for (membno = 0; /*void */ ; membno++) {
- sprintf(member_name, name, membno);
-
- /*
- * Open the family member. After the first member is opened or created,
- * turn off the creation flag so we don't create a zillion family
- * members.
- */
- member = H5F_low_open(H5F_LOW_DFLT, member_name, flags,
- 0 == membno ? key : NULL);
- if (!member) {
- if (0 == membno) {
- HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL,
- "can't open first family member");
- }
- break;
- }
- flags &= ~H5F_ACC_CREAT;
-
- /* Add the member to the family */
- if (lf->u.fam.nmemb >= lf->u.fam.nalloc) {
- lf->u.fam.nalloc = MAX(100, 2 * lf->u.fam.nalloc);
- lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb,
- lf->u.fam.nalloc * sizeof(H5F_low_t *));
- }
- lf->u.fam.memb[lf->u.fam.nmemb++] = member;
- member = NULL;
+ for (membno = 0; /*void*/; membno++) {
+ sprintf(member_name, name, membno);
+
+ /*
+ * Open the family member. After the first member is opened or
+ * created, turn off the creation flag so we don't create a zillion
+ * family members.
+ */
+ member = H5F_low_open(memb_type, member_name,
+ access_parms->u.fam.memb_access, flags,
+ 0 == membno ? key : NULL);
+ if (!member) {
+ if (0 == membno) {
+ HGOTO_ERROR(H5E_IO, H5E_CANTOPENFILE, NULL,
+ "can't open first family member");
+ }
+ break;
+ }
+ flags &= ~H5F_ACC_CREAT;
+
+ /* Add the member to the family */
+ if (lf->u.fam.nmemb >= lf->u.fam.nalloc) {
+ lf->u.fam.nalloc = MAX(100, 2 * lf->u.fam.nalloc);
+ lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb,
+ lf->u.fam.nalloc * sizeof(H5F_low_t *));
+ }
+ lf->u.fam.memb[lf->u.fam.nmemb++] = member;
+ member = NULL;
}
/*
@@ -155,32 +179,36 @@ H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ )
* member.
*/
if (lf->u.fam.nmemb >= 2) {
- size_t size = H5F_low_size(lf->u.fam.memb[0], &tmp_addr);
- for (nbits = 8 * sizeof(size_t) - 1; nbits > 0; --nbits) {
- size_t mask = (size_t) 1 << nbits;
- if (size & mask) {
- if (size != mask) {
- size++;
+ size_t size = H5F_low_size(lf->u.fam.memb[0], &tmp_addr);
+ for (nbits=8*sizeof(size_t)-1; nbits>0; --nbits) {
+ size_t mask = (size_t)1 << nbits;
+ if (size & mask) {
+ if (size != mask) {
+ size++;
#ifdef H5F_DEBUG
- fprintf(stderr, "HDF5-DIAG: family member size was rounded up "
- "to a power of 2");
+ fprintf(stderr, "HDF5-DIAG: family member size was rounded up "
+ "to a power of 2");
#endif
- }
- break;
- }
- }
+ }
+ break;
+ }
+ }
}
lf->u.fam.offset_bits = nbits;
#ifdef H5F_DEBUG
if (nbits >= 30) {
- fprintf(stderr, "HDF5-DIAG: family members are %dGB\n", 1 << (nbits - 30));
+ fprintf(stderr, "HDF5-DIAG: family members are %dGB\n",
+ 1 << (nbits-30));
} else if (nbits >= 20) {
- fprintf(stderr, "HDF5-DIAG: family members are %dMB\n", 1 << (nbits - 20));
+ fprintf(stderr, "HDF5-DIAG: family members are %dMB\n",
+ 1 << (nbits-20));
} else if (nbits >= 10) {
- fprintf(stderr, "HDF5-DIAG: family members are %dkB\n", 1 << (nbits - 10));
+ fprintf(stderr, "HDF5-DIAG: family members are %dkB\n",
+ 1 << (nbits-10));
} else {
- fprintf(stderr, "HDF5-DIAG: family members are %d bytes\n", 1 << nbits);
+ fprintf(stderr, "HDF5-DIAG: family members are %d bytes\n",
+ 1 << nbits);
}
#endif
@@ -188,50 +216,51 @@ H5F_fam_open(const char *name, uintn flags, H5F_search_t *key /*out */ )
* Get the total family size and store it in the max_addr field.
*/
assert(lf->u.fam.nmemb >= 1);
- lf->eof.offset = (size_t) 1 << lf->u.fam.offset_bits;
- lf->eof.offset *= (lf->u.fam.nmemb - 1);
- lf->eof.offset += lf->u.fam.memb[lf->u.fam.nmemb - 1]->eof.offset;
+ lf->eof.offset = (size_t)1 << lf->u.fam.offset_bits;
+ lf->eof.offset *= (lf->u.fam.nmemb-1);
+ lf->eof.offset += lf->u.fam.memb[lf->u.fam.nmemb-1]->eof.offset;
HRETURN(lf);
done:
if (!ret_value) {
- if (lf) {
- H5F_fam_close(lf);
- H5MM_xfree(lf);
- }
+ if (lf) {
+ H5F_fam_close(lf, access_parms);
+ H5MM_xfree(lf);
+ }
}
FUNC_LEAVE(ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5F_fam_close
+ * Function: H5F_fam_close
*
- * Purpose: Closes all members of a file family and releases resources
- * used by the file descriptor.
+ * Purpose: Closes all members of a file family and releases resources
+ * used by the file descriptor.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Monday, November 10, 1997
+ * Programmer: Robb Matzke
+ * Monday, November 10, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_fam_close(H5F_low_t *lf)
+H5F_fam_close(H5F_low_t *lf, const H5F_access_t *access_parms)
{
- intn membno;
+ intn membno;
FUNC_ENTER(H5F_fam_close, FAIL);
assert(lf);
for (membno = 0; membno < lf->u.fam.nmemb; membno++) {
- lf->u.fam.memb[membno] = H5F_low_close(lf->u.fam.memb[membno]);
+ lf->u.fam.memb[membno] = H5F_low_close(lf->u.fam.memb[membno],
+ access_parms->u.fam.memb_access);
}
H5MM_xfree(lf->u.fam.memb);
H5MM_xfree(lf->u.fam.name);
@@ -240,36 +269,37 @@ H5F_fam_close(H5F_low_t *lf)
}
/*-------------------------------------------------------------------------
- * Function: H5F_fam_read
+ * Function: H5F_fam_read
*
- * Purpose: Reads a chunk of contiguous data from the file family.
- * Reading past the physical end of a file returns zeros instead
- * of failing. We must insure that if the logical end of file is
- * before the physical end of file that we will read zeros there
- * also (the only time this can happen is if we create a family
- * and then close it before the first member is filled, since
- * flushing the file causes the first member to be physically
- * extended to it's maximum size).
+ * Purpose: Reads a chunk of contiguous data from the file family.
+ * Reading past the physical end of a file returns zeros instead
+ * of failing. We must insure that if the logical end of file is
+ * before the physical end of file that we will read zeros there
+ * also (the only time this can happen is if we create a family
+ * and then close it before the first member is filled, since
+ * flushing the file causes the first member to be physically
+ * extended to it's maximum size).
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Monday, November 10, 1997
+ * Programmer: Robb Matzke
+ * Monday, November 10, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_fam_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf)
+H5F_fam_read(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, uint8 *buf)
{
- size_t nbytes;
- haddr_t cur_addr;
- uintn membno;
- off_t offset;
- size_t member_size;
+ size_t nbytes;
+ haddr_t cur_addr;
+ uintn membno;
+ off_t offset;
+ size_t member_size;
FUNC_ENTER(H5F_fam_read, FAIL);
@@ -283,154 +313,168 @@ H5F_fam_read(H5F_low_t *lf, const haddr_t *addr, size_t size, uint8 *buf)
cur_addr = *addr;
while (size > 0) {
- if (membno >= lf->u.fam.nmemb) {
- HDmemset(buf, 0, size);
- break;
- } else {
- nbytes = MIN(size, member_size - offset);
- cur_addr.offset = offset;
- if (H5F_low_read(lf->u.fam.memb[membno], &cur_addr,
- nbytes, buf) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
- "can't read from family member");
- }
- buf += nbytes;
- size -= nbytes;
- membno++;
- offset = 0;
- }
+ if (membno >= lf->u.fam.nmemb) {
+ HDmemset(buf, 0, size);
+ break;
+ } else {
+ nbytes = MIN(size, member_size - offset);
+ cur_addr.offset = offset;
+ if (H5F_low_read(lf->u.fam.memb[membno],
+ access_parms->u.fam.memb_access,
+ &cur_addr, nbytes, buf) < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
+ "can't read from family member");
+ }
+ buf += nbytes;
+ size -= nbytes;
+ membno++;
+ offset = 0;
+ }
}
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5F_fam_write
+ * Function: H5F_fam_write
*
- * Purpose: Writes BUF to the family of files. The superclass has
- * already insured that we aren't writing past the logical end
- * of file, so this function will extend the physical file to
- * accommodate the new data if necessary.
+ * Purpose: Writes BUF to the family of files. The superclass has
+ * already insured that we aren't writing past the logical end
+ * of file, so this function will extend the physical file to
+ * accommodate the new data if necessary.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Monday, November 10, 1997
+ * Programmer: Robb Matzke
+ * Monday, November 10, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_fam_write(H5F_low_t *lf, const haddr_t *addr, size_t size,
- const uint8 *buf)
+H5F_fam_write(H5F_low_t *lf, const H5F_access_t *access_parms,
+ const haddr_t *addr, size_t size, const uint8 *buf)
{
- size_t nbytes;
- haddr_t cur_addr, max_addr;
- uintn membno;
- off_t offset;
- H5F_low_t *member = NULL;
- char member_name[4096];
- intn i;
- size_t member_size;
-
+ size_t nbytes;
+ haddr_t cur_addr, max_addr;
+ uintn membno;
+ off_t offset;
+ H5F_low_t *member = NULL;
+ char member_name[4096];
+ intn i;
+ size_t member_size;
+ const H5F_low_class_t *memb_type = NULL;
+
FUNC_ENTER(H5F_fam_write, FAIL);
+ /* Check args */
assert(lf);
assert(addr && H5F_addr_defined(addr));
assert(buf);
+ assert (access_parms);
+ assert (H5F_LOW_FAMILY==access_parms->driver);
+ /* Get the member driver */
+ if (access_parms->u.fam.memb_access) {
+ memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
+ } else {
+ memb_type = H5F_low_class (H5F_LOW_DFLT);
+ }
+
member_size = (size_t) 1 << lf->u.fam.offset_bits;
membno = H5F_FAM_MEMBNO(addr, lf->u.fam.offset_bits);
offset = H5F_FAM_OFFSET(addr, lf->u.fam.offset_bits);
cur_addr = *addr;
while (size > 0) {
- nbytes = MIN(size, member_size - offset);
- cur_addr.offset = offset;
-
- if (membno >= lf->u.fam.nmemb) {
- /*
- * We're writing past the end of the last family member--create the
- * new family member(s)
- */
- for (i = lf->u.fam.nmemb; i <= membno; i++) {
- sprintf(member_name, lf->u.fam.name, i);
- member = H5F_low_open(H5F_LOW_DFLT, member_name,
- lf->u.fam.flags | H5F_ACC_CREAT,
- NULL);
- if (!member) {
- HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL,
- "can't create a new member");
- }
- /*
- * For members in the middle, set their logical eof to the
- * maximum possible value.
- */
- if (i < membno) {
- H5F_addr_reset(&max_addr);
- H5F_addr_inc(&max_addr, member_size);
- H5F_low_seteof(member, &max_addr);
- }
- if (lf->u.fam.nmemb >= lf->u.fam.nalloc) {
- lf->u.fam.nalloc *= 2;
- lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb,
- (lf->u.fam.nalloc *
- sizeof(H5F_low_t *)));
- }
- lf->u.fam.memb[lf->u.fam.nmemb++] = member;
- }
- }
- /*
- * Make sure the logical eof is large enough to handle the request.
- */
- max_addr = cur_addr;
- H5F_addr_inc(&max_addr, nbytes);
- H5F_low_seteof(lf->u.fam.memb[membno], &max_addr);
-
- /* Write the data to the member */
- if (H5F_low_write(lf->u.fam.memb[membno], &cur_addr,
- nbytes, buf) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
- "can't write to family member");
- }
- buf += nbytes;
- size -= nbytes;
- membno++;
- offset = 0;
+ nbytes = MIN(size, member_size - offset);
+ cur_addr.offset = offset;
+
+ if (membno >= lf->u.fam.nmemb) {
+ /*
+ * We're writing past the end of the last family member--create the
+ * new family member(s)
+ */
+ for (i = lf->u.fam.nmemb; i <= membno; i++) {
+ sprintf(member_name, lf->u.fam.name, i);
+ member = H5F_low_open(memb_type, member_name,
+ access_parms->u.fam.memb_access,
+ lf->u.fam.flags | H5F_ACC_CREAT,
+ NULL);
+ if (!member) {
+ HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL,
+ "can't create a new member");
+ }
+ /*
+ * For members in the middle, set their logical eof to the
+ * maximum possible value.
+ */
+ if (i < membno) {
+ H5F_addr_reset(&max_addr);
+ H5F_addr_inc(&max_addr, member_size);
+ H5F_low_seteof(member, &max_addr);
+ }
+ if (lf->u.fam.nmemb >= lf->u.fam.nalloc) {
+ lf->u.fam.nalloc *= 2;
+ lf->u.fam.memb = H5MM_xrealloc(lf->u.fam.memb,
+ (lf->u.fam.nalloc *
+ sizeof(H5F_low_t *)));
+ }
+ lf->u.fam.memb[lf->u.fam.nmemb++] = member;
+ }
+ }
+ /*
+ * Make sure the logical eof is large enough to handle the request.
+ */
+ max_addr = cur_addr;
+ H5F_addr_inc(&max_addr, nbytes);
+ H5F_low_seteof(lf->u.fam.memb[membno], &max_addr);
+
+ /* Write the data to the member */
+ if (H5F_low_write(lf->u.fam.memb[membno],
+ access_parms->u.fam.memb_access,
+ &cur_addr, nbytes, buf) < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
+ "can't write to family member");
+ }
+ buf += nbytes;
+ size -= nbytes;
+ membno++;
+ offset = 0;
}
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5F_fam_flush
+ * Function: H5F_fam_flush
*
- * Purpose: Flushes all data to disk and makes sure that the first member
- * is as large as a member can be so we can accurately detect
- * the member size if we open this file for read access at a
- * later date.
+ * Purpose: Flushes all data to disk and makes sure that the first member
+ * is as large as a member can be so we can accurately detect
+ * the member size if we open this file for read access at a
+ * later date.
*
- * Return: Success: SUCCEED
+ * Return: Success: SUCCEED
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Monday, November 10, 1997
+ * Programmer: Robb Matzke
+ * Monday, November 10, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_fam_flush(H5F_low_t *lf)
+H5F_fam_flush(H5F_low_t *lf, const H5F_access_t *access_parms)
{
- int membno, nerrors = 0;
- uint8 buf[1];
- haddr_t addr1, addr2, addr3;
- size_t max_offset;
+ int membno, nerrors = 0;
+ uint8 buf[1];
+ haddr_t addr1, addr2, addr3;
+ size_t max_offset;
FUNC_ENTER(H5F_fam_flush, FAIL);
@@ -444,98 +488,118 @@ H5F_fam_flush(H5F_low_t *lf)
max_offset = H5F_FAM_MASK(lf->u.fam.offset_bits);
H5F_addr_reset(&addr1);
H5F_addr_inc(&addr1, max_offset);
- H5F_low_size(lf->u.fam.memb[0], &addr2); /*remember logical eof */
+ H5F_low_size(lf->u.fam.memb[0], &addr2); /*remember logical eof */
addr3 = addr1;
H5F_addr_inc(&addr3, (size_t) 1);
- H5F_low_seteof(lf->u.fam.memb[0], &addr3); /*prevent a warning */
- if (H5F_low_read(lf->u.fam.memb[0], &addr1, 1, buf) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
- "can't read from first family member");
+ H5F_low_seteof(lf->u.fam.memb[0], &addr3); /*prevent a warning */
+ if (H5F_low_read(lf->u.fam.memb[0], access_parms->u.fam.memb_access,
+ &addr1, 1, buf) < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL,
+ "can't read from first family member");
}
- if (H5F_low_write(lf->u.fam.memb[0], &addr1, 1, buf) < 0) {
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
- "can't write to first family member");
+ if (H5F_low_write(lf->u.fam.memb[0], access_parms->u.fam.memb_access,
+ &addr1, 1, buf) < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
+ "can't write to first family member");
}
- H5F_low_seteof(lf->u.fam.memb[0], &addr2); /*reset old eof */
+ H5F_low_seteof(lf->u.fam.memb[0], &addr2); /*reset old eof */
/*
- * Flush each member file. Don't return an error status until we've
+ * Flush each member file. Don't return an error status until we've
* flushed as much as possible.
*/
for (membno = 0; membno < lf->u.fam.nmemb; membno++) {
- if (H5F_low_flush(lf->u.fam.memb[membno]) < 0) {
- nerrors++;
- }
+ if (H5F_low_flush(lf->u.fam.memb[membno],
+ access_parms->u.fam.memb_access) < 0) {
+ nerrors++;
+ }
}
if (nerrors) {
- HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
- "can't flush family member");
+ HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,
+ "can't flush family member");
}
FUNC_LEAVE(SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5F_fam_access
+ * Function: H5F_fam_access
*
- * Purpose: Determines if all members of the file family can be accessed
- * and returns the key for the first member of the family.
+ * Purpose: Determines if all members of the file family can be accessed
+ * and returns the key for the first member of the family.
*
- * Return: Success: TRUE or FALSE
+ * Return: Success: TRUE or FALSE
*
- * Failure: FAIL
+ * Failure: FAIL
*
- * Programmer: Robb Matzke
- * Monday, November 10, 1997
+ * Programmer: Robb Matzke
+ * Monday, November 10, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static hbool_t
-H5F_fam_access(const char *name, int mode, H5F_search_t *key /*out */ )
+H5F_fam_access(const char *name, const H5F_access_t *access_parms,
+ int mode, H5F_search_t *key/*out*/)
{
- intn membno;
- char member_name[4096];
- hbool_t status;
- hbool_t ret_value = FALSE;
+ intn membno;
+ char member_name[4096];
+ hbool_t status;
+ hbool_t ret_value = FALSE;
+ const H5F_low_class_t *memb_type = NULL;
FUNC_ENTER(H5F_fam_access, FAIL);
+ /* Check args */
+ assert (name && *name);
+ assert (access_parms);
+ assert (H5F_LOW_FAMILY==access_parms->driver);
+
+ /* Get the driver for the family members */
+ if (access_parms->u.fam.memb_access) {
+ memb_type = H5F_low_class (access_parms->u.fam.memb_access->driver);
+ } else {
+ memb_type = H5F_low_class (H5F_LOW_DFLT);
+ }
+
+ /* Access the members */
for (membno=0; /*void*/; membno++) {
- sprintf(member_name, name, membno);
- status = H5F_low_access(H5F_LOW_DFLT, member_name, mode,
- 0 == membno ? key : NULL);
-
- if (!status) {
- if (F_OK == mode) {
- /*
- * If we didn't find a member then we must have gotten to the end
- * of the family. As long as we found the first member(s) the
- * family exists.
- */
- ret_value = membno > 0 ? TRUE : FALSE;
+ sprintf(member_name, name, membno);
+ status = H5F_low_access(memb_type, member_name, NULL, mode,
+ 0 == membno ? key : NULL);
+
+ if (!status) {
+ if (F_OK == mode) {
+ /*
+ * If we didn't find a member then we must have gotten to the
+ * end of the family. As long as we found the first
+ * member(s) the family exists.
+ */
+ ret_value = membno > 0 ? TRUE : FALSE;
break;
- } else if (H5F_low_access(H5F_LOW_DFLT, member_name, F_OK, NULL)) {
- /*
- * The file exists but didn't have the write access permissions.
- */
+ } else if (H5F_low_access(memb_type, member_name,
+ access_parms->u.fam.memb_access,
+ F_OK, NULL)) {
+ /*
+ * The file exists but didn't have the write access permissions.
+ */
ret_value = FALSE;
break;
- } else {
- /*
- * The file doesn't exist because we got to the end of the
- * family.
- */
+ } else {
+ /*
+ * The file doesn't exist because we got to the end of the
+ * family.
+ */
ret_value = TRUE;
break;
- }
- }
- if (status < 0) {
- HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL,
- "access method failed for a member file");
- }
+ }
+ }
+ if (status < 0) {
+ HRETURN_ERROR(H5E_IO, H5E_CANTOPENFILE, FAIL,
+ "access method failed for a member file");
+ }
}
FUNC_LEAVE(ret_value);