From ce7f9328b67687756afa530885659bc2ced77539 Mon Sep 17 00:00:00 2001 From: Raymond Lu Date: Thu, 30 Nov 2006 15:49:01 -0500 Subject: [svn-r13001] Enabled CORE file driver to read or write an existing file depending the setting of backing store through H5Pset_core_fapl and file open flag. Added test cases in vfd.c. --- src/H5FDcore.c | 63 +++++++++++++++++++++++---- test/vfd.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+), 9 deletions(-) diff --git a/src/H5FDcore.c b/src/H5FDcore.c index cbbda53..b27949b 100644 --- a/src/H5FDcore.c +++ b/src/H5FDcore.c @@ -49,6 +49,7 @@ typedef struct H5FD_core_t { haddr_t eoa; /*end of allocated region */ haddr_t eof; /*current allocated size */ size_t increment; /*multiples for mem allocation */ + hbool_t backing_store; /*write to file name on flush */ int fd; /*backing store file descriptor */ hbool_t dirty; /*changes not saved? */ } H5FD_core_t; @@ -368,23 +369,29 @@ done: * Modifications: * Robb Matzke, 1999-10-19 * The backing store file is created and opened if specified. + * + * Raymond Lu, 2006-11-30 + * Enabled the driver to read an existing file depending on + * the setting of the backing_store and file open flags. *------------------------------------------------------------------------- */ static H5FD_t * -H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id, +H5FD_core_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { + int o_flags; H5FD_core_t *file=NULL; H5FD_core_fapl_t *fa=NULL; H5P_genplist_t *plist; /* Property list pointer */ + h5_stat_t sb; int fd=-1; H5FD_t *ret_value; FUNC_ENTER_NOAPI(H5FD_core_open, NULL) /* Check arguments */ - if (!(H5F_ACC_CREAT & flags)) - HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, NULL, "must create core files, not open them") + if (!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name") if (0==maxaddr || HADDR_UNDEF==maxaddr) HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr") if (ADDR_OVERFLOW(maxaddr)) @@ -395,10 +402,18 @@ H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id, fa = H5P_get_driver_info(plist); } /* end if */ - /* Open backing store */ - if (fa && fa->backing_store && name && - (fd=HDopen(name, (O_CREAT|O_TRUNC|O_RDWR), 0666))<0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open backing store") + /* Build the open flags */ + o_flags = (H5F_ACC_RDWR & flags) ? O_RDWR : O_RDONLY; + if (H5F_ACC_TRUNC & flags) o_flags |= O_TRUNC; + if (H5F_ACC_CREAT & flags) o_flags |= O_CREAT; + if (H5F_ACC_EXCL & flags) o_flags |= O_EXCL; + + /* Open backing store. The only case that backing store is off is when + * the backing_store flag is off and H5F_ACC_CREAT is on. */ + if(fa->backing_store || !(H5F_ACC_CREAT & flags)) { + if (fa && (fd=HDopen(name, o_flags, 0666))<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") + } /* Create the new file struct */ if (NULL==(file=H5MM_calloc(sizeof(H5FD_core_t)))) @@ -414,6 +429,34 @@ H5FD_core_open(const char *name, unsigned UNUSED flags, hid_t fapl_id, */ file->increment = (fa && fa->increment>0) ? fa->increment : H5FD_CORE_INCREMENT; + /* If save data in backing store. */ + file->backing_store = fa->backing_store; + + /* If an existing file is opened, load the whole file into memory. */ + if(!(H5F_ACC_CREAT & flags)) { + unsigned char *x; + size_t size; + + if (HDfstat(file->fd, &sb)<0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") + + size = (size_t)sb.st_size; + + if(size) { + if (NULL==file->mem) + x = (unsigned char*)H5MM_malloc(size); + + if (!x) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory block") + + file->mem = x; + file->eof = size; + + if(HDread(file->fd, file->mem, size)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read file") + } + } + /* Set return value */ ret_value=(H5FD_t *)file; @@ -808,7 +851,9 @@ done: * Friday, October 15, 1999 * * Modifications: - * + * Raymond Lu, 2006-11-30 + * Added a condition check for backing store flag, for an + * existing file can be opened for read and write now. *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -821,7 +866,7 @@ H5FD_core_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) FUNC_ENTER_NOAPI(H5FD_core_flush, FAIL) /* Write to backing store */ - if (file->dirty && file->fd>=0) { + if (file->dirty && file->fd>=0 && file->backing_store) { haddr_t size = file->eof; unsigned char *ptr = file->mem; diff --git a/test/vfd.c b/test/vfd.c index c8b67f7..21d022c 100644 --- a/test/vfd.c +++ b/test/vfd.c @@ -365,6 +365,10 @@ test_core(void) char filename[1024]; void *fhandle=NULL; hsize_t file_size; + int *points, *check, *p1, *p2; + hid_t dset1=-1, space1=-1; + hsize_t dims1[2]; + int i, j, n; TESTING("CORE file driver"); @@ -405,7 +409,138 @@ test_core(void) if(H5Fclose(file)<0) TEST_ERROR; + + + /* Open the file with backing store off for read and write. + * Changes won't be saved in file. */ + if(H5Pset_fapl_core(fapl, CORE_INCREMENT, FALSE)<0) + TEST_ERROR; + + if((file=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) + TEST_ERROR; + + /* Allocate memory for data set. */ + points=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int)); + check=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int)); + + /* Initialize the dset1 */ + p1 = points; + for (i = n = 0; i < DSET1_DIM1; i++) + for (j = 0; j < DSET1_DIM2; j++) + *p1++ = n++; + + /* Create the data space1 */ + dims1[0] = DSET1_DIM1; + dims1[1] = DSET1_DIM2; + if ((space1 = H5Screate_simple(2, dims1, NULL))<0) + TEST_ERROR; + + /* Create the dset1 */ + if ((dset1 = H5Dcreate(file, DSET1_NAME, H5T_NATIVE_INT, space1, H5P_DEFAULT))<0) + TEST_ERROR; + + /* Write the data to the dset1 */ + if (H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points)<0) + TEST_ERROR; + + if(H5Dclose(dset1)<0) + TEST_ERROR; + + if((dset1=H5Dopen(file, DSET1_NAME))<0) + TEST_ERROR; + + /* Read the data back from dset1 */ + if (H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, check)<0) + TEST_ERROR; + + /* Check that the values read are the same as the values written */ + p1 = points; + p2 = check; + for (i = 0; i < DSET1_DIM1; i++) { + for (j = 0; j < DSET1_DIM2; j++) { + if (*p1++ != *p2++) { + H5_FAILED(); + printf(" Read different values than written in data set 1.\n"); + printf(" At index %d,%d\n", i, j); + TEST_ERROR; + } + } + } + + if(H5Dclose(dset1)<0) + TEST_ERROR; + + if(H5Fclose(file)<0) + TEST_ERROR; + + /* Open the file with backing store on for read and write. + * Changes will be saved in file. */ + if(H5Pset_fapl_core(fapl, CORE_INCREMENT, TRUE)<0) + TEST_ERROR; + + if((file=H5Fopen(filename, H5F_ACC_RDWR, fapl))<0) + TEST_ERROR; + + /* Create the dset1 */ + if ((dset1 = H5Dcreate(file, DSET1_NAME, H5T_NATIVE_INT, space1, H5P_DEFAULT))<0) + TEST_ERROR; + + /* Write the data to the dset1 */ + if (H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, points)<0) + TEST_ERROR; + + if(H5Dclose(dset1)<0) + TEST_ERROR; + + if((dset1=H5Dopen(file, DSET1_NAME))<0) + TEST_ERROR; + + /* Reallocate memory for reading buffer. */ + if(check) + free(check); + + check=(int*)malloc(DSET1_DIM1*DSET1_DIM2*sizeof(int)); + + /* Read the data back from dset1 */ + if (H5Dread(dset1, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, check)<0) + TEST_ERROR; + + /* Check that the values read are the same as the values written */ + p1 = points; + p2 = check; + for (i = 0; i < DSET1_DIM1; i++) { + for (j = 0; j < DSET1_DIM2; j++) { + if (*p1++ != *p2++) { + H5_FAILED(); + printf(" Read different values than written in data set 1.\n"); + printf(" At index %d,%d\n", i, j); + TEST_ERROR; + } + } + } + + /* Check file size API */ + if(H5Fget_filesize(file, &file_size) < 0) + TEST_ERROR; + + /* There is no garantee the size of metadata in file is constant. + * Just try to check if it's reasonable. */ + if(file_size<64*KB || file_size>256*KB) + TEST_ERROR; + + if(H5Sclose(space1)<0) + TEST_ERROR; + if(H5Dclose(dset1)<0) + TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR; + if(points) + free(points); + if(check) + free(check); + h5_cleanup(FILENAME, fapl); + PASSED(); return 0; -- cgit v0.12