diff options
author | Vailin Choi <vchoi@hdfgroup.org> | 2015-06-26 18:44:27 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@hdfgroup.org> | 2015-06-26 18:44:27 (GMT) |
commit | 130e77f4fa8044b2e2e06cf18b74ed8f8c64665a (patch) | |
tree | 0aaac762383218a930bc513108de585225eb6cf9 /hl | |
parent | 39b99473ea6e83aa394779a591eeef55fe141487 (diff) | |
download | hdf5-130e77f4fa8044b2e2e06cf18b74ed8f8c64665a.zip hdf5-130e77f4fa8044b2e2e06cf18b74ed8f8c64665a.tar.gz hdf5-130e77f4fa8044b2e2e06cf18b74ed8f8c64665a.tar.bz2 |
[svn-r27288] Bring revision #24622 from revise_chksum_retry branch to revise_chunks. h5committested.
#test-p fails but will be fixed with merges later: #26569 (revise_chksum_retry) + v3 metadata cache #27237 (trunk).
Diffstat (limited to 'hl')
-rw-r--r-- | hl/src/H5DO.c | 203 | ||||
-rw-r--r-- | hl/src/H5DOpublic.h | 7 | ||||
-rw-r--r-- | hl/src/H5HLprivate2.h | 91 | ||||
-rw-r--r-- | hl/src/H5LD.c | 2 | ||||
-rw-r--r-- | hl/test/Makefile.am | 8 | ||||
-rw-r--r-- | hl/test/Makefile.in | 82 | ||||
-rw-r--r-- | hl/test/gen_test_ld.c | 14 | ||||
-rw-r--r-- | hl/test/ld_extend.c | 151 | ||||
-rw-r--r-- | hl/test/ld_monitor.c | 190 | ||||
-rw-r--r-- | hl/test/ld_mx.c | 353 | ||||
-rw-r--r-- | hl/test/test_dset_append.c | 1198 | ||||
-rw-r--r-- | hl/test/test_file_image.c | 40 | ||||
-rw-r--r-- | hl/test/test_ld.h5 | bin | 28336 -> 42955 bytes | |||
-rw-r--r-- | hl/test/test_ld.sh.in | 46 | ||||
-rw-r--r-- | hl/test/test_table_be.h5 | bin | 55912 -> 55912 bytes | |||
-rw-r--r-- | hl/test/test_table_cray.h5 | bin | 55912 -> 55912 bytes | |||
-rw-r--r-- | hl/test/test_table_le.h5 | bin | 53880 -> 53880 bytes | |||
-rw-r--r-- | hl/tools/h5watch/h5watch.c | 2 | ||||
-rw-r--r-- | hl/tools/h5watch/testh5watch.sh.in | 2 |
19 files changed, 1894 insertions, 495 deletions
diff --git a/hl/src/H5DO.c b/hl/src/H5DO.c index 99dbd93..b6c2328 100644 --- a/hl/src/H5DO.c +++ b/hl/src/H5DO.c @@ -97,3 +97,206 @@ done: return(ret_value); } /* end H5DOwrite_chunk() */ + +/* + * Function: H5DOappend() + * + * Purpose: To append elements to a dataset. + * axis: the dataset dimension (zero-based) for the append + * extension: the # of elements to append for the axis-th dimension + * memtype: the datatype + * buf: buffer with data for the append + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Jan 2014 + * + * Note: + * This routine is copied from the fast forward feature branch: features/hdf5_ff + * src/H5FF.c:H5DOappend() with the following modifications: + * 1) Remove and replace macro calls such as + * FUNC_ENTER_API, H5TRACE, HGOTO_ERROR + * accordingly because hl does not have these macros + * 2) Replace H5I_get_type() by H5Iget_type() + * 3) Replace H5P_isa_class() by H5Pisa_class() + * 4) Fix a bug in the following: replace extension by size[axis] + * if(extension < old_size) { + * ret_value = FAIL; + * goto done; + * } + */ +herr_t +H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, + hid_t memtype, const void *buf) +{ + + hsize_t size[H5S_MAX_RANK]; /* The new size (after extension */ + hsize_t old_size=0; /* The size of the dimension to be extended */ + int ndims, i; /* Number of dimensions in dataspace */ + hid_t space_id = FAIL; /* Old file space */ + hid_t new_space_id = FAIL; /* New file space (after extension) */ + hid_t mem_space_id = FAIL; /* Memory space for data buffer */ + hsize_t nelmts; /* Number of elements in selection */ + hid_t dapl = FAIL; /* Dataset access property list */ + + hsize_t start[H5S_MAX_RANK]; /* H5Sselect_Hyperslab: starting offset */ + hsize_t count[H5S_MAX_RANK]; /* H5Sselect_hyperslab: # of blocks to select */ + hsize_t stride[H5S_MAX_RANK]; /* H5Sselect_hyperslab: # of elements to move when selecting */ + hsize_t block[H5S_MAX_RANK]; /* H5Sselect_hyperslab: # of elements in a block */ + + hsize_t *boundary = NULL; /* Boundary set in append flush property */ + H5D_append_cb_t append_cb; /* Callback function set in append flush property */ + void *udata; /* User data set in append flush property */ + hbool_t hit = FALSE; /* Boundary is hit or not */ + hsize_t k; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + /* check arguments */ + if(H5I_DATASET != H5Iget_type(dset_id)) { + ret_value = FAIL; + goto done; + } + + /* Get the default dataset transfer property list if the user didn't provide one */ + if(H5P_DEFAULT == dxpl_id) + dxpl_id = H5P_DATASET_XFER_DEFAULT; + else + if(TRUE != H5Pisa_class(dxpl_id, H5P_DATASET_XFER)) { + ret_value = FAIL; + goto done; + } + + /* Get the dataspace of the dataset */ + if(FAIL == (space_id = H5Dget_space(dset_id))) { + ret_value = FAIL; + goto done; + } + + /* Get the rank of this dataspace */ + if((ndims = H5Sget_simple_extent_ndims(space_id)) < 0) { + ret_value = FAIL; + goto done; + } + + /* Verify correct axis */ + if((int)axis >= ndims) { + ret_value = FAIL; + goto done; + } + + /* Get the dimensions sizes of the dataspace */ + if(H5Sget_simple_extent_dims(space_id, size, NULL) < 0) { + ret_value = FAIL; + goto done; + } + + /* Adjust the dimension size of the requested dimension, + but first record the old dimension size */ + old_size = size[axis]; + size[axis] += extension; + if(size[axis] < old_size) { + ret_value = FAIL; + goto done; + } + + /* Set the extent of the dataset to the new dimension */ + if(H5Dset_extent(dset_id, size) < 0) { + ret_value = FAIL; + goto done; + } + + /* Get the new dataspace of the dataset */ + if(FAIL == (new_space_id = H5Dget_space(dset_id))) { + ret_value = FAIL; + goto done; + } + + /* Select a hyperslab corresponding to the append operation */ + for(i=0 ; i<ndims ; i++) { + start[i] = 0; + stride[i] = 1; + count[i] = size[i]; + block[i] = 1; + if(i == (int)axis) { + count[i] = extension; + start[i] = old_size; + } + } + if(FAIL == H5Sselect_hyperslab(new_space_id, H5S_SELECT_SET, start, stride, count, block)) { + ret_value = FAIL; + goto done; + } + + /* The # of elemnts in the new extended dataspace */ + nelmts = H5Sget_select_npoints(new_space_id); + + /* create a memory space */ + mem_space_id = H5Screate_simple(1, &nelmts, NULL); + + /* Write the data */ + if(H5Dwrite(dset_id, memtype, mem_space_id, new_space_id, dxpl_id, buf) < 0) { + ret_value = FAIL; + goto done; + } + + /* Obtain the dataset's access property list */ + if((dapl = H5Dget_access_plist(dset_id)) < 0) { + ret_value = FAIL; + goto done; + } + + /* Allocate the boundary array */ + boundary = (hsize_t *)HDmalloc(ndims * sizeof(hsize_t)); + + /* Retrieve the append flush property */ + if(H5Pget_append_flush(dapl, ndims, boundary, &append_cb, &udata) < 0) { + ret_value = FAIL; + goto done; + } + + /* No boundary for this axis */ + if(boundary[axis] == 0) + goto done; + + /* Determine whether a boundary is hit or not */ + for(k = start[axis]; k < size[axis]; k++) + if(!((k + 1) % boundary[axis])) { + hit = TRUE; + break; + } + + if(hit) { /* Hit the boundary */ + /* Invoke callback if there is one */ + if(append_cb && append_cb(dset_id, size, udata) < 0) { + ret_value = FAIL; + goto done; + } + /* Does a dataset flush */ + if(H5Dflush(dset_id) < 0) { + ret_value = FAIL; + goto done; + } + } + +done: + /* Close old dataspace */ + if(space_id != FAIL && H5Sclose(space_id) < 0) + ret_value = FAIL; + + /* Close new dataspace */ + if(new_space_id != FAIL && H5Sclose(new_space_id) < 0) + ret_value = FAIL; + + /* Close memory dataspace */ + if(mem_space_id != FAIL && H5Sclose(mem_space_id) < 0) + ret_value = FAIL; + + /* Close the dataset access property list */ + if(dapl != FAIL && H5Pclose(dapl) < 0) + ret_value = FAIL; + + if(boundary) + HDfree(boundary); + + return ret_value; +} /* H5DOappend() */ diff --git a/hl/src/H5DOpublic.h b/hl/src/H5DOpublic.h index 774709e..34facc6 100644 --- a/hl/src/H5DOpublic.h +++ b/hl/src/H5DOpublic.h @@ -22,7 +22,7 @@ extern "C" { /*------------------------------------------------------------------------- * - * Direct chunk write function + * Direct chunk write function, Dataset append operation * *------------------------------------------------------------------------- */ @@ -34,6 +34,11 @@ H5_HLDLL herr_t H5DOwrite_chunk(hid_t dset_id, size_t data_size, const void *buf); +herr_t +H5DOappend(hid_t dset_id, hid_t dxpl_id, unsigned axis, size_t extension, + hid_t memtype, const void *buf); + + #ifdef __cplusplus } #endif diff --git a/hl/src/H5HLprivate2.h b/hl/src/H5HLprivate2.h index b7a9362..1b67c70 100644 --- a/hl/src/H5HLprivate2.h +++ b/hl/src/H5HLprivate2.h @@ -25,96 +25,5 @@ /* HDF5 private functions */ #include "H5private.h" -/* - * Status return values for the `herr_t' type. - * Since some unix/c routines use 0 and -1 (or more precisely, non-negative - * vs. negative) as their return code, and some assumption had been made in - * the code about that, it is important to keep these constants the same - * values. When checking the success or failure of an integer-valued - * function, remember to compare against zero and not one of these two - * values. - */ -#define SUCCEED 0 -#define FAIL (-1) -#define UFAIL (unsigned)(-1) - -/* minimum of two, three, or four values */ -#undef MIN -#define MIN(a,b) (((a)<(b)) ? (a) : (b)) -#define MIN2(a,b) MIN(a,b) -#define MIN3(a,b,c) MIN(a,MIN(b,c)) -#define MIN4(a,b,c,d) MIN(MIN(a,b),MIN(c,d)) - -/* maximum of two, three, or four values */ -#undef MAX -#define MAX(a,b) (((a)>(b)) ? (a) : (b)) -#define MAX2(a,b) MAX(a,b) -#define MAX3(a,b,c) MAX(a,MAX(b,c)) -#define MAX4(a,b,c,d) MAX(MAX(a,b),MAX(c,d)) - -/* - * HDF Boolean type. - */ -#ifndef FALSE -# define FALSE 0 -#endif -#ifndef TRUE -# define TRUE 1 -#endif -#ifndef HDassert - #define HDassert(X) assert(X) -#endif /* HDassert */ -#ifndef HDcalloc - #define HDcalloc(N,Z) calloc(N,Z) -#endif /* HDcalloc */ -#ifndef HDfflush - #define HDfflush(F) fflush(F) -#endif /* HDfflush */ -H5_DLL int HDfprintf (FILE *stream, const char *fmt, ...); -#ifndef HDfree - #define HDfree(M) free(M) -#endif /* HDfree */ -#ifndef HDmemcpy - #define HDmemcpy(X,Y,Z) memcpy((char*)(X),(const char*)(Y),Z) -#endif /* HDmemcpy */ -#ifndef HDmemset - #define HDmemset(X,C,Z) memset(X,C,Z) -#endif /* HDmemset */ -#ifndef HDrealloc - #define HDrealloc(M,Z) realloc(M,Z) -#endif /* HDrealloc */ -#ifndef HDsleep - #define HDsleep(N) sleep(N) -#endif /* HDsleep */ -#ifndef HDstrcat - #define HDstrcat(X,Y) strcat(X,Y) -#endif /* HDstrcat */ -#ifndef HDstrcmp - #define HDstrcmp(X,Y) strcmp(X,Y) -#endif /* HDstrcmp */ -#ifndef HDstrlen - #define HDstrlen(S) strlen(S) -#endif /* HDstrlen */ -#ifndef HDstrrchr - #define HDstrrchr(S,C) strrchr(S,C) -#endif /* HDstrrchr */ -#ifndef HDstrtod - #define HDstrtod(S,R) strtod(S,R) -#endif /* HDstrtod */ -#ifndef HDstrtol - #define HDstrtol(S,R,N) strtol(S,R,N) -#endif /* HDstrtol */ -/* - * And now for a couple non-Posix functions... Watch out for systems that - * define these in terms of macros. - */ -#if !defined strdup && !defined H5_HAVE_STRDUP -extern char *strdup(const char *s); -#endif - -#ifndef HDstrdup - #define HDstrdup(S) strdup(S) -#endif /* HDstrdup */ - #endif /* _H5HLprivate2_H */ diff --git a/hl/src/H5LD.c b/hl/src/H5LD.c index cd748c5..df81b11 100644 --- a/hl/src/H5LD.c +++ b/hl/src/H5LD.c @@ -184,7 +184,7 @@ H5LD_construct_vector(char *fields, H5LD_memb_t *listv[]/*OUT*/, hid_t par_tid) len = HDstrlen(fields_ptr)/2 + 2; /* Allocate memory for an H5LD_memb_t for storing a field's info */ - if((memb = (H5LD_memb_t *)HDcalloc(1, sizeof(H5LD_memb_t))) == NULL) { + if((memb = (H5LD_memb_t *)HDcalloc((size_t)1, sizeof(H5LD_memb_t))) == NULL) { ret_value = FAIL; break; } diff --git a/hl/test/Makefile.am b/hl/test/Makefile.am index b933c44..7e6a8e9 100644 --- a/hl/test/Makefile.am +++ b/hl/test/Makefile.am @@ -26,16 +26,16 @@ AM_CPPFLAGS+=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top_b # Test script TEST_SCRIPT = test_ld.sh check_SCRIPTS = $(TEST_SCRIPT) -SCRIPT_DEPEND = ld_monitor$(EXEEXT) ld_extend$(EXEEXT) +SCRIPT_DEPEND = ld_mx$(EXEEXT) # The tests depend on the hdf5, hdf5 test, and hdf5_hl libraries LDADD=$(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) # Test programs. These are our main targets. They should be listed in the # order to be executed, generally most specific tests to least specific tests. -TEST_PROG=test_lite test_image test_file_image test_table test_ds test_packet test_dset_opt - test_ld -check_PROGRAMS=$(TEST_PROG) ld_monitor ld_extend +TEST_PROG=test_lite test_image test_file_image test_table test_ds test_packet test_dset_opt \ + test_ld test_dset_append +check_PROGRAMS=$(TEST_PROG) ld_mx # These programs generate test files for the tests. They don't need to be # compiled every time we want to test the library. However, putting diff --git a/hl/test/Makefile.in b/hl/test/Makefile.in index 7a5df10..23aab728 100644 --- a/hl/test/Makefile.in +++ b/hl/test/Makefile.in @@ -102,8 +102,7 @@ DIST_COMMON = $(top_srcdir)/config/commence.am \ $(srcdir)/H5srcdir_str.h.in $(srcdir)/test_ld.sh.in \ $(top_srcdir)/bin/depcomp $(top_srcdir)/bin/test-driver \ COPYING -check_PROGRAMS = $(am__EXEEXT_1) ld_monitor$(EXEEXT) \ - ld_extend$(EXEEXT) +check_PROGRAMS = $(am__EXEEXT_1) ld_mx$(EXEEXT) @BUILD_ALL_CONDITIONAL_TRUE@noinst_PROGRAMS = $(am__EXEEXT_2) TESTS = $(am__EXEEXT_1) $(TEST_SCRIPT) subdir = hl/test @@ -118,7 +117,8 @@ CONFIG_CLEAN_FILES = H5srcdir_str.h test_ld.sh CONFIG_CLEAN_VPATH_FILES = am__EXEEXT_1 = test_lite$(EXEEXT) test_image$(EXEEXT) \ test_file_image$(EXEEXT) test_table$(EXEEXT) test_ds$(EXEEXT) \ - test_packet$(EXEEXT) test_dset_opt$(EXEEXT) + test_packet$(EXEEXT) test_dset_opt$(EXEEXT) test_ld$(EXEEXT) \ + test_dset_append$(EXEEXT) am__EXEEXT_2 = gen_test_ds$(EXEEXT) gen_test_ld$(EXEEXT) PROGRAMS = $(noinst_PROGRAMS) gen_test_ds_SOURCES = gen_test_ds.c @@ -133,18 +133,18 @@ gen_test_ld_SOURCES = gen_test_ld.c gen_test_ld_OBJECTS = gen_test_ld.$(OBJEXT) gen_test_ld_LDADD = $(LDADD) gen_test_ld_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) -ld_extend_SOURCES = ld_extend.c -ld_extend_OBJECTS = ld_extend.$(OBJEXT) -ld_extend_LDADD = $(LDADD) -ld_extend_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) -ld_monitor_SOURCES = ld_monitor.c -ld_monitor_OBJECTS = ld_monitor.$(OBJEXT) -ld_monitor_LDADD = $(LDADD) -ld_monitor_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) +ld_mx_SOURCES = ld_mx.c +ld_mx_OBJECTS = ld_mx.$(OBJEXT) +ld_mx_LDADD = $(LDADD) +ld_mx_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) test_ds_SOURCES = test_ds.c test_ds_OBJECTS = test_ds.$(OBJEXT) test_ds_LDADD = $(LDADD) test_ds_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) +test_dset_append_SOURCES = test_dset_append.c +test_dset_append_OBJECTS = test_dset_append.$(OBJEXT) +test_dset_append_LDADD = $(LDADD) +test_dset_append_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) test_dset_opt_SOURCES = test_dset_opt.c test_dset_opt_OBJECTS = test_dset_opt.$(OBJEXT) test_dset_opt_LDADD = $(LDADD) @@ -157,6 +157,10 @@ test_image_SOURCES = test_image.c test_image_OBJECTS = test_image.$(OBJEXT) test_image_LDADD = $(LDADD) test_image_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) +test_ld_SOURCES = test_ld.c +test_ld_OBJECTS = test_ld.$(OBJEXT) +test_ld_LDADD = $(LDADD) +test_ld_DEPENDENCIES = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) test_lite_SOURCES = test_lite.c test_lite_OBJECTS = test_lite.$(OBJEXT) test_lite_LDADD = $(LDADD) @@ -203,12 +207,12 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = -SOURCES = gen_test_ds.c gen_test_ld.c ld_extend.c ld_monitor.c \ - test_ds.c test_dset_opt.c test_file_image.c test_image.c \ - test_lite.c test_packet.c test_table.c -DIST_SOURCES = gen_test_ds.c gen_test_ld.c ld_extend.c ld_monitor.c \ - test_ds.c test_dset_opt.c test_file_image.c test_image.c \ - test_lite.c test_packet.c test_table.c +SOURCES = gen_test_ds.c gen_test_ld.c ld_mx.c test_ds.c \ + test_dset_append.c test_dset_opt.c test_file_image.c \ + test_image.c test_ld.c test_lite.c test_packet.c test_table.c +DIST_SOURCES = gen_test_ds.c gen_test_ld.c ld_mx.c test_ds.c \ + test_dset_append.c test_dset_opt.c test_file_image.c \ + test_image.c test_ld.c test_lite.c test_packet.c test_table.c am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -716,14 +720,16 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog *.clog2 \ # Test script TEST_SCRIPT = test_ld.sh check_SCRIPTS = $(TEST_SCRIPT) -SCRIPT_DEPEND = ld_monitor$(EXEEXT) ld_extend$(EXEEXT) +SCRIPT_DEPEND = ld_mx$(EXEEXT) # The tests depend on the hdf5, hdf5 test, and hdf5_hl libraries LDADD = $(LIBH5_HL) $(LIBH5TEST) $(LIBHDF5) # Test programs. These are our main targets. They should be listed in the # order to be executed, generally most specific tests to least specific tests. -TEST_PROG = test_lite test_image test_file_image test_table test_ds test_packet test_dset_opt +TEST_PROG = test_lite test_image test_file_image test_table test_ds test_packet test_dset_opt \ + test_ld test_dset_append + # These programs generate test files for the tests. They don't need to be # compiled every time we want to test the library. However, putting @@ -818,18 +824,18 @@ gen_test_ld$(EXEEXT): $(gen_test_ld_OBJECTS) $(gen_test_ld_DEPENDENCIES) $(EXTRA @rm -f gen_test_ld$(EXEEXT) $(AM_V_CCLD)$(LINK) $(gen_test_ld_OBJECTS) $(gen_test_ld_LDADD) $(LIBS) -ld_extend$(EXEEXT): $(ld_extend_OBJECTS) $(ld_extend_DEPENDENCIES) $(EXTRA_ld_extend_DEPENDENCIES) - @rm -f ld_extend$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(ld_extend_OBJECTS) $(ld_extend_LDADD) $(LIBS) - -ld_monitor$(EXEEXT): $(ld_monitor_OBJECTS) $(ld_monitor_DEPENDENCIES) $(EXTRA_ld_monitor_DEPENDENCIES) - @rm -f ld_monitor$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(ld_monitor_OBJECTS) $(ld_monitor_LDADD) $(LIBS) +ld_mx$(EXEEXT): $(ld_mx_OBJECTS) $(ld_mx_DEPENDENCIES) $(EXTRA_ld_mx_DEPENDENCIES) + @rm -f ld_mx$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(ld_mx_OBJECTS) $(ld_mx_LDADD) $(LIBS) test_ds$(EXEEXT): $(test_ds_OBJECTS) $(test_ds_DEPENDENCIES) $(EXTRA_test_ds_DEPENDENCIES) @rm -f test_ds$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_ds_OBJECTS) $(test_ds_LDADD) $(LIBS) +test_dset_append$(EXEEXT): $(test_dset_append_OBJECTS) $(test_dset_append_DEPENDENCIES) $(EXTRA_test_dset_append_DEPENDENCIES) + @rm -f test_dset_append$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_dset_append_OBJECTS) $(test_dset_append_LDADD) $(LIBS) + test_dset_opt$(EXEEXT): $(test_dset_opt_OBJECTS) $(test_dset_opt_DEPENDENCIES) $(EXTRA_test_dset_opt_DEPENDENCIES) @rm -f test_dset_opt$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_dset_opt_OBJECTS) $(test_dset_opt_LDADD) $(LIBS) @@ -842,6 +848,10 @@ test_image$(EXEEXT): $(test_image_OBJECTS) $(test_image_DEPENDENCIES) $(EXTRA_te @rm -f test_image$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_image_OBJECTS) $(test_image_LDADD) $(LIBS) +test_ld$(EXEEXT): $(test_ld_OBJECTS) $(test_ld_DEPENDENCIES) $(EXTRA_test_ld_DEPENDENCIES) + @rm -f test_ld$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(test_ld_OBJECTS) $(test_ld_LDADD) $(LIBS) + test_lite$(EXEEXT): $(test_lite_OBJECTS) $(test_lite_DEPENDENCIES) $(EXTRA_test_lite_DEPENDENCIES) @rm -f test_lite$(EXEEXT) $(AM_V_CCLD)$(LINK) $(test_lite_OBJECTS) $(test_lite_LDADD) $(LIBS) @@ -862,12 +872,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_test_ds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gen_test_ld.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ld_extend.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ld_monitor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ld_mx.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ds.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dset_append.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dset_opt.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_file_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_image.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ld.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lite.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_table.Po@am__quote@ @@ -1130,6 +1141,20 @@ test_dset_opt.log: test_dset_opt$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +test_ld.log: test_ld$(EXEEXT) + @p='test_ld$(EXEEXT)'; \ + b='test_ld'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +test_dset_append.log: test_dset_append$(EXEEXT) + @p='test_dset_append$(EXEEXT)'; \ + b='test_dset_append'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) .sh.log: @p='$<'; \ $(am__set_b); \ @@ -1314,7 +1339,6 @@ uninstall-am: help: @$(top_srcdir)/bin/makehelp - test_ld # lib/progs/tests targets recurse into subdirectories. build-* targets # build files in this directory. diff --git a/hl/test/gen_test_ld.c b/hl/test/gen_test_ld.c index bf130df..3940180 100644 --- a/hl/test/gen_test_ld.c +++ b/hl/test/gen_test_ld.c @@ -144,6 +144,7 @@ int main(void) { hid_t fid; /* File id */ + hid_t fapl; /* File access property list */ hsize_t cur_dims[1]; /* Dimension sizes */ hsize_t max_dims[1]; /* Maximum dimension sizes */ hsize_t cur2_dims[2]; /* Current dimension sizes */ @@ -160,8 +161,16 @@ main(void) set_t two_cbuf[TWO_DIMS0*TWO_DIMS1]; /* Buffer for data with compound type */ int i; /* Local index variable */ + /* Create a file access property list */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + goto done; + + /* Set to use latest library format */ + if((H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST)) < 0) + goto done; + /* Create a file */ - if((fid = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) + if((fid = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) goto done; /* Initialization for one-dimensional dataset */ @@ -334,6 +343,8 @@ main(void) if(H5Tclose(esc_sub2_tid) < 0) goto done; if(H5Tclose(esc_sub4_tid) < 0) goto done; if(H5Tclose(esc_set_tid) < 0) goto done; + + if(H5Pclose(fapl) < 0) goto done; if(H5Fclose(fid) < 0) goto done; exit(EXIT_SUCCESS); @@ -353,6 +364,7 @@ done: H5Dclose(scalar_did); H5Sclose(scalar_sid); + H5Pclose(fapl); H5Fclose(fid); H5E_END_TRY diff --git a/hl/test/ld_extend.c b/hl/test/ld_extend.c deleted file mode 100644 index 3ddd883..0000000 --- a/hl/test/ld_extend.c +++ /dev/null @@ -1,151 +0,0 @@ -#include "H5HLprivate2.h" -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> -#include <unistd.h> - -/* Size of data buffer */ -#define TEST_BUF_SIZE 100 - -/* - * Test variations (incremental) for one-dimensional dataset: - * Varies from 10->13->12->12->1->3 - */ -#define ONE_NTESTS 5 -int one_tests[ONE_NTESTS] = {3, -1, 0, -11, 2}; - -/* - * Test variations (incremental) for two-dimensional dataset: - * Varies from {4,10}->{6,12}->{8,1}->{10,1}-> - * {3,3}->{2,2}->{1,2}-> - * {1,4}->{1,3}->{1,3} - */ -#define TWO_NTESTS 9 -int two_tests[TWO_NTESTS][2] = { {2, 2}, {2, -11}, {2, 0}, - {-7, 2}, {-1, -1}, {-1, 0}, - {0, 2}, {0, -1}, {0, 0} - }; - -static int extend_dset(const char *file, char *dname); - -/* - * Extend the specified dataset in the file with ld_monitor.c monitoring - * the dataset on the other end: - * - * 1) Extend the dataset according to the variations: ONE_NTESTS, TWO_NTESTS - * 2) Write to the dataset (currently, only for integer dataset) - * 3) Flush the dataset - */ -static int -extend_dset(const char *file, char *dname) -{ - hid_t fid; /* file id */ - hid_t did; /* dataset id */ - hid_t dtype; /* dataset's datatype */ - hid_t sid; /* dataspace id */ - int i, j, k; /* local index variable */ - int ndims; /* number of dimensions */ - int buf[TEST_BUF_SIZE]; /* buffer for data */ - hsize_t cur_dims[2]; /* current dimension sizes */ - hsize_t ext_dims[2]; /* new dimension sizes after extension */ - - /* Open the file */ - if((fid = H5Fopen(file, H5F_ACC_RDWR, H5P_DEFAULT)) < 0) - goto done; - - /* Open the dataset */ - if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) - goto done; - - /* Get the dataset's data space */ - if((sid = H5Dget_space(did)) < 0) - goto done; - - /* Get the # of dimensions for the dataset */ - if((ndims = H5Sget_simple_extent_ndims(sid)) < 0) - goto done; - - /* Initialize data written to the dataset */ - HDmemset(buf, 0, sizeof(buf)); - for(k = 0; k < TEST_BUF_SIZE; k++) - buf[k] = k; - - /* Loop through different variations of extending the dataset */ - for(i = 0; i < (ndims == 1 ? ONE_NTESTS: TWO_NTESTS); i++) { - - sleep(2); - - /* Get the dataset's current dimension sizes */ - if(H5LDget_dset_dims(did, cur_dims) < 0) - goto done; - - /* Set up the new extended dimension sizes */ - for(j = 0; j < ndims; j++) - ext_dims[j] = cur_dims[j] + (ndims == 1 ? (hsize_t)one_tests[i] : (hsize_t)two_tests[i][j]); - - /* Extend the dataset */ - if(H5Dset_extent(did, ext_dims) < 0) - goto done; - - /* Get the dataset's data type */ - if((dtype = H5Tget_native_type(H5Dget_type(did), H5T_DIR_DEFAULT)) < 0) - goto done; - - /* Write to the whole dataset after extension */ - if(H5Dwrite(did, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) - goto done; - - /* Flush the data */ - if(H5Dflush(did) < 0) - goto done; - - } /* end for ONE_NTESTS or TWO_NTESTS */ - - /* Closing */ - if(H5Tclose(dtype) < 0) goto done; - if(H5Sclose(sid) < 0) goto done; - if(H5Dclose(did) < 0) goto done; - if(H5Fclose(fid) < 0) goto done; - - return(0); - -done: - H5E_BEGIN_TRY - H5Tclose(dtype); - H5Sclose(sid); - H5Dclose(did); - H5Fclose(fid); - H5E_END_TRY - - return(-1); -} /* extend_dset() */ - - -/* Usage: extend_dset xx.h5 dname */ -int -main(int argc, const char *argv[]) -{ - char *dname = NULL; /* dataset name */ - char *fname = NULL; /* file name */ - - if(argc != 3) { - fprintf(stderr, "Should have file name and dataset name to be extended...\n"); - goto done; - } - - /* Get the file and dataset names to be extended */ - fname = HDstrdup(argv[1]); - dname = HDstrdup(argv[2]); - - /* Extend the specified dataset in the file */ - if(extend_dset(fname, dname) < 0) - goto done; - - exit(EXIT_SUCCESS); - -done: - if(dname) HDfree(dname); - if(fname) HDfree(fname); - exit(EXIT_FAILURE); -} /* main() */ diff --git a/hl/test/ld_monitor.c b/hl/test/ld_monitor.c deleted file mode 100644 index 9dc666f..0000000 --- a/hl/test/ld_monitor.c +++ /dev/null @@ -1,190 +0,0 @@ -#include "H5HLprivate2.h" -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> -#include <unistd.h> -#ifdef SWMR_DEBUG -#include <termios.h> -#include <fcntl.h> - -static void set_mode(int want_key) -{ - static struct termios old_val, new_val; - - if (!want_key) { - HDtcsetattr(STDIN_FILENO, TCSANOW, &old_val); - return; - } - - HDtcgetattr(STDIN_FILENO, &old_val); - new_val = old_val; - new_val.c_lflag &= (tcflag_t)~(ICANON | ECHO); - HDtcsetattr(STDIN_FILENO, TCSANOW, &new_val); -} - -static int get_key(void) -{ - int c = 0; - struct timeval tv; - fd_set fs; - - tv.tv_sec = 0; - tv.tv_usec = 0; - - FD_ZERO(&fs); - FD_SET(STDIN_FILENO, &fs); - HDselect(STDIN_FILENO + 1, &fs, 0, 0, &tv); - - if (FD_ISSET(STDIN_FILENO, &fs)) { - c = HDgetchar(); - set_mode(0); - } - return c; -} -#endif /* SWMR_DEBUG */ - -#define TEST_BUF_SIZE 100 - -/* - * Monitor the specified dataset in the file while ld_extend.c extending - * and writing to the dataset on the other end: - * - * 1) Retrieve the dataset's current dimension sizes - * 2) If there are changes in dimension sizes: - * print the dimension sizes - * retrieve the appended data and print them - */ -static int -monitor_dset(const char *fname, const char *dname) -{ - hid_t fid; /* dataset id */ - hid_t did; /* dataset id */ - hid_t sid; /* dataspace id */ - int ndims; /* # of dimensions in the dataspace */ - int i, u; /* local index variable */ - hsize_t cur_dims[H5S_MAX_RANK]; /* current dimension sizes */ - hsize_t prev_dims[H5S_MAX_RANK]; /* previous dimension sizes */ - int buf[TEST_BUF_SIZE]; /* Buffer for data */ - herr_t ret_value = 0; /* return value */ - - /* Open the file with SWMR */ - if((fid = H5Fopen(fname, H5F_ACC_SWMR_READ, H5P_DEFAULT)) < 0) - goto done; - - HDfprintf(stdout, "Monitoring dataset %s...\n", dname); - - /* Open the dataset for minitoring */ - if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) { - HDfprintf(stdout, "error in opening dataset \"%s\"\n", dname); - ret_value = -1; - goto done; - } - - /* Get the dataset's data space */ - if((sid = H5Dget_space(did)) < 0) { - HDfprintf(stdout, "error in getting dataspace id for dataset \"%s\"\n", dname); - ret_value = -1; - goto done; - } - - /* Get the dataset's dimension sizes */ - if((ndims = H5Sget_simple_extent_dims(sid, prev_dims, NULL)) < 0) { - HDfprintf(stdout, "unable to get dimensions sizes for \"%s\"\n", dname); - ret_value = -1; - goto done; - } - -#ifdef SWMR_DEBUG - /* Monitor for keypresses */ - set_mode(1); -#endif /* SWMR_DEBUG */ - - /* Monitor the dataset for changes */ - while(1) { - - /* Refresh the dataset */ - if(H5Drefresh(did) < 0) { - ret_value = -1; - goto done; - } - - /* Get the dataset's current dimension sizes */ - if(H5LDget_dset_dims(did, cur_dims) < 0) { - HDfprintf(stdout, "unable to get dimension sizes for \"%s\"\n", dname); - ret_value = -1; - goto done; - } - - /* Check for changes in dimension sizes */ - for(u = 0; u < ndims; u++) { - if(cur_dims[u] != prev_dims[u]) - break; - } - - /* Printing only when there are changes */ - if(u < ndims) { - /* Print the current dimension sizes */ - HDfprintf(stdout, "\n"); - for(i = 0; i < ndims; i++) - HDfprintf(stdout, "%d ", (int)cur_dims[i]); - HDfprintf(stdout, "\n"); - - /* Get data appended to the dataset and print the data */ - HDmemset(buf, 0, sizeof(buf)); - if(H5LDget_dset_elmts(did, prev_dims, cur_dims, NULL, buf) >= 0) { - - for(i = 0; i < TEST_BUF_SIZE; i++) { - if(i % 10) - HDfprintf(stdout, "%d ", buf[i]); - else - HDfprintf(stdout, "\n%d ", buf[i]); - } - HDfprintf(stdout, "\n"); - } - - /* Flush the output to stdout */ - HDfflush(stdout); - /* Update the dimension sizes */ - HDmemcpy(prev_dims, cur_dims, (size_t)ndims * sizeof(hsize_t)); - } - - /* Sleep before next monitor */ - sleep(1); - -#ifdef SWMR_DEBUG - /* Check for keypress */ - if(get_key()) - break; -#endif /* SWMR_DEBUG */ - } /* end while */ - -done: - /* Closing */ - H5E_BEGIN_TRY - H5Sclose(sid); - H5Dclose(did); - H5E_END_TRY - - return(ret_value); -} /* monitor_dset() */ - -/* usage: monitor xx.h5 dname */ -int -main(int argc, const char *argv[]) -{ - if(argc != 3) { - HDfprintf(stderr, "Should have file name and dataset name to be monitored...\n"); - goto done; - } - - /* only integer dataset */ - if(monitor_dset(argv[1], argv[2]) < 0) - goto done; - - exit(EXIT_SUCCESS); - -done: - exit(EXIT_FAILURE); -} - diff --git a/hl/test/ld_mx.c b/hl/test/ld_mx.c new file mode 100644 index 0000000..9d45823 --- /dev/null +++ b/hl/test/ld_mx.c @@ -0,0 +1,353 @@ +#include "h5hltest.h" +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> + +/* Size of data buffer */ +#define TEST_BUF_SIZE 100 + +/* Note: These two defines should be the same as the defines in test_ld.sh.in */ +/* The message sent by extend_dset that the file is done with file open releasing the file lock */ +#define WRITER_MESSAGE "LD_WRITER_MESSAGE" +/* The message sent by monitor_dset that it is done setting up */ +#define READER_MESSAGE "LD_READER_MESSAGE" + +/* + * Test variations (incremental) for one-dimensional dataset: + * Varies from 10->13->12->12->1->3 + */ +#define ONE_NTESTS 5 +int one_tests[ONE_NTESTS] = {3, -1, 0, -11, 2}; + +/* + * Test variations (incremental) for two-dimensional dataset: + * Varies from {4,10}->{6,12}->{8,1}->{10,1}-> + * {3,3}->{2,2}->{1,2}-> + * {1,4}->{1,3}->{1,3} + */ +#define TWO_NTESTS 9 +int two_tests[TWO_NTESTS][2] = { {2, 2}, {2, -11}, {2, 0}, + {-7, 2}, {-1, -1}, {-1, 0}, + {0, 2}, {0, -1}, {0, 0} + }; + +/* + * Extend the specified dataset in the file with "monitor_dset" monitoring + * the dataset on the other end: + * 1) Extend the dataset according to the variations: ONE_NTESTS, TWO_NTESTS + * 2) Write to the dataset (currently, only for integer dataset) + * 3) Flush the dataset + * + * Due to the implementation of file locking, coordination is needed in file + * opening for the writer/reader tests to proceed as expected: + * --it will send the WRITER_MESSAGE when the file open is done: + * to notify monitor_dset() to start monitoring the dataset + * --it will wait for the READER_MESSAGE from monitor_dset() before extending + * the dataset + */ +static int +extend_dset(const char *file, char *dname) +{ + hid_t fid; /* file id */ + hid_t fapl; /* file access property list */ + hid_t did; /* dataset id */ + hid_t dtype; /* dataset's datatype */ + hid_t sid; /* dataspace id */ + int i, j, k; /* local index variable */ + int ndims; /* number of dimensions */ + int buf[TEST_BUF_SIZE]; /* buffer for data */ + hsize_t cur_dims[2]; /* current dimension sizes */ + hsize_t ext_dims[2]; /* new dimension sizes after extension */ + + /* Create a file access property list */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + goto done; + + /* Set to use latest library format */ + if((H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST)) < 0) + goto done; + + /* Open the file with SWMR write */ + if((fid = H5Fopen(file, H5F_ACC_RDWR|H5F_ACC_SWMR_WRITE, fapl)) < 0) + goto done; + + /* Send message that "extend_dset" (this routine) is done with H5Fopen--the file lock is released */ + h5_send_message(WRITER_MESSAGE); + + /* Open the dataset */ + if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) + goto done; + + /* Get the dataset's data space */ + if((sid = H5Dget_space(did)) < 0) + goto done; + + /* Get the # of dimensions for the dataset */ + if((ndims = H5Sget_simple_extent_ndims(sid)) < 0) + goto done; + + /* Initialize data written to the dataset */ + HDmemset(buf, 0, sizeof(buf)); + for(k = 0; k < TEST_BUF_SIZE; k++) + buf[k] = k; + + /* Wait for message from "monitor_dset" before starting to extend the dataset */ + if(h5_wait_message(READER_MESSAGE) < 0) + goto done; + + /* Loop through different variations of extending the dataset */ + for(i = 0; i < (ndims == 1 ? ONE_NTESTS: TWO_NTESTS); i++) { + HDsleep(2); + + /* Get the dataset's current dimension sizes */ + if(H5LDget_dset_dims(did, cur_dims) < 0) + goto done; + + /* Set up the new extended dimension sizes */ + for(j = 0; j < ndims; j++) + ext_dims[j] = cur_dims[j] + (ndims == 1 ? (hsize_t)one_tests[i] : (hsize_t)two_tests[i][j]); + + /* Extend the dataset */ + if(H5Dset_extent(did, ext_dims) < 0) + goto done; + + /* Get the dataset's data type */ + if((dtype = H5Tget_native_type(H5Dget_type(did), H5T_DIR_DEFAULT)) < 0) + goto done; + + /* Write to the whole dataset after extension */ + if(H5Dwrite(did, dtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) < 0) + goto done; + + /* Flush the data */ + if(H5Dflush(did) < 0) + goto done; + + } /* end for ONE_NTESTS or TWO_NTESTS */ + + /* Closing */ + if(H5Tclose(dtype) < 0) goto done; + if(H5Sclose(sid) < 0) goto done; + if(H5Dclose(did) < 0) goto done; + if(H5Pclose(fapl) < 0) goto done; + if(H5Fclose(fid) < 0) goto done; + + return(0); + +done: + H5E_BEGIN_TRY + H5Tclose(dtype); + H5Sclose(sid); + H5Dclose(did); + H5Pclose(fapl); + H5Fclose(fid); + H5E_END_TRY + + return(-1); +} /* extend_dset() */ + + +/* + * Monitor the specified dataset in the file while "extend_dset" is extending + * and writing to the dataset on the other end: + * + * 1) Retrieve the dataset's current dimension sizes + * 2) If there are changes in dimension sizes: + * print the dimension sizes + * retrieve the appended data and print them + * + * Due to the implementation of file locking, coordination is needed in file + * opening for the writer/reader tests to proceed as expected: + * --it will wait for the WRITER_MESSAGE from extend_dset() before opening + * the test file + * --it will send the READER_MESSAGE when the setup is done: + * to notify extend_dset() to start extending the dataset + */ +static int +monitor_dset(const char *fname, char *dname) +{ + hid_t fid; /* file id */ + hid_t fapl; /* file access property list */ + hid_t did; /* dataset id */ + hid_t sid; /* dataspace id */ + int ndims; /* # of dimensions in the dataspace */ + int i, u; /* local index variable */ + hsize_t cur_dims[H5S_MAX_RANK]; /* current dimension sizes */ + hsize_t prev_dims[H5S_MAX_RANK]; /* previous dimension sizes */ + int buf[TEST_BUF_SIZE]; /* Buffer for data */ + herr_t ret_value = 0; /* return value */ + + /* Wait for message from "extend_dset" before opening the file */ + if(h5_wait_message(WRITER_MESSAGE) < 0) + goto done; + + /* Create a file access property list */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + goto done; + + /* Set to use latest library format */ + if((H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST)) < 0) + goto done; + + /* Open the file with SWMR access */ + if((fid = H5Fopen(fname, H5F_ACC_SWMR_READ, fapl)) < 0) { + ret_value = -1; + goto done; + } + + HDfprintf(stdout, "Monitoring dataset %s...\n", dname); + + /* Open the dataset for minitoring */ + if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) { + HDfprintf(stdout, "error in opening dataset \"%s\"\n", dname); + ret_value = -1; + goto done; + } + + /* Get the dataset's data space */ + if((sid = H5Dget_space(did)) < 0) { + HDfprintf(stdout, "error in getting dataspace id for dataset \"%s\"\n", dname); + ret_value = -1; + goto done; + } + + /* Get the dataset's dimension sizes */ + if((ndims = H5Sget_simple_extent_dims(sid, prev_dims, NULL)) < 0) { + HDfprintf(stdout, "unable to get dimensions sizes for \"%s\"\n", dname); + ret_value = -1; + goto done; + } + + /* Send message that "monitor_dset" (this routine) is done with setting up */ + h5_send_message(READER_MESSAGE); + + /* Monitor the dataset for changes */ + while(1) { + + /* Refresh the dataset */ + if(H5Drefresh(did) < 0) { + ret_value = -1; + goto done; + } + + /* Get the dataset's current dimension sizes */ + if(H5LDget_dset_dims(did, cur_dims) < 0) { + HDfprintf(stdout, "unable to get dimension sizes for \"%s\"\n", dname); + ret_value = -1; + goto done; + } + + /* Check for changes in dimension sizes */ + for(u = 0; u < ndims; u++) { + if(cur_dims[u] != prev_dims[u]) { + break; + } + } + + /* Printing only when there are changes */ + if(u < ndims) { + /* Print the current dimension sizes */ + HDfprintf(stdout, "\n"); + for(i = 0; i < ndims; i++) + HDfprintf(stdout, "%d ", (int)cur_dims[i]); + HDfprintf(stdout, "\n"); + + /* Get data appended to the dataset and print the data */ + HDmemset(buf, 0, sizeof(buf)); + if(H5LDget_dset_elmts(did, prev_dims, cur_dims, NULL, buf) >= 0) { + + for(i = 0; i < TEST_BUF_SIZE; i++) { + if(i % 10) + HDfprintf(stdout, "%d ", buf[i]); + else + HDfprintf(stdout, "\n%d ", buf[i]); + } + HDfprintf(stdout, "\n"); + } + + /* Flush the output to stdout */ + HDfflush(stdout); + /* Update the dimension sizes */ + HDmemcpy(prev_dims, cur_dims, ndims * sizeof(hsize_t)); + } + HDsleep(1); + } /* end for */ + +done: + /* Closing */ + H5E_BEGIN_TRY + H5Sclose(sid); + H5Dclose(did); + H5Pclose(fapl); + H5E_END_TRY + + return(ret_value); +} /* monitor_dset() */ + +/* Usage: + * ld_mx -m fname dname -- to monitor the file's dataset + * or + * ld_mx -x fname dname -- to extend the file's dataset + */ +/* This file is a combination of ld_monitor.c and ld_extend.c which are svn deleted */ +int +main(int argc, char *argv[]) +{ + char *dname = NULL; /* dataset name */ + char *fname = NULL; /* file name */ + int opt = 0; + unsigned int monitor = 0, extend = 0; + + if(argc != 4) { + fprintf(stderr, "Usage: ld_mx -m fname dname for monitoring the dataset 'dname' in the file 'fname'\n"); + fprintf(stderr, "Usage: ld_mx -x fname dname for extending the dataset 'dname' in the file 'fname'\n"); + goto done; + } + /* Parse command line options */ + while((opt = getopt(argc, argv, "mx")) != -1) { + switch(opt) { + case 'm': /* monitor dataset */ + monitor = 1; + break; + + case 'x': /* extend dataset */ + extend = 1; + break; + default: + printf("Invalid option encountered\n"); + break; + } + } + + if((extend && monitor) || (!extend && !monitor)) { + fprintf(stderr, "Usage: ldmx -m/-x fname dname\n"); + goto done; + } + + if(optind != 2) { + fprintf(stderr, "Usage: ldmx -m/-x fname dname\n"); + goto done; + } + + fname = HDstrdup(argv[optind++]); + dname = HDstrdup(argv[optind++]); + + + if(extend) { + if(extend_dset(fname, dname) < 0) + goto done; + } else if(monitor) { + if(monitor_dset(fname, dname) < 0) + goto done; + } + + exit(EXIT_SUCCESS); + +done: + if(dname) HDfree(dname); + if(fname) HDfree(fname); + exit(EXIT_FAILURE); +} /* main() */ diff --git a/hl/test/test_dset_append.c b/hl/test/test_dset_append.c new file mode 100644 index 0000000..bb646cb --- /dev/null +++ b/hl/test/test_dset_append.c @@ -0,0 +1,1198 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +* Copyright by The HDF Group. * +* Copyright by the Board of Trustees of the University of Illinois. * +* All rights reserved. * +* * +* This file is part of HDF5. The full HDF5 copyright notice, including * +* terms governing use, modification, and redistribution, is contained in * +* the files COPYING and Copyright.html. COPYING can be found at the root * +* of the source code distribution tree; Copyright.html can be found at the * +* root level of an installed copy of the electronic HDF5 document set and * +* is linked from the top-level documents page. It can also be found at * +* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * +* access to either file, you may request a copy from help@hdfgroup.org. * +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include <stdlib.h> +#include <string.h> +#include "h5hltest.h" +#include "H5srcdir.h" +#include "H5DOpublic.h" +#include <math.h> + +#if defined(H5_HAVE_ZLIB_H) && !defined(H5_ZLIB_HEADER) +# define H5_ZLIB_HEADER "zlib.h" +#endif +#if defined(H5_ZLIB_HEADER) +# include H5_ZLIB_HEADER /* "zlib.h" */ +#endif + +#define FILE "test_append.h5" +#define DNAME_UNLIM "dataset_unlim" +#define DNAME_LESS "dataset_less" +#define DNAME_VARY "dataset_vary" +#define DNAME_LINE "dataset_line" +#define DNAME_COLUMN "dataset_column" +#define DBUGNAME1 "dataset_bug1" +#define DBUGNAME2 "dataset_bug2" + +/* The callback function for the object flush property */ +static herr_t +flush_func(hid_t obj_id, void *_udata) +{ + unsigned *flush_ct = (unsigned*)_udata; + ++(*flush_ct); + return 0; +} + +/* The callback function for the append flush property */ +static herr_t +append_func(hid_t dset_id, hsize_t *cur_dims, void *_udata) +{ + unsigned *append_ct = (unsigned *)_udata; + ++(*append_ct); + return 0; +} + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_lines_columns + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending lines and columns to a dataset + * with 2 extendible dimensions. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_lines_columns(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* A copy of dataset creation property */ + hid_t dapl = -1; /* A copy of dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {0, 10}; /* Current dimension sizes */ + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int lbuf[10], cbuf[6]; /* The data buffers */ + int buf[6][13], rbuf[6][13]; /* The data buffers */ + int i, j; /* Local index variables */ + + hsize_t boundary[2] = {1, 1}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append lines & columns"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 2 extendible dimensions */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DNAME_UNLIM, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append 6 lines to the dataset */ + for(i = 0; i < 6; i++) { + for(j = 0; j < 10; j++) + lbuf[j] = buf[i][j] = (i*10) + (j+1); + if(H5DOappend(did, H5P_DEFAULT, 0, (size_t)1, H5T_NATIVE_INT, lbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 6) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 6) + TEST_ERROR; + + /* Append 3 columns to the dataset */ + for(i = 0; i < 3; i++) { + for(j = 0; j < 6; j++) + cbuf[j] = buf[j][i+10] = ((i*6) + (j+1)) * -1; + if(H5DOappend(did, H5P_DEFAULT, 1, (size_t)1, H5T_NATIVE_INT, cbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 9) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 9) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Clear the buffer */ + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DNAME_UNLIM, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dapl); + H5Pclose(dcpl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_lines_columns() */ + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_lines + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending lines to a dataset with + * one extendible dimension (line). + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_lines(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* A copy of dataset creation property */ + hid_t dapl = -1; /* A copy of dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {0, 10}; /* Current dimension sizes */ + hsize_t maxdims[2] = {H5S_UNLIMITED, 10}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int lbuf[10]; /* The data buffer */ + int buf[6][10], rbuf[6][10]; /* The data buffers */ + int i, j; /* Local index variables */ + + hsize_t boundary[2] = {1, 0}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append lines"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 1 extendible dimension */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DNAME_LINE, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append 6 lines to the dataset */ + for(i = 0; i < 6; i++) { + for(j = 0; j < 10; j++) + lbuf[j] = buf[i][j] = (i*10) + (j+1); + if(H5DOappend(did, H5P_DEFAULT, 0, (size_t)1, H5T_NATIVE_INT, lbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 6) + TEST_ERROR; + + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 6) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 10; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Clear the buffer */ + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DNAME_LINE, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 10; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dapl); + H5Pclose(dcpl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_lines() */ + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_columns + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending columns to a dataset + * with one extendible dimension (column). + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_columns(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* A copy of dataset creation property */ + hid_t dapl = -1; /* A copy of dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {6, 0}; /* Current dimension sizes */ + hsize_t maxdims[2] = {6, H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int cbuf[6]; /* The data buffer */ + int buf[6][3], rbuf[6][3]; /* The data buffers */ + int i, j; /* Local index variable */ + + hsize_t boundary[2] = {0, 1}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append columns"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 1 extendible dimension */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DNAME_COLUMN, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append 3 columns to the dataset */ + for(i = 0; i < 3; i++) { + for(j = 0; j < 6; j++) + cbuf[j] = buf[j][i] = ((i*6) + (j+1)) * -1; + if(H5DOappend(did, H5P_DEFAULT, 1, (size_t)1, H5T_NATIVE_INT, cbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 3) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 3) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 3; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Clear the buffer */ + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DNAME_COLUMN, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 3; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dapl); + H5Pclose(dcpl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_columns() */ + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_BUG1 + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending lines and columns to an + * extendible dataset. + * A BUG occurs: + * when the extendible dataset is set up as follows: + * hsize_t dims[2] = {0, 10}; + * hsize_t maxdims[2] = {H5S_UNLIMITED, 50}; + * when append 6 lines and 3 columns to the dataset; + * The data is correct when the dataset is read at this point; + * The data is incorrect when the dataset is closed, opened again, and read at this point; + * NOTE: the problem does not occur when H5Dflush() is not performed for each line/column. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_BUG1(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* Dataset creation property */ + hid_t dapl = -1; /* Dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {0, 10}; /* Current dimension sizes */ + hsize_t maxdims[2] = {H5S_UNLIMITED, 50}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int lbuf[10], cbuf[6]; /* The data buffers */ + int buf[6][13], rbuf[6][13]; /* The data buffers */ + int i, j; /* Local index variables */ + + hsize_t boundary[2] = {1, 1}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append lines & columns--BUG1"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 2 extendible dimensions */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DBUGNAME1, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append 6 lines to the dataset */ + for(i = 0; i < 6; i++) { + for(j = 0; j < 10; j++) + lbuf[j] = buf[i][j] = (i*10) + (j+1); + if(H5DOappend(did, H5P_DEFAULT, 0, (size_t)1, H5T_NATIVE_INT, lbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 6) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 6) + TEST_ERROR; + + + /* Append 3 columns to the dataset */ + for(i = 0; i < 3; i++) { + for(j = 0; j < 6; j++) + cbuf[j] = buf[j][i+10] = ((i*6) + (j+1)) * -1; + if(H5DOappend(did, H5P_DEFAULT, 1, (size_t)1, H5T_NATIVE_INT, cbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 9) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 9) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + +#ifdef BUG1 + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DBUGNAME1, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; +#endif + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dcpl); + H5Pclose(dapl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_BUG1() */ + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_BUG2 + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending lines and columns to an + * extendible dataset. + * A BUG occurs: + * when the extendible dataset is set up as follows: + * hsize_t dims[2] = {0, 10}; + * hsize_t maxdims[2] = {50, H5S_UNLIMITED}; + * when append 6 lines and 3 columns to the dataset; + * The data is correct when the dataset is read at this point; + * The data is incorrect when the dataset is closed, opened again, and read at this point; + * NOTE: the problem does not occur when H5Dflush() is not performed for each line/column. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_BUG2(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* Dataset creation property */ + hid_t dapl = -1; /* Dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {0, 10}; /* Current dimension sizes */ + hsize_t maxdims[2] = {50, H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int lbuf[10], cbuf[6]; /* Data buffers */ + int buf[6][13], rbuf[6][13]; /* Data buffers */ + int i, j; /* Local index variables */ + + hsize_t boundary[2] = {1, 1}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append lines & columns--BUG2"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 2 extendible dimensions */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DBUGNAME2, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append 6 lines to the dataset */ + for(i = 0; i < 6; i++) { + for(j = 0; j < 10; j++) + lbuf[j] = buf[i][j] = (i*10) + (j+1); + if(H5DOappend(did, H5P_DEFAULT, 0, (size_t)1, H5T_NATIVE_INT, lbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 6) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 6) + TEST_ERROR; + + + /* Append 3 columns to the dataset */ + for(i = 0; i < 3; i++) { + for(j = 0; j < 6; j++) + cbuf[j] = buf[j][i+10] = ((i*6) + (j+1)) * -1; + if(H5DOappend(did, H5P_DEFAULT, 1, (size_t)1, H5T_NATIVE_INT, cbuf) < 0) + TEST_ERROR; + } + + /* Verify the # of appends */ + if(append_ct != 9) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 9) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + +#ifdef BUG2 + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DBUGNAME2, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; +#endif + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dcpl); + H5Pclose(dapl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_BUG2() */ + + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_less + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending lines and columns to an + * extendible dataset where the append size is less than the boundary + * size. + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_less(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* A copy of dataset creation property */ + hid_t dapl = -1; /* A copy of dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {0, 10}; /* Current dimension sizes */ + hsize_t maxdims[2] = {100, 100}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int lbuf[20], cbuf[6][3]; /* Data buffers */ + int buf[6][13], rbuf[6][13]; /* Data buffers */ + int i, j, k; /* Local index variables */ + + hsize_t boundary[2] = {3, 3}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append size < boundary size"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 2 extendible dimensions */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DNAME_LESS, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append to the dataset 2 lines at a time for 3 times */ + for(i = 0, k = 0; i < 6; i++) { + for(j = 0; j < 10; j++, k++) + buf[i][j] = lbuf[k] = (i*10) + (j+1); + + if((i + 1) % 2 == 0) { + if(H5DOappend(did, H5P_DEFAULT, 0, (size_t)2, H5T_NATIVE_INT, lbuf) < 0) + TEST_ERROR; + k = 0; + } + } + + /* Verify the # of appends */ + if(append_ct != 2) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 2) + TEST_ERROR; + + /* Append to the dataset 3 columns at a time for 1 time */ + for(i = 0; i < 3; i++) { + for(j = 0; j < 6; j++, k++) + cbuf[j][i] = buf[j][i+10] = ((i*6) + (j+1)) * -1; + } + if(H5DOappend(did, H5P_DEFAULT, 1, (size_t)3, H5T_NATIVE_INT, cbuf) < 0) + TEST_ERROR; + + /* Verify the # of appends */ + if(append_ct != 3) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 3) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Clear the buffer */ + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DNAME_LESS, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dapl); + H5Pclose(dcpl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_less() */ + +/*------------------------------------------------------------------------- + * Function: test_dataset_append_vary + * + * Purpose: Verify that the object flush property and the append flush property + * are working properly when appending lines and columns to an + * extendible dataset where + * line: the append size is 3 times of the boundary size + * the append callback/flush is performed on the 1st boundary hit + * column: the boundary is greater than the append size + * the boundary is not hit at all + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +static int +test_dataset_append_vary(hid_t fid) +{ + hid_t did = -1; /* Dataset ID */ + hid_t sid = -1; /* Dataspace ID */ + hid_t dcpl = -1; /* A copy of dataset creation property */ + hid_t dapl = -1; /* A copy of dataset access property */ + hid_t ffapl = -1; /* The file's file access property list */ + + hsize_t dims[2] = {0, 10}; /* Current dimension sizes */ + hsize_t maxdims[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; /* Maximum dimension sizes */ + hsize_t chunk_dims[2] = {2,5}; /* Chunk dimension sizes */ + int lbuf[60], cbuf[6][3]; /* Data buffers */ + int buf[6][13], rbuf[6][13]; /* Data buffers */ + int i, j, k; /* Local index variables */ + + hsize_t boundary[2] = {3, 7}; /* Boundary sizes */ + unsigned append_ct = 0; /* The # of appends */ + unsigned *flush_ptr; /* Points to the flush counter */ + + TESTING("Append flush with H5DOappend()--append & boundary size vary"); + + /* Get the file's file access property list */ + if((ffapl = H5Fget_access_plist(fid)) < 0) + FAIL_STACK_ERROR; + + /* Set to create a chunked dataset with 2 extendible dimensions */ + if((sid = H5Screate_simple(2, dims, maxdims)) < 0) + FAIL_STACK_ERROR; + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_chunk(dcpl, 2, chunk_dims) < 0) + FAIL_STACK_ERROR; + + /* Set append flush property */ + if((dapl = H5Pcreate(H5P_DATASET_ACCESS)) < 0) + FAIL_STACK_ERROR; + if(H5Pset_append_flush(dapl, 2, boundary, append_func, &append_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the dataset */ + if((did = H5Dcreate2(fid, DNAME_VARY, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, dapl)) < 0) + TEST_ERROR; + + /* Append to the dataset 6 lines at a time for 1 time */ + for(i = 0, k = 0; i < 6; i++) { + for(j = 0; j < 10; j++, k++) + buf[i][j] = lbuf[k] = (i*10) + (j+1); + } + if(H5DOappend(did, H5P_DEFAULT, 0, (size_t)6, H5T_NATIVE_INT, lbuf) < 0) + TEST_ERROR; + + /* Verify the # of appends */ + if(append_ct != 1) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 1) + TEST_ERROR; + + /* Append to the dataset 3 columns at a time for 1 time */ + for(i = 0; i < 3; i++) { + for(j = 0; j < 6; j++, k++) + cbuf[j][i] = buf[j][i+10] = ((i*6) + (j+1)) * -1; + } + if(H5DOappend(did, H5P_DEFAULT, 1, (size_t)3, H5T_NATIVE_INT, cbuf) < 0) + TEST_ERROR; + + /* Verify the # of appends */ + if(append_ct != 1) + TEST_ERROR; + + /* Retrieve and verify object flush counts */ + if(H5Pget_object_flush_cb(ffapl, NULL, (void **)&flush_ptr) < 0) + FAIL_STACK_ERROR; + if(*flush_ptr != 1) + TEST_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Clear the dataset */ + HDmemset(rbuf, 0, sizeof(rbuf)); + + /* Close the dataset */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + + /* Open the dataset again */ + if((did = H5Dopen(fid, DNAME_VARY, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR; + + /* Read the dataset */ + if(H5Dread(did, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) + FAIL_STACK_ERROR; + + /* Verify the data */ + for(i = 0; i < 6; i++) + for(j = 0; j < 13; j++) + if(buf[i][j] != rbuf[i][j]) + TEST_ERROR; + + /* Closing */ + if(H5Dclose(did) < 0) + FAIL_STACK_ERROR; + if(H5Sclose(sid) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dapl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(dcpl) < 0) + FAIL_STACK_ERROR; + if(H5Pclose(ffapl) < 0) + FAIL_STACK_ERROR; + + PASSED(); + + return 0; + +error: + H5E_BEGIN_TRY { + H5Pclose(dapl); + H5Pclose(dcpl); + H5Pclose(sid); + H5Dclose(did); + H5Pclose(ffapl); + } H5E_END_TRY; + + return 1; +} /* test_dataset_append_vary() */ + +/*------------------------------------------------------------------------- + * Function: Main function + * + * Purpose: Test H5Pset/get_object_flush_cb() and H5Pset/get_append_flush() + * along with H5DOappend(). + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +int main(void) +{ + hid_t fid = -1; /* File ID */ + hid_t fapl = -1; /* File access property list */ + unsigned flush_ct = 0; /* The # of flushes */ + int nerrors = 0; /* The # of errors encountered */ + + /* Get a copy of file access property list */ + if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0) + FAIL_STACK_ERROR; + + /* Set to use the latest library format */ + if(H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) + FAIL_STACK_ERROR; + + /* Set object flush property */ + if(H5Pset_object_flush_cb(fapl, flush_func, &flush_ct) < 0) + FAIL_STACK_ERROR; + + /* Create the test file */ + if((fid = H5Fcreate(FILE, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + FAIL_STACK_ERROR; + + nerrors += test_dataset_append_lines_columns(fid); + + flush_ct = 0; /* Reset flush counter */ + nerrors += test_dataset_append_lines(fid); + + flush_ct = 0; /* Reset flush counter */ + nerrors += test_dataset_append_columns(fid); + +#ifdef BUG1_BUG2 +/* + * The following tests illustrate the scenarios when H5DOappend does not work with extensible array indexing: + * - when the the dataset has 1 unlimited dimension and the other dimension is fixed but extendible + * - the dataset expands along 1 dimension and then expands along the other dimension + */ + flush_ct = 0; /* Reset flush counter */ + nerrors += test_dataset_append_BUG1(fid); + + flush_ct = 0; /* Reset flush counter */ + nerrors += test_dataset_append_BUG2(fid); +#endif + + flush_ct = 0; /* Reset flush counter */ + nerrors += test_dataset_append_less(fid); + + flush_ct = 0; /* Reset flush counter */ + nerrors += test_dataset_append_vary(fid); + + /* Closing */ + if(H5Pclose(fapl) < 0) + FAIL_STACK_ERROR; + if(H5Fclose(fid) < 0) + FAIL_STACK_ERROR; + + /* Check for errors */ + if(nerrors) + goto error; + + return 0; + +error: + return 1; +} diff --git a/hl/test/test_file_image.c b/hl/test/test_file_image.c index 831fa23..fe0329d 100644 --- a/hl/test/test_file_image.c +++ b/hl/test/test_file_image.c @@ -20,6 +20,12 @@ #define RANK 2 +/* For superblock version 0, 1: the offset to "file consistency flags" is 20 with size of 4 bytes */ +/* The file consistency flags is the "status_flags" field in H5F_super_t */ +/* Note: the offset and size will be different when using superblock version 2 for the test file */ +#define SUPER_STATUS_FLAGS_OFF_V0_V1 20 +#define SUPER_STATUS_FLAGS_SIZE_V0_V1 4 + /* Test of file image operations. The following code provides a means to thoroughly test the file image @@ -158,7 +164,7 @@ test_file_image(size_t open_images, size_t nflags, unsigned *flags) FAIL_PUTS_ERROR("H5Dclose() failed"); /* get size of the file image i */ - if ((buf_size[i] = H5Fget_file_image(file_id[i], NULL, 0)) < 0) + if ((buf_size[i] = H5Fget_file_image(file_id[i], NULL, (size_t)0)) < 0) FAIL_PUTS_ERROR("H5Fget_file_image() failed"); /* allocate buffer for the file image i */ @@ -214,10 +220,32 @@ test_file_image(size_t open_images, size_t nflags, unsigned *flags) else VERIFY(*core_buf_ptr_ptr != buf_ptr[i], "vfd buffer and user buffer should be different"); - /* test whether the contents of the user buffer and driver buffer */ - /* are equal. */ - if (HDmemcmp(*core_buf_ptr_ptr, buf_ptr[i], (size_t)buf_size[i]) != 0) - FAIL_PUTS_ERROR("comparison of vfd and user buffer failed"); + /* + * When the vfd and user buffers are different and H5LT_FILE_IMAGE_OPEN_RW is enabled, + * status_flags in the superblock needs to be cleared in the vfd buffer for + * the comparison to proceed as expected. The user buffer as returned from H5Fget_file_image() + * has already cleared status_flags. The superblock's status_flags is used for the + * implementation of file locking. + */ + if(input_flags[i] & H5LT_FILE_IMAGE_OPEN_RW && !(input_flags[i] & H5LT_FILE_IMAGE_DONT_COPY)) { + + void *tmp_ptr = HDmalloc((size_t)buf_size[i]); + /* Copy vfd buffer to a temporary buffer */ + HDmemcpy(tmp_ptr, (void *)*core_buf_ptr_ptr, (size_t)buf_size[i]); + /* Clear status_flags in the superblock for the vfd buffer: file locking is using status_flags */ + HDmemset((uint8_t *)tmp_ptr + SUPER_STATUS_FLAGS_OFF_V0_V1, (int)0, (size_t)SUPER_STATUS_FLAGS_SIZE_V0_V1); + /* Does the comparision */ + if(HDmemcmp(tmp_ptr, buf_ptr[i], (size_t)buf_size[i]) != 0) + FAIL_PUTS_ERROR("comparison of TMP vfd and user buffer failed"); + /* Free the temporary buffer */ + if(tmp_ptr) HDfree(tmp_ptr); + } else { + + /* test whether the contents of the user buffer and driver buffer */ + /* are equal. */ + if (HDmemcmp(*core_buf_ptr_ptr, buf_ptr[i], (size_t)buf_size[i]) != 0) + FAIL_PUTS_ERROR("comparison of vfd and user buffer failed"); + } } /* end else */ } /* end for */ @@ -370,7 +398,7 @@ test_file_image(size_t open_images, size_t nflags, unsigned *flags) H5Aclose(attr_id); } H5E_END_TRY; #endif - file_id[i] = -1; + file_id[i] = -1; } /* end if */ else { /* write dataset without extending it */ diff --git a/hl/test/test_ld.h5 b/hl/test/test_ld.h5 Binary files differindex 40c4ff0..db34c25 100644 --- a/hl/test/test_ld.h5 +++ b/hl/test/test_ld.h5 diff --git a/hl/test/test_ld.sh.in b/hl/test/test_ld.sh.in index 69beea6..b263f2a 100644 --- a/hl/test/test_ld.sh.in +++ b/hl/test/test_ld.sh.in @@ -21,14 +21,14 @@ DEPRECATED_SYMBOLS="@DEPRECATED_SYMBOLS@" CMP='cmp -s' DIFF='diff -c' -CP='cp' -KILL='kill' -SLEEP='sleep' -LD_MONITOR=ld_monitor +LD_MONITOR='ld_mx -m' LD_MONITOR_BIN=`pwd`/$LD_MONITOR -LD_EXTEND=ld_extend +LD_EXTEND='ld_mx -x' LD_EXTEND_BIN=`pwd`/$LD_EXTEND - +# These two message files should be the same as the two defines in ./ld_mx.c +READER_MESSAGE='LD_READER_MESSAGE' +WRITER_MESSAGE='LD_WRITER_MESSAGE' +# nerrors=0 verbose=yes @@ -51,18 +51,24 @@ TESTING() { # $2 -- the dataset name to be monitored and extended # $3 -- the expected output from monitoring the dataset TESTLD() { - expect="$srcdir/testfiles/$3" # the expected output - actual="./testfiles/$3.OUT" # the actual output - FNAME="`basename $1 .h5`_$2.h5" # the HDF5 file - $CP $srcdir/$1 ./$FNAME # copy the file to a temporary file + expect="$srcdir/testfiles/$3" # the expected output + actual="./testfiles/$3.OUT" # the actual output + FNAME="`basename $1 .h5`_$2.h5" # the HDF5 file + cp $srcdir/$1 ./$FNAME # copy the file to a temporary file +# + rm -f $WRITER_MESSAGE # remove the message file just to be sure + rm -f $READER_MESSAGE # remove the message file just to be sure +# + $LD_EXTEND_BIN $FNAME $2 & # extend the dataset + EXTEND_PID=$! # get the id of the "extend" process $LD_MONITOR_BIN $FNAME $2 > $actual 2>&1 & # monitor the dataset in the file - MONITOR_PID=$! # get the id of the monitor process - $LD_EXTEND_BIN $FNAME $2 # extend the dataset - echo "Sleeping for 3 seconds..." - $SLEEP 3 # sleep to allow output to be flushed - echo "Killing the monitor..." - $KILL $MONITOR_PID # kill the monitor process - if $CMP $expect $actual; then # compare the output with the expected output + MONITOR_PID=$! # get the id of the "monitor" process + wait $EXTEND_PID # wait for the completion of the "extend" process +# + sleep 1 # sleep to ensure that the monitoring completes + kill $MONITOR_PID # kill the "monitor" process +# + if $CMP $expect $actual; then # compare the output with the expected output echo " PASSED" else echo "*FAILED*" @@ -70,7 +76,7 @@ TESTLD() { nerrors="`expr $nerrors + 1`" test yes = "$verbose" && $DIFF $expect $actual |sed 's/^/ /' fi - if test -z "$HDF5_NOCLEANUP"; then # clean up output file, temporary HDF5 file + if test -z "$HDF5_NOCLEANUP"; then # clean up output file, temporary HDF5 file rm -f $actual $FNAME fi } @@ -84,9 +90,11 @@ TESTLD() { # Monitor DSET_ONE while extending the dataset TESTLD test_ld.h5 DSET_ONE test_ld_out1 # +# # Monitor DSET_TWO while extending the dataset TESTLD test_ld.h5 DSET_TWO test_ld_out2 - +# +# if test $nerrors -eq 0 ; then echo "All high level H5LD concurrent tests passed." fi diff --git a/hl/test/test_table_be.h5 b/hl/test/test_table_be.h5 Binary files differindex 3639695..970018e 100644 --- a/hl/test/test_table_be.h5 +++ b/hl/test/test_table_be.h5 diff --git a/hl/test/test_table_cray.h5 b/hl/test/test_table_cray.h5 Binary files differindex d22dce3..1fcd75b 100644 --- a/hl/test/test_table_cray.h5 +++ b/hl/test/test_table_cray.h5 diff --git a/hl/test/test_table_le.h5 b/hl/test/test_table_le.h5 Binary files differindex 6c330fd..ee5b532 100644 --- a/hl/test/test_table_le.h5 +++ b/hl/test/test_table_le.h5 diff --git a/hl/tools/h5watch/h5watch.c b/hl/tools/h5watch/h5watch.c index 615504e..c5f6f8d 100644 --- a/hl/tools/h5watch/h5watch.c +++ b/hl/tools/h5watch/h5watch.c @@ -30,6 +30,7 @@ #define FIELD_SEP "," /* nested field separator */ #define DEFAULT_RETRY 10 /* number of times to try opening the file */ + /* * Note:(see comments in hl/src/H5LDprivate.h) * This tool uses private routines H5LD_construct_vector()and H5LD_clean_vector() @@ -108,7 +109,6 @@ static struct long_options l_opts[] = { { NULL, 0, '\0' } }; - /*------------------------------------------------------------------------- * Function: doprint() * diff --git a/hl/tools/h5watch/testh5watch.sh.in b/hl/tools/h5watch/testh5watch.sh.in index 324ddb3..6de127e 100644 --- a/hl/tools/h5watch/testh5watch.sh.in +++ b/hl/tools/h5watch/testh5watch.sh.in @@ -191,7 +191,7 @@ TEST_WATCH() { wait $extend_pid # Wait for "extend" process to complete extend_exit=$? # Collect "extend" process' exit code sleep 1 # Sleep to make sure output is flushed - kill $watch_pid # Kill h5watch + kill $watch_pid # Kill h5watch wait $watch_pid # Wait for "h5watch" process to complete # if [ $extend_exit -ne 0 ]; then # Error returned from "extend" process |