summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormyang6 <myang6@hdfgroup.org>2021-11-02 17:20:14 (GMT)
committermyang6 <myang6@hdfgroup.org>2021-11-02 17:20:14 (GMT)
commit2045b7984b6ffb71cb75393230a11edfed03f3fb (patch)
tree62c99fff7e213d12d403902d2710821335b68f9f
parentabed0f75f22ebbcd777def072ff286f296d32908 (diff)
downloadhdf5-2045b7984b6ffb71cb75393230a11edfed03f3fb.zip
hdf5-2045b7984b6ffb71cb75393230a11edfed03f3fb.tar.gz
hdf5-2045b7984b6ffb71cb75393230a11edfed03f3fb.tar.bz2
1. Close the log file when the file closing flag is true in H5F_vfd_swmr_close_or_flush().
2. Move the log test to the group performance test code with an option. 3. Use constant variables for log message lengths. 4. Misc. clean-up.
-rw-r--r--MANIFEST1
-rw-r--r--src/H5FDvfd_swmr_private.h3
-rw-r--r--src/H5Fint.c33
-rw-r--r--src/H5Fpkg.h10
-rw-r--r--src/H5Fvfd_swmr.c36
-rw-r--r--test/Makefile.am3
-rw-r--r--test/vfd_swmr_gperf_writer.c37
-rw-r--r--test/vfd_swmr_log_writer.c2929
8 files changed, 77 insertions, 2975 deletions
diff --git a/MANIFEST b/MANIFEST
index 208bfc3..75a7aca 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1444,7 +1444,6 @@
./test/vfd_swmr_vlstr_writer.c
./test/vfd_swmr_writer.c
./test/vfd_swmr_zoo_writer.c
-./test/vfd_swmr_log_writer.c
./test/vfd.c
./test/vol.c
./test/vol_plugin.c
diff --git a/src/H5FDvfd_swmr_private.h b/src/H5FDvfd_swmr_private.h
index 02e1c44..985bd70 100644
--- a/src/H5FDvfd_swmr_private.h
+++ b/src/H5FDvfd_swmr_private.h
@@ -84,8 +84,5 @@ H5_DLL herr_t H5F_vfd_swmr_insert_entry_eot(struct H5F_t *f);
H5_DLL void H5F_vfd_swmr_update_entry_eot(eot_queue_entry_t *);
H5_DLL herr_t H5F_dump_eot_queue(void);
-/***************************************/
-/* Log Macros and Functions */
-/***************************************/
#endif /* H5FDvfd_swmr_private_H */
diff --git a/src/H5Fint.c b/src/H5Fint.c
index 1adc7d5..c0579bd 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -2014,23 +2014,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Short cuts */
shared = file->shared;
- /* Set up the VFD SWMR LOG file */
- /* Kent*/
- if (vfd_swmr_config_ptr->version) {
- if (HDstrlen(vfd_swmr_config_ptr->log_file_path) > 0)
- shared->vfd_swmr_log_on = TRUE;
- if (TRUE == shared->vfd_swmr_log_on) {
- /* Create the log file */
- if ((shared->vfd_swmr_log_file_ptr = HDfopen(vfd_swmr_config_ptr->log_file_path, "w")) == NULL)
- HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create the log file")
- if (H5_timer_init(&(shared->vfd_swmr_log_start_time)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't initialize HDF5 timer.")
- if (H5_timer_start(&(shared->vfd_swmr_log_start_time)) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't obtain the time from the HDF5 timer.")
- }
- }
- /* End of Kent */
-
lf = shared->lf;
/* Set the file locking flag. If the file is already open, the file
@@ -2110,6 +2093,22 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id)
/* Checked if configured for VFD SWMR */
if (H5F_VFD_SWMR_CONFIG(file)) {
+
+ /* Set up the VFD SWMR LOG file */
+ /* Kent*/
+ if (HDstrlen(vfd_swmr_config_ptr->log_file_path) > 0)
+ shared->vfd_swmr_log_on = TRUE;
+ if (TRUE == shared->vfd_swmr_log_on) {
+ /* Create the log file */
+ if ((shared->vfd_swmr_log_file_ptr = HDfopen(vfd_swmr_config_ptr->log_file_path, "w")) == NULL)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to create the log file")
+ if (H5_timer_init(&(shared->vfd_swmr_log_start_time)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't initialize HDF5 timer.")
+ if (H5_timer_start(&(shared->vfd_swmr_log_start_time)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't obtain the time from the HDF5 timer.")
+ }
+ /* End of Kent */
+
/* Initialization for VFD SWMR writer and reader */
if (1 == shared->nrefs) {
if (H5F_vfd_swmr_init(file, file_create) < 0)
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 3de5a84..3bece42 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -625,7 +625,7 @@ H5_DLL herr_t H5F__reparse_file_lock_variable_test(void);
* a log entry_type_code, which generates a log tag, and the message log_info, which
* the developers want to save into a log file.
*
- * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, number_entry_production, m) is
+ * The macro H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, number_entry_production, m) is
* called by H5F_POST_VFD_SWMR_LOG_ENTRY when the HDF5 library is built with the
* production mode. Number_entry_production will control the number of entry tags that
* applications can receive. Currently this number is set to 1 and is subject to change
@@ -649,21 +649,21 @@ H5_DLL void H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log
} \
} while (0)
-#define H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(fp, entry_type_code, max_code, log_info) \
+#define H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(fp, entry_type_code, max_code, log_info) \
do { \
if (entry_type_code < max_code) { \
H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(fp, entry_type_code, log_info); \
} \
} while (0)
-/* Note: change H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, 1, m) on the following lines to
- * H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, your_number_entry_production, m)
+/* Note: change H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m) on the following lines to
+ * H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, your_number_entry_production, m)
* as necessary.
*/
#ifndef NDEBUG
#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_INTERNAL(f, c, m)
#else
-#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_RELEASE(f, c, 1, m)
+#define H5F_POST_VFD_SWMR_LOG_ENTRY(f, c, m) H5F_POST_VFD_SWMR_LOG_ENTRY_PRODUCTION(f, c, 1, m)
#endif
#endif /* H5Fpkg_H */
diff --git a/src/H5Fvfd_swmr.c b/src/H5Fvfd_swmr.c
index 476af3e..9404cf4 100644
--- a/src/H5Fvfd_swmr.c
+++ b/src/H5Fvfd_swmr.c
@@ -54,6 +54,7 @@
#define nanosecs_per_second 1000000000 /* nanoseconds per second */
#define nanosecs_per_tenth_sec 100000000 /* nanoseconds per 0.1 second */
+
/* Declare an array of string to identify the VFD SMWR Log tags.
* Note this array is used to generate the entry tag by the log reporting macro
* H5F_POST_VFD_SWMR_LOG_ENTRY.
@@ -86,6 +87,12 @@ static const char *H5Fvfd_swmr_log_tags[] = {
*/
const char *log_fmt_str = "%-26s: %.3lf s: %s\n";
+/* The length of the EOT processing time log message, subject to change */
+const unsigned int eot_pt_log_mesg_length = 48;
+
+/* The length of error message in the log */
+const unsigned int log_err_mesg_length = 14;
+
/********************/
/* Local Prototypes */
/********************/
@@ -350,8 +357,9 @@ H5F_vfd_swmr_close_or_flush(H5F_t *f, hbool_t closing)
if (H5F__vfd_swmr_update_end_of_tick_and_tick_num(shared, TRUE) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTSET, FAIL, "unable to update end of tick");
}
-#if 1 /*Kent Save the end of close or flush info. to the log file, subject to comment out. */
- H5F_POST_VFD_SWMR_LOG_ENTRY(f, 2, "VFD SWMR File close or flush ends");
+#if 1 /*Kent Save the end of close info. to the log file, subject to comment out. */
+ if(closing)
+ H5F_POST_VFD_SWMR_LOG_ENTRY(f, 2, "VFD SWMR File close ends");
#endif
done:
@@ -359,7 +367,7 @@ done:
* Please REVIEW to ensure this is the right place to
* close the log file.
*/
- if (shared->vfd_swmr_log_on) {
+ if (shared->vfd_swmr_log_on && closing) {
H5_timer_stop(&(shared->vfd_swmr_log_start_time));
HDfclose(shared->vfd_swmr_log_file_ptr);
}
@@ -948,11 +956,12 @@ done:
if (H5_timer_get_times(shared->vfd_swmr_log_start_time, &current_time) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get time from H5_timer_get_times")
end_elapsed_time = current_time.elapsed;
- log_msg = HDmalloc(48);
- temp_time = (unsigned int)((end_elapsed_time - start_elapsed_time) * 1000);
- HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time);
- H5F_POST_VFD_SWMR_LOG_ENTRY(f, 0, log_msg);
- HDfree(log_msg);
+ if(NULL != (log_msg = HDmalloc(eot_pt_log_mesg_length*sizeof(char)))) {
+ temp_time = (unsigned int)((end_elapsed_time - start_elapsed_time) * 1000);
+ HDsprintf(log_msg, "Writer time is %u milliseconds", temp_time);
+ H5F_POST_VFD_SWMR_LOG_ENTRY(f, 0, log_msg);
+ HDfree(log_msg);
+ }
}
/* Kent */
FUNC_LEAVE_NOAPI(ret_value)
@@ -1988,11 +1997,12 @@ H5F_post_vfd_swmr_log_entry(H5F_t *f, int entry_type_code, char *log_info)
else obtain the elapsed time in seconds since the log file
was created and write the time to the log file. */
if (H5_timer_get_times(f->shared->vfd_swmr_log_start_time, &current_time) < 0) {
- gettime_error = HDmalloc(14);
- HDsprintf(gettime_error, "gettime_error");
- HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code],
- gettime_error);
- HDfree(gettime_error);
+ if(NULL != (gettime_error = HDmalloc(log_err_mesg_length*sizeof(char)))) {
+ HDsprintf(gettime_error, "gettime_error");
+ HDfprintf(f->shared->vfd_swmr_log_file_ptr, "%-26s: %s\n", H5Fvfd_swmr_log_tags[entry_type_code],
+ gettime_error);
+ HDfree(gettime_error);
+ }
}
else {
temp_time = current_time.elapsed;
diff --git a/test/Makefile.am b/test/Makefile.am
index a97e968..87b2925 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -56,7 +56,6 @@ SCRIPT_DEPEND = error_test$(EXEEXT) err_compat$(EXEEXT) links_env$(EXEEXT) \
vfd_swmr_zoo_reader$(EXEEXT) vfd_swmr_zoo_writer$(EXEEXT) \
vfd_swmr_gperf_reader$(EXEEXT) vfd_swmr_gperf_writer$(EXEEXT) \
vfd_swmr_gfail_reader$(EXEEXT) vfd_swmr_gfail_writer$(EXEEXT) \
- vfd_swmr_log_reader$(EXEEXT) vfd_swmr_log_writer$(EXEEXT) \
vds_env$(EXEEXT) \
vds_swmr_gen$(EXEEXT) vds_swmr_reader$(EXEEXT) vds_swmr_writer$(EXEEXT)
if HAVE_SHARED_CONDITIONAL
@@ -116,7 +115,6 @@ check_PROGRAMS=$(TEST_PROG) error_test err_compat tcheck_version \
vfd_swmr_attrdset_reader vfd_swmr_attrdset_writer \
vfd_swmr_gperf_reader vfd_swmr_gperf_writer \
vfd_swmr_gfail_reader vfd_swmr_gfail_writer \
- vfd_swmr_log_reader vfd_swmr_log_writer \
vfd_swmr_check_compat \
vfd_swmr_dsetchks_reader vfd_swmr_dsetchks_writer \
swmr_check_compat_vfd vds_env vds_swmr_gen vds_swmr_reader vds_swmr_writer \
@@ -186,7 +184,6 @@ vfd_swmr_bigset_reader_SOURCES=vfd_swmr_bigset_writer.c
vfd_swmr_group_reader_SOURCES=vfd_swmr_group_writer.c
vfd_swmr_gperf_reader_SOURCES=vfd_swmr_gperf_writer.c
vfd_swmr_gfail_reader_SOURCES=vfd_swmr_gfail_writer.c
-vfd_swmr_log_reader_SOURCES=vfd_swmr_log_writer.c
vfd_swmr_dsetops_reader_SOURCES=vfd_swmr_dsetops_writer.c
vfd_swmr_attrdset_writer_SOURCES=vfd_swmr_attrdset_writer.c
diff --git a/test/vfd_swmr_gperf_writer.c b/test/vfd_swmr_gperf_writer.c
index e21f931..ad2b373 100644
--- a/test/vfd_swmr_gperf_writer.c
+++ b/test/vfd_swmr_gperf_writer.c
@@ -12,6 +12,12 @@
/* Description of this program:
* This program checks the performance of group creations for VFD SWMR.
+ * It also has an option to turn on the VFD SWMR logging feature and generates
+ * a log message for group creations. The performance test illustration is in
+ * section I. The log feature illustration is in section II.
+ *
+ * I. Performance tests with options
+ *
* Currently the group creation time, H5Fopen and H5Fclose time are measured.
* After compiling the program,
* ./vfd_swmr_gperf_writer -n 1000 -P -N 5 -q
@@ -29,6 +35,18 @@
* The program is run with max_lag = 8, tick_len = 4;
* The page buffer size is 16384 bytes. The page size is 8192 bytes.
*
+ * II. How to generate log message
+ *
+ * ./vfd_swmr_gperf_writer -n 100000 -P -L -q
+ * will generate 100000 groups, each group has one attribute. It also writes the log message
+ * to file "log-test" under the same directory.
+ * To turn on the log feature, one just needs to provide the log file path as
+ * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main
+ * function. The init_vfd_swmr_log is defined inside the vfd_swmr_common.c.
+ * The "log-test" should include something like:
+ * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds'
+ * The standard output of performance measurement can help check the correctness in the "log-test".
+ *
*/
#define H5F_FRIEND /*suppress error about including H5Fpkg */
@@ -63,6 +81,7 @@ typedef struct {
uint32_t max_lag;
uint32_t tick_len;
bool gperf;
+ bool glog;
double min_gc_time;
double max_gc_time;
double mean_gc_time;
@@ -84,7 +103,7 @@ typedef struct {
.file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \
.filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \
.old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \
- .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \
+ .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .glog = false, .min_gc_time = 100., \
.max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \
.fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \
.pbs = 4096, .nglevels = 0 \
@@ -95,14 +114,16 @@ usage(const char *progname)
{
fprintf(stderr,
"usage: ./%s -P -n 1000 -N 5 -q (create 1000 groups, each group has 5 attributes)\n"
+ "usage: ./%s -P -L -n 100000 -q (create 100000 groups and generate log message to file 'log-test')\n"
"Options: \n"
- " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n"
+ " [-P] [-S] [-G] [-L] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n"
" [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n"
" [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n"
"\n"
"-P: carry out the performance test\n"
"-S: do not use VFD SWMR\n"
"-G: old-style type of group\n"
+ "-L: Turn on the logging feature.\n"
"-t tick_len: length of a tick in tenths of a second.\n"
"-m max_lag: maximum expected lag(in ticks) between writer and readers\n"
"-B pbs: page Buffer Size in bytes:\n"
@@ -174,7 +195,7 @@ usage(const char *progname)
" (Don't recommend to use this option for performance test.)\n"
"-q: silence printouts, few messages\n"
"\n",
- progname);
+ progname,progname);
exit(EXIT_FAILURE);
}
@@ -203,7 +224,7 @@ state_init(state_t *s, int argc, char **argv)
if (argc == 1)
usage(s->progname);
- while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) {
+ while ((ch = getopt(argc, argv, "PSGLa:bVt:m:B:s:n:qA:N:l:O:")) != -1) {
switch (ch) {
case 'P':
s->gperf = true;
@@ -214,6 +235,9 @@ state_init(state_t *s, int argc, char **argv)
case 'G':
s->old_style_grp = true;
break;
+ case 'L':
+ s->glog = true;
+ break;
case 'a':
case 'n':
case 'N':
@@ -2764,6 +2788,11 @@ main(int argc, char **argv)
/* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow");
+ /* If the log flag is on, create the log file log-test under the current directory. */
+ if(s.glog == true)
+ init_vfd_swmr_log(&config, "./log-test");
+
+
/* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST)
* as the second parameter of H5Pset_libver_bound() that is called by
* vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST)
diff --git a/test/vfd_swmr_log_writer.c b/test/vfd_swmr_log_writer.c
deleted file mode 100644
index 06b5654..0000000
--- a/test/vfd_swmr_log_writer.c
+++ /dev/null
@@ -1,2929 +0,0 @@
-/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- * Copyright by The HDF Group. *
- * 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 COPYING file, which can be found at the root of the source code *
- * distribution tree, or in https://www.hdfgroup.org/licenses. *
- * If you do not have access to either file, you may request a copy from *
- * help@hdfgroup.org. *
- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
-/* Description of this program:
- * This program shows an example on how a VFD log file can be written.
- * It is adapted from the group performence test. Most options of the
- * group performance test are still kept.
- * To turn on the log feature, one just needs to provide the log file path as
- * indicated by the line init_vfd_swmr_log(&config, "./log-test") in the main
- * function. The init_vfd_swmr_log is defined inside the vfd_swmr_common.c.
- * For the demo of the log feature,
- * one just needs to do te following:
- * After compiling the program, just run the following line
- * ./vfd_swmr_log_writer -n 100000 -P -q
- * A VFD SWMR log file "log-test" is generated.
- * The "log-test" should include something like:
- * 'EOT_PROCESSING_TIME : 0.040 s: Writer time is 1 milliseconds'
- * This program also checks the performance of group creations for VFD SWMR.
- * Currently the group creation time, H5Fopen and H5Fclose time are measured.
- * The standard output can help check the contents in the "log-test".
- *
- */
-#define H5F_FRIEND /*suppress error about including H5Fpkg */
-
-#include "hdf5.h"
-
-#include "H5Fpkg.h"
-#include "H5HGprivate.h"
-#include "H5VLprivate.h"
-
-#include "testhdf5.h"
-#include "vfd_swmr_common.h"
-
-#ifndef H5_HAVE_WIN32_API
-
-#define VS_ATTR_NAME_LEN 21
-
-#define TIME_PASSED(X, Y) \
- ((double)((Y.tv_sec - X.tv_sec) * 1000000000 + (Y.tv_nsec - X.tv_nsec))) / 1000000000.0
-
-typedef struct {
- hid_t file, filetype, one_by_one_sid;
- char filename[PATH_MAX];
- char progname[PATH_MAX];
- unsigned int asteps;
- unsigned int nsteps;
- bool use_vfd_swmr;
- bool old_style_grp;
- char grp_op_pattern;
- bool grp_op_test;
- char at_pattern;
- bool attr_test;
- uint32_t max_lag;
- uint32_t tick_len;
- bool gperf;
- double min_gc_time;
- double max_gc_time;
- double mean_gc_time;
- double total_gc_time;
- double total_time;
- double mean_time;
- double fo_total_time;
- double fc_total_time;
- unsigned int num_attrs;
- bool vlstr_test;
- unsigned int ps;
- unsigned int pbs;
- unsigned int nglevels;
-} state_t;
-
-#define ALL_HID_INITIALIZER \
- (state_t) \
- { \
- .file = H5I_INVALID_HID, .one_by_one_sid = H5I_INVALID_HID, .filename = "", \
- .filetype = H5T_NATIVE_UINT32, .asteps = 1, .nsteps = 100, .use_vfd_swmr = true, \
- .old_style_grp = false, .grp_op_pattern = ' ', .grp_op_test = false, .at_pattern = ' ', \
- .attr_test = false, .tick_len = 4, .max_lag = 7, .gperf = false, .min_gc_time = 100., \
- .max_gc_time = 0., .mean_gc_time = 0., .total_gc_time = 0., .total_time = 0., .mean_time = 0., \
- .fo_total_time = 0., .fc_total_time = 0., .num_attrs = 1, .vlstr_test = false, .ps = 4096, \
- .pbs = 4096, .nglevels = 0 \
- }
-
-static void
-usage(const char *progname)
-{
- fprintf(stderr,
- "usage: ./%s -P -n 100000 -q (create 100000 groups, each group has 1 attribute)\n"
- "Options: \n"
- " [-P] [-S] [-G] [-t tick_len] [-m max_lag][-B pbs] [-s ps]\n"
- " [-n ngroups] [-l ng_levels] [-O grp_op_pattern]\n"
- " [-N num_attrs] [-V] [-b] [-A at_pattern] [-a steps] [-q]\n"
- "\n"
- "-P: carry out the performance test\n"
- "-S: do not use VFD SWMR\n"
- "-G: old-style type of group\n"
- "-t tick_len: length of a tick in tenths of a second.\n"
- "-m max_lag: maximum expected lag(in ticks) between writer and readers\n"
- "-B pbs: page Buffer Size in bytes:\n"
- " The default value is 4K(4096).\n"
- "-s ps: page size used by page aggregation, page buffer and \n"
- " the metadata file. \n"
- "-n ngroups: the number of groups\n"
- "-l ng_levels: the number of level of nested groups. \n"
- " If all the groups are under the root group, \n"
- " this number should be 0.\n"
- "-N num_attrs: the number of attributes \n"
- "-V use variable length string attributes for performance test\n"
- "-b: write data in big-endian byte order\n"
- " (For the performance test, -V overwrites -b)\n"
- "-A at_pattern: `at_pattern' for different attribute tests\n"
- "-O grp_op_pattern: `grp_op_pattern' for different group operation tests\n"
- "-a steps: `steps` between adding attributes\n"
- " (Don't recommend to use this option for performance test.)\n"
- "-q: silence printouts, few messages\n"
- "\n",
- progname);
- exit(EXIT_FAILURE);
-}
-
-static bool
-state_init(state_t *s, int argc, char **argv)
-{
- unsigned long tmp;
- int ch;
- const hsize_t dims = 1;
- char * tfile = NULL;
- char * end;
-
- *s = ALL_HID_INITIALIZER;
-
- if (H5_basename(argv[0], &tfile) < 0) {
- printf("H5_basename failed\n");
- TEST_ERROR;
- }
-
- esnprintf(s->progname, sizeof(s->progname), "%s", tfile);
-
- if (tfile) {
- HDfree(tfile);
- tfile = NULL;
- }
-
- if (argc == 1)
- usage(s->progname);
- while ((ch = getopt(argc, argv, "PSGa:bVt:m:B:s:n:qA:N:l:O:")) != -1) {
- switch (ch) {
- case 'P':
- s->gperf = true;
- break;
- case 'S':
- s->use_vfd_swmr = false;
- break;
- case 'G':
- s->old_style_grp = true;
- break;
- case 'a':
- case 'n':
- case 'N':
- case 'l':
- case 't':
- case 'm':
- case 'B':
- case 's':
- errno = 0;
- tmp = HDstrtoul(optarg, &end, 0);
- if (end == optarg || *end != '\0') {
- printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
- TEST_ERROR;
- }
- else if (errno != 0) {
- printf("couldn't parse `-%c` argument `%s`\n", ch, optarg);
- TEST_ERROR;
- }
- else if (tmp > UINT_MAX) {
- printf("`-%c` argument `%lu` too large\n", ch, tmp);
- TEST_ERROR;
- }
-
- if (ch == 'a')
- s->asteps = (unsigned)tmp;
- else if (ch == 'n')
- s->nsteps = (unsigned)tmp;
- else if (ch == 'N')
- s->num_attrs = (unsigned)tmp;
- else if (ch == 'l')
- s->nglevels = (unsigned)tmp;
- else if (ch == 't')
- s->tick_len = (unsigned)tmp;
- else if (ch == 'm')
- s->max_lag = (unsigned)tmp;
- else if (ch == 's')
- s->ps = (unsigned)tmp;
- else if (ch == 'B')
- s->pbs = (unsigned)tmp;
- break;
- case 'b':
- s->filetype = H5T_STD_U32BE;
- break;
- case 'V':
- s->vlstr_test = true;
- break;
- case 'O':
- if (HDstrcmp(optarg, "grp-creation") == 0)
- s->grp_op_pattern = 'c';
- else if (HDstrcmp(optarg, "grp-deletion") == 0)
- s->grp_op_pattern = 'd';
- else if (HDstrcmp(optarg, "grp-move") == 0)
- s->grp_op_pattern = 'm';
- else if (HDstrcmp(optarg, "grp-ins-links") == 0)
- s->grp_op_pattern = 'i';
- else if (HDstrcmp(optarg, "grp-del-links") == 0)
- s->grp_op_pattern = 'D';
- else if (HDstrcmp(optarg, "grp-compact-t-dense") == 0)
- s->grp_op_pattern = 't';
- else if (HDstrcmp(optarg, "grp-dense-t-compact") == 0)
- s->grp_op_pattern = 'T';
- else {
- printf("Invalid -O argument \"%s\"", optarg);
- TEST_ERROR;
- }
- break;
- case 'A':
- if (HDstrcmp(optarg, "compact") == 0)
- s->at_pattern = 'c';
- else if (HDstrcmp(optarg, "dense") == 0)
- s->at_pattern = 'd';
- else if (HDstrcmp(optarg, "compact-add-to-dense") == 0)
- s->at_pattern = 't';
- else if (HDstrcmp(optarg, "compact-del") == 0)
- s->at_pattern = 'C';
- else if (HDstrcmp(optarg, "dense-del") == 0)
- s->at_pattern = 'D';
- else if (HDstrcmp(optarg, "dense-del-to-compact") == 0)
- s->at_pattern = 'T';
- else if (HDstrcmp(optarg, "modify") == 0)
- s->at_pattern = 'M';
- else if (HDstrcmp(optarg, "add-vstr") == 0)
- s->at_pattern = 'v';
- else if (HDstrcmp(optarg, "remove-vstr") == 0)
- s->at_pattern = 'r';
- else if (HDstrcmp(optarg, "modify-vstr") == 0)
- s->at_pattern = 'm';
- else if (HDstrcmp(optarg, "add-ohr-block") == 0)
- s->at_pattern = 'a';
- else if (HDstrcmp(optarg, "del-ohr-block") == 0)
- s->at_pattern = 'R';
- else {
- printf("Invalid -A argument \"%s\"", optarg);
- TEST_ERROR;
- }
- break;
- case 'q':
- verbosity = 0;
- break;
- case '?':
- default:
- usage(s->progname);
- break;
- }
- }
- argc -= optind;
- argv += optind;
-
- if (s->grp_op_pattern != ' ')
- s->grp_op_test = true;
- if (s->at_pattern != ' ')
- s->attr_test = true;
-
- if (!s->grp_op_test) {
- if (s->asteps < 1 || s->asteps > s->nsteps) {
- printf("attribute interval is out of bounds\n");
- TEST_ERROR;
- }
- }
-
- if (s->grp_op_test && s->attr_test) {
- printf("Cannot test both group operation and attribute tests!\n");
- printf("Attribute tests are ignored.\n");
- }
-
- if (argc > 0) {
- printf("unexpected command-line arguments\n");
- TEST_ERROR;
- }
-
- /* space for attributes */
- if ((s->one_by_one_sid = H5Screate_simple(1, &dims, &dims)) < 0) {
- printf("H5Screate_simple failed\n");
- TEST_ERROR;
- }
-
- esnprintf(s->filename, sizeof(s->filename), "vfd_swmr_group.h5");
-
- return true;
-
-error:
- if (tfile)
- HDfree(tfile);
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: check_ohr_num_chunk
- *
- * Purpose: Check if the number of object header chunks is as expected.
- *
- * Parameters: hid_t oid
- * HDF5 object ID (in this file: means group ID)
- *
- * bool one_chunk_ohr
- * flag to indicate if the object header chunk is 1 or greater
- * 1: true
- * greater than 1: false
- *
- * Return: Success: true
- * Failure: false
- *
- *-------------------------------------------------------------------------
- */
-
-static bool
-check_ohr_num_chunk(hid_t g, bool one_chunk_ohr)
-{
-
- H5O_native_info_t ninfo;
-
- /* Get the object information */
- if (H5Oget_native_info(g, &ninfo, H5O_NATIVE_INFO_HDR) < 0) {
- printf("H5Oget_native_info failed\n");
- TEST_ERROR;
- }
-
- if (true == one_chunk_ohr) {
- if (ninfo.hdr.nchunks != 1) {
- printf("Object header should have only one chunk,but it is not.\n");
- TEST_ERROR;
- }
- }
- else {
- if (ninfo.hdr.nchunks <= 1) {
- printf("Object header should have more than one chunk,but it is not.\n");
- TEST_ERROR;
- }
- }
-
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_attr
- *
- * Purpose: Add attributes to a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t oid
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group name. The group name is "group-which".
- *
- * unsigned num_attrs
- * The number of attributes to be created
- *
- * const char*aname_fmt
- * The attribute name template used to create unique attribute names.
- *
- * unsigned int g_which
- * This parameter is used to generate correct group name in a key
- * debugging message.
- *
- * Return: Success: true
- * Failure: false
- *
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_attr(state_t *s, hid_t oid, unsigned int which, unsigned num_attrs, const char *aname_fmt,
- unsigned int g_which)
-{
-
- char attrname[VS_ATTR_NAME_LEN];
- unsigned u;
- unsigned attr_value;
- hid_t aid = H5I_INVALID_HID;
- hid_t amtype = H5I_INVALID_HID;
- hid_t atype = s->filetype;
- hid_t sid = s->one_by_one_sid;
-
- /* Need to obtain native datatype for H5Aread */
- if ((amtype = H5Tget_native_type(atype, H5T_DIR_ASCEND)) < 0) {
- printf("H5Tget_native_type failed\n");
- TEST_ERROR;
- }
-
- for (u = 0; u < num_attrs; u++) {
-
- /* Create attribute */
- /* Construct attribute name like attr-0-0 */
- HDsprintf(attrname, aname_fmt, which, u);
- if ((aid = H5Acreate2(oid, attrname, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
- printf("H5Acreate2 failed\n");
- TEST_ERROR;
- }
-
- attr_value = u + which;
-
- dbgf(1, "setting attribute %s on group %u to %u\n", attrname, g_which, u + which);
-
- /* Write data into the attribute */
- if (H5Awrite(aid, amtype, &attr_value) < 0) {
- printf("H5Awrite failed\n");
- TEST_ERROR;
- }
-
- /* Close attribute */
- if (H5Aclose(aid) < 0) {
- printf("H5Aclose failed\n");
- TEST_ERROR;
- }
-
- /* If coming to an "object header continuation block" test,
- * we need to check if this test behaves as expected. */
- if (s->at_pattern == 'a' || s->at_pattern == 'R') {
- if (false == check_ohr_num_chunk(oid, false)) {
- printf("An object header continuation block should be created. \n");
- printf("But it is not.\n");
- TEST_ERROR;
- }
- }
-
- } /* end for */
-
- if (H5Tclose(amtype) < 0) {
- TEST_ERROR;
- }
-
- return true;
-
-error:
- H5E_BEGIN_TRY
- {
- H5Aclose(aid);
- H5Tclose(amtype);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_vlstr_attr
- *
- * Purpose: Add a variable length string attribute to a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "vstr" test.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_vlstr_attr(state_t *s, hid_t g, unsigned int which)
-{
-
- hid_t aid = H5I_INVALID_HID;
- hid_t atype = H5I_INVALID_HID;
- char name[VS_ATTR_NAME_LEN];
- char *astr_val = NULL;
- hid_t sid = s->one_by_one_sid;
-
- /* Allocate buffer for the VL string value */
- astr_val = HDmalloc(VS_ATTR_NAME_LEN);
- if (astr_val == NULL) {
- printf("Allocate memory for VL string failed.\n");
- TEST_ERROR;
- }
-
- /* Assign the VL string value and the attribute name.. */
- HDsprintf(astr_val, "%u", which);
- esnprintf(name, sizeof(name), "attr-%u", which);
-
- dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which);
-
- /* Create a datatype to refer to. */
- if ((atype = H5Tcopy(H5T_C_S1)) < 0) {
- printf("Cannot create variable length datatype.\n");
- TEST_ERROR;
- }
-
- if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
- printf("Cannot set variable length datatype.\n");
- TEST_ERROR;
- }
-
- /* Generate the VL string attribute.*/
- if ((aid = H5Acreate2(g, name, atype, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
- printf("H5Acreate2 failed.\n");
- TEST_ERROR;
- }
-
- if (H5Awrite(aid, atype, &astr_val) < 0) {
- printf("H5Awrite failed.\n");
- TEST_ERROR;
- }
-
- if (H5Tclose(atype) < 0) {
- printf("H5Tclose() failed\n");
- TEST_ERROR;
- }
- if (H5Aclose(aid) < 0) {
- printf("H5Aclose() failed\n");
- TEST_ERROR;
- }
-
- HDfree(astr_val);
-
- return true;
-
-error:
- H5E_BEGIN_TRY
- {
- H5Aclose(aid);
- H5Tclose(atype);
- }
- H5E_END_TRY;
-
- if (astr_val)
- HDfree(astr_val);
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_vlstr_attrs
- *
- * Purpose: Add variable length string attributes to a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which". The attribute names
- * are "attr-which","attr-which+1"....
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the performance test that has the VL string type.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_vlstr_attrs(state_t *s, hid_t g, unsigned int which, unsigned int num_attrs)
-{
- unsigned u;
- bool ret_value = true;
- for (u = 0; u < num_attrs; u++) {
- ret_value = add_vlstr_attr(s, g, u + which);
- if (ret_value == false)
- break;
- }
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_default_group_attr
- *
- * Purpose: Add an attribute to a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This function is used for the "dense" storage test.
- * It is also used by the group-only, "add-ohr-block"
- * and "del-ohr-block" tests.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_default_group_attr(state_t *s, hid_t g, unsigned int which)
-{
-
- const char *aname_format = "attr-%u-%u";
-
- /* Note: the number of attributes can be configurable,
- * the default number of attribute is 1.
- */
- /* If the vl string attribute type is chosen. */
- if (s->vlstr_test == true)
- return add_vlstr_attrs(s, g, which, s->num_attrs);
- else
- return add_attr(s, g, which, s->num_attrs, aname_format, which);
-}
-
-/*-------------------------------------------------------------------------
- * Function: del_one_attr
- *
- * Purpose: delete one attribute in a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t obj_id
- * HDF5 object ID (in this file: means group ID)
- *
- * bool is_dense
- * if the deleted attribute is for checking the dense storage
- *
- * bool is_vl_or_ohrc
- * if the deleted attribute is a VL string or for object header
- * continuation check test
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute names
- * according to if this attribute is a VL string or for checking
- * the dense storage or the storage transition from dense to
- * compact.
- *
- *
- * Return: Success: true
- * Failure: false
- *
- *-------------------------------------------------------------------------
- */
-
-static bool
-del_one_attr(state_t *s, hid_t obj_id, bool is_dense, bool is_vl_or_ohrc, unsigned int which)
-{
-
- char attrname[VS_ATTR_NAME_LEN];
-
- /*attribute name template for the dense storage related deletion operation */
- const char *aname_format_d = "attr-d-%u-%u";
-
- /*attribute name template used for general attribute deletion operation */
- const char *aname_format = "attr-%u-%u";
-
- /*attribute name template used for VL string attribute deletion
- * or object header continuation check operations */
- const char *aname_format_vl = "attr-%u";
-
- dbgf(2, "writer: coming to delete the attribute.\n");
-
- /* Construct the attribute name */
- if (is_dense == true)
- HDsprintf(attrname, aname_format_d, which, 0);
- else if (is_vl_or_ohrc == true)
- HDsprintf(attrname, aname_format_vl, which, 0);
- else
- HDsprintf(attrname, aname_format, which, 0);
-
- /* Delete the attribute */
- if (H5Adelete(obj_id, attrname) < 0) {
- printf("H5Adelete() failed\n");
- TEST_ERROR;
- }
-
- /* If coming to an "object header continuation block" test,
- * we need to check if this test behaves as expected. */
- if (s->at_pattern == 'R') {
- if (false == check_ohr_num_chunk(obj_id, true)) {
- printf("The object header chunk should not continue. \n");
- TEST_ERROR;
- }
- }
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_del_vlstr_attr
- *
- * Purpose: Add a variable length string attribute
- * then delete this attribute in this a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "remove-vstr" test.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_del_vlstr_attr(state_t *s, hid_t g, unsigned int which)
-{
-
- bool ret_value = false;
-
- /* Add a VL string attribute then delete it. */
- ret_value = add_vlstr_attr(s, g, which);
- if (ret_value == true)
- ret_value = del_one_attr(s, g, false, true, which);
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: modify_attr
- *
- * Purpose: Modify the value of an attribute in a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * const char*aname_fmt
- * The attribute name template used to create unique attribute names.
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group name. The group name is "group-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- *-------------------------------------------------------------------------
- */
-
-static bool
-modify_attr(state_t *s, hid_t g, const char *aname_fmt, unsigned int which)
-{
-
- char attrname[VS_ATTR_NAME_LEN];
- hid_t aid = H5I_INVALID_HID;
- hid_t amtype = H5I_INVALID_HID;
- unsigned int modify_value;
-
- HDsprintf(attrname, aname_fmt, which, 0);
- if ((aid = H5Aopen(g, attrname, H5P_DEFAULT)) < 0) {
- printf("H5Aopen failed\n");
- TEST_ERROR;
- }
-
- if ((amtype = H5Tget_native_type(s->filetype, H5T_DIR_ASCEND)) < 0) {
- printf("H5Tget_native_type failed\n");
- TEST_ERROR;
- }
-
- /* Make a large number to verify the change easily */
- modify_value = which + 10000;
-
- if (H5Awrite(aid, amtype, &modify_value) < 0) {
- printf("H5Awrite failed\n");
- TEST_ERROR;
- }
- if (H5Tclose(amtype) < 0) {
- printf("H5Tclose failed\n");
- TEST_ERROR;
- }
- if (H5Aclose(aid) < 0) {
- printf("H5Aclose failed\n");
- TEST_ERROR;
- }
-
- return true;
-error:
- H5E_BEGIN_TRY
- {
- H5Aclose(aid);
- H5Tclose(aid);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: modify_vlstr_attr
- *
- * Purpose: Modify the value of an VL string attribute in a group.
- *
- * Parameters:
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group name. The group name is "group-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- *-------------------------------------------------------------------------
- */
-
-static bool
-modify_vlstr_attr(hid_t g, unsigned int which)
-{
-
- hid_t aid = H5I_INVALID_HID;
- hid_t atype = H5I_INVALID_HID;
- char name[VS_ATTR_NAME_LEN];
- char *astr_val = NULL;
-
- astr_val = HDmalloc(VS_ATTR_NAME_LEN);
- if (astr_val == NULL) {
- printf("Allocate memory for VL string failed.\n");
- TEST_ERROR;
- }
-
- /* Change the VL string value and create the attribute name. */
- HDsprintf(astr_val, "%u%c", which, 'A');
- esnprintf(name, sizeof(name), "attr-%u", which);
-
- dbgf(1, "setting attribute %s on group %u to %u\n", name, which, which);
-
- /* Create a datatype to refer to. */
- if ((atype = H5Tcopy(H5T_C_S1)) < 0) {
- printf("Cannot create variable length datatype.\n");
- TEST_ERROR;
- }
-
- if (H5Tset_size(atype, H5T_VARIABLE) < 0) {
- printf("Cannot set variable length datatype.\n");
- TEST_ERROR;
- }
-
- /* Open this attribute. */
- if ((aid = H5Aopen(g, name, H5P_DEFAULT)) < 0) {
- printf("H5Aopen failed.\n");
- TEST_ERROR;
- }
-
- dbgf(1, "The modified VL string value is %s \n", astr_val);
-
- if (H5Awrite(aid, atype, &astr_val) < 0) {
- printf("H5Awrite failed.\n");
- TEST_ERROR;
- }
-
- if (H5Tclose(atype) < 0) {
- printf("H5Tclose() failed\n");
- TEST_ERROR;
- }
-
- if (H5Aclose(aid) < 0) {
- printf("H5Aclose() failed\n");
- TEST_ERROR;
- }
-
- HDfree(astr_val);
-
- return true;
-
-error:
- H5E_BEGIN_TRY
- {
- H5Aclose(aid);
- H5Tclose(atype);
- }
- H5E_END_TRY;
-
- if (astr_val)
- HDfree(astr_val);
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_modify_vlstr_attr
- *
- * Purpose: Add a variable length string attribute
- * then modify this attribute in the group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "modify-vstr" test.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_modify_vlstr_attr(state_t *s, hid_t g, unsigned int which)
-{
-
- bool ret_value = false;
- ret_value = add_vlstr_attr(s, g, which);
- if (true == ret_value)
- ret_value = modify_vlstr_attr(g, which);
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_attrs_compact
- *
- * Purpose: Add some attributes to the group.
- * the number of attributes should be the maximal number of
- * attributes that the compact storage can hold
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "modify-vstr" test.
- * For attribute compact/dense storage, check the reference
- * manual of H5Pget_attr_phase_change.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
-{
-
- unsigned max_compact = 0;
- unsigned min_dense = 0;
- const char *aname_format = "attr-%u-%u";
-
- if (s->old_style_grp)
- max_compact = 2;
- else {
- /* Obtain the maximal number of attributes to be stored in compact
- * storage and the minimal number of attributes to be stored in
- * dense storage. */
- if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
- printf("H5Pget_attr_phase_change() failed\n");
- TEST_ERROR;
- }
- }
-
- /* Add max_compact attributes, these attributes are stored in
- * compact storage. */
- return add_attr(s, g, which, max_compact, aname_format, which);
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_attrs_compact_dense
- *
- * Purpose: Add some attributes to the group.
- * First, the number of attributes should be the maximal number
- * of attributes that the compact storage can hold.
- * Then, add another atribute, the storage becomes dense.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "compact-to-dense" test.
- * For attribute compact/dense storage, check the reference
- * manual of H5Pget_attr_phase_change.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
-{
-
- unsigned max_compact = 0;
- unsigned min_dense = 0;
- const char *aname_format = "attr-d-%u-%u";
- bool ret_value = false;
-
- if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
- printf("H5Pget_attr_phase_change failed\n");
- TEST_ERROR;
- }
-
- /* Add attributes, until just before converting to dense storage */
- ret_value = add_attrs_compact(s, g, gcpl, which);
-
- /* Add another attribute, the storage becomes dense. */
- if (ret_value == true)
- ret_value = add_attr(s, g, which + max_compact, 1, aname_format, which);
-
- return ret_value;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: del_attrs_compact_dense_compact
- *
- * Purpose: delete some attributes in the group.
- * The number of attributes are deleted in such a way
- * that the attribute storage changes from compact to
- * dense then to compact again.
- *
- * Parameters: hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is an internal function used by the
- * "dense-del-to-compact" test.
- * For attribute compact/dense storage, check the reference
- * manual of H5Pget_attr_phase_change.
- *-------------------------------------------------------------------------
- */
-
-static bool
-del_attrs_compact_dense_compact(hid_t obj_id, hid_t gcpl, unsigned int which)
-{
-
- unsigned max_compact = 0;
- unsigned min_dense = 0;
- unsigned u = 0;
-
- char attrname[VS_ATTR_NAME_LEN];
- const char *aname_format = "attr-%u-%u";
- const char *adname_format = "attr-d-%u-%u";
-
- /* Obtain the maximal number of attributes to be stored in compact
- * storage and the minimal number of attributes to be stored in
- * dense storage. */
- if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
- printf("H5Pget_attr_phase_change failed\n");
- TEST_ERROR;
- }
- u = max_compact + 1;
-
- /* delete a number of attributes so that the attribute storage just becomes dense.*/
- for (u--; u >= (min_dense - 1); u--) {
- HDsprintf(attrname, aname_format, which, max_compact - u);
- if (H5Adelete(obj_id, attrname) < 0) {
- printf("H5Adelete failed\n");
- TEST_ERROR;
- }
- }
-
- /* The writer deletes another attribute, the storage is
- * still dense. However, the attribute to be deleted
- * doesn't follow the previous for loop. It may be
- * in different location in the object header. Just add
- * a litter variation to check if this operation is successful.
- * The attribute name to be deleted is attr-max_compact+which-0
- */
-
- HDsprintf(attrname, adname_format, max_compact + which, 0);
- if (H5Adelete(obj_id, attrname) < 0) {
- printf("H5Adelete failed\n");
- TEST_ERROR;
- }
-
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_del_attrs_compact
- *
- * Purpose: Add some attributes to the group and then delete one attribute.
- * First, the number of attributes to be added should be the
- * maximal number of attributes that the compact storage can hold.
- * Then, delete one atribute, the storage is still compact.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "compact-del" test.
- * For attribute compact/dense storage, check the reference
- * manual of H5Pget_attr_phase_change.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_del_attrs_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
-{
-
- bool ret_value = false;
- ret_value = add_attrs_compact(s, g, gcpl, which);
- if (ret_value == true) {
- dbgf(2, "writer: before deleting the attribute.\n");
- ret_value = del_one_attr(s, g, false, false, which);
- }
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_del_attrs_compact_dense
- *
- * Purpose: Add some attributes to the group and then delete one attribute.
- * First, the number of attributes to be added exceeds
- * the maximal number of attributes that the compact storage can hold.
- * The storage changes from compact to dense.
- * Then, delete one atribute, the storage is still dense.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "dense-del" test.
- * For attribute compact/dense storage, check the reference
- * manual of H5Pget_attr_phase_change.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_del_attrs_compact_dense(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
-{
-
- bool ret_value = false;
- unsigned max_compact = 0;
- unsigned min_dense = 0;
-
- if (H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense) < 0) {
- printf("H5Pget_attr_phase_change failed\n");
- TEST_ERROR;
- }
-
- ret_value = add_attrs_compact_dense(s, g, gcpl, which);
- if (ret_value == true)
- ret_value = del_one_attr(s, g, true, false, which + max_compact);
-
- return ret_value;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_del_attrs_compact_dense_compact
- *
- * Purpose: Add attributes to the group and then delete some of them.
- * First, the number of attributes to be added exceeds
- * the maximal number of attributes that the compact storage can hold.
- * The storage changes from compact to dense.
- * Then, delete some attributes, the storage changes from
- * dense to compact again.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is for the "dense-del-to-compact" test.
- * For attribute compact/dense storage, check the reference
- * manual of H5Pget_attr_phase_change.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_del_attrs_compact_dense_compact(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
-{
-
- bool ret_value = false;
- ret_value = add_attrs_compact_dense(s, g, gcpl, which);
- if (ret_value == true)
- ret_value = del_attrs_compact_dense_compact(g, gcpl, which);
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: add_modify_default_group_attr
- *
- * Purpose: Add an attribute then modify the value to a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This function is used for the "modify" test.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_modify_default_group_attr(state_t *s, hid_t g, unsigned int which)
-{
-
- bool ret_value = false;
- const char *aname_format = "attr-%u";
- ret_value = add_default_group_attr(s, g, which);
- if (ret_value == true)
- ret_value = modify_attr(s, g, aname_format, which);
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: del_ohr_block_attr
- *
- * Purpose: Add an attribute to force creation of object header
- * continuation block and remove this attribute to delete
- * the object header continuation block
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- * The group name is "group-which" and the attribute name
- * is "attr-which".
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This function is used for the
- * "deletion of object header continuation block" test.
- *-------------------------------------------------------------------------
- */
-
-static bool
-del_ohr_block_attr(state_t *s, hid_t g, unsigned int which)
-{
-
- bool ret_value = false;
- ret_value = add_default_group_attr(s, g, which);
- if (ret_value == true)
- ret_value = del_one_attr(s, g, false, true, which);
- return ret_value;
-}
-/*-------------------------------------------------------------------------
- * Function: add_group_attribute
- *
- * Purpose: Check the attribute test pattern and then call the
- * correponding test function..
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t g
- * HDF5 object ID (in this file: means group ID)
- *
- * hid_t gcpl
- * Object creation property list ID
- *
- * unsigned int which
- * The number of iterations for group creation, use to generate
- * newly created group and attribute names.
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the write_group() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-add_group_attribute(state_t *s, hid_t g, hid_t gcpl, unsigned int which)
-{
-
- bool ret_value = false;
- char test_pattern = s->at_pattern;
-
- switch (test_pattern) {
- case 'c':
- ret_value = add_attrs_compact(s, g, gcpl, which);
- break;
- case 't':
- ret_value = add_attrs_compact_dense(s, g, gcpl, which);
- break;
- case 'C':
- ret_value = add_del_attrs_compact(s, g, gcpl, which);
- break;
- case 'D':
- ret_value = add_del_attrs_compact_dense(s, g, gcpl, which);
- break;
- case 'T':
- ret_value = add_del_attrs_compact_dense_compact(s, g, gcpl, which);
- break;
- case 'M':
- ret_value = add_modify_default_group_attr(s, g, which);
- break;
- case 'v':
- ret_value = add_vlstr_attr(s, g, which);
- break;
- case 'r':
- ret_value = add_del_vlstr_attr(s, g, which);
- break;
- case 'm':
- ret_value = add_modify_vlstr_attr(s, g, which);
- break;
- case 'R':
- ret_value = del_ohr_block_attr(s, g, which);
- break;
- case 'a':
- case 'd':
- case ' ':
- default:
- ret_value = add_default_group_attr(s, g, which);
- break;
- }
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: write_group
- *
- * Purpose: Create a group and carry out attribute operations(add,delete etc.)
- * according to the attribute test pattern.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations for group creation
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the main() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-write_group(state_t *s, unsigned int which)
-{
- char name[sizeof("/group-9999999999")];
- hid_t g = H5I_INVALID_HID;
- hid_t dummy_d = H5I_INVALID_HID;
- hid_t gcpl = H5I_INVALID_HID;
- bool result = true;
- H5G_info_t group_info;
- struct timespec start_time, end_time;
- double temp_time;
-
- if (which >= s->nsteps) {
- printf("Number of created groups is out of bounds\n");
- TEST_ERROR;
- }
-
- esnprintf(name, sizeof(name), "/group-%u", which);
-
- if (s->old_style_grp)
- gcpl = H5P_DEFAULT;
- else {
- gcpl = H5Pcreate(H5P_GROUP_CREATE);
- if (gcpl < 0) {
- printf("H5Pcreate failed\n");
- TEST_ERROR;
- }
-
- /* If we test the dense storage, change the attribute phase. */
- if (s->at_pattern == 'd') {
- if (H5Pset_attr_phase_change(gcpl, 0, 0) < 0) {
- printf("H5Pset_attr_phase_change failed for the dense storage.\n");
- TEST_ERROR;
- }
- }
- }
-
- if (s->gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
-
- fprintf(stderr, "HDclock_gettime failed");
-
- TEST_ERROR;
- }
- }
-
- if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) {
- printf("H5Gcreate2 failed\n");
- TEST_ERROR;
- }
-
- if (s->gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
-
- fprintf(stderr, "HDclock_gettime failed");
-
- TEST_ERROR;
- }
-
- temp_time = TIME_PASSED(start_time, end_time);
- if (temp_time < s->min_gc_time)
- s->min_gc_time = temp_time;
- if (temp_time > s->max_gc_time)
- s->max_gc_time = temp_time;
- s->total_gc_time += temp_time;
- }
-
- /* We need to create a dummy dataset for the object header continuation block test. */
- if (s->at_pattern == 'a' || s->at_pattern == 'R') {
- if ((dummy_d = H5Dcreate2(g, "Dataset", H5T_NATIVE_INT, s->one_by_one_sid, H5P_DEFAULT, H5P_DEFAULT,
- H5P_DEFAULT)) < 0) {
- printf("H5Dcreate2 failed\n");
- TEST_ERROR;
- }
- }
- /* We only need to check the first group */
- if (which == 0) {
- if (H5Gget_info(g, &group_info) < 0) {
- printf("H5Gget_info failed\n");
- TEST_ERROR;
- }
-
- if (s->old_style_grp) {
- if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
- printf("Old-styled group test: but the group is not in old-style. \n");
- TEST_ERROR;
- }
- dbgf(2, "Writer: group is created with the old-style.\n");
- }
- else {
- if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
- printf("The created group should NOT be in old-style . \n");
- TEST_ERROR;
- }
- dbgf(2, "Writer: group is created with the new-style.\n");
- }
- }
-
- /* If coming to an "object header continuation block" test,
- * we need to check if this test behaves as expected. */
- if (s->at_pattern == 'a' || s->at_pattern == 'R') {
- if (false == check_ohr_num_chunk(g, true)) {
- printf("An object header continuation block should NOT be created. \n");
- printf("But it is created.\n");
- TEST_ERROR;
- }
- }
-
- /* Then carry out the attribute operation. */
- if (s->asteps != 0 && which % s->asteps == 0)
- result = add_group_attribute(s, g, gcpl, which);
-
- if (s->at_pattern == 'a' || s->at_pattern == 'R') {
- if (H5Dclose(dummy_d) < 0) {
- printf("H5Dclose failed\n");
- TEST_ERROR;
- }
- }
-
- if (H5Gclose(g) < 0) {
- printf("H5Gclose failed\n");
- TEST_ERROR;
- }
-
- if (!s->old_style_grp && H5Pclose(gcpl) < 0) {
- printf("H5Pclose failed\n");
- TEST_ERROR;
- }
-
- return result;
-
-error:
-
- H5E_BEGIN_TRY
- {
- H5Gclose(g);
- if (s->at_pattern == 'a' || s->at_pattern == 'R')
- H5Dclose(dummy_d);
- if (!s->old_style_grp)
- H5Pclose(gcpl);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: create_group_id
- *
- * Purpose: Create a group and return the group ID.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations for group creation
- * This is used to generate the group name.
- *
- * bool dense_to_compact
- * true if this function is used to test the transition from dense to
- * compact, false if the test is from compact to dense.
- *
- * Return: Success: the group ID
- * Failure: -1
- *
- * Note: Only used by testing the link storage transit functions.
- *-------------------------------------------------------------------------
- */
-
-static hid_t
-create_group_id(state_t *s, unsigned int which, bool dense_to_compact)
-{
-
- char name[sizeof("/group-9999999999")];
- hid_t g = H5I_INVALID_HID;
- hid_t gcpl = H5I_INVALID_HID;
- H5G_info_t group_info;
-
- if (which >= s->nsteps) {
- printf("Number of created groups is out of bounds\n");
- TEST_ERROR;
- }
-
- gcpl = H5Pcreate(H5P_GROUP_CREATE);
- if (gcpl < 0) {
- printf("H5Pcreate failed\n");
- TEST_ERROR;
- }
-
- if (dense_to_compact) {
- if (H5Pset_link_phase_change(gcpl, 2, 2) < 0) {
- printf("H5Pset_link_phase_change failed for dense to compact.\n");
- TEST_ERROR;
- }
- }
- else {
- if (H5Pset_link_phase_change(gcpl, 1, 1) < 0) {
- printf("H5Pset_attr_phase_change failed for compact to dense.\n");
- TEST_ERROR;
- }
- }
-
- esnprintf(name, sizeof(name), "/group-%u", which);
- if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, gcpl, H5P_DEFAULT)) < 0) {
- printf("H5Gcreate2 failed\n");
- TEST_ERROR;
- }
-
- if (H5Gget_info(g, &group_info) < 0) {
- printf("H5Gget_info failed\n");
- TEST_ERROR;
- }
-
- /* The storage type should always be compact when a group is created. */
- if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) {
- printf("New-style group link storage test:. \n");
- printf(" still be compact after group creation. \n");
- TEST_ERROR;
- }
-
- if (H5Pclose(gcpl) < 0) {
- printf("H5Pclose failed\n");
- TEST_ERROR;
- }
-
- return g;
-
-error:
-
- H5E_BEGIN_TRY
- {
- H5Pclose(gcpl);
- }
- H5E_END_TRY;
-
- return -1;
-}
-
-/*-------------------------------------------------------------------------
- * Function: close_group_id
- *
- * Purpose: Verify is a group is closed successfully.
- *
- * Parameters: hid_t g
- * The ID of the group to be closed.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is used by the link storage transit functions.
- *-------------------------------------------------------------------------
- */
-
-static bool
-close_group_id(hid_t g)
-{
-
- if (H5Gclose(g) < 0) {
- printf("H5Gclose failed\n");
- TEST_ERROR;
- }
-
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: create_group
- *
- * Purpose: Create a group
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations for group creation
- * This is used to generate the group name.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the main() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-create_group(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- hid_t g = H5I_INVALID_HID;
- H5G_info_t group_info;
-
- if (which >= s->nsteps) {
- printf("Number of created groups is out of bounds\n");
- TEST_ERROR;
- }
-
- esnprintf(name, sizeof(name), "/group-%u", which);
- if ((g = H5Gcreate2(s->file, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
- printf("H5Gcreate2 failed\n");
- TEST_ERROR;
- }
-
- if (H5Gget_info(g, &group_info) < 0) {
- printf("H5Gget_info failed\n");
- TEST_ERROR;
- }
-
- if (s->old_style_grp) {
- if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
- printf("Old-styled group test: but the group is not in old-style. \n");
- TEST_ERROR;
- }
- dbgf(2, "Writer: group is created with the old-style.\n");
- }
- else {
- if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
- printf("The created group should NOT be in old-style . \n");
- TEST_ERROR;
- }
- dbgf(2, "Writer: group is created with the new-style.\n");
- }
-
- if (H5Gclose(g) < 0) {
- printf("H5Gclose failed\n");
- TEST_ERROR;
- }
-
- return true;
-
-error:
-
- H5E_BEGIN_TRY
- {
- H5Gclose(g);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: delete_one_link
- *
- * Purpose: Delete a link(either hard/soft) in group operation tests.
- * according to the group test pattern.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t obj_id
- * The HDF5 object ID that the deleted link is attached to.
- *
- * const char *name
- * The name of the link to be deleted.
- *
- * short link_storage
- * <=0: link storage is ignored.
- * 1: link storage should be compact after link deletion..
- * >1: link storage should be dense after link deletion.
- *
- * unsigned int which
- * The number of iterations for group creation
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is used by delete_groups() and delete_links() functions.
- *-------------------------------------------------------------------------
- */
-
-static bool
-delete_one_link(state_t *s, hid_t obj_id, const char *name, short link_storage, unsigned int which)
-{
-
- H5G_info_t group_info;
-
- if (which >= s->nsteps) {
- printf("Number of created groups is out of bounds\n");
- TEST_ERROR;
- }
-
- if (H5Ldelete(obj_id, name, H5P_DEFAULT) < 0) {
- printf("H5Ldelete failed\n");
- TEST_ERROR;
- }
-
- if (link_storage > 0) {
-
- if (s->old_style_grp) {
- printf("Old style group doesn't support the indexed storage.\n");
- TEST_ERROR;
- }
-
- if (H5Gget_info(obj_id, &group_info) < 0) {
- printf("H5Gget_info failed\n");
- TEST_ERROR;
- }
-
- if (link_storage == 1) {
-
- if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) {
- printf("The group link storage should be compact. \n");
- TEST_ERROR;
- }
- }
- else {
-
- if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) {
- printf("The group link storage should be dense. \n");
- TEST_ERROR;
- }
- }
- }
-
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: delete_group
- *
- * Purpose: Delete a group and carry out group operations(add,delete etc.)
- * according to the group operation test pattern.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations for group creation
- * This is used to generate the group name
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the group_operations() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-delete_group(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- bool ret_value = create_group(s, which);
- if (ret_value == true) {
- esnprintf(name, sizeof(name), "/group-%u", which);
- ret_value = delete_one_link(s, s->file, name, 0, which);
- }
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: move_one_group
- *
- * Purpose: A helper function used by the move_group operation.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t obj_id
- * ID of the object this group is attached to
- *
- * const char *name
- * The original group name
- *
- * const char *newname
- * The new group name
- *
- * unsigned int which
- * The number of iterations for group creation
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the move_group() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-move_one_group(state_t *s, hid_t obj_id, const char *name, const char *newname, unsigned int which)
-{
-
- if (which >= s->nsteps) {
- printf("Number of created groups is out of bounds\n");
- TEST_ERROR;
- }
-
- if (H5Lmove(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
- printf("H5Ldelete failed\n");
- TEST_ERROR;
- }
-
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: move_group
- *
- * Purpose: Move a group to another group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations for group creation
- * used to generate the group name.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the group_operations() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-move_group(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- char new_name[sizeof("/new-group-9999999999")];
- bool ret_value = create_group(s, which);
- if (ret_value == true) {
- esnprintf(name, sizeof(name), "/group-%u", which);
- esnprintf(new_name, sizeof(new_name), "/new-group-%u", which);
- ret_value = move_one_group(s, s->file, name, new_name, which);
- }
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: insert_one_link
- *
- * Purpose: A helper function used to attach a link to a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * hid_t obj_id
- * ID of the object this link is attached to
- *
- * const char *name
- * The name of the target object used by creating links
- *
- * const char *newname
- * The name of the linked objects
- *
- * bool is_hard
- * true if inserting a hard link
- * false if inserting a soft link
- *
- * short link_storage
- * <=0: link storage is ignored.
- * 1: link storage should be compact.
- * >1: link storage should be dense.
-
- * unsigned int which
- * The number of iterations for group creation
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the insert_links and link storage transit functions.
- * For link storage, we test at both the writer and the reader.
- *-------------------------------------------------------------------------
-*/
-
-static bool
-insert_one_link(state_t *s, hid_t obj_id, const char *name, const char *newname, bool is_hard,
- short link_storage, unsigned int which)
-{
-
- H5G_info_t group_info;
-
- if (which >= s->nsteps) {
- printf("Number of created groups is out of bounds\n");
- TEST_ERROR;
- }
-
- /* For storage transit and insert_links cases, we
- * create links in different style, just add a little
- * variation of the tests.*/
- if (is_hard) {
- if (link_storage > 0) {
- if (H5Lcreate_hard(s->file, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
- printf("H5Lcreate_hard failed\n");
- TEST_ERROR;
- }
- }
- else {
- if (H5Lcreate_hard(obj_id, name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
- printf("H5Lcreate_hard failed\n");
- TEST_ERROR;
- }
- }
- }
- else {
- if (link_storage > 0) {
- if (H5Lcreate_soft("/", obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
- printf("H5Lcreate_soft failed\n");
- TEST_ERROR;
- }
- }
- else {
- if (H5Lcreate_soft(name, obj_id, newname, H5P_DEFAULT, H5P_DEFAULT) < 0) {
- printf("H5Lcreate_soft failed.\n");
- TEST_ERROR;
- }
- }
- }
-
- if (link_storage > 0) {
-
- if (s->old_style_grp) {
- printf("Old style group doesn't support dense or compact storage.\n");
- TEST_ERROR;
- }
-
- if (H5Gget_info(obj_id, &group_info) < 0) {
- printf("H5Gget_info failed\n");
- TEST_ERROR;
- }
-
- if (link_storage == 1) {
- if (group_info.storage_type != H5G_STORAGE_TYPE_COMPACT) {
- printf("The group link storage should be compact. \n");
- TEST_ERROR;
- }
- }
- else {
- if (group_info.storage_type != H5G_STORAGE_TYPE_DENSE) {
- printf("The group link storage should be dense. \n");
- TEST_ERROR;
- }
- }
- }
-
- return true;
-
-error:
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: insert_links
- *
- * Purpose: create links with a group.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations
- * used to generate the group name.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the group_operations() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-insert_links(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- char hd_name[sizeof("/hd-group-9999999999")];
- char st_name[sizeof("/st-group-9999999999")];
-
- bool ret_value = create_group(s, which);
- if (ret_value == true) {
- esnprintf(name, sizeof(name), "/group-%u", which);
- esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which);
- esnprintf(st_name, sizeof(st_name), "/st-group-%u", which);
- ret_value = insert_one_link(s, s->file, name, hd_name, true, 0, which);
- if (ret_value == true)
- ret_value = insert_one_link(s, s->file, name, st_name, false, 0, which);
- }
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: delete_links
- *
- * Purpose: create links with a group and then delete them successfully.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations
- * used to generate the group name.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the group_operations() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-delete_links(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- char hd_name[sizeof("/hd-group-9999999999")];
- char st_name[sizeof("/st-group-9999999999")];
-
- bool ret_value = insert_links(s, which);
- if (ret_value == true) {
- esnprintf(name, sizeof(name), "/group-%u", which);
- esnprintf(hd_name, sizeof(hd_name), "/hd-group-%u", which);
- esnprintf(st_name, sizeof(st_name), "/st-group-%u", which);
- ret_value = delete_one_link(s, s->file, hd_name, 0, which);
- if (ret_value == true)
- ret_value = delete_one_link(s, s->file, st_name, 0, which);
- }
-
- return ret_value;
-}
-
-/*-------------------------------------------------------------------------
- * Function: transit_storage_compact_to_dense
- *
- * Purpose: Add links so that the link storage transits from
- * compact to dense.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations used to generate the group name.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the group_operations() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-transit_storage_compact_to_dense(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- char hd_name[sizeof("/hd-group-9999999999")];
- char st_name[sizeof("/st-group-9999999999")];
-
- hid_t g = create_group_id(s, which, false);
- if (g < 0) {
- printf("create_group_id failed\n");
- TEST_ERROR;
- }
-
- /* First insert a hard link, compact storage. */
- esnprintf(name, sizeof(name), "/group-%u", which);
- esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which);
- if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) {
- printf("insert_one_link for compact storage failed\n");
- TEST_ERROR;
- }
-
- /* Then insert a soft link, the storage becomes dense. */
- esnprintf(st_name, sizeof(st_name), "st-group-%u", which);
- if (insert_one_link(s, g, name, st_name, false, 2, which) == false) {
- printf("insert_one_link for dense storage failed\n");
- TEST_ERROR;
- }
-
- if (close_group_id(g) == false) {
- printf("insert_one_link for dense storage failed\n");
- TEST_ERROR;
- }
-
- return true;
-
-error:
- H5E_BEGIN_TRY
- {
- H5Gclose(g);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: transit_storage_dense_to_compact
- *
- * Purpose: Add or delete links so that the link storage transits from
- * compact to dense then to compact.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations used to generate the group name.
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the group_operations() function.
- *-------------------------------------------------------------------------
- */
-
-static bool
-transit_storage_dense_to_compact(state_t *s, unsigned int which)
-{
-
- char name[sizeof("/group-9999999999")];
- char hd_name[sizeof("/hd-group-9999999999")];
- char st_name[sizeof("st-group-9999999999")];
- char st2_name[sizeof("st2-group-9999999999")];
-
- hid_t g = create_group_id(s, which, true);
- if (g < 0) {
- printf("create_group_id failed\n");
- TEST_ERROR;
- }
-
- /* Insert a link, storage is compact. */
- esnprintf(name, sizeof(name), "/group-%u", which);
- esnprintf(hd_name, sizeof(hd_name), "hd-group-%u", which);
- if (insert_one_link(s, g, name, hd_name, true, 1, which) == false) {
- printf("insert_one_link for compact storage failed\n");
- TEST_ERROR;
- }
-
- /* Insert a link, storage is still compact. */
- esnprintf(st_name, sizeof(st_name), "st-group-%u", which);
- if (insert_one_link(s, g, name, st_name, false, 1, which) == false) {
- printf("insert_one_link for compact storage failed\n");
- TEST_ERROR;
- }
-
- /* Insert a link, storage becomes dense. */
- esnprintf(st2_name, sizeof(st2_name), "st2-group-%u", which);
- if (insert_one_link(s, g, name, st2_name, false, 2, which) == false) {
- printf("insert_one_link for dense storage failed\n");
- TEST_ERROR;
- }
-
- /* Delete a link, storage is still dense */
- if (delete_one_link(s, g, st_name, 2, which) == false) {
- printf("delete_one_link for dense storage failed\n");
- TEST_ERROR;
- }
-
- /* Delete another link, storage becomes compact */
- if (delete_one_link(s, g, st2_name, 1, which) == false) {
- printf("delete_one_link for compact storage failed\n");
- TEST_ERROR;
- }
-
- if (close_group_id(g) == false) {
- printf("insert_one_link for dense storage failed\n");
- TEST_ERROR;
- }
-
- return true;
-
-error:
- H5E_BEGIN_TRY
- {
- H5Gclose(g);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-/*-------------------------------------------------------------------------
- * Function: group_operations
- *
- * Purpose: Carry out group and attribute operations(add,delete etc.)
- * according to the group operation and attribute test patterns.
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int which
- * The number of iterations for group creation
- *
- *
- * Return: Success: true
- * Failure: false
- *
- * Note: This is called by the main() function. The check of attribute
- * operations is inside the write_group() function.
- *-------------------------------------------------------------------------
- */
-static bool
-group_operations(state_t *s, unsigned int which)
-{
-
- bool ret_value = false;
- char test_pattern = s->grp_op_pattern;
-
- switch (test_pattern) {
- case 'c':
- ret_value = create_group(s, which);
- break;
- case 'd':
- ret_value = delete_group(s, which);
- break;
- case 'm':
- ret_value = move_group(s, which);
- break;
- case 'i':
- ret_value = insert_links(s, which);
- break;
- case 'D':
- ret_value = delete_links(s, which);
- break;
- case 't':
- ret_value = transit_storage_compact_to_dense(s, which);
- break;
- case 'T':
- ret_value = transit_storage_dense_to_compact(s, which);
- break;
- case ' ':
- default:
- ret_value = write_group(s, which);
- break;
- }
- return ret_value;
-}
-
-static unsigned int grp_counter = 0;
-
-/*-------------------------------------------------------------------------
- * Function: UI_Pow
- *
- * Purpose: Helper function to obtain the power 'n' of
- * an unsigned integer 'x'
- * Similar to pow(x,y) but for an unsigned integer.
- *
- * Parameters: unsigned int x
- * unsigned int n
- *
- * Return: Return an unsigned integer of value of pow(x,n)
- * Note: If the returned value is > 2^32-1, an overflow
- * may occur. For our testing purpose, this may never happen.
- *
- *-------------------------------------------------------------------------
- */
-
-static unsigned int
-UI_Pow(unsigned int x, unsigned int n)
-{
- unsigned int i; /* Variable used in loop grp_counter */
- unsigned int number = 1;
-
- for (i = 0; i < n; ++i)
- number *= x;
-
- return (number);
-}
-
-/*-------------------------------------------------------------------------
- * Function: obtain_tree_level_elems
- *
- * Purpose: Helper function to obtain the maximum number of elements
- * at one level.
- *
- * Parameters: unsigned int total_ele
- * The total number of elements of a tree(excluding the root)
- *
- * unsigned int level
- * The number of nested levels
- * (If every element of the tree is under the root,
- * the level is 0.)
- *
- * Return: Return the maximum number of elements at one level
- *
- * Example: If the total number of elements is 6 and level is 1,
- * the maximum number of elements is 2.The tree is
- * a perfectly balanced tree.
- * Such as:
- * 0
- * 1 2
- * 3 4 5 6
- *
- * If the total number of elements is 5 and level is 1,
- * the maximum number of elements is still 2. The
- * tree is not balanced, there is no element on the
- * right-most leaf but the level is still 1.
- * Such as:
- * 0
- * 1 2
- * 3 4 5
- *
- *-------------------------------------------------------------------------
- */
-
-static unsigned int
-obtain_tree_level_elems(unsigned int total_ele, unsigned int level)
-{
-
- assert(level <= total_ele);
- /* if every element is under the root, just return the total number of elements. */
- if (level == 0)
- return total_ele;
- else {
- unsigned int test_elems_level = 0;
- unsigned total = 0;
- unsigned int i = 1;
- /* Obtain the maximum number of elements for a level with the brutal force way. */
- while (total < total_ele) {
- test_elems_level++;
- total = 0;
- for (i = 1; i <= level + 1; i++)
- total += UI_Pow(test_elems_level, i);
- }
- if (total == total_ele)
- dbgf(2, "Perfectly match: Number of elements per level is %u\n", test_elems_level);
- return test_elems_level;
- }
-}
-
-/*-------------------------------------------------------------------------
- * Function: gen_tree_struct
- *
- * Purpose: Generate the nested groups
- *
- * Parameters: state_t *s
- * The struct that stores information of HDF5 file
- * and some VFD SWMR configuration parameters
- *
- * unsigned int level
- * The number of nested levels +1
- * (Note: If every element of the tree is under the root,
- * the level is 1 in this function.)
- * unsigned num_elems_per_level
- * The maximum number of element in a level
- * hid_t group_id
- * The ID of the parent group
- *
- * Return: Success: true
- * Failure: false
- */
-static bool
-gen_tree_struct(state_t *s, unsigned int level, unsigned ne_per_level, hid_t pgrp_id)
-{
-
- char name[sizeof("group-9999999999")];
- unsigned int i;
- hid_t grp_id;
- bool result = true;
- H5G_info_t group_info;
- struct timespec start_time, end_time;
- double temp_time;
-
- if (level > 0 && grp_counter < s->nsteps) {
-
- for (i = 0; i < ne_per_level; i++) {
-
- /* For each i a group is created.
- Use grp_counter to generate the group name.
- printf("id: %u,level: %u, index: %u\n",id,level,i);
- */
- esnprintf(name, sizeof(name), "group-%u", grp_counter);
- if (grp_counter == s->nsteps)
- break;
-
- dbgf(2, "writer in nested group: step %d\n", grp_counter);
- if (s->gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
- fprintf(stderr, "HDclock_gettime failed");
- TEST_ERROR;
- }
- }
-
- if ((grp_id = H5Gcreate2(pgrp_id, name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) {
- printf("H5Gcreate2 failed\n");
- TEST_ERROR;
- }
-
- if (s->gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
-
- fprintf(stderr, "HDclock_gettime failed");
-
- TEST_ERROR;
- }
-
- temp_time = TIME_PASSED(start_time, end_time);
- if (temp_time < s->min_gc_time)
- s->min_gc_time = temp_time;
- if (temp_time > s->max_gc_time)
- s->max_gc_time = temp_time;
- s->total_gc_time += temp_time;
- }
-
- /* Just check the first group information. */
- if (grp_counter == 0) {
- if (H5Gget_info(grp_id, &group_info) < 0) {
- printf("H5Gget_info failed\n");
- TEST_ERROR;
- }
-
- if (s->old_style_grp) {
- if (group_info.storage_type != H5G_STORAGE_TYPE_SYMBOL_TABLE) {
- printf("Old-styled group test: but the group is not in old-style. \n");
- TEST_ERROR;
- }
- dbgf(2, "Writer: group is created with the old-style.\n");
- }
- else {
- if (group_info.storage_type == H5G_STORAGE_TYPE_SYMBOL_TABLE) {
- printf("The created group should NOT be in old-style . \n");
- TEST_ERROR;
- }
- dbgf(2, "Writer: group is created with the new-style.\n");
- }
- }
-
- /* Then carry out the attribute operation. */
- if (s->asteps != 0 && grp_counter % s->asteps == 0)
- result = add_default_group_attr(s, grp_id, grp_counter);
-
- if (result == false) {
- printf("Cannot create group attributes. \n");
- TEST_ERROR;
- }
- grp_counter++;
-
- /* Generate groups in the next level */
- result = gen_tree_struct(s, level - 1, ne_per_level, grp_id);
- if (result == false) {
- printf("Cannot create nested groups. \n");
- TEST_ERROR;
- }
-
- /* close the group ID. No problem. */
- if (H5Gclose(grp_id) < 0) {
- printf("H5Gclose failed. \n");
- TEST_ERROR;
- }
- }
- }
-
- return true;
-
-error:
-
- H5E_BEGIN_TRY
- {
- H5Gclose(grp_id);
- }
- H5E_END_TRY;
-
- return false;
-}
-
-int
-main(int argc, char **argv)
-{
- hid_t fapl = H5I_INVALID_HID, fcpl = H5I_INVALID_HID;
- unsigned step;
- bool writer = false;
- state_t s;
- const char * personality;
- H5F_vfd_swmr_config_t config;
- bool wg_ret = false;
- struct timespec start_time, end_time;
- unsigned int num_elems_per_level;
-
- if (!state_init(&s, argc, argv)) {
- printf("state_init failed\n");
- TEST_ERROR;
- }
-
- personality = HDstrstr(s.progname, "vfd_swmr_log_");
-
- if (personality != NULL && HDstrcmp(personality, "vfd_swmr_log_writer") == 0)
- writer = true;
- else if (personality != NULL && HDstrcmp(personality, "vfd_swmr_log_reader") == 0)
- writer = false;
- else {
- printf("unknown personality, expected vfd_swmr_log_{reader,writer}\n");
- TEST_ERROR;
- }
-
- if (writer == false) {
- printf("Reader is skipped for the performance tests.\n");
- return EXIT_SUCCESS;
- }
-
- /* config, tick_len, max_lag, writer, flush_raw_data, md_pages_reserved, md_file_path */
- init_vfd_swmr_config(&config, s.tick_len, s.max_lag, writer, FALSE, 128, "./group-shadow");
- /* Create the log file log-test under the current directory. */
- init_vfd_swmr_log(&config, "./log-test");
-
- /* If old-style option is chosen, use the earliest file format(H5F_LIBVER_EARLIEST)
- * as the second parameter of H5Pset_libver_bound() that is called by
- * vfd_swmr_create_fapl. Otherwise, the latest file format(H5F_LIBVER_LATEST)
- * should be used as the second parameter of H5Pset_libver_bound().
- * Also pass the use_vfd_swmr, only_meta_page, page buffer size, config to vfd_swmr_create_fapl().*/
- if ((fapl = vfd_swmr_create_fapl(!s.old_style_grp, s.use_vfd_swmr, true, s.pbs, &config)) < 0) {
- printf("vfd_swmr_create_fapl failed\n");
- TEST_ERROR;
- }
-
- /* Set fs_strategy (file space strategy) and fs_page_size (file space page size) */
- if ((fcpl = vfd_swmr_create_fcpl(H5F_FSPACE_STRATEGY_PAGE, s.ps)) < 0) {
- HDprintf("vfd_swmr_create_fcpl() failed");
- TEST_ERROR;
- }
-
- if (s.nglevels > 0) {
- if (s.grp_op_pattern != ' ' || s.at_pattern != ' ') {
- printf("For nested group creation test, only the default option is supported.\n");
- printf("Please re-run the tests with the appopriate option.\n");
- TEST_ERROR;
- }
- }
-
- if (s.gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
- fprintf(stderr, "HDclock_gettime failed");
- TEST_ERROR;
- }
- }
-
- s.file = H5Fcreate(s.filename, H5F_ACC_TRUNC, fcpl, fapl);
-
- if (s.gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
- fprintf(stderr, "HDclock_gettime failed");
- TEST_ERROR;
- }
-
- s.fo_total_time = TIME_PASSED(start_time, end_time);
- }
-
- if (s.file < 0) {
- printf("H5Fcreate failed\n");
- TEST_ERROR;
- }
-
- /* If generating nested groups, calculate the maximum number of
- elements per level. */
- if (s.nglevels > 0)
- num_elems_per_level = obtain_tree_level_elems(s.nsteps, s.nglevels);
-
- if (s.gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
- fprintf(stderr, "HDclock_gettime failed");
- TEST_ERROR;
- }
- }
-
- /* If generating nested groups */
- if (s.nglevels > 0) {
-
- /* for the recursive call, the groups under the root is treated as one level */
- wg_ret = gen_tree_struct(&s, s.nglevels + 1, num_elems_per_level, s.file);
- if (wg_ret == false) {
- printf("write nested group failed at group counter %u\n", grp_counter);
- TEST_ERROR;
- }
- }
- else {
- for (step = 0; step < s.nsteps; step++) {
-
- dbgf(2, "writer: step %d\n", step);
- wg_ret = group_operations(&s, step);
- if (wg_ret == false) {
- printf("write_group failed at step %d\n", step);
- TEST_ERROR;
- }
- }
- }
-
- if (s.gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
-
- fprintf(stderr, "HDclock_gettime failed");
- TEST_ERROR;
- }
-
- s.total_time = TIME_PASSED(start_time, end_time);
- s.mean_time = s.total_time / s.nsteps;
- s.mean_gc_time = s.total_gc_time / s.nsteps;
- }
-
- if (H5Pclose(fapl) < 0) {
- printf("H5Pclose failed\n");
- TEST_ERROR;
- }
-
- if (H5Pclose(fcpl) < 0) {
- printf("H5Pclose failed\n");
- TEST_ERROR;
- }
-
- if (H5Sclose(s.one_by_one_sid) < 0) {
- printf("H5Sclose failed\n");
- TEST_ERROR;
- }
-
- if (s.gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &start_time) == -1) {
-
- fprintf(stderr, "HDclock_gettime failed");
-
- TEST_ERROR;
- }
- }
-
- if (H5Fclose(s.file) < 0) {
- printf("H5Fclose failed\n");
- TEST_ERROR;
- }
-
- if (s.gperf) {
-
- if (HDclock_gettime(CLOCK_MONOTONIC, &end_time) == -1) {
-
- fprintf(stderr, "HDclock_gettime failed");
-
- TEST_ERROR;
- }
-
- s.fc_total_time = TIME_PASSED(start_time, end_time);
- }
-
- /* Performance statistics summary */
- if (s.gperf) {
-
- if (verbosity != 0) {
-
- fprintf(stdout, "\nPerformance Test Configuration: ");
- if (s.use_vfd_swmr)
- fprintf(stdout, " Using VFD SWMR \n");
- else
- fprintf(stdout, " Not using VFD SWMR \n");
-
- if (s.old_style_grp)
- fprintf(stdout, " Groups: Created via the earlist file format(old-style) \n");
- else
- fprintf(stdout, " Groups: Created via the latest file format(new-style) \n");
-
- fprintf(stdout, "\n");
-
- fprintf(stdout, "The length of a tick = %u\n", s.tick_len);
- fprintf(stdout, "The maximum expected lag(in ticks)= %u\n", s.max_lag);
- fprintf(stdout, "The page size(in bytes) = %u\n", s.ps);
- fprintf(stdout, "The page buffer size(in bytes) = %u\n", s.pbs);
- fprintf(stdout, "\n");
- fprintf(stdout, "Number of groups = %u\n", s.nsteps);
- fprintf(stdout, "Group Nested levels = %u\n", s.nglevels);
- fprintf(stdout, "Number of attributes = %u\n", s.num_attrs);
- fprintf(stdout, "Number of element per attribute = 1\n");
- if (s.vlstr_test)
- fprintf(stdout, "Attribute datatype is variable length string. \n");
- else if (s.filetype == H5T_STD_U32BE)
- fprintf(stdout, "Attribute datatype is big-endian unsigned 32-bit integer.\n");
- else
- fprintf(stdout, "Attribute datatype is native unsigned 32-bit integer.\n");
-
- fprintf(stdout, "\n");
- fprintf(stdout,
- "(If the nested level is 0, all the groups are created directly under the root.)\n\n");
- fprintf(stdout, "group creation maximum time =%lf\n", s.max_gc_time);
- fprintf(stdout, "group creation minimum time =%lf\n", s.min_gc_time);
- }
-
- fprintf(stdout, "group creation total time = %lf\n", s.total_gc_time);
- fprintf(stdout, "group creation mean time(per group) = %lf\n", s.mean_gc_time);
- fprintf(stdout, "group creation and attributes generation total time = %lf\n", s.total_time);
- fprintf(stdout, "group creation and attributes generation mean time(per group) = %lf\n", s.mean_time);
- fprintf(stdout, "H5Fcreate time = %lf\n", s.fo_total_time);
- fprintf(stdout, "H5Fclose time = %lf\n", s.fc_total_time);
- }
-
- return EXIT_SUCCESS;
-
-error:
- H5E_BEGIN_TRY
- {
- H5Pclose(fapl);
- H5Pclose(fcpl);
- H5Sclose(s.one_by_one_sid);
- H5Fclose(s.file);
- }
- H5E_END_TRY;
-
- return EXIT_FAILURE;
-}
-
-#else /* H5_HAVE_WIN32_API */
-
-int
-main(void)
-{
- HDfprintf(stderr, "Non-POSIX platform. Skipping.\n");
- return EXIT_SUCCESS;
-} /* end main() */
-
-#endif /* H5_HAVE_WIN32_API */