summaryrefslogtreecommitdiffstats
path: root/hl
diff options
context:
space:
mode:
authorVailin Choi <vchoi@hdfgroup.org>2015-06-26 18:44:27 (GMT)
committerVailin Choi <vchoi@hdfgroup.org>2015-06-26 18:44:27 (GMT)
commit130e77f4fa8044b2e2e06cf18b74ed8f8c64665a (patch)
tree0aaac762383218a930bc513108de585225eb6cf9 /hl
parent39b99473ea6e83aa394779a591eeef55fe141487 (diff)
downloadhdf5-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.c203
-rw-r--r--hl/src/H5DOpublic.h7
-rw-r--r--hl/src/H5HLprivate2.h91
-rw-r--r--hl/src/H5LD.c2
-rw-r--r--hl/test/Makefile.am8
-rw-r--r--hl/test/Makefile.in82
-rw-r--r--hl/test/gen_test_ld.c14
-rw-r--r--hl/test/ld_extend.c151
-rw-r--r--hl/test/ld_monitor.c190
-rw-r--r--hl/test/ld_mx.c353
-rw-r--r--hl/test/test_dset_append.c1198
-rw-r--r--hl/test/test_file_image.c40
-rw-r--r--hl/test/test_ld.h5bin28336 -> 42955 bytes
-rw-r--r--hl/test/test_ld.sh.in46
-rw-r--r--hl/test/test_table_be.h5bin55912 -> 55912 bytes
-rw-r--r--hl/test/test_table_cray.h5bin55912 -> 55912 bytes
-rw-r--r--hl/test/test_table_le.h5bin53880 -> 53880 bytes
-rw-r--r--hl/tools/h5watch/h5watch.c2
-rw-r--r--hl/tools/h5watch/testh5watch.sh.in2
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
index 40c4ff0..db34c25 100644
--- a/hl/test/test_ld.h5
+++ b/hl/test/test_ld.h5
Binary files differ
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
index 3639695..970018e 100644
--- a/hl/test/test_table_be.h5
+++ b/hl/test/test_table_be.h5
Binary files differ
diff --git a/hl/test/test_table_cray.h5 b/hl/test/test_table_cray.h5
index d22dce3..1fcd75b 100644
--- a/hl/test/test_table_cray.h5
+++ b/hl/test/test_table_cray.h5
Binary files differ
diff --git a/hl/test/test_table_le.h5 b/hl/test/test_table_le.h5
index 6c330fd..ee5b532 100644
--- a/hl/test/test_table_le.h5
+++ b/hl/test/test_table_le.h5
Binary files differ
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