summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Mainzer <mainzer@hdfgroup.org>2005-04-28 16:40:07 (GMT)
committerJohn Mainzer <mainzer@hdfgroup.org>2005-04-28 16:40:07 (GMT)
commita9ba92287d48568c901ec906b8aaf32ff32076aa (patch)
treef79047eaf353389a61b3395bab0a169385a6824b
parent097185980325a30153ceb0090f128a8f4e873a77 (diff)
downloadhdf5-a9ba92287d48568c901ec906b8aaf32ff32076aa.zip
hdf5-a9ba92287d48568c901ec906b8aaf32ff32076aa.tar.gz
hdf5-a9ba92287d48568c901ec906b8aaf32ff32076aa.tar.bz2
[svn-r10688] Purpose:
Add API calls allowing user control of the metadata cache. Description: Prior to this update, the metadata cache was not configurable from outside the library. Solution: Add API calls allowing the user to configure the metadata cache either at file open time, or for any open file. Also added calls permitting the user to monitor cache size and hit rate. These latter facilities are needed for "manual" cache size control Platforms tested: h5committested Misc. update:
-rwxr-xr-xbin/trace2
-rw-r--r--src/H5AC.c518
-rw-r--r--src/H5ACprivate.h60
-rw-r--r--src/H5ACpublic.h243
-rw-r--r--src/H5C.c470
-rw-r--r--src/H5Cpkg.h1
-rw-r--r--src/H5Cprivate.h34
-rw-r--r--src/H5Cpublic.h14
-rw-r--r--src/H5F.c337
-rw-r--r--src/H5Fpkg.h6
-rw-r--r--src/H5Fprivate.h8
-rw-r--r--src/H5Fpublic.h13
-rw-r--r--src/H5MPprivate.h7
-rw-r--r--src/H5Pfapl.c150
-rw-r--r--src/H5Ppublic.h13
-rw-r--r--test/cache.c3005
16 files changed, 4620 insertions, 261 deletions
diff --git a/bin/trace b/bin/trace
index badb7a4..85cbebd 100755
--- a/bin/trace
+++ b/bin/trace
@@ -30,6 +30,7 @@ $Source = "";
%TypeString = ("haddr_t" => "a",
"hbool_t" => "b",
"double" => "d",
+ "H5AC_cache_config_t*" => "x",
"H5D_alloc_time_t" => "Da",
"H5D_fill_time_t" => "Df",
"H5D_fill_value_t" => "DF",
@@ -54,6 +55,7 @@ $Source = "";
"hssize_t" => "Hs",
"hid_t" => "i",
"int" => "Is",
+ "int32_t" => "Is",
"unsigned" => "Iu",
"unsigned int" => "Iu",
"H5I_type_t" => "It",
diff --git a/src/H5AC.c b/src/H5AC.c
index 1bb0066..5904b39 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -334,6 +334,23 @@ H5AC_term_interface(void)
* the similar function in H5C.c. The function is now a
* wrapper for H5C_create().
* JRM - 6/4/04
+ *
+ * Deleted the old size_hint parameter and added the
+ * max_cache_size, and min_clean_size parameters.
+ *
+ * JRM - 3/10/05
+ *
+ * Deleted the max_cache_size, and min_clean_size parameters,
+ * and added the config_ptr parameter. Added code to
+ * validate the resize configuration before we do anything.
+ *
+ * JRM - 3/24/05
+ *
+ * Changed the type of config_ptr from H5AC_auto_size_ctl_t *
+ * to H5AC_cache_config_t *. Propagated associated changes
+ * through the function.
+ * JRM - 4/7/05
+ *
*-------------------------------------------------------------------------
*/
@@ -352,76 +369,34 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] =
};
herr_t
-H5AC_create(const H5F_t *f, int UNUSED size_hint)
+H5AC_create(const H5F_t *f,
+ H5AC_cache_config_t *config_ptr)
{
- int ret_value = SUCCEED; /* Return value */
-#if 1 /* JRM */ /* test code -- remove when done */
- H5C_auto_size_ctl_t auto_size_ctl =
- {
- /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
-#if 1
- /* H5C_auto_resize_report_fcn rpt_fcn = */ NULL,
-#else
- /* H5C_auto_resize_report_fcn rpt_fcn = */ H5C_def_auto_resize_rpt_fcn,
-#endif
- /* hbool_t set_initial_size = */ TRUE,
- /* size_t initial_size = */ (1 * 1024 * 1024),
-
- /* double min_clean_fraction = */ 0.25,
-
- /* size_t max_size = */ (32 * 1024 * 1024),
- /* size_t min_size = */ ( 1 * 1024 * 1024),
-
- /* int64_t epoch_length = */ 50000,
-
-#if 0
- /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off,
-#else
- /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
-#endif
- /* double lower_hr_threshold = */ 0.75,
-
- /* double increment = */ 2.0,
-
- /* hbool_t apply_max_increment = */ TRUE,
- /* size_t max_increment = */ (8 * 1024 * 1024),
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
-#if 0
- /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off,
-#else
- /* enum H5C_cache_decr_mode decr_mode = */
- H5C_decr__age_out_with_threshold,
-#endif
-
- /* double upper_hr_threshold = */ 0.999,
-
- /* double decrement = */ 0.9,
-
- /* hbool_t apply_max_decrement = */ TRUE,
- /* size_t max_decrement = */ (1 * 1024 * 1024),
-
- /* int32_t epochs_before_eviction = */ 3,
+ FUNC_ENTER_NOAPI(H5AC_create, FAIL)
- /* hbool_t apply_empty_reserve = */ TRUE,
- /* double empty_reserve = */ 0.1
- };
+ HDassert ( f );
+ HDassert ( NULL == f->shared->cache );
+ HDassert ( config_ptr != NULL ) ;
-#endif /* JRM */
+ result = H5AC_validate_config(config_ptr);
- FUNC_ENTER_NOAPI(H5AC_create, FAIL)
+ if ( result != SUCCEED ) {
- HDassert(f);
- HDassert(NULL == f->shared->cache);
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad cache configuration");
+ }
- /* this is test code that should be removed when we start passing
- * in proper size hints.
+ /* The default max cache size and min clean size will frequently be
+ * overwritten shortly by the subsequent set resize config call.
* -- JRM
*/
- f->shared->cache = H5C_create(H5C__DEFAULT_MAX_CACHE_SIZE,
- H5C__DEFAULT_MIN_CLEAN_SIZE,
- (H5AC_NTYPES - 1),
- (const char **)H5AC_entry_type_names,
- H5AC_check_if_write_permitted);
+ f->shared->cache = H5C_create(H5AC__DEFAULT_MAX_CACHE_SIZE,
+ H5AC__DEFAULT_MIN_CLEAN_SIZE,
+ (H5AC_NTYPES - 1),
+ (const char **)H5AC_entry_type_names,
+ H5AC_check_if_write_permitted);
if ( NULL == f->shared->cache ) {
@@ -429,14 +404,13 @@ H5AC_create(const H5F_t *f, int UNUSED size_hint)
}
-#if 1 /* JRM */ /* test code -- remove when done */
- if ( H5C_set_cache_auto_resize_config(f->shared->cache, &auto_size_ctl)
- != SUCCEED ) {
+ result = H5AC_set_cache_auto_resize_config(f->shared->cache, config_ptr);
+
+ if ( result != SUCCEED ) {
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \
- "auto resize config test failed")
+ "auto resize configuration failed")
}
-#endif /* JRM */
done:
@@ -1254,6 +1228,418 @@ done:
} /* H5AC_stats() */
+/*-------------------------------------------------------------------------
+ * Function: H5AC_get_cache_auto_resize_config
+ *
+ * Purpose: Wrapper function for H5C_get_cache_auto_resize_config().
+ *
+ * Return: SUCCEED on success, and FAIL on failure.
+ *
+ * Programmer: John Mainzer
+ * 3/10/05
+ *
+ * Modifications:
+ *
+ * JRM - 4/6/05
+ * Reworked for the addition of struct H5AC_cache_config_t.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_get_cache_auto_resize_config(H5AC_t * cache_ptr,
+ H5AC_cache_config_t *config_ptr)
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5C_auto_size_ctl_t internal_config;
+
+ FUNC_ENTER_NOAPI(H5AC_get_cache_auto_resize_config, FAIL)
+
+ if ( ( cache_ptr == NULL ) ||
+ ( config_ptr == NULL ) ||
+ ( config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION ) )
+ {
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "Bad cache_ptr or config_ptr on entry.")
+
+ }
+
+ result = H5C_get_cache_auto_resize_config((H5C_t *)cache_ptr,
+ &internal_config);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_get_cache_auto_resize_config() failed.")
+ }
+
+ if ( internal_config.rpt_fcn == NULL ) {
+
+ config_ptr->rpt_fcn_enabled = FALSE;
+
+ } else {
+
+ config_ptr->rpt_fcn_enabled = TRUE;
+ }
+
+ config_ptr->set_initial_size = internal_config.set_initial_size;
+ config_ptr->initial_size = internal_config.initial_size;
+ config_ptr->min_clean_fraction = internal_config.min_clean_fraction;
+ config_ptr->max_size = internal_config.max_size;
+ config_ptr->min_size = internal_config.min_size;
+ config_ptr->epoch_length = internal_config.epoch_length;
+ config_ptr->incr_mode = internal_config.incr_mode;
+ config_ptr->lower_hr_threshold = internal_config.lower_hr_threshold;
+ config_ptr->increment = internal_config.increment;
+ config_ptr->apply_max_increment = internal_config.apply_max_increment;
+ config_ptr->max_increment = internal_config.max_increment;
+ config_ptr->decr_mode = internal_config.decr_mode;
+ config_ptr->upper_hr_threshold = internal_config.upper_hr_threshold;
+ config_ptr->decrement = internal_config.decrement;
+ config_ptr->apply_max_decrement = internal_config.apply_max_decrement;
+ config_ptr->max_decrement = internal_config.max_decrement;
+ config_ptr->epochs_before_eviction = internal_config.epochs_before_eviction;
+ config_ptr->apply_empty_reserve = internal_config.apply_empty_reserve;
+ config_ptr->empty_reserve = internal_config.empty_reserve;
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_get_cache_auto_resize_config() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC_get_cache_size
+ *
+ * Purpose: Wrapper function for H5C_get_cache_size().
+ *
+ * Return: SUCCEED on success, and FAIL on failure.
+ *
+ * Programmer: John Mainzer
+ * 3/11/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_get_cache_size(H5AC_t * cache_ptr,
+ size_t * max_size_ptr,
+ size_t * min_clean_size_ptr,
+ size_t * cur_size_ptr,
+ int32_t * cur_num_entries_ptr)
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5AC_get_cache_size, FAIL)
+
+ result = H5C_get_cache_size((H5C_t *)cache_ptr,
+ max_size_ptr,
+ min_clean_size_ptr,
+ cur_size_ptr,
+ cur_num_entries_ptr);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_get_cache_size() failed.")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_get_cache_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC_get_cache_hit_rate
+ *
+ * Purpose: Wrapper function for H5C_get_cache_hit_rate().
+ *
+ * Return: SUCCEED on success, and FAIL on failure.
+ *
+ * Programmer: John Mainzer
+ * 3/10/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_get_cache_hit_rate(H5AC_t * cache_ptr,
+ double * hit_rate_ptr)
+
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5AC_get_cache_hit_rate, FAIL)
+
+ result = H5C_get_cache_hit_rate((H5C_t *)cache_ptr, hit_rate_ptr);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_get_cache_hit_rate() failed.")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_get_cache_hit_rate() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5AC_reset_cache_hit_rate_stats()
+ *
+ * Purpose: Wrapper function for H5C_reset_cache_hit_rate_stats().
+ *
+ * Return: SUCCEED on success, and FAIL on failure.
+ *
+ * Programmer: John Mainzer, 3/10/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_reset_cache_hit_rate_stats(H5AC_t * cache_ptr)
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5AC_reset_cache_hit_rate_stats, FAIL)
+
+ result = H5C_reset_cache_hit_rate_stats((H5C_t *)cache_ptr);
+
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_reset_cache_hit_rate_stats() failed.")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_reset_cache_hit_rate_stats() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC_set_cache_auto_resize_config
+ *
+ * Purpose: Wrapper function for H5C_set_cache_auto_resize_config().
+ *
+ * Return: SUCCEED on success, and FAIL on failure.
+ *
+ * Programmer: John Mainzer
+ * 3/10/05
+ *
+ * Modifications:
+ *
+ * John Mainzer -- 4/6/05
+ * Updated for the addition of H5AC_cache_config_t.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
+ H5AC_cache_config_t *config_ptr)
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5C_auto_size_ctl_t internal_config;
+
+ FUNC_ENTER_NOAPI(H5AC_set_cache_auto_resize_config, FAIL)
+
+ if ( cache_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL cache_ptr on entry.")
+ }
+
+ if ( config_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL config_ptr on entry.")
+ }
+
+ if ( config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown config version.")
+ }
+
+ if ( ( config_ptr->rpt_fcn_enabled != TRUE ) &&
+ ( config_ptr->rpt_fcn_enabled != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "config_ptr->rpt_fcn_enabled must be either TRUE or FALSE.")
+ }
+
+ internal_config.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+
+ if ( config_ptr->rpt_fcn_enabled ) {
+
+ internal_config.rpt_fcn = H5C_def_auto_resize_rpt_fcn;
+
+ } else {
+
+ internal_config.rpt_fcn = NULL;
+ }
+
+ internal_config.set_initial_size = config_ptr->set_initial_size;
+ internal_config.initial_size = config_ptr->initial_size;
+ internal_config.min_clean_fraction = config_ptr->min_clean_fraction;
+ internal_config.max_size = config_ptr->max_size;
+ internal_config.min_size = config_ptr->min_size;
+ internal_config.epoch_length = config_ptr->epoch_length;
+
+ internal_config.incr_mode = config_ptr->incr_mode;
+ internal_config.lower_hr_threshold = config_ptr->lower_hr_threshold;
+ internal_config.increment = config_ptr->increment;
+ internal_config.apply_max_increment = config_ptr->apply_max_increment;
+ internal_config.max_increment = config_ptr->max_increment;
+
+ internal_config.decr_mode = config_ptr->decr_mode;
+ internal_config.upper_hr_threshold = config_ptr->upper_hr_threshold;
+ internal_config.decrement = config_ptr->decrement;
+ internal_config.apply_max_decrement = config_ptr->apply_max_decrement;
+ internal_config.max_decrement = config_ptr->max_decrement;
+ internal_config.epochs_before_eviction = config_ptr->epochs_before_eviction;
+ internal_config.apply_empty_reserve = config_ptr->apply_empty_reserve;
+ internal_config.empty_reserve = config_ptr->empty_reserve;
+
+ result = H5C_set_cache_auto_resize_config((H5C_t *)cache_ptr,
+ &internal_config);
+ if ( result < 0 ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5C_set_cache_auto_resize_config() failed.")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_set_cache_auto_resize_config() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5AC_validate_config()
+ *
+ * Purpose: Run a sanity check on the contents of the supplied
+ * instance of H5AC_cache_config_t.
+ *
+ * Do nothing and return SUCCEED if no errors are detected,
+ * and flag an error and return FAIL otherwise.
+ *
+ * At present, this function operates by packing the data
+ * from the instance of H5AC_cache_config_t into an instance
+ * of H5C_auto_size_ctl_t, and then calling
+ * H5C_validate_resize_config(). As H5AC_cache_config_t and
+ * H5C_auto_size_ctl_t diverge, we may have to change this.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 4/6/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5AC_validate_config(H5AC_cache_config_t * config_ptr)
+
+{
+ herr_t result;
+ herr_t ret_value = SUCCEED; /* Return value */
+ H5C_auto_size_ctl_t internal_config;
+
+ FUNC_ENTER_NOAPI(H5AC_validate_config, FAIL)
+
+ if ( config_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL config_ptr on entry.")
+ }
+
+ if ( config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown config version.")
+ }
+
+ if ( ( config_ptr->rpt_fcn_enabled != TRUE ) &&
+ ( config_ptr->rpt_fcn_enabled != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "config_ptr->rpt_fcn_enabled must be either TRUE or FALSE.")
+ }
+
+ internal_config.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+
+ if ( config_ptr->rpt_fcn_enabled ) {
+
+ internal_config.rpt_fcn = H5C_def_auto_resize_rpt_fcn;
+
+ } else {
+
+ internal_config.rpt_fcn = NULL;
+ }
+
+ internal_config.set_initial_size = config_ptr->set_initial_size;
+ internal_config.initial_size = config_ptr->initial_size;
+ internal_config.min_clean_fraction = config_ptr->min_clean_fraction;
+ internal_config.max_size = config_ptr->max_size;
+ internal_config.min_size = config_ptr->min_size;
+ internal_config.epoch_length = config_ptr->epoch_length;
+
+ internal_config.incr_mode = config_ptr->incr_mode;
+ internal_config.lower_hr_threshold = config_ptr->lower_hr_threshold;
+ internal_config.increment = config_ptr->increment;
+ internal_config.apply_max_increment = config_ptr->apply_max_increment;
+ internal_config.max_increment = config_ptr->max_increment;
+
+ internal_config.decr_mode = config_ptr->decr_mode;
+ internal_config.upper_hr_threshold = config_ptr->upper_hr_threshold;
+ internal_config.decrement = config_ptr->decrement;
+ internal_config.apply_max_decrement = config_ptr->apply_max_decrement;
+ internal_config.max_decrement = config_ptr->max_decrement;
+ internal_config.epochs_before_eviction = config_ptr->epochs_before_eviction;
+ internal_config.apply_empty_reserve = config_ptr->apply_empty_reserve;
+ internal_config.empty_reserve = config_ptr->empty_reserve;
+
+ result = H5C_validate_resize_config(&internal_config,
+ H5C_RESIZE_CFG__VALIDATE_ALL);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "error(s) in new config.")
+ }
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5AC_validate_config() */
+
+
/*************************************************************************/
/**************************** Private Functions: *************************/
/*************************************************************************/
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index cb5839a..71d79ef 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -70,6 +70,14 @@
#endif /* H5C_COLLECT_CACHE_STATS */
+/* Default max metadata cache size and min clean size are give here.
+ * At present, these are the same as those given in H5Cprivate.h.
+ */
+
+#define H5AC__DEFAULT_MAX_CACHE_SIZE H5C__DEFAULT_MAX_CACHE_SIZE
+#define H5AC__DEFAULT_MIN_CLEAN_SIZE H5C__DEFAULT_MIN_CLEAN_SIZE
+
+
/*
* Class methods pertaining to caching. Each type of cached object will
* have a constant variable with permanent life-span that describes how
@@ -137,7 +145,7 @@ typedef enum H5AC_protect_t {
} H5AC_protect_t;
-/* Typedef for metadata cache (defined in H5C.c) */
+/* Typedef for metadata cache (defined in H5Cpkg.h) */
typedef H5C_t H5AC_t;
/* Metadata specific properties for FAPL */
@@ -164,6 +172,35 @@ extern hid_t H5AC_dxpl_id;
/* (Global variable declaration, definition is in H5AC.c) */
extern hid_t H5AC_ind_dxpl_id;
+
+/* Default cache configuration. */
+
+#define H5AC__DEFAULT_CACHE_CONFIG \
+{ \
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER, \
+ /* hbool_t rpt_fcn_enabled = */ FALSE, \
+ /* hbool_t set_initial_size = */ TRUE, \
+ /* size_t initial_size = */ (1 * 1024 * 1024), \
+ /* double min_clean_fraction = */ 0.25, \
+ /* size_t max_size = */ (16 * 1024 * 1024), \
+ /* size_t min_size = */ ( 1 * 1024 * 1024), \
+ /* int64_t epoch_length = */ 50000, \
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold, \
+ /* double lower_hr_threshold = */ 0.9, \
+ /* double increment = */ 2.0, \
+ /* hbool_t apply_max_increment = */ TRUE, \
+ /* size_t max_increment = */ (4 * 1024 * 1024), \
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,\
+ /* double upper_hr_threshold = */ 0.999, \
+ /* double decrement = */ 0.9, \
+ /* hbool_t apply_max_decrement = */ TRUE, \
+ /* size_t max_decrement = */ (1 * 1024 * 1024), \
+ /* int32_t epochs_before_eviction = */ 3, \
+ /* hbool_t apply_empty_reserve = */ TRUE, \
+ /* double empty_reserve = */ 0.1 \
+}
+
+
/*
* Library prototypes.
*/
@@ -183,7 +220,7 @@ extern hid_t H5AC_ind_dxpl_id;
H5_DLL herr_t H5AC_init(void);
-H5_DLL herr_t H5AC_create(const H5F_t *f, int size_hint);
+H5_DLL herr_t H5AC_create(const H5F_t *f, H5AC_cache_config_t *config_ptr);
H5_DLL herr_t H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
haddr_t addr, void *thing, unsigned int flags);
H5_DLL void *H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type,
@@ -198,5 +235,24 @@ H5_DLL herr_t H5AC_rename(H5F_t *f, const H5AC_class_t *type,
H5_DLL herr_t H5AC_dest(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5AC_stats(const H5F_t *f);
+H5_DLL herr_t H5AC_get_cache_auto_resize_config(H5AC_t * cache_ptr,
+ H5AC_cache_config_t *config_ptr);
+
+H5_DLL herr_t H5AC_get_cache_size(H5AC_t * cache_ptr,
+ size_t * max_size_ptr,
+ size_t * min_clean_size_ptr,
+ size_t * cur_size_ptr,
+ int32_t * cur_num_entries_ptr);
+
+H5_DLL herr_t H5AC_get_cache_hit_rate(H5AC_t * cache_ptr,
+ double * hit_rate_ptr);
+
+H5_DLL herr_t H5AC_reset_cache_hit_rate_stats(H5AC_t * cache_ptr);
+
+H5_DLL herr_t H5AC_set_cache_auto_resize_config(H5AC_t * cache_ptr,
+ H5AC_cache_config_t *config_ptr);
+
+H5_DLL herr_t H5AC_validate_config(H5AC_cache_config_t * config_ptr);
+
#endif /* !_H5ACprivate_H */
diff --git a/src/H5ACpublic.h b/src/H5ACpublic.h
index 9eb5156..fab825b 100644
--- a/src/H5ACpublic.h
+++ b/src/H5ACpublic.h
@@ -29,11 +29,254 @@
/* Public headers needed by this file */
#include "H5public.h"
+#include "H5Cpublic.h"
#ifdef __cplusplus
extern "C" {
#endif
+/****************************************************************************
+ *
+ * structure H5AC_cache_config_t
+ *
+ * H5AC_cache_config_t is a public structure intended for use in public APIs.
+ * At least in its initial incarnation, it is a essentially a copy of
+ * struct H5C_auto_size_ctl_t, minus the report_fcn field. This is omitted,
+ * as including it would require us to make H5C_t structure public.
+ *
+ * The structure is in H5ACpublic.h as we may wish to allow different
+ * configuration options for metadata and raw data caches.
+ *
+ * The fields of the structure are discussed individually below:
+ *
+ * version: Integer field containing the version number of this version
+ * of the H5AC_cache_config_t structure. Any instance of
+ * H5AC_cache_config_t passed to the cache must have a known
+ * version number, or an error will be flagged.
+ *
+ * rpt_fcn_enabled: Boolean field used to enable and disable the default
+ * reporting function. This function is invoked every time the
+ * automatic cache resize code is run, and reports on its activities.
+ *
+ * This is a debugging function, and should normally be turned off.
+ *
+ * set_initial_size: Boolean flag indicating whether the size of the
+ * initial size of the cache is to be set to the value given in
+ * the initial_size field. If set_initial_size is FALSE, the
+ * initial_size field is ignored.
+ *
+ * initial_size: If enabled, this field contain the size the cache is
+ * to be set to upon receipt of this structure. Needless to say,
+ * initial_size must lie in the closed interval [min_size, max_size].
+ *
+ * min_clean_fraction: double in the range 0 to 1 indicating the fraction
+ * of the cache that is to be kept clean. This field is only used
+ * in parallel mode. Typical values are 0.1 to 0.5.
+ *
+ * max_size: Maximum size to which the cache can be adjusted. The
+ * supplied value must fall in the closed interval
+ * [MIN_MAX_CACHE_SIZE, MAX_MAX_CACHE_SIZE]. Also, max_size must
+ * be greater than or equal to min_size.
+ *
+ * min_size: Minimum size to which the cache can be adjusted. The
+ * supplied value must fall in the closed interval
+ * [H5C__MIN_MAX_CACHE_SIZE, H5C__MAX_MAX_CACHE_SIZE]. Also, min_size
+ * must be less than or equal to max_size.
+ *
+ * epoch_length: Number of accesses on the cache over which to collect
+ * hit rate stats before running the automatic cache resize code,
+ * if it is enabled.
+ *
+ * At the end of an epoch, we discard prior hit rate data and start
+ * collecting afresh. The epoch_length must lie in the closed
+ * interval [H5C__MIN_AR_EPOCH_LENGTH, H5C__MAX_AR_EPOCH_LENGTH].
+ *
+ *
+ * Cache size increase control fields:
+ *
+ * incr_mode: Instance of the H5C_cache_incr_mode enumerated type whose
+ * value indicates how we determine whether the cache size should be
+ * increased. At present there are two possible values:
+ *
+ * H5C_incr__off: Don't attempt to increase the size of the cache
+ * automatically.
+ *
+ * When this increment mode is selected, the remaining fields
+ * in the cache size increase section ar ignored.
+ *
+ * H5C_incr__threshold: Attempt to increase the size of the cache
+ * whenever the average hit rate over the last epoch drops
+ * below the value supplied in the lower_hr_threshold
+ * field.
+ *
+ * Note that this attempt will fail if the cache is already
+ * at its maximum size, or if the cache is not already using
+ * all available space.
+ *
+ * lower_hr_threshold: Lower hit rate threshold. If the increment mode
+ * (incr_mode) is H5C_incr__threshold and the hit rate drops below the
+ * value supplied in this field in an epoch, increment the cache size by
+ * size_increment. Note that cache size may not be incremented above
+ * max_size, and that the increment may be further restricted by the
+ * max_increment field if it is enabled.
+ *
+ * When enabled, this field must contain a value in the range [0.0, 1.0].
+ * Depending on the incr_mode selected, it may also have to be less than
+ * upper_hr_threshold.
+ *
+ * increment: Double containing the multiplier used to derive the new
+ * cache size from the old if a cache size increment is triggered.
+ * The increment must be greater than 1.0, and should not exceed 2.0.
+ *
+ * The new cache size is obtained my multiplying the current max cache
+ * size by the increment, and then clamping to max_size and to stay
+ * within the max_increment as necessary.
+ *
+ * apply_max_increment: Boolean flag indicating whether the max_increment
+ * field should be used to limit the maximum cache size increment.
+ *
+ * max_increment: If enabled by the apply_max_increment field described
+ * above, this field contains the maximum number of bytes by which the
+ * cache size can be increased in a single re-size.
+ *
+ *
+ * Cache size decrease control fields:
+ *
+ * decr_mode: Instance of the H5C_cache_decr_mode enumerated type whose
+ * value indicates how we determine whether the cache size should be
+ * decreased. At present there are four possibilities.
+ *
+ * H5C_decr__off: Don't attempt to decrease the size of the cache
+ * automatically.
+ *
+ * When this increment mode is selected, the remaining fields
+ * in the cache size decrease section are ignored.
+ *
+ * H5C_decr__threshold: Attempt to decrease the size of the cache
+ * whenever the average hit rate over the last epoch rises
+ * above the value supplied in the upper_hr_threshold
+ * field.
+ *
+ * H5C_decr__age_out: At the end of each epoch, search the cache for
+ * entries that have not been accessed for at least the number
+ * of epochs specified in the epochs_before_eviction field, and
+ * evict these entries. Conceptually, the maximum cache size
+ * is then decreased to match the new actual cache size. However,
+ * this reduction may be modified by the min_size, the
+ * max_decrement, and/or the empty_reserve.
+ *
+ * H5C_decr__age_out_with_threshold: Same as age_out, but we only
+ * attempt to reduce the cache size when the hit rate observed
+ * over the last epoch exceeds the value provided in the
+ * upper_hr_threshold field.
+ *
+ * upper_hr_threshold: Upper hit rate threshold. The use of this field
+ * varies according to the current decr_mode:
+ *
+ * H5C_decr__off or H5C_decr__age_out: The value of this field is
+ * ignored.
+ *
+ * H5C_decr__threshold: If the hit rate exceeds this threshold in any
+ * epoch, attempt to decrement the cache size by size_decrement.
+ *
+ * Note that cache size may not be decremented below min_size.
+ *
+ * Note also that if the upper_threshold is 1.0, the cache size
+ * will never be reduced.
+ *
+ * H5C_decr__age_out_with_threshold: If the hit rate exceeds this
+ * threshold in any epoch, attempt to reduce the cache size
+ * by evicting entries that have not been accessed for more
+ * than the specified number of epochs.
+ *
+ * decrement: This field is only used when the decr_mode is
+ * H5C_decr__threshold.
+ *
+ * The field is a double containing the multiplier used to derive the
+ * new cache size from the old if a cache size decrement is triggered.
+ * The decrement must be in the range 0.0 (in which case the cache will
+ * try to contract to its minimum size) to 1.0 (in which case the
+ * cache will never shrink).
+ *
+ * apply_max_decrement: Boolean flag used to determine whether decrements
+ * in cache size are to be limited by the max_decrement field.
+ *
+ * max_decrement: Maximum number of bytes by which the cache size can be
+ * decreased in a single re-size. Note that decrements may also be
+ * restricted by the min_size of the cache, and (in age out modes) by
+ * the empty_reserve field.
+ *
+ * epochs_before_eviction: Integer field used in H5C_decr__age_out and
+ * H5C_decr__age_out_with_threshold decrement modes.
+ *
+ * This field contains the number of epochs an entry must remain
+ * unaccessed before it is evicted in an attempt to reduce the
+ * cache size. If applicable, this field must lie in the range
+ * [1, H5C__MAX_EPOCH_MARKERS].
+ *
+ * apply_empty_reserve: Boolean field controlling whether the empty_reserve
+ * field is to be used in computing the new cache size when the
+ * decr_mode is H5C_decr__age_out or H5C_decr__age_out_with_threshold.
+ *
+ * empty_reserve: To avoid a constant racheting down of cache size by small
+ * amounts in the H5C_decr__age_out and H5C_decr__age_out_with_threshold
+ * modes, this field allows one to require that any cache size
+ * reductions leave the specified fraction of unused space in the cache.
+ *
+ * The value of this field must be in the range [0.0, 1.0]. I would
+ * expect typical values to be in the range of 0.01 to 0.1.
+ *
+ ****************************************************************************/
+
+#define H5AC__CURR_CACHE_CONFIG_VERSION 1
+
+typedef struct H5AC_cache_config_t
+{
+ /* general configuration fields: */
+ int32_t version;
+
+ hbool_t rpt_fcn_enabled;
+
+ hbool_t set_initial_size;
+ size_t initial_size;
+
+ double min_clean_fraction;
+
+ size_t max_size;
+ size_t min_size;
+
+ int64_t epoch_length;
+
+
+ /* size increase control fields: */
+ enum H5C_cache_incr_mode incr_mode;
+
+ double lower_hr_threshold;
+
+ double increment;
+
+ hbool_t apply_max_increment;
+ size_t max_increment;
+
+
+ /* size decrease control fields: */
+ enum H5C_cache_decr_mode decr_mode;
+
+ double upper_hr_threshold;
+
+ double decrement;
+
+ hbool_t apply_max_decrement;
+ size_t max_decrement;
+
+ int32_t epochs_before_eviction;
+
+ hbool_t apply_empty_reserve;
+ double empty_reserve;
+
+} H5AC_cache_config_t;
+
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5C.c b/src/H5C.c
index cd9e249..4038e48 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -1898,7 +1898,8 @@ H5C_create(size_t max_cache_size,
FUNC_ENTER_NOAPI(H5C_create, NULL)
- HDassert( max_cache_size > 0 );
+ HDassert( max_cache_size >= H5C__MIN_MAX_CACHE_SIZE );
+ HDassert( max_cache_size <= H5C__MAX_MAX_CACHE_SIZE );
HDassert( min_clean_size <= max_cache_size );
HDassert( max_type_id >= 0 );
@@ -2901,14 +2902,22 @@ H5C_insert_entry(H5F_t * f,
HDassert( entry_ptr->size <= H5C_MAX_ENTRY_SIZE );
- space_needed = (cache_ptr->index_size + entry_ptr->size) -
- cache_ptr->max_cache_size;
+ space_needed = entry_ptr->size;
- /* It would be nice to be able to do a tight sanity check on
- * space_needed here, but it is hard to assign an upper bound on
- * its value other than then value assigned to it.
- *
- * This fact springs from several features of the cache:
+ if ( space_needed > cache_ptr->max_cache_size ) {
+
+ space_needed = cache_ptr->max_cache_size;
+ }
+
+ /* Note that space_needed is just the amount of space that
+ * needed to insert the new entry without exceeding the cache
+ * size limit. The subsequent call to H5C_make_space_in_cache()
+ * may evict the entries required to free more or less space
+ * depending on conditions. It MAY be less if the cache is
+ * currently undersized, or more if the cache is oversized.
+ *
+ * The cache can exceed its maximum size limit via the following
+ * mechanisms:
*
* First, it is possible for the cache to grow without
* bound as long as entries are protected and not unprotected.
@@ -2916,16 +2925,13 @@ H5C_insert_entry(H5F_t * f,
* Second, when writes are not permitted it is also possible
* for the cache to grow without bound.
*
- * Finally, we don't check to see if the cache is oversized
- * at the end of an unprotect. As a result, it is possible
- * to have a vastly oversized cache with no protected entries
- * as long as all the protects preceed the unprotects.
+ * Finally, we usually don't check to see if the cache is
+ * oversized at the end of an unprotect. As a result, it is
+ * possible to have a vastly oversized cache with no protected
+ * entries as long as all the protects preceed the unprotects.
*
* Since items 1 and 2 are not changing any time soon, I see
* no point in worrying about the third.
- *
- * In any case, I hope this explains why there is no sanity
- * check on space_needed here.
*/
result = H5C_make_space_in_cache(f,
@@ -3146,6 +3152,12 @@ done:
* call to H5C__auto_adjust_cache_size() if that function
* sets the size_decreased flag is TRUE.
*
+ * JRM -- 4/25/05
+ * The size_decreased flag can also be set to TRUE in
+ * H5C_set_cache_auto_resize_config() if a new configuration
+ * forces an immediate reduction in cache size. Modified
+ * the code to deal with this eventuallity.
+ *
*-------------------------------------------------------------------------
*/
@@ -3231,14 +3243,22 @@ H5C_protect(H5F_t * f,
HDassert( entry_ptr->size <= H5C_MAX_ENTRY_SIZE );
- space_needed = (cache_ptr->index_size + entry_ptr->size) -
- cache_ptr->max_cache_size;
+ space_needed = entry_ptr->size;
- /* It would be nice to be able to do a tight sanity check on
- * space_needed here, but it is hard to assign an upper bound on
- * its value other than then value assigned to it.
+ if ( space_needed > cache_ptr->max_cache_size ) {
+
+ space_needed = cache_ptr->max_cache_size;
+ }
+
+ /* Note that space_needed is just the amount of space that
+ * needed to insert the new entry without exceeding the cache
+ * size limit. The subsequent call to H5C_make_space_in_cache()
+ * may evict the entries required to free more or less space
+ * depending on conditions. It MAY be less if the cache is
+ * currently undersized, or more if the cache is oversized.
*
- * This fact springs from several features of the cache:
+ * The cache can exceed its maximum size limit via the following
+ * mechanisms:
*
* First, it is possible for the cache to grow without
* bound as long as entries are protected and not unprotected.
@@ -3246,16 +3266,13 @@ H5C_protect(H5F_t * f,
* Second, when writes are not permitted it is also possible
* for the cache to grow without bound.
*
- * Finally, we don't check to see if the cache is oversized
- * at the end of an unprotect. As a result, it is possible
- * to have a vastly oversized cache with no protected entries
- * as long as all the protects preceed the unprotects.
+ * Finally, we usually don't check to see if the cache is
+ * oversized at the end of an unprotect. As a result, it is
+ * possible to have a vastly oversized cache with no protected
+ * entries as long as all the protects preceed the unprotects.
*
* Since items 1 and 2 are not changing any time soon, I see
* no point in worrying about the third.
- *
- * In any case, I hope this explains why there is no sanity
- * check on space_needed here.
*/
result = H5C_make_space_in_cache(f, primary_dxpl_id,
@@ -3302,9 +3319,11 @@ H5C_protect(H5F_t * f,
H5C__UPDATE_STATS_FOR_PROTECT(cache_ptr, entry_ptr, hit)
- if ( ( cache_ptr->resize_enabled ) &&
- ( cache_ptr->cache_accesses >=
- (cache_ptr->resize_ctl).epoch_length ) ) {
+
+ if ( ( cache_ptr->size_decreased ) ||
+ ( ( cache_ptr->resize_enabled ) &&
+ ( cache_ptr->cache_accesses >=
+ (cache_ptr->resize_ctl).epoch_length ) ) ) {
if ( ! have_write_permitted ) {
@@ -3329,19 +3348,24 @@ H5C_protect(H5F_t * f,
}
}
- result = H5C__auto_adjust_cache_size(cache_ptr,
- f,
- primary_dxpl_id,
- secondary_dxpl_id,
- write_permitted,
- &first_flush);
+ if ( ( cache_ptr->resize_enabled ) &&
+ ( cache_ptr->cache_accesses >=
+ (cache_ptr->resize_ctl).epoch_length ) ) {
- if ( result != SUCCEED ) {
+ result = H5C__auto_adjust_cache_size(cache_ptr,
+ f,
+ primary_dxpl_id,
+ secondary_dxpl_id,
+ write_permitted,
+ &first_flush);
+ if ( result != SUCCEED ) {
- HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
- "Cache auto-resize failed.")
-
- } else if ( cache_ptr->size_decreased ) {
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, \
+ "Cache auto-resize failed.")
+ }
+ }
+
+ if ( cache_ptr->size_decreased ) {
cache_ptr->size_decreased = FALSE;
@@ -3360,7 +3384,7 @@ H5C_protect(H5F_t * f,
result = H5C_make_space_in_cache(f, primary_dxpl_id,
secondary_dxpl_id, cache_ptr,
- space_needed, write_permitted,
+ (size_t)0, write_permitted,
&first_flush);
if ( result < 0 ) {
@@ -3391,10 +3415,7 @@ done:
*
* Modifications:
*
- * JRM - 7/21/04
- * Updated the function for the addition of the hash table.
- * In particular, we now add dirty entries to the skip list if
- * they aren't in the list already.
+ * None.
*
*-------------------------------------------------------------------------
*/
@@ -3444,6 +3465,11 @@ done:
* Reworked function to match major changes in
* H5C_auto_size_ctl_t.
*
+ * JRM -- 4/25/05
+ * Added code to set cache_ptr->size_decreased to TRUE
+ * if the new configuration forces an immediate reduction
+ * in cache size.
+ *
*-------------------------------------------------------------------------
*/
@@ -3474,125 +3500,32 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
}
/* check general configuration section of the config: */
- if ( ( config_ptr->max_size > H5C__MAX_MAX_CACHE_SIZE )
- ||
- ( config_ptr->max_size < config_ptr->min_size )
- ||
- ( config_ptr->min_size < H5C__MIN_MAX_CACHE_SIZE )
- ||
- ( ( config_ptr->set_initial_size ) &&
- ( config_ptr->initial_size > config_ptr->max_size )
- )
- ||
- ( ( config_ptr->set_initial_size ) &&
- ( config_ptr->initial_size < config_ptr->min_size )
- )
- ||
- ( config_ptr->min_clean_fraction > 1.0 )
- ||
- ( config_ptr->min_clean_fraction < 0.0 )
- ||
- ( config_ptr->epoch_length < H5C__MIN_AR_EPOCH_LENGTH )
- ||
- ( config_ptr->epoch_length > H5C__MAX_AR_EPOCH_LENGTH )
- ) {
+ if ( SUCCEED != H5C_validate_resize_config(config_ptr,
+ H5C_RESIZE_CFG__VALIDATE_GENERAL) ) {
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, \
"error in general configuration fields of new config.")
}
/* check size increase control fields of the config: */
- if ( ( ( config_ptr->incr_mode != H5C_incr__off )
- &&
- ( config_ptr->incr_mode != H5C_incr__threshold )
- )
- ||
- ( ( config_ptr->incr_mode == H5C_incr__threshold )
- &&
- ( ( config_ptr->lower_hr_threshold < 0.0 )
- ||
- ( config_ptr->lower_hr_threshold > 1.0 )
- ||
- ( config_ptr->increment < 1.0 )
- /* no need to check max_increment, as it is a size_t,
- * and thus must be non-negative.
- */
- )
- )
- ) {
+ if ( SUCCEED != H5C_validate_resize_config(config_ptr,
+ H5C_RESIZE_CFG__VALIDATE_INCREMENT) ) {
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, \
"error in the size increase control fields of new config.")
}
/* check size decrease control fields of the config: */
- if ( ( ( config_ptr->decr_mode != H5C_decr__off )
- &&
- ( config_ptr->decr_mode != H5C_decr__threshold )
- &&
- ( config_ptr->decr_mode != H5C_decr__age_out )
- &&
- ( config_ptr->decr_mode != H5C_decr__age_out_with_threshold )
- )
- ||
- ( ( config_ptr->decr_mode == H5C_decr__threshold )
- &&
- ( ( config_ptr->upper_hr_threshold > 1.0 )
- ||
- ( config_ptr->decrement > 1.0 )
- ||
- ( config_ptr->decrement < 0.0 )
- /* no need to check max_decrement as it is a size_t
- * and thus must be non-negative.
- */
- )
- )
- ||
- ( ( ( config_ptr->decr_mode == H5C_decr__age_out )
- ||
- ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
- )
- &&
- (
- ( config_ptr->epochs_before_eviction < 1 )
- ||
- ( config_ptr->epochs_before_eviction > H5C__MAX_EPOCH_MARKERS )
- ||
- ( ( config_ptr->apply_empty_reserve )
- &&
- ( config_ptr->empty_reserve < 0.0 )
- )
- ||
- ( ( config_ptr->apply_empty_reserve )
- &&
- ( config_ptr->empty_reserve > 1.0 )
- )
- /* no need to check max_decrement as it is a size_t
- * and thus must be non-negative.
- */
- )
- )
- ||
- ( ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
- &&
- ( config_ptr->upper_hr_threshold > 1.0 )
- )
- ) {
+ if ( SUCCEED != H5C_validate_resize_config(config_ptr,
+ H5C_RESIZE_CFG__VALIDATE_DECREMENT) ) {
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, \
"error in the size decrease control fields of new config.")
}
/* check for conflicts between size increase and size decrease controls: */
- if ( ( config_ptr->incr_mode == H5C_incr__threshold )
- &&
- ( ( config_ptr->decr_mode == H5C_decr__threshold )
- ||
- ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
- )
- &&
- ( config_ptr->lower_hr_threshold >= config_ptr->upper_hr_threshold )
- ) {
+ if ( SUCCEED != H5C_validate_resize_config(config_ptr,
+ H5C_RESIZE_CFG__VALIDATE_INTERACTIONS) ) {
HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, \
"conflicting threshold fields in new config.")
@@ -3713,6 +3646,11 @@ H5C_set_cache_auto_resize_config(H5C_t * cache_ptr,
HDassert( (cache_ptr->resize_ctl).min_size <= new_max_cache_size );
HDassert( new_max_cache_size <= (cache_ptr->resize_ctl).max_size );
+ if ( new_max_cache_size < cache_ptr->max_cache_size ) {
+
+ cache_ptr->size_decreased = TRUE;
+ }
+
cache_ptr->max_cache_size = new_max_cache_size;
cache_ptr->min_clean_size = new_min_clean_size;
@@ -4309,6 +4247,242 @@ done:
} /* H5C_unprotect() */
+/*-------------------------------------------------------------------------
+ * Function: H5C_validate_resize_config()
+ *
+ * Purpose: Run a sanity check on the specified sections of the
+ * provided instance of struct H5C_auto_size_ctl_t.
+ *
+ * Do nothing and return SUCCEED if no errors are detected,
+ * and flag an error and return FAIL otherwise.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 3/23/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
+ unsigned int tests)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5C_validate_resize_config, FAIL)
+
+ if ( config_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "NULL config_ptr on entry.")
+ }
+
+ if ( config_ptr->version != H5C__CURR_AUTO_SIZE_CTL_VER ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Unknown config version.")
+ }
+
+
+ if ( (tests & H5C_RESIZE_CFG__VALIDATE_GENERAL) != 0 ) {
+
+ if ( ( config_ptr->set_initial_size != TRUE ) &&
+ ( config_ptr->set_initial_size != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "set_initial_size must be either TRUE or FALSE");
+ }
+
+ if ( config_ptr->max_size > H5C__MAX_MAX_CACHE_SIZE ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "max_size too big");
+ }
+
+ if ( config_ptr->min_size < H5C__MIN_MAX_CACHE_SIZE ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "min_size too small");
+ }
+
+ if ( config_ptr->min_size > config_ptr->max_size ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "min_size > max_size");
+ }
+
+ if ( ( config_ptr->set_initial_size ) &&
+ ( ( config_ptr->initial_size < config_ptr->min_size ) ||
+ ( config_ptr->initial_size > config_ptr->max_size ) ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "initial_size must be in the interval [min_size, max_size]");
+ }
+
+ if ( ( config_ptr->min_clean_fraction < 0.0 ) ||
+ ( config_ptr->min_clean_fraction > 1.0 ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "min_clean_fraction must be in the interval [0.0, 1.0]");
+ }
+
+ if ( config_ptr->epoch_length < H5C__MIN_AR_EPOCH_LENGTH ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epoch_length too small");
+ }
+
+ if ( config_ptr->epoch_length > H5C__MAX_AR_EPOCH_LENGTH ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "epoch_length too big");
+ }
+ } /* H5C_RESIZE_CFG__VALIDATE_GENERAL */
+
+
+ if ( (tests & H5C_RESIZE_CFG__VALIDATE_INCREMENT) != 0 ) {
+
+ if ( ( config_ptr->incr_mode != H5C_incr__off ) &&
+ ( config_ptr->incr_mode != H5C_incr__threshold ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid incr_mode");
+ }
+
+ if ( config_ptr->incr_mode == H5C_incr__threshold ) {
+
+ if ( ( config_ptr->lower_hr_threshold < 0.0 ) ||
+ ( config_ptr->lower_hr_threshold > 1.0 ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "lower_hr_threshold must be in the range [0.0, 1.0]");
+ }
+
+ if ( config_ptr->increment < 1.0 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "increment must be greater than or equal to 1.0");
+ }
+
+ if ( ( config_ptr->apply_max_increment != TRUE ) &&
+ ( config_ptr->apply_max_increment != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "apply_max_increment must be either TRUE or FALSE");
+ }
+
+ /* no need to check max_increment, as it is a size_t,
+ * and thus must be non-negative.
+ */
+ } /* H5C_incr__threshold */
+
+ } /* H5C_RESIZE_CFG__VALIDATE_INCREMENT */
+
+
+ if ( (tests & H5C_RESIZE_CFG__VALIDATE_DECREMENT) != 0 ) {
+
+ if ( ( config_ptr->decr_mode != H5C_decr__off ) &&
+ ( config_ptr->decr_mode != H5C_decr__threshold ) &&
+ ( config_ptr->decr_mode != H5C_decr__age_out ) &&
+ ( config_ptr->decr_mode != H5C_decr__age_out_with_threshold )
+ ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Invalid decr_mode");
+ }
+
+ if ( config_ptr->decr_mode == H5C_decr__threshold ) {
+
+ if ( config_ptr->upper_hr_threshold > 1.0 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "upper_hr_threshold must be <= 1.0");
+ }
+
+ if ( ( config_ptr->decrement > 1.0 ) ||
+ ( config_ptr->decrement < 0.0 ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "decrement must be in the interval [0.0, 1.0]");
+ }
+
+ /* no need to check max_decrement as it is a size_t
+ * and thus must be non-negative.
+ */
+ } /* H5C_decr__threshold */
+
+ if ( ( config_ptr->decr_mode == H5C_decr__age_out ) ||
+ ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
+ ) {
+
+ if ( config_ptr->epochs_before_eviction < 1 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "epochs_before_eviction must be positive");
+ }
+
+ if ( config_ptr->epochs_before_eviction > H5C__MAX_EPOCH_MARKERS ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "epochs_before_eviction too big");
+ }
+
+ if ( ( config_ptr->apply_empty_reserve != TRUE ) &&
+ ( config_ptr->apply_empty_reserve != FALSE ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "apply_empty_reserve must be either TRUE or FALSE");
+ }
+
+ if ( ( config_ptr->apply_empty_reserve ) &&
+ ( ( config_ptr->empty_reserve > 1.0 ) ||
+ ( config_ptr->empty_reserve < 0.0 ) ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "empty_reserve must be in the interval [0.0, 1.0]");
+ }
+
+ /* no need to check max_decrement as it is a size_t
+ * and thus must be non-negative.
+ */
+ } /* H5C_decr__age_out || H5C_decr__age_out_with_threshold */
+
+ if ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold ) {
+
+ if ( ( config_ptr->upper_hr_threshold > 1.0 ) ||
+ ( config_ptr->upper_hr_threshold < 0.0 ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "upper_hr_threshold must be in the interval [0.0, 1.0]");
+ }
+ } /* H5C_decr__age_out_with_threshold */
+
+ } /* H5C_RESIZE_CFG__VALIDATE_DECREMENT */
+
+
+ if ( (tests & H5C_RESIZE_CFG__VALIDATE_INTERACTIONS) != 0 ) {
+
+ if ( ( config_ptr->incr_mode == H5C_incr__threshold )
+ &&
+ ( ( config_ptr->decr_mode == H5C_decr__threshold )
+ ||
+ ( config_ptr->decr_mode == H5C_decr__age_out_with_threshold )
+ )
+ &&
+ ( config_ptr->lower_hr_threshold
+ >=
+ config_ptr->upper_hr_threshold
+ )
+ ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "conflicting threshold fields in config.")
+ }
+ } /* H5C_RESIZE_CFG__VALIDATE_INTERACTIONS */
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+
+} /* H5C_validate_resize_config() */
+
+
/*************************************************************************/
/**************************** Private Functions: *************************/
/*************************************************************************/
diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h
index 9b1a2a2..7d708f8 100644
--- a/src/H5Cpkg.h
+++ b/src/H5Cpkg.h
@@ -575,7 +575,6 @@
#define H5C__H5C_T_MAGIC 0x005CAC0E
#define H5C__MAX_NUM_TYPE_IDS 10
-#define H5C__MAX_EPOCH_MARKERS 10
struct H5C_t
{
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index 7830b26..9f8dd78 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -459,7 +459,7 @@ typedef struct H5C_cache_entry_t
* cache size from the old if a cache size increment is triggered.
* The increment must be greater than 1.0, and should not exceed 2.0.
*
- * The new cache size is obtained my multiplying the current max cache
+ * The new cache size is obtained by multiplying the current max cache
* size by the increment, and then clamping to max_size and to stay
* within the max_increment as necessary.
*
@@ -559,9 +559,23 @@ typedef struct H5C_cache_entry_t
*
****************************************************************************/
+#define H5C_RESIZE_CFG__VALIDATE_GENERAL 0x1
+#define H5C_RESIZE_CFG__VALIDATE_INCREMENT 0x2
+#define H5C_RESIZE_CFG__VALIDATE_DECREMENT 0x4
+#define H5C_RESIZE_CFG__VALIDATE_INTERACTIONS 0x8
+#define H5C_RESIZE_CFG__VALIDATE_ALL \
+( \
+ H5C_RESIZE_CFG__VALIDATE_GENERAL | \
+ H5C_RESIZE_CFG__VALIDATE_INCREMENT | \
+ H5C_RESIZE_CFG__VALIDATE_DECREMENT | \
+ H5C_RESIZE_CFG__VALIDATE_INTERACTIONS \
+)
+
#define H5C__CURR_AUTO_SIZE_CTL_VER 1
#define H5C__CURR_AUTO_RESIZE_RPT_FCN_VER 1
+#define H5C__MAX_EPOCH_MARKERS 10
+
#define H5C__DEF_AR_UPPER_THRESHHOLD 0.9999
#define H5C__DEF_AR_LOWER_THRESHHOLD 0.9
#define H5C__DEF_AR_MAX_SIZE ((size_t)(16 * 1024 * 1024))
@@ -590,20 +604,6 @@ enum H5C_resize_status
not_full
}; /* enum H5C_resize_conditions */
-enum H5C_cache_incr_mode
-{
- H5C_incr__off,
- H5C_incr__threshold
-};
-
-enum H5C_cache_decr_mode
-{
- H5C_decr__off,
- H5C_decr__threshold,
- H5C_decr__age_out,
- H5C_decr__age_out_with_threshold
-};
-
typedef void (*H5C_auto_resize_rpt_fcn)(H5C_t * cache_ptr,
int32_t version,
double hit_rate,
@@ -612,6 +612,7 @@ typedef void (*H5C_auto_resize_rpt_fcn)(H5C_t * cache_ptr,
size_t new_max_cache_size,
size_t old_min_clean_size,
size_t new_min_clean_size);
+
typedef struct H5C_auto_size_ctl_t
{
/* general configuration fields: */
@@ -768,5 +769,8 @@ H5_DLL herr_t H5C_unprotect(H5F_t * f,
void * thing,
unsigned int flags);
+H5_DLL herr_t H5C_validate_resize_config(H5C_auto_size_ctl_t * config_ptr,
+ unsigned int tests);
+
#endif /* !_H5Cprivate_H */
diff --git a/src/H5Cpublic.h b/src/H5Cpublic.h
index d4e82be..cb0fa13 100644
--- a/src/H5Cpublic.h
+++ b/src/H5Cpublic.h
@@ -34,6 +34,20 @@
extern "C" {
#endif
+enum H5C_cache_incr_mode
+{
+ H5C_incr__off,
+ H5C_incr__threshold
+};
+
+enum H5C_cache_decr_mode
+{
+ H5C_decr__off,
+ H5C_decr__threshold,
+ H5C_decr__age_out,
+ H5C_decr__age_out_with_threshold
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/src/H5F.c b/src/H5F.c
index 9a80f04..f12aac8 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -143,6 +143,11 @@ done:
*
* Raymond Lu, 2001-10-14
* Change File creation property list to generic property list mechanism.
+ *
+ * J. Mainzer, 2005-03-10
+ * Updated function for changes in property list entries required
+ * by the new metadata cache.
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -175,7 +180,7 @@ H5F_init_interface(void)
unsigned sharedheader_ver = H5F_CRT_SHARE_HEAD_VERS_DEF;
/* File access property class variables. In sequence, they are
* - File access property class to modify
- * - Size of meta data cache(elements)
+ * - Initial metadata cache resize configuration
* - Size of raw data chunk cache(elements)
* - Size of raw data chunk cache(bytes)
* - Preemption for reading chunks
@@ -188,7 +193,8 @@ H5F_init_interface(void)
* - File driver info
*/
H5P_genclass_t *acs_pclass;
- int mdc_nelmts = H5F_ACS_META_CACHE_SIZE_DEF;
+ H5AC_cache_config_t
+ mdc_initCacheCfg = H5F_ACS_META_CACHE_INIT_CONFIG_DEF;
size_t rdcc_nelmts = H5F_ACS_DATA_CACHE_ELMT_SIZE_DEF;
size_t rdcc_nbytes = H5F_ACS_DATA_CACHE_BYTE_SIZE_DEF;
double rdcc_w0 = H5F_ACS_PREEMPT_READ_CHUNKS_DEF;
@@ -295,8 +301,9 @@ H5F_init_interface(void)
/* Assume that if there are properties in the class, they are the default ones */
if(nprops==0) {
- /* Register the size of meta data cache(elements) */
- if(H5P_register(acs_pclass,H5F_ACS_META_CACHE_SIZE_NAME,H5F_ACS_META_CACHE_SIZE_SIZE, &mdc_nelmts,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0)
+
+ /* Register the initial metadata cache resize configuration */
+ if(H5P_register(acs_pclass,H5F_ACS_META_CACHE_INIT_CONFIG_NAME,H5F_ACS_META_CACHE_INIT_CONFIG_SIZE, &mdc_initCacheCfg,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
/* Register the size of raw data chunk cache (elements) */
@@ -761,6 +768,10 @@ done:
* Fixed bug where the driver ID and info in the property
* list were being overwritten but the original ID and info
* weren't being close.
+ *
+ * J Mainzer, Mar 10, 2005
+ * Updated function for changes in the propertly list entries
+ * used by the new metadata cache.
*
*-------------------------------------------------------------------------
*/
@@ -789,8 +800,8 @@ H5Fget_access_plist(hid_t file_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Copy properties of the file access property list */
- if(H5P_set(new_plist, H5F_ACS_META_CACHE_SIZE_NAME, &(f->shared->mdc_nelmts)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set meta data cache size")
+ if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial meta data cache resize config.")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache element size")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
@@ -1392,13 +1403,16 @@ done:
* Changed the file creation and access property list to the
* new generic property list.
*
+ * J Mainzer, Mar 10, 2005
+ * Updated for the new metadata cache, and associated
+ * property list changes.
+ *
*-------------------------------------------------------------------------
*/
static H5F_t *
H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
{
H5F_t *f=NULL, *ret_value;
- int n;
H5P_genplist_t *plist; /* Property list */
FUNC_ENTER_NOAPI_NOINIT(H5F_new)
@@ -1450,9 +1464,9 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
+ if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial meta data cache resize config")
- if(H5P_get(plist, H5F_ACS_META_CACHE_SIZE_NAME, &(f->shared->mdc_nelmts)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data cache size")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache element size")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
@@ -1474,10 +1488,12 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id)
* The cache might be created with a different number of elements and
* the access property list should be updated to reflect that.
*/
- if ((n=H5AC_create(f, f->shared->mdc_nelmts))<0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache")
+ if ( SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)) ) {
- f->shared->mdc_nelmts = n;
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, \
+ "unable to create meta data cache")
+
+ }
/* Create the file's "open object" information */
if(H5FO_create(f)<0)
@@ -4746,6 +4762,303 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Fget_mdc_config
+ *
+ * Purpose: Retrieves the current automatic cache resize configuration
+ * from the metadata cache, and return it in *config_ptr.
+ *
+ * Note that the version field of *config_Ptr must be correctly
+ * filled in by the caller. This allows us to adapt for
+ * obsolete versions of the structure.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 3/24/05
+ *
+ * Modifications:
+ *
+ * Reworked for the addition of the config_ptr parameter.
+ * JRM -- 4/7/05
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5Fget_mdc_config(hid_t file_id,
+ H5AC_cache_config_t *config_ptr)
+{
+ H5F_t *file=NULL; /* File object for file ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
+
+ FUNC_ENTER_API(H5Fget_mdc_config, FAIL)
+ H5TRACE2("e","ix",file_id,config_ptr);
+
+ /* Check args */
+ if ( NULL == (file = H5I_object_verify(file_id, H5I_FILE)) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ }
+
+ if ( ( NULL == config_ptr ) ||
+ ( config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION ) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Bad config_ptr")
+ }
+
+ /* Go get the resize configuration */
+ result = H5AC_get_cache_auto_resize_config(file->shared->cache, config_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5AC_get_cache_auto_resize_config() failed.");
+ }
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* H5Fget_mdc_config() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fset_mdc_config
+ *
+ * Purpose: Sets the current metadata cache automatic resize
+ * configuration, using the contents of the instance of
+ * H5AC_cache_config_t pointed to by config_ptr.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 3/24/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5Fset_mdc_config(hid_t file_id,
+ H5AC_cache_config_t *config_ptr)
+{
+ H5F_t *file=NULL; /* File object for file ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
+
+ FUNC_ENTER_API(H5Fset_mdc_config, FAIL)
+ H5TRACE2("e","ix",file_id,config_ptr);
+
+ /* Check args */
+ if ( NULL == (file = H5I_object_verify(file_id, H5I_FILE)) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ }
+
+ /* set the resize configuration */
+ result = H5AC_set_cache_auto_resize_config(file->shared->cache, config_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "H5AC_set_cache_auto_resize_config() failed.");
+ }
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* H5Fset_mdc_config() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fget_mdc_hit_rate
+ *
+ * Purpose: Retrieves the current hit rate from the metadata cache.
+ * This rate is the overall hit rate since the last time
+ * the hit rate statistics were reset either manually or
+ * automatically.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 3/24/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5Fget_mdc_hit_rate(hid_t file_id,
+ double *hit_rate_ptr)
+{
+ H5F_t *file=NULL; /* File object for file ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
+
+ FUNC_ENTER_API(H5Fget_mdc_hit_rate, FAIL)
+ H5TRACE2("e","i*d",file_id,hit_rate_ptr);
+
+ /* Check args */
+ if ( NULL == (file = H5I_object_verify(file_id, H5I_FILE)) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ }
+
+ if ( NULL == hit_rate_ptr ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL hit rate pointer")
+ }
+
+ /* Go get the current hit rate */
+ result = H5AC_get_cache_hit_rate(file->shared->cache, hit_rate_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5AC_get_cache_hit_rate() failed.");
+ }
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* H5Fget_mdc_hit_rate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fget_mdc_size
+ *
+ * Purpose: Retrieves the maximum size, minimum clean size, current
+ * size, and current number of entries from the metadata
+ * cache associated with the specified file. If any of
+ * the ptr parameters are NULL, the associated datum is
+ * not returned.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 3/24/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5Fget_mdc_size(hid_t file_id,
+ size_t *max_size_ptr,
+ size_t *min_clean_size_ptr,
+ size_t *cur_size_ptr,
+ int32_t *cur_num_entries_ptr)
+{
+ H5F_t *file=NULL; /* File object for file ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
+
+ FUNC_ENTER_API(H5Fget_mdc_size, FAIL)
+ H5TRACE5("e","i*z*z*z*Is",file_id,max_size_ptr,min_clean_size_ptr,
+ cur_size_ptr,cur_num_entries_ptr);
+
+ /* Check args */
+ if ( NULL == (file = H5I_object_verify(file_id, H5I_FILE)) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ }
+
+ /* Go get the size data */
+ result = H5AC_get_cache_size(file->shared->cache,
+ max_size_ptr,
+ min_clean_size_ptr,
+ cur_size_ptr,
+ cur_num_entries_ptr);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5AC_get_cache_size() failed.");
+ }
+
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* H5Fget_mdc_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Freset_mdc_hit_rate_stats
+ *
+ * Purpose: Reset the hit rate statistic whose current value can
+ * be obtained via the H5Fget_mdc_hit_rate() call. Note
+ * that this statistic will also be reset once per epoch
+ * by the automatic cache resize code if it is enabled.
+ *
+ * It is probably a bad idea to call this function unless
+ * you are controlling cache size from your program instead
+ * of using our cache size control code.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: John Mainzer
+ * 3/24/05
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5Freset_mdc_hit_rate_stats(hid_t file_id)
+{
+ H5F_t *file=NULL; /* File object for file ID */
+ herr_t ret_value = SUCCEED; /* Return value */
+ herr_t result;
+
+ FUNC_ENTER_API(H5Freset_mdc_hit_rate_stats, FAIL)
+ H5TRACE1("e","i",file_id);
+
+ /* Check args */
+ if ( NULL == (file = H5I_object_verify(file_id, H5I_FILE)) ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+ }
+
+ /* Reset the hit rate statistic */
+ result = H5AC_reset_cache_hit_rate_stats(file->shared->cache);
+
+ if ( result != SUCCEED ) {
+
+ HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \
+ "H5AC_reset_cache_hit_rate_stats() failed.");
+ }
+
+
+done:
+
+ FUNC_LEAVE_API(ret_value)
+
+} /* H5Freset_mdc_hit_rate_stats() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Fget_name
*
* Purpose: Gets the name of the file to which object OBJ_ID belongs.
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 7997524..c281da3 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -96,8 +96,12 @@ typedef struct H5F_file_t {
unsigned super_chksum; /* Superblock checksum */
unsigned drvr_chksum; /* Driver info block checksum */
H5AC_t *cache; /* The object cache */
+ H5AC_cache_config_t
+ mdc_initCacheCfg; /* initial configuration for the */
+ /* metadata cache. This structure is */
+ /* fixed at creation time and should */
+ /* not change thereafter. */
hid_t fcpl_id; /* File creation property list ID */
- int mdc_nelmts; /* Size of meta data cache (elements) */
size_t rdcc_nelmts; /* Size of raw data chunk cache (elmts) */
size_t rdcc_nbytes; /* Size of raw data chunk cache (bytes) */
double rdcc_w0; /* Preempt read chunks first? [0.0..1.0]*/
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 71f00a1..51ea689 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -316,10 +316,10 @@ typedef struct H5F_t H5F_t;
#define H5F_CRT_SHARE_HEAD_VERS_DEF HDF5_SHAREDHEADER_VERSION
/* ========= File Access properties ============ */
-/* Definitions for size of meta data cache(elements) */
-#define H5F_ACS_META_CACHE_SIZE_NAME "mdc_nelmts"
-#define H5F_ACS_META_CACHE_SIZE_SIZE sizeof(int)
-#define H5F_ACS_META_CACHE_SIZE_DEF H5AC_NSLOTS
+/* Definitions for the initial metadata cache resize configuration */
+#define H5F_ACS_META_CACHE_INIT_CONFIG_NAME "mdc_initCacheCfg"
+#define H5F_ACS_META_CACHE_INIT_CONFIG_SIZE sizeof(H5AC_cache_config_t)
+#define H5F_ACS_META_CACHE_INIT_CONFIG_DEF H5AC__DEFAULT_CACHE_CONFIG
/* Definitions for size of raw data chunk cache(elements) */
#define H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME "rdcc_nelmts"
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 4718aa3..a0e3780 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -20,6 +20,8 @@
/* Public header files needed by this file */
#include "H5public.h"
+#include "H5Cpublic.h"
+#include "H5ACpublic.h"
#include "H5Ipublic.h"
/*
@@ -114,6 +116,17 @@ H5_DLL herr_t H5Fmount(hid_t loc, const char *name, hid_t child, hid_t plist);
H5_DLL herr_t H5Funmount(hid_t loc, const char *name);
H5_DLL hssize_t H5Fget_freespace(hid_t file_id);
H5_DLL herr_t H5Fget_filesize(hid_t file_id, hsize_t *size);
+H5_DLL herr_t H5Fget_mdc_config(hid_t file_id,
+ H5AC_cache_config_t * config_ptr);
+H5_DLL herr_t H5Fset_mdc_config(hid_t file_id,
+ H5AC_cache_config_t * config_ptr);
+H5_DLL herr_t H5Fget_mdc_hit_rate(hid_t file_id, double * hit_rate_ptr);
+H5_DLL herr_t H5Fget_mdc_size(hid_t file_id,
+ size_t * max_size_ptr,
+ size_t * min_clean_size_ptr,
+ size_t * cur_size_ptr,
+ int32_t * cur_num_entries_ptr);
+H5_DLL herr_t H5Freset_mdc_hit_rate_stats(hid_t file_id);
H5_DLL ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size);
#ifdef __cplusplus
diff --git a/src/H5MPprivate.h b/src/H5MPprivate.h
index 1a55171..97188c5 100644
--- a/src/H5MPprivate.h
+++ b/src/H5MPprivate.h
@@ -138,6 +138,11 @@
#define color_H5Funmount "red"
#define color_H5Fget_freespace "red"
#define color_H5Fget_filesize "red"
+#define color_H5Fget_mdc_config "red"
+#define color_H5Fset_mdc_config "red"
+#define color_H5Fget_mdc_hit_rate "red"
+#define color_H5Fget_mdc_size "red"
+#define color_H5Freset_mdc_hit_rate_stats "red"
#define color_H5Fget_name "red"
#define color_H5Gcreate "red"
@@ -361,6 +366,8 @@
#define color_H5Pset_scaleoffset "red"
#define color_H5Pset_cache "red"
#define color_H5Pget_cache "red"
+#define color_H5Pset_mdc_config "red"
+#define color_H5Pget_mdc_config "red"
#define color_H5Pset_hyper_cache "red"
#define color_H5Pget_hyper_cache "red"
#define color_H5Pset_htree_ratios "red"
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 469a65c..587ab2f 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -802,11 +802,16 @@ done:
* Raymond Lu
* Tuesday, Oct 23, 2001
* Changed the file access list to the new generic property list.
+ *
+ * J. Mainzer
+ * Thurs. 3/17/05
+ * The mdc_nelmts entry is no more in the FAPL, so I modified
+ * the code to ignore it.
*
*-------------------------------------------------------------------------
*/
herr_t
-H5Pset_cache(hid_t plist_id, int mdc_nelmts,
+H5Pset_cache(hid_t plist_id, int UNUSED mdc_nelmts,
size_t rdcc_nelmts, size_t rdcc_nbytes, double rdcc_w0)
{
H5P_genplist_t *plist; /* Property list pointer */
@@ -816,8 +821,6 @@ H5Pset_cache(hid_t plist_id, int mdc_nelmts,
H5TRACE5("e","iIszzd",plist_id,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0);
/* Check arguments */
- if (mdc_nelmts<0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "meta data cache size must be non-negative");
if (rdcc_w0<0.0 || rdcc_w0>1.0)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "raw data cache w0 value must be between 0.0 and 1.0 inclusive");
@@ -826,8 +829,6 @@ H5Pset_cache(hid_t plist_id, int mdc_nelmts,
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Set sizes */
- if(H5P_set(plist, H5F_ACS_META_CACHE_SIZE_NAME, &mdc_nelmts) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set meta data cache size");
if(H5P_set(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &rdcc_nelmts) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET,FAIL, "can't set data cache element size");
if(H5P_set(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &rdcc_nbytes) < 0)
@@ -860,6 +861,11 @@ done:
* Tuesday, Oct 23, 2001
* Changed the file access list to the new generic property
* list.
+ *
+ * J Mainzer
+ * Thurs, 3/17/05
+ * The mdc_nelmts fapl entry is no more, so we now just
+ * return a constant when that value is requested.
*
*-------------------------------------------------------------------------
*/
@@ -879,9 +885,11 @@ H5Pget_cache(hid_t plist_id, int *mdc_nelmts,
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
/* Get sizes */
+
+ /* the mdc_nelmts FAPL entry no longer exists, so just return a constant */
if (mdc_nelmts)
- if(H5P_get(plist, H5F_ACS_META_CACHE_SIZE_NAME, mdc_nelmts) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get meta data cache size");
+ *mdc_nelmts = 0;
+
if (rdcc_nelmts)
if(H5P_get(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, rdcc_nelmts) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, "can't get data cache element size");
@@ -898,6 +906,134 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Pset_mdc_config
+ *
+ * Purpose: Set the initial metadata cache resize configuration in the
+ * target FAPL.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: J. Mainzer
+ * Thursday, April 7, 2005
+ *
+ * Modifications:
+ *
+ * Done.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_mdc_config(hid_t plist_id,
+ H5AC_cache_config_t *config_ptr)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pset_mdc_config, FAIL);
+ H5TRACE2("e","ix",plist_id,config_ptr);
+
+ /* Get the plist structure */
+ if( NULL == ( plist = H5P_object_verify(plist_id,H5P_FILE_ACCESS) ) ) {
+
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ }
+
+ /* validate the new configuration */
+ if ( H5AC_validate_config(config_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, \
+ "invalid metadata cache configuration");
+ }
+
+ /* set the modified config */
+
+ /* If we ever support multiple versions of H5AC_cache_config_t, we
+ * will have to test the version and do translation here.
+ */
+
+ if(H5P_set(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, config_ptr)<0) {
+
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, \
+ "can't set metadata cache initial config");
+ }
+
+done:
+
+ FUNC_LEAVE_API(ret_value);
+
+} /* H5Pset_mdc_config() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_mdc_config
+ *
+ * Purpose: Retrieve the metadata cache initial resize configuration
+ * from the target FAPL.
+ *
+ * Observe that the function will fail if config_ptr is
+ * NULL, or if config_ptr->version specifies an unknown
+ * version of H5AC_cache_config_t.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: J. Mainzer
+ * Thursday, April 7, 2005
+ *
+ * Modifications:
+ *
+ * None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+herr_t
+H5Pget_mdc_config(hid_t plist_id,
+ H5AC_cache_config_t *config_ptr)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ herr_t ret_value = SUCCEED; /* return value */
+ H5C_auto_size_ctl_t resizeCfg;
+
+ FUNC_ENTER_API(H5Pget_mdc_config, FAIL);
+ H5TRACE2("e","ix",plist_id,config_ptr);
+
+ /* Get the plist structure */
+ if ( NULL == (plist = H5P_object_verify(plist_id,H5P_FILE_ACCESS)) ) {
+
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID");
+ }
+
+ /* validate the config_ptr */
+ if ( config_ptr == NULL ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "NULL config_ptr on entry.")
+ }
+
+ if ( config_ptr->version != H5AC__CURR_CACHE_CONFIG_VERSION ) {
+
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown config version.")
+ }
+
+ /* If we ever support multiple versions of H5AC_cache_config_t, we
+ * will have to get the cannonical version here, and then translate
+ * to the version of the structure supplied.
+ */
+
+ /* Get the current initial metadata cache resize configuration */
+ if ( H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, config_ptr) < 0 ) {
+
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET,FAIL, \
+ "can't get metadata cache initial resize config");
+ }
+
+done:
+
+ FUNC_LEAVE_API(ret_value);
+
+} /* H5Pget_mdc_config() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_gc_references
*
* Purpose: Sets the flag for garbage collecting references for the file.
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 179e7f6..be2f2ee 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -24,6 +24,7 @@
/* Public headers needed by this file */
#include "H5public.h"
+#include "H5Cpublic.h"
#include "H5Ipublic.h"
#include "H5Dpublic.h"
#include "H5Fpublic.h"
@@ -252,11 +253,17 @@ H5_DLL herr_t H5Pset_edc_check(hid_t plist_id, H5Z_EDC_t check);
H5_DLL H5Z_EDC_t H5Pget_edc_check(hid_t plist_id);
H5_DLL herr_t H5Pset_filter_callback(hid_t plist_id, H5Z_filter_func_t func,
void* op_data);
-H5_DLL herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts, size_t rdcc_nelmts,
- size_t rdcc_nbytes, double rdcc_w0);
-H5_DLL herr_t H5Pget_cache(hid_t plist_id, int *mdc_nelmts/*out*/,
+H5_DLL herr_t H5Pset_cache(hid_t plist_id, int mdc_nelmts,
+ size_t rdcc_nelmts, size_t rdcc_nbytes,
+ double rdcc_w0);
+H5_DLL herr_t H5Pget_cache(hid_t plist_id,
+ int *mdc_nelmts, /* out */
size_t *rdcc_nelmts/*out*/,
size_t *rdcc_nbytes/*out*/, double *rdcc_w0);
+H5_DLL herr_t H5Pset_mdc_config(hid_t plist_id,
+ H5AC_cache_config_t * config_ptr);
+H5_DLL herr_t H5Pget_mdc_config(hid_t plist_id,
+ H5AC_cache_config_t * config_ptr); /* out */
H5_DLL herr_t H5Pset_btree_ratios(hid_t plist_id, double left, double middle,
double right);
H5_DLL herr_t H5Pget_btree_ratios(hid_t plist_id, double *left/*out*/,
diff --git a/test/cache.c b/test/cache.c
index 9fb940e..3fe7895 100644
--- a/test/cache.c
+++ b/test/cache.c
@@ -20,6 +20,7 @@
*/
#include "h5test.h"
#include "H5Iprivate.h"
+#include "H5ACprivate.h"
const char *FILENAME[] = {
"cache",
@@ -30,6 +31,10 @@ const char *FILENAME[] = {
#include "H5Cpkg.h"
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+
+#include "H5Fpkg.h"
+
/* with apologies for the abuse of terminology... */
#define PICO_ENTRY_TYPE 0
@@ -694,6 +699,33 @@ static void verify_clean(void);
static void verify_unprotected(void);
+static void check_fapl_mdc_api_calls(void);
+
+static void validate_mdc_config(hid_t file_id,
+ H5AC_cache_config_t * ext_config_ptr,
+ hbool_t compare_init,
+ int test_num);
+
+static void check_file_mdc_api_calls(void);
+
+static void check_and_validate_cache_hit_rate(hid_t file_id,
+ double * hit_rate_ptr,
+ hbool_t dump_data,
+ int64_t min_accesses,
+ double min_hit_rate);
+
+static void check_and_validate_cache_size(hid_t file_id,
+ size_t * max_size_ptr,
+ size_t * min_clean_size_ptr,
+ size_t * cur_size_ptr,
+ int32_t * cur_num_entries_ptr,
+ hbool_t dump_data);
+
+static void mdc_api_call_smoke_check(void);
+
+static void check_fapl_mdc_api_errs(void);
+
+static void check_file_mdc_api_errs(void);
/* address translation funtions: */
@@ -17464,6 +17496,2964 @@ check_auto_cache_resize_aux_fcns(void)
/*-------------------------------------------------------------------------
+ * Function: check_fapl_mdc_api_calls()
+ *
+ * Purpose: Verify that the file access property list related
+ * metadata cache related API calls are functioning
+ * correctly.
+ *
+ * Since we have tested the H5C code elsewhere, it should
+ * be sufficient to verify that the desired configuration
+ * data is getting to the cache.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/12/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define CACHE_CONFIGS_EQUAL(a, b, cmp_set_init, cmp_init_size) \
+ ( ( (a).version == (b).version ) && \
+ ( (a).rpt_fcn_enabled == (b).rpt_fcn_enabled ) && \
+ ( ( ! cmp_set_init ) || \
+ ( (a).set_initial_size == (b).set_initial_size ) ) && \
+ ( ( ! cmp_init_size ) || \
+ ( (a).initial_size == (b).initial_size ) ) && \
+ ( (a).min_clean_fraction == (b).min_clean_fraction ) && \
+ ( (a).max_size == (b).max_size ) && \
+ ( (a).min_size == (b).min_size ) && \
+ ( (a).epoch_length == (b).epoch_length ) && \
+ ( (a).incr_mode == (b).incr_mode ) && \
+ ( (a).lower_hr_threshold == (b).lower_hr_threshold ) && \
+ ( (a).increment == (b).increment ) && \
+ ( (a).apply_max_increment == (b).apply_max_increment ) && \
+ ( (a).max_increment == (b).max_increment ) && \
+ ( (a).decr_mode == (b).decr_mode ) && \
+ ( (a).upper_hr_threshold == (b).upper_hr_threshold ) && \
+ ( (a).decrement == (b).decrement ) && \
+ ( (a).apply_max_decrement == (b).apply_max_decrement ) && \
+ ( (a).max_decrement == (b).max_decrement ) && \
+ ( (a).epochs_before_eviction == (b).epochs_before_eviction ) && \
+ ( (a).apply_empty_reserve == (b).apply_empty_reserve ) && \
+ ( (a).empty_reserve == (b).empty_reserve ) )
+
+#define XLATE_EXT_TO_INT_MDC_CONFIG(i, e) \
+{ \
+ (i).version = H5C__CURR_AUTO_SIZE_CTL_VER; \
+ if ( (e).rpt_fcn_enabled ) \
+ (i).rpt_fcn = H5C_def_auto_resize_rpt_fcn; \
+ else \
+ (i).rpt_fcn = NULL; \
+ (i).set_initial_size = (e).set_initial_size; \
+ (i).initial_size = (e).initial_size; \
+ (i).min_clean_fraction = (e).min_clean_fraction; \
+ (i).max_size = (e).max_size; \
+ (i).min_size = (e).min_size; \
+ (i).epoch_length = (e).epoch_length; \
+ (i).incr_mode = (e).incr_mode; \
+ (i).lower_hr_threshold = (e).lower_hr_threshold; \
+ (i).increment = (e).increment; \
+ (i).apply_max_increment = (e).apply_max_increment; \
+ (i).max_increment = (e).max_increment; \
+ (i).decr_mode = (e).decr_mode; \
+ (i).upper_hr_threshold = (e).upper_hr_threshold; \
+ (i).decrement = (e).decrement; \
+ (i).apply_max_decrement = (e).apply_max_decrement; \
+ (i).max_decrement = (e).max_decrement; \
+ (i).epochs_before_eviction = (e).epochs_before_eviction; \
+ (i).apply_empty_reserve = (e).apply_empty_reserve; \
+ (i).empty_reserve = (e).empty_reserve; \
+}
+
+static void
+check_fapl_mdc_api_calls(void)
+{
+ const char * fcn_name = "check_fapl_mdc_api_calls()";
+ char filename[512];
+ herr_t result;
+ hid_t fapl_id = -1;
+ hid_t test_fapl_id = -1;
+ hid_t file_id = -1;
+ H5F_t * file_ptr = NULL;
+ H5C_t * cache_ptr = NULL;
+ H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG;
+ H5AC_cache_config_t mod_config =
+ {
+ /* int32_t version = */
+ H5AC__CURR_CACHE_CONFIG_VERSION,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024 + 1),
+ /* double min_clean_fraction = */ 0.2,
+ /* size_t max_size = */ (16 * 1024 * 1024 + 1),
+ /* size_t min_size = */ ( 1 * 1024 * 1024 + 1),
+ /* int64_t epoch_length = */ 50001,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.91,
+ /* double increment = */ 2.1,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024 + 1),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out,
+ /* double upper_hr_threshold = */ 0.998,
+ /* double decrement = */ 0.91,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024 - 1),
+ /* int32_t epochs_before_eviction = */ 4,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.05
+ };
+ H5AC_cache_config_t scratch;
+ H5C_auto_size_ctl_t default_auto_size_ctl;
+ H5C_auto_size_ctl_t mod_auto_size_ctl;
+
+ TESTING("MDC/FAPL related API calls");
+
+ pass = TRUE;
+
+ XLATE_EXT_TO_INT_MDC_CONFIG(default_auto_size_ctl, default_config)
+ XLATE_EXT_TO_INT_MDC_CONFIG(mod_auto_size_ctl, mod_config)
+
+ /* Create a FAPL and verify that it contains the default
+ * initial mdc configuration
+ */
+
+ if ( pass ) {
+
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+
+ if ( fapl_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pcreate(H5P_FILE_ACCESS) failed.\n";
+ }
+ }
+
+ if ( pass ) {
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+
+ result = H5Pget_mdc_config(fapl_id, &scratch);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() failed.\n";
+
+ } else if (!CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE)) {
+
+ pass = FALSE;
+ failure_mssg = "retrieved config doesn't match default.";
+ }
+ }
+
+
+ /* Modify the initial mdc configuration in a FAPL, and verify that
+ * the changes can be read back
+ */
+
+ if ( pass ) {
+
+ result = H5Pset_mdc_config(fapl_id, &mod_config);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pset_mdc_config() failed.\n";
+ }
+ }
+
+ if ( pass ) {
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+
+ result = H5Pget_mdc_config(fapl_id, &scratch);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() failed.\n";
+
+ } else if ( ! CACHE_CONFIGS_EQUAL(mod_config, scratch, TRUE, TRUE) ) {
+
+ pass = FALSE;
+ failure_mssg = "retrieved config doesn't match mod config.";
+ }
+ }
+
+ if ( pass ) {
+
+ if ( H5Pclose(fapl_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pclose() failed.\n";
+ }
+ }
+
+ /* Open a file using the default FAPL. Verify that the resulting
+ * metadata cache uses the default configuration as well. Get a
+ * copy of the FAPL from the file, and verify that it contains the
+ * default initial meta data cache configuration. Close and delete
+ * the file.
+ */
+
+ /* setup the file name */
+ if ( pass ) {
+
+ if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename))
+ == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "h5_fixname() failed.\n";
+ }
+ }
+
+ /* create the file using the default FAPL */
+ if ( pass ) {
+
+ file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ if ( file_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fcreate() failed.\n";
+ }
+ }
+
+ /* get a pointer to the files internal data structure */
+ if ( pass ) {
+
+ file_ptr = H5I_object_verify(file_id, H5I_FILE);
+
+ if ( file_ptr == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "Can't get file_ptr.\n";
+
+ } else {
+
+ cache_ptr = file_ptr->shared->cache;
+ }
+ }
+
+ /* verify that we can access the internal version of the cache config */
+ if ( pass ) {
+
+ if ( ( cache_ptr == NULL ) ||
+ ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ||
+ ( cache_ptr->resize_ctl.version != H5C__CURR_AUTO_SIZE_CTL_VER ) ){
+
+ pass = FALSE;
+ failure_mssg = "Can't access cache resize_ctl.\n";
+ }
+ }
+
+ /* conpare the cache's internal configuration with the expected value */
+ if ( pass ) {
+
+ if ( ! RESIZE_CONFIGS_ARE_EQUAL(default_auto_size_ctl, \
+ cache_ptr->resize_ctl, TRUE) ) {
+
+
+ pass = FALSE;
+ failure_mssg = "Unexpected value(s) in cache resize_ctl.\n";
+ }
+ }
+
+ /* get a copy of the files FAPL */
+ if ( pass ) {
+
+ fapl_id = H5Fget_access_plist(file_id);
+
+ if ( fapl_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_access_plist() failed.\n";
+ }
+ }
+
+ /* compare the initial cache config from the copy of the file's FAPL
+ * to the expected value. If all goes well, close the copy of the FAPL.
+ */
+ if ( pass ) {
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+
+ result = H5Pget_mdc_config(fapl_id, &scratch);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() failed.\n";
+
+ } else if (!CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE)) {
+
+ pass = FALSE;
+ failure_mssg = "config retrieved from file doesn't match default.";
+
+ } else if ( H5Pclose(fapl_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pclose() failed.\n";
+ }
+ }
+
+ /* close the file and delete it */
+ if ( pass ) {
+
+ if ( H5Fclose(file_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fclose() failed.\n";
+
+ } else if ( HDremove(filename) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "HDremove() failed.\n";
+ }
+ }
+
+
+ /* Open a file using a FAPL with a modified initial metadata cache
+ * configuration. Verify that the resulting metadata cache uses the
+ * modified configuration as well. Get a copy of the FAPL from the
+ * file, and verify that it contains the modified initial meta data
+ * cache configuration. Close and delete the file.
+ */
+
+ /* Create a FAPL */
+ if ( pass ) {
+
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+
+ if ( fapl_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pcreate(H5P_FILE_ACCESS) failed.\n";
+ }
+ }
+
+ /* Modify the initial mdc configuration in the FAPL. */
+
+ if ( pass ) {
+
+ result = H5Pset_mdc_config(fapl_id, &mod_config);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pset_mdc_config() failed.\n";
+ }
+ }
+
+ /* setup the file name */
+ if ( pass ) {
+
+ if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename))
+ == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "h5_fixname() failed.\n";
+ }
+ }
+
+ /* create the file using the modified FAPL */
+ if ( pass ) {
+
+ file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
+
+ if ( file_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fcreate() failed.\n";
+ }
+ }
+
+ /* get a pointer to the files internal data structure */
+ if ( pass ) {
+
+ file_ptr = H5I_object_verify(file_id, H5I_FILE);
+
+ if ( file_ptr == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "Can't get file_ptr.\n";
+
+ } else {
+
+ cache_ptr = file_ptr->shared->cache;
+ }
+ }
+
+ /* verify that we can access the internal version of the cache config */
+ if ( pass ) {
+
+ if ( ( cache_ptr == NULL ) ||
+ ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ||
+ ( cache_ptr->resize_ctl.version != H5C__CURR_AUTO_SIZE_CTL_VER ) ){
+
+ pass = FALSE;
+ failure_mssg = "Can't access cache resize_ctl.\n";
+ }
+ }
+
+ /* conpare the cache's internal configuration with the expected value */
+ if ( pass ) {
+
+ if ( ! RESIZE_CONFIGS_ARE_EQUAL(mod_auto_size_ctl, \
+ cache_ptr->resize_ctl, TRUE) ) {
+
+
+ pass = FALSE;
+ failure_mssg = "Unexpected value(s) in cache resize_ctl.\n";
+ }
+ }
+
+ /* get a copy of the files FAPL */
+ if ( pass ) {
+
+ test_fapl_id = H5Fget_access_plist(file_id);
+
+ if ( test_fapl_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_access_plist() failed.\n";
+ }
+ }
+
+ /* compare the initial cache config from the copy of the file's FAPL
+ * to the expected value. If all goes well, close the copy of the FAPL.
+ */
+ if ( pass ) {
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+
+ result = H5Pget_mdc_config(test_fapl_id, &scratch);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() failed.\n";
+
+ } else if ( ! CACHE_CONFIGS_EQUAL(mod_config, scratch, TRUE, TRUE) ) {
+
+ pass = FALSE;
+ failure_mssg = "config retrieved from file doesn't match.";
+
+ } else if ( H5Pclose(test_fapl_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pclose() failed.\n";
+ }
+ }
+
+ /* close the fapl used to create the file */
+ if ( pass ) {
+
+ if ( H5Pclose(fapl_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pclose() failed.\n";
+ }
+ }
+
+ /* close the file and delete it */
+ if ( pass ) {
+
+ if ( H5Fclose(file_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fclose() failed.\n";
+
+ } else if ( HDremove(filename) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "HDremove() failed.\n";
+ }
+ }
+
+ if ( pass ) { PASSED(); } else { H5_FAILED(); }
+
+ if ( ! pass )
+ HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n",
+ fcn_name, failure_mssg);
+
+} /* check_fapl_mdc_api_calls() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: validate_mdc_config()
+ *
+ * Purpose: Verify that the file indicated by the file_id parameter
+ * has both internal and external configuration matching
+ * *config_ptr.
+ *
+ * Do nothin on success. On failure, set pass to FALSE, and
+ * load an error message into failue_mssg. Note that
+ * failure_msg is assumed to be at least 128 bytes in length.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/14/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+validate_mdc_config(hid_t file_id,
+ H5AC_cache_config_t * ext_config_ptr,
+ hbool_t compare_init,
+ int test_num)
+{
+ /* const char * fcn_name = "validate_mdc_config()"; */
+ static char msg[256];
+ H5F_t * file_ptr = NULL;
+ H5C_t * cache_ptr = NULL;
+ H5AC_cache_config_t scratch;
+ H5C_auto_size_ctl_t int_config;
+
+ XLATE_EXT_TO_INT_MDC_CONFIG(int_config, (*ext_config_ptr))
+
+ /* get a pointer to the files internal data structure */
+ if ( pass ) {
+
+ file_ptr = H5I_object_verify(file_id, H5I_FILE);
+
+ if ( file_ptr == NULL ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128, "Can't get file_ptr #%d.", test_num);
+ failure_mssg = msg;
+
+ } else {
+
+ cache_ptr = file_ptr->shared->cache;
+ }
+ }
+
+ /* verify that we can access the internal version of the cache config */
+ if ( pass ) {
+
+ if ( ( cache_ptr == NULL ) ||
+ ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ||
+ ( cache_ptr->resize_ctl.version != H5C__CURR_AUTO_SIZE_CTL_VER ) ){
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Can't access cache resize_ctl #%d.", test_num);
+ failure_mssg = msg;
+ }
+ }
+
+ /* compare the cache's internal configuration with the expected value */
+ if ( pass ) {
+
+ if ( ! RESIZE_CONFIGS_ARE_EQUAL(int_config, cache_ptr->resize_ctl,
+ compare_init) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Unexpected internal config #%d.", test_num);
+ failure_mssg = msg;
+ }
+ }
+
+ /* obtain external cache config */
+ if ( pass ) {
+
+ scratch.version = H5AC__CURR_CACHE_CONFIG_VERSION;
+
+ if ( H5Fget_mdc_config(file_id, &scratch) < 0 ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "H5Fget_mdc_config() failed #%d.", test_num);
+ failure_mssg = msg;
+ }
+ }
+
+ if ( pass ) {
+
+ /* Recall that in any configuration supplied by the cache
+ * at run time, the set_initial_size field will always
+ * be FALSE, regardless of the value passed in. Thus we
+ * always resume that this field need not match that of
+ * the supplied external configuration.
+ *
+ * The cache also sets the initial_size field to the current
+ * cache max size instead of the value initialy supplied.
+ * Depending on circumstances, this may or may not match
+ * the original. Hence the compare_init parameter.
+ */
+ if ( ! CACHE_CONFIGS_EQUAL((*ext_config_ptr), scratch, \
+ FALSE, compare_init) ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "Unexpected external config #%d.", test_num);
+ failure_mssg = msg;
+ }
+ }
+
+ return;
+
+} /* validate_mdc_config() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_file_mdc_api_calls()
+ *
+ * Purpose: Verify that the file related metadata cache API calls are
+ * functioning correctly.
+ *
+ * Since we have tested the H5C code elsewhere, it should
+ * be sufficient to verify that the desired configuration
+ * data is getting in and out of the cache. Similarly,
+ * we need only verify that the cache monitoring calls
+ * return the data that the cache thinks they should return.
+ * We shouldn't need to verify data correctness beyond that
+ * point.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/14/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_file_mdc_api_calls(void)
+{
+ const char * fcn_name = "check_file_mdc_api_calls()";
+ char filename[512];
+ hid_t file_id = -1;
+ size_t max_size;
+ size_t min_clean_size;
+ size_t cur_size;
+ int32_t cur_num_entries;
+ double hit_rate;
+ H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG;
+ H5AC_cache_config_t mod_config_1 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024 + 1),
+ /* double min_clean_fraction = */ 0.2,
+ /* size_t max_size = */ (16 * 1024 * 1024 + 1),
+ /* size_t min_size = */ ( 1 * 1024 * 1024 + 1),
+ /* int64_t epoch_length = */ 50001,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.91,
+ /* double increment = */ 2.1,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024 + 1),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out,
+ /* double upper_hr_threshold = */ 0.998,
+ /* double decrement = */ 0.91,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024 - 1),
+ /* int32_t epochs_before_eviction = */ 4,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.05
+ };
+ H5AC_cache_config_t mod_config_2 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ TRUE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (512 * 1024),
+ /* double min_clean_fraction = */ 0.1,
+ /* size_t max_size = */ ( 8 * 1024 * 1024),
+ /* size_t min_size = */ ( 512 * 1024),
+ /* int64_t epoch_length = */ 25000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (2 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold,
+ /* double upper_hr_threshold = */ 0.9995,
+ /* double decrement = */ 0.95,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (512 * 1024),
+ /* int32_t epochs_before_eviction = */ 4,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.05
+ };
+ H5AC_cache_config_t mod_config_3 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.2,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off,
+ /* double lower_hr_threshold = */ 0.90,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ FALSE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024 - 1),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ FALSE,
+ /* double empty_reserve = */ 0.05
+ };
+ H5AC_cache_config_t mod_config_4 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.15,
+ /* size_t max_size = */ (20 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 75000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (2 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */
+ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ };
+
+ TESTING("MDC/FILE related API calls");
+
+ pass = TRUE;
+
+ /* Open a file with the default FAPL. Verify that the cache is
+ * configured as per the default both by looking at its internal
+ * configuration, and via the H5Fget_mdc_config() call.
+ *
+ * Then set serveral different configurations, and verify that
+ * they took as per above.
+ */
+
+ /* setup the file name */
+ if ( pass ) {
+
+ if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename))
+ == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "h5_fixname() failed.\n";
+ }
+ }
+
+ /* create the file using the default FAPL */
+ if ( pass ) {
+
+ file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ if ( file_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fcreate() failed.\n";
+ }
+ }
+
+ /* verify that the cache is set to the default config */
+ validate_mdc_config(file_id, &default_config, TRUE, 1);
+
+ /* set alternate config 1 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_1) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 1.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_1, TRUE, 2);
+
+ /* set alternate config 2 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_2) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 2.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_2, TRUE, 3);
+
+ /* set alternate config 3 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_3) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 3.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_3, TRUE, 4);
+
+ /* set alternate config 4 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_4) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 4.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_4, TRUE, 5);
+
+
+ /* Run some quick smoke checks on the cache status monitoring
+ * calls -- no interesting data as the cache hasn't had a
+ * chance to do much yet.
+ */
+
+ if ( pass ) {
+
+ if ( H5Fget_mdc_hit_rate(file_id, &hit_rate) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_hit_rate() failed 1.\n";
+
+ } else if ( hit_rate != 0.0 ) {
+
+ pass = FALSE;
+ failure_mssg =
+ "H5Fget_mdc_hit_rate() returned unexpected hit rate.\n";
+
+ }
+#if 0 /* this may be useful now and then -- keep it around */
+ else {
+
+ HDfprintf(stdout,
+ "H5Fget_mdc_hit_rate() reports hit_rate = %lf:\n",
+ hit_rate);
+ }
+#endif
+ }
+
+ if ( pass ) {
+
+ if ( H5Fget_mdc_size(file_id, &max_size, &min_clean_size,
+ &cur_size, &cur_num_entries) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_size() failed 1.\n";
+
+ } else if ( ( mod_config_4.initial_size != max_size ) ||
+ ( min_clean_size != (size_t)
+ ((double)max_size * mod_config_4.min_clean_fraction) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_size() returned unexpected value(s).\n";
+
+ }
+#if 0 /* this may be useful now and then -- keep it around */
+ else {
+
+ HDfprintf(stdout, "H5Fget_mdc_size() reports:\n");
+ HDfprintf(stdout, " max_size: %ld, min_clean_size: %ld\n",
+ (long)max_size, (long)min_clean_size);
+ HDfprintf(stdout, " cur_size: %ld, cur_num_entries: %d\n",
+ (long)cur_size, cur_num_entries);
+ }
+#endif
+ }
+
+ /* close the file and delete it */
+ if ( pass ) {
+
+ if ( H5Fclose(file_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fclose() failed.\n";
+
+ } else if ( HDremove(filename) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "HDremove() failed.\n";
+ }
+ }
+
+ if ( pass ) { PASSED(); } else { H5_FAILED(); }
+
+ if ( ! pass )
+ HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n",
+ fcn_name, failure_mssg);
+
+} /* check_file_mdc_api_calls() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_and_validate_cache_hit_rate()
+ *
+ * Purpose: Use the API functions to get and reset the cache hit rate.
+ * Verify that the value returned by the API call agrees with
+ * the cache internal data structures.
+ *
+ * If the number of cache accesses exceeds the value provided
+ * in the min_accesses parameter, and the hit rate is less than
+ * min_hit_rate, set pass to FALSE, and set failure_mssg to
+ * a string indicating that hit rate was unexpectedly low.
+ *
+ * Return hit rate in *hit_rate_ptr, and print the data to
+ * stdout if requested.
+ *
+ * If an error is detected, set pass to FALSE, and set
+ * failure_mssg to an appropriate value.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/18/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_and_validate_cache_hit_rate(hid_t file_id,
+ double * hit_rate_ptr,
+ hbool_t dump_data,
+ int64_t min_accesses,
+ double min_hit_rate)
+{
+ /* const char * fcn_name = "check_and_validate_cache_hit_rate()"; */
+ herr_t result;
+ int64_t cache_hits;
+ int64_t cache_accesses;
+ double expected_hit_rate;
+ double hit_rate;
+ H5F_t * file_ptr = NULL;
+ H5C_t * cache_ptr = NULL;
+
+ /* get a pointer to the files internal data structure */
+ if ( pass ) {
+
+ file_ptr = H5I_object_verify(file_id, H5I_FILE);
+
+ if ( file_ptr == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "Can't get file_ptr.";
+
+ } else {
+
+ cache_ptr = file_ptr->shared->cache;
+ }
+ }
+
+ /* verify that we can access the cache data structure */
+ if ( pass ) {
+
+ if ( ( cache_ptr == NULL ) ||
+ ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Can't access cache resize_ctl.";
+ }
+ }
+
+ /* compare the cache's internal configuration with the expected value */
+ if ( pass ) {
+
+ cache_hits = cache_ptr->cache_hits;
+ cache_accesses = cache_ptr->cache_accesses;
+
+ if ( cache_accesses > 0 ) {
+
+ expected_hit_rate = ((double)cache_hits) / ((double)cache_accesses);
+
+ } else {
+
+ expected_hit_rate = 0.0;
+ }
+
+ result = H5Fget_mdc_hit_rate(file_id, &hit_rate);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_hit_rate() failed.";
+
+ } else if ( hit_rate != expected_hit_rate ) {
+
+ pass = FALSE;
+ failure_mssg = "unexpected hit rate.";
+ }
+ }
+
+ if ( pass ) { /* reset the hit rate */
+
+ result = H5Freset_mdc_hit_rate_stats(file_id);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Freset_mdc_hit_rate_stats() failed.";
+ }
+ }
+
+ /* set *hit_rate_ptr if appropriate */
+ if ( ( pass ) && ( hit_rate_ptr != NULL ) ) {
+
+ *hit_rate_ptr = hit_rate;
+ }
+
+ /* dump data to stdout if requested */
+ if ( ( pass ) && ( dump_data ) ) {
+
+ HDfprintf(stdout,
+ "cache_hits: %ld, cache_accesses: %ld, hit_rate: %lf\n",
+ (long)cache_hits, (long)cache_accesses, hit_rate);
+ }
+
+ if ( ( pass ) &&
+ ( cache_accesses > min_accesses ) &&
+ ( hit_rate < min_hit_rate ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Unexpectedly low hit rate.";
+ }
+
+ return;
+
+} /* check_and_validate_cache_hit_rate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_and_validate_cache_size()
+ *
+ * Purpose: Use the API function to get the cache size data. Verify
+ * that the values returned by the API call agree with
+ * the cache internal data structures.
+ *
+ * Return size data in the locations specified by the pointer
+ * parameters if these parameters are not NULL. Print the
+ * data to stdout if requested.
+ *
+ * If an error is detected, set pass to FALSE, and set
+ * failure_mssg to an appropriate value.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/18/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_and_validate_cache_size(hid_t file_id,
+ size_t * max_size_ptr,
+ size_t * min_clean_size_ptr,
+ size_t * cur_size_ptr,
+ int32_t * cur_num_entries_ptr,
+ hbool_t dump_data)
+{
+ /* const char * fcn_name = "check_and_validate_cache_size()"; */
+ herr_t result;
+ size_t expected_max_size;
+ size_t max_size;
+ size_t expected_min_clean_size;
+ size_t min_clean_size;
+ size_t expected_cur_size;
+ size_t cur_size;
+ int32_t expected_cur_num_entries;
+ int32_t cur_num_entries;
+ H5F_t * file_ptr = NULL;
+ H5C_t * cache_ptr = NULL;
+
+ /* get a pointer to the files internal data structure */
+ if ( pass ) {
+
+ file_ptr = H5I_object_verify(file_id, H5I_FILE);
+
+ if ( file_ptr == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "Can't get file_ptr.";
+
+ } else {
+
+ cache_ptr = file_ptr->shared->cache;
+ }
+ }
+
+ /* verify that we can access the cache data structure */
+ if ( pass ) {
+
+ if ( ( cache_ptr == NULL ) ||
+ ( cache_ptr->magic != H5C__H5C_T_MAGIC ) ) {
+
+ pass = FALSE;
+ failure_mssg = "Can't access cache data structure.";
+ }
+ }
+
+ /* compare the cache's internal configuration with the expected value */
+ if ( pass ) {
+
+ expected_max_size = cache_ptr->max_cache_size;
+ expected_min_clean_size = cache_ptr->min_clean_size;
+ expected_cur_size = cache_ptr->index_size;
+ expected_cur_num_entries = cache_ptr->index_len;
+
+ result = H5Fget_mdc_size(file_id,
+ &max_size,
+ &min_clean_size,
+ &cur_size,
+ &cur_num_entries);
+
+ if ( result < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_size() failed.";
+
+ } else if ( ( max_size != expected_max_size ) ||
+ ( min_clean_size != expected_min_clean_size ) ||
+ ( cur_size != expected_cur_size ) ||
+ ( cur_num_entries != expected_cur_num_entries ) ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_size() returned unexpected value(s).";
+
+ }
+ }
+
+ /* return size values if requested */
+ if ( ( pass ) && ( max_size_ptr != NULL ) ) {
+
+ *max_size_ptr = max_size;
+ }
+
+ if ( ( pass ) && ( min_clean_size_ptr != NULL ) ) {
+
+ *min_clean_size_ptr = min_clean_size;
+ }
+
+ if ( ( pass ) && ( cur_size_ptr != NULL ) ) {
+
+ *cur_size_ptr = cur_size;
+ }
+
+ if ( ( pass ) && ( cur_num_entries_ptr != NULL ) ) {
+
+ *cur_num_entries_ptr = cur_num_entries;
+ }
+
+
+ /* dump data to stdout if requested */
+ if ( ( pass ) && ( dump_data ) ) {
+
+ HDfprintf(stdout,
+ "max_sz: %ld, min_clean_sz: %ld, cur_sz: %ld, cur_ent: %ld\n",
+ (long)max_size, (long)min_clean_size, (long)cur_size,
+ (long)cur_num_entries);
+ }
+
+ return;
+
+} /* check_and_validate_cache_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: mdc_api_call_smoke_check()
+ *
+ * Purpose:
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/14/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define CHUNK_SIZE 2
+#define DSET_SIZE (200 * CHUNK_SIZE)
+#define NUM_DSETS 6
+#define NUM_RANDOM_ACCESSES 200000
+
+static void
+mdc_api_call_smoke_check(void)
+{
+ const char * fcn_name = "mdc_api_call_smoke_check()";
+ char filename[512];
+ hbool_t valid_chunk;
+ hbool_t dump_hit_rate = FALSE;
+ int64_t min_accesses = 1000;
+ double min_hit_rate = 0.90;
+ hbool_t dump_cache_size = FALSE;
+ hid_t file_id = -1;
+ hid_t dataspace_id;
+ hid_t filespace_ids[NUM_DSETS];
+ hid_t memspace_id;
+ hid_t dataset_ids[NUM_DSETS];
+ hid_t properties;
+ char dset_name[64];
+ int i, j, k, l, m, n;
+ herr_t status;
+ hsize_t dims[2];
+ hsize_t a_size[2];
+ hsize_t offset[2];
+ hsize_t chunk_size[2];
+ int data_chunk[CHUNK_SIZE][CHUNK_SIZE];
+ H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG;
+ H5AC_cache_config_t mod_config_1 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ 500000,
+ /* double min_clean_fraction = */ 0.1,
+ /* size_t max_size = */ 16000000,
+ /* size_t min_size = */ 250000,
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off,
+ /* double lower_hr_threshold = */ 0.95,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ FALSE,
+ /* size_t max_increment = */ 4000000,
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ FALSE,
+ /* size_t max_decrement = */ 1000000,
+ /* int32_t epochs_before_eviction = */ 2,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.05
+ };
+ H5AC_cache_config_t mod_config_2 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ 12000000,
+ /* double min_clean_fraction = */ 0.1,
+ /* size_t max_size = */ 16000000,
+ /* size_t min_size = */ 250000,
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off,
+ /* double lower_hr_threshold = */ 0.95,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ FALSE,
+ /* size_t max_increment = */ 4000000,
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ FALSE,
+ /* size_t max_decrement = */ 1000000,
+ /* int32_t epochs_before_eviction = */ 2,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.05
+ };
+ H5AC_cache_config_t mod_config_3 =
+ {
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ 2000000,
+ /* double min_clean_fraction = */ 0.1,
+ /* size_t max_size = */ 16000000,
+ /* size_t min_size = */ 250000,
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__off,
+ /* double lower_hr_threshold = */ 0.95,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ FALSE,
+ /* size_t max_increment = */ 4000000,
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__off,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ FALSE,
+ /* size_t max_decrement = */ 1000000,
+ /* int32_t epochs_before_eviction = */ 2,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.05
+ };
+
+ TESTING("MDC API smoke check");
+
+ pass = TRUE;
+
+ /* Open a file with the default FAPL. Verify that the cache is
+ * configured as per the default both by looking at its internal
+ * configuration, and via the H5Fget_mdc_config() call.
+ *
+ * Then set the cache to mod_config_1, which fixes cache size at
+ * 500000 bytes, and turns off automatic cache resize.
+ */
+
+ /* setup the file name */
+ if ( pass ) {
+
+ if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename))
+ == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "h5_fixname() failed.\n";
+ }
+ }
+
+ /* create the file using the default FAPL */
+ if ( pass ) {
+
+ file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ if ( file_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fcreate() failed.\n";
+ }
+ }
+
+ /* verify that the cache is set to the default config */
+ validate_mdc_config(file_id, &default_config, TRUE, 1);
+
+ /* set alternate config 1 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_1) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 1.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_1, TRUE, 2);
+
+
+ /* create the datasets */
+ if ( pass ) {
+
+ i = 0;
+
+ while ( ( pass ) && ( i < NUM_DSETS ) )
+ {
+ /* create a dataspace for the chunked dataset */
+ dims[0] = DSET_SIZE;
+ dims[1] = DSET_SIZE;
+ dataspace_id = H5Screate_simple(2, dims, NULL);
+
+ if ( dataspace_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Screate_simple() failed.";
+ }
+
+ /* set the dataset creation plist to specify that the raw data is
+ * to be partioned into 10X10 element chunks.
+ */
+
+ if ( pass ) {
+
+ chunk_size[0] = CHUNK_SIZE;
+ chunk_size[1] = CHUNK_SIZE;
+ properties = H5Pcreate(H5P_DATASET_CREATE);
+
+ if ( properties < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pcreate() failed.";
+ }
+ }
+
+ if ( pass ) {
+
+ if ( H5Pset_chunk(properties, 2, chunk_size) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pset_chunk() failed.";
+ }
+ }
+
+ /* create the dataset */
+ if ( pass ) {
+
+ sprintf(dset_name, "/dset%03d", i);
+ dataset_ids[i] = H5Dcreate(file_id, dset_name, H5T_STD_I32BE,
+ dataspace_id, properties);
+
+ if ( dataset_ids[i] < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Dcreate() failed.";
+ }
+ }
+
+ /* get the file space ID */
+ if ( pass ) {
+
+ filespace_ids[i] = H5Dget_space(dataset_ids[i]);
+
+ if ( filespace_ids[i] < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Dget_space() failed.";
+ }
+ }
+
+ i++;
+ }
+ }
+
+ /* create the mem space to be used to read and write chunks */
+ if ( pass ) {
+
+ dims[0] = CHUNK_SIZE;
+ dims[1] = CHUNK_SIZE;
+ memspace_id = H5Screate_simple(2, dims, NULL);
+
+ if ( memspace_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Screate_simple() failed.";
+ }
+ }
+
+ /* select in memory hyperslab */
+ if ( pass ) {
+
+ offset[0] = 0; /*offset of hyperslab in memory*/
+ offset[1] = 0;
+ a_size[0] = CHUNK_SIZE; /*size of hyperslab*/
+ a_size[1] = CHUNK_SIZE;
+ status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL,
+ a_size, NULL);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Sselect_hyperslab() failed.";
+ }
+ }
+
+ /* initialize all datasets on a round robin basis */
+ i = 0;
+ while ( ( pass ) && ( i < DSET_SIZE ) )
+ {
+ j = 0;
+ while ( ( pass ) && ( j < DSET_SIZE ) )
+ {
+ m = 0;
+ while ( ( pass ) && ( m < NUM_DSETS ) )
+ {
+ /* initialize the slab */
+ for ( k = 0; k < CHUNK_SIZE; k++ )
+ {
+ for ( l = 0; l < CHUNK_SIZE; l++ )
+ {
+ data_chunk[k][l] = (DSET_SIZE * DSET_SIZE * m) +
+ (DSET_SIZE * (i + k)) + j + l;
+ }
+ }
+
+ /* select on disk hyperslab */
+ offset[0] = i; /*offset of hyperslab in file*/
+ offset[1] = j;
+ a_size[0] = CHUNK_SIZE; /*size of hyperslab*/
+ a_size[1] = CHUNK_SIZE;
+ status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET,
+ offset, NULL, a_size, NULL);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "disk H5Sselect_hyperslab() failed.";
+ }
+
+ /* write the chunk to file */
+ status = H5Dwrite(dataset_ids[m], H5T_NATIVE_INT, memspace_id,
+ filespace_ids[m], H5P_DEFAULT, data_chunk);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Dwrite() failed.";
+ }
+ m++;
+ }
+ j += CHUNK_SIZE;
+ }
+
+ /* check the cache hit rate, and reset the counters.
+ * Hit rate should be just about unity here, so we will just
+ * get the data and (possibly) print it without checking it
+ * beyond ensuring that it agrees with the cache internal
+ * data structures.
+ *
+ * similarly, check cache size.
+ */
+
+ if ( ( pass ) && ( i % (DSET_SIZE / 4) == 0 ) ) {
+
+ check_and_validate_cache_hit_rate(file_id, NULL, dump_hit_rate,
+ min_accesses, min_hit_rate);
+
+ check_and_validate_cache_size(file_id, NULL, NULL, NULL, NULL,
+ dump_cache_size);
+ }
+
+ i += CHUNK_SIZE;
+ }
+
+ /* set alternate config 2 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_2) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 2.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_2, TRUE, 3);
+
+ /* do random reads on all datasets */
+ n = 0;
+ while ( ( pass ) && ( n < NUM_RANDOM_ACCESSES ) )
+ {
+ m = rand() % NUM_DSETS;
+ i = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE;
+ j = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE;
+
+ /* select on disk hyperslab */
+ offset[0] = i; /*offset of hyperslab in file*/
+ offset[1] = j;
+ a_size[0] = CHUNK_SIZE; /*size of hyperslab*/
+ a_size[1] = CHUNK_SIZE;
+ status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET,
+ offset, NULL, a_size, NULL);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "disk hyperslab create failed.";
+ }
+
+ /* read the chunk from file */
+ if ( pass ) {
+
+ status = H5Dread(dataset_ids[m], H5T_NATIVE_INT, memspace_id,
+ filespace_ids[m], H5P_DEFAULT, data_chunk);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "disk hyperslab create failed.";
+ }
+ }
+
+ /* validate the slab */
+ if ( pass ) {
+
+ valid_chunk = TRUE;
+ for ( k = 0; k < CHUNK_SIZE; k++ )
+ {
+ for ( l = 0; l < CHUNK_SIZE; l++ )
+ {
+ if ( data_chunk[k][l]
+ !=
+ ((DSET_SIZE * DSET_SIZE * m) +
+ (DSET_SIZE * (i + k)) + j + l) ) {
+
+ valid_chunk = FALSE;
+#if 0 /* this will be useful from time to time -- lets keep it*/
+ HDfprintf(stdout,
+ "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
+ k, l, data_chunk[k][l],
+ ((DSET_SIZE * DSET_SIZE * m) +
+ (DSET_SIZE * (i + k)) + j + l));
+ HDfprintf(stdout,
+ "m = %d, i = %d, j = %d, k = %d, l = %d\n",
+ m, i, j, k, l);
+#endif
+ }
+ }
+ }
+
+ if ( ! valid_chunk ) {
+#if 1
+ pass = FALSE;
+ failure_mssg = "slab validation failed.";
+#else /* as above */
+ fprintf(stdout, "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
+ i, j, m);
+#endif
+ }
+ }
+
+ if ( ( pass ) && ( n % (NUM_RANDOM_ACCESSES / 4) == 0 ) ) {
+
+ check_and_validate_cache_hit_rate(file_id, NULL, dump_hit_rate,
+ min_accesses, min_hit_rate);
+
+ check_and_validate_cache_size(file_id, NULL, NULL, NULL, NULL,
+ dump_cache_size);
+ }
+
+ n++;
+ }
+
+ /* close the file spaces we are done with */
+ i = 1;
+ while ( ( pass ) && ( i < NUM_DSETS ) )
+ {
+ if ( H5Sclose(filespace_ids[i]) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Sclose() failed.";
+ }
+ i++;
+ }
+
+
+ /* close the datasets we are done with */
+ i = 1;
+ while ( ( pass ) && ( i < NUM_DSETS ) )
+ {
+ if ( H5Dclose(dataset_ids[i]) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Dclose() failed.";
+ }
+ i++;
+ }
+
+ /* set alternate config 3 */
+ if ( pass ) {
+
+ if ( H5Fset_mdc_config(file_id, &mod_config_3) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() failed 3.\n";
+ }
+ }
+
+ /* verify that the cache is now set to the alternate config */
+ validate_mdc_config(file_id, &mod_config_3, TRUE, 4);
+
+ /* do random reads on data set 0 only */
+ m = 0;
+ n = 0;
+ while ( ( pass ) && ( n < NUM_RANDOM_ACCESSES ) )
+ {
+ i = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE;
+ j = (rand() % (DSET_SIZE / CHUNK_SIZE)) * CHUNK_SIZE;
+
+ /* select on disk hyperslab */
+ offset[0] = i; /*offset of hyperslab in file*/
+ offset[1] = j;
+ a_size[0] = CHUNK_SIZE; /*size of hyperslab*/
+ a_size[1] = CHUNK_SIZE;
+ status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET,
+ offset, NULL, a_size, NULL);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "disk hyperslab create failed.";
+ }
+
+ /* read the chunk from file */
+ if ( pass ) {
+
+ status = H5Dread(dataset_ids[m], H5T_NATIVE_INT, memspace_id,
+ filespace_ids[m], H5P_DEFAULT, data_chunk);
+
+ if ( status < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "disk hyperslab create failed.";
+ }
+ }
+
+ /* validate the slab */
+ if ( pass ) {
+
+ valid_chunk = TRUE;
+ for ( k = 0; k < CHUNK_SIZE; k++ )
+ {
+ for ( l = 0; l < CHUNK_SIZE; l++ )
+ {
+ if ( data_chunk[k][l]
+ !=
+ ((DSET_SIZE * DSET_SIZE * m) +
+ (DSET_SIZE * (i + k)) + j + l) ) {
+
+ valid_chunk = FALSE;
+ }
+#if 0 /* this will be useful from time to time -- lets keep it */
+ HDfprintf(stdout, "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
+ k, l, data_chunk[k][l],
+ ((DSET_SIZE * DSET_SIZE * m) +
+ (DSET_SIZE * (i + k)) + j + l));
+#endif
+ }
+ }
+
+ if ( ! valid_chunk ) {
+
+ pass = FALSE;
+ failure_mssg = "slab validation failed.";
+#if 0 /* as above */
+ fprintf(stdout, "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
+ i, j, m);
+#endif
+ }
+ }
+
+ if ( ( pass ) && ( n % (NUM_RANDOM_ACCESSES / 4) == 0 ) ) {
+
+ check_and_validate_cache_hit_rate(file_id, NULL, dump_hit_rate,
+ min_accesses, min_hit_rate);
+
+ check_and_validate_cache_size(file_id, NULL, NULL, NULL, NULL,
+ dump_cache_size);
+ }
+
+ n++;
+ }
+
+ /* close file space 0 */
+ if ( pass ) {
+
+ if ( H5Sclose(filespace_ids[0]) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Sclose(filespace_ids[0]) failed.";
+ }
+ }
+
+ /* close the data space */
+ if ( pass ) {
+
+ if ( H5Sclose(dataspace_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Sclose(dataspace) failed.";
+ }
+ }
+
+ /* close the mem space */
+ if ( pass ) {
+
+ if ( H5Sclose(memspace_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Sclose(memspace_id) failed.";
+ }
+ }
+
+ /* close dataset 0 */
+ if ( pass ) {
+
+ if ( H5Dclose(dataset_ids[0]) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Dclose(dataset_ids[0]) failed.";
+ }
+ }
+
+ /* close the file and delete it */
+ if ( pass ) {
+
+ if ( H5Fclose(file_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fclose() failed.\n";
+
+ }
+ else if ( HDremove(filename) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "HDremove() failed.\n";
+ }
+ }
+
+ if ( pass ) { PASSED(); } else { H5_FAILED(); }
+
+ if ( ! pass )
+ HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n",
+ fcn_name, failure_mssg);
+
+} /* mdc_api_call_smoke_check() */
+
+
+/* The following array of invalid external MDC cache configurations is
+ * used to test error rejection in the MDC related API calls.
+ */
+
+#define NUM_INVALID_CONFIGS 29
+
+const H5AC_cache_config_t invalid_configs[NUM_INVALID_CONFIGS] =
+{
+ {
+ /* 0 -- bad version */
+ /* int32_t version = */ -1,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 1 -- bad rpt_fcn_enabled */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ -1,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 2 -- bad set_initial_size */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ 2,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 3 -- max_size too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ H5C__MAX_MAX_CACHE_SIZE + 1,
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 4 -- min_size too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ H5C__MIN_MAX_CACHE_SIZE - 1,
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 5 -- min_size > max_size */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ FALSE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ (16 * 1024 * 1024 + 1),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 6 -- initial size out of range (too big) */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (16 * 1024 * 1024 + 1),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 7 -- initial_size out of range (too small) */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024 - 1),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 8 -- min_clean_fraction too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 1.000001,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 9 -- min_clean_fraction too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ -0.00000001,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 10 -- epoch_length too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ H5C__MIN_AR_EPOCH_LENGTH - 1,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 11 -- epoch_length too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ H5C__MAX_AR_EPOCH_LENGTH + 1,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 12 -- invalid incr_mode */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ -1,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 13 -- lower_hr_threshold too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ -0.000001,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 14 -- lower_hr_threshold too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 1.00000001,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 15 -- increment too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 0.999999999999,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 16 -- bad apply_max_increment */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ -1,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 17 -- bad decr_mode */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ -1,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 18 -- upper_hr_threshold too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold,
+ /* double upper_hr_threshold = */ 1.00001,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 19 -- decrement too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ -0.0000000001,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 20 -- decrement too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 1.0000000001,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 21 -- epochs_before_eviction too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 0,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 22 -- epochs_before_eviction too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ H5C__MAX_EPOCH_MARKERS + 1,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 23 -- invalid apply_empty_reserve */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ 2,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 24 -- empty_reserve too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ -0.0000000001
+ },
+ {
+ /* 25 -- empty_reserve too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.999,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 1.00000000001
+ },
+ {
+ /* 26 -- upper_hr_threshold too small */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ -0.000000001,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 27 -- upper_hr_threshold too big */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 1.00000001,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ },
+ {
+ /* 28 -- upper_hr_threshold <= lower_hr_threshold */
+ /* int32_t version = */ H5C__CURR_AUTO_SIZE_CTL_VER,
+ /* hbool_t rpt_fcn_enabled = */ FALSE,
+ /* hbool_t set_initial_size = */ TRUE,
+ /* size_t initial_size = */ (1 * 1024 * 1024),
+ /* double min_clean_fraction = */ 0.25,
+ /* size_t max_size = */ (16 * 1024 * 1024),
+ /* size_t min_size = */ ( 1 * 1024 * 1024),
+ /* int64_t epoch_length = */ 50000,
+ /* enum H5C_cache_incr_mode incr_mode = */ H5C_incr__threshold,
+ /* double lower_hr_threshold = */ 0.9,
+ /* double increment = */ 2.0,
+ /* hbool_t apply_max_increment = */ TRUE,
+ /* size_t max_increment = */ (4 * 1024 * 1024),
+ /* enum H5C_cache_decr_mode decr_mode = */ H5C_decr__age_out_with_threshold,
+ /* double upper_hr_threshold = */ 0.9,
+ /* double decrement = */ 0.9,
+ /* hbool_t apply_max_decrement = */ TRUE,
+ /* size_t max_decrement = */ (1 * 1024 * 1024),
+ /* int32_t epochs_before_eviction = */ 3,
+ /* hbool_t apply_empty_reserve = */ TRUE,
+ /* double empty_reserve = */ 0.1
+ }
+};
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_fapl_mdc_api_errs()
+ *
+ * Purpose: Verify that the FAPL related MDC API calls reject input
+ * errors gracefully.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/19/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_fapl_mdc_api_errs(void)
+{
+ const char * fcn_name = "check_fapl_mdc_api_errs()";
+ static char msg[128];
+ int i;
+ herr_t result;
+ hid_t fapl_id;
+ H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG;
+ H5AC_cache_config_t scratch;
+
+ TESTING("MDC/FAPL related API input errors");
+
+ pass = TRUE;
+
+
+ /* first test H5Pget_mdc_config().
+ */
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+ if ( pass ) {
+
+ H5E_BEGIN_TRY { result = H5Pget_mdc_config(-1, &scratch); } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() accepted invalid plist_id.";
+ }
+ }
+
+ /* Create a FAPL for test purposes, and veify that it contains the
+ * default MDC configuration.
+ */
+
+ if ( pass ) {
+
+ fapl_id = H5Pcreate(H5P_FILE_ACCESS);
+
+ if ( fapl_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pcreate(H5P_FILE_ACCESS) failed.\n";
+ }
+ }
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+ if ( ( pass ) &&
+ ( ( H5Pget_mdc_config(fapl_id, &scratch) < 0 ) ||
+ ( !CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE) ) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "New FAPL has unexpected metadata cache config?!?!?.\n";
+ }
+
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Pget_mdc_config(fapl_id, NULL);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() accepted NULL config_ptr.";
+ }
+ }
+
+ /* one last test for H5Pget_mdc_config() */
+
+ scratch.version = -1; /* a convenient, invalid value */
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Pget_mdc_config(fapl_id, &scratch);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pget_mdc_config() accepted bad config version.";
+ }
+ }
+
+
+ /* now test H5Pset_mdc_config()
+ */
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Pset_mdc_config(-1, &default_config);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pset_mdc_config() accepted bad invalid plist_id.";
+ }
+ }
+
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Pset_mdc_config(fapl_id, NULL);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Pset_mdc_config() accepted NULL config_ptr.";
+ }
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < NUM_INVALID_CONFIGS ) )
+ {
+ H5E_BEGIN_TRY {
+ result = H5Pset_mdc_config(fapl_id, &(invalid_configs[i]));
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "H5Pset_mdc_config() accepted invalid_configs[%d].", i);
+ failure_mssg = msg;
+ }
+ i++;
+ }
+
+ /* verify that none of the above calls to H5Pset_mdc_config() changed
+ * the configuration in the FAPL.
+ */
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+ if ( ( pass ) &&
+ ( ( H5Pget_mdc_config(fapl_id, &scratch) < 0 ) ||
+ ( !CACHE_CONFIGS_EQUAL(default_config, scratch, TRUE, TRUE) ) ) ) {
+
+ pass = FALSE;
+ failure_mssg = "FAPL metadata cache config changed???.\n";
+ }
+
+ if ( pass ) { PASSED(); } else { H5_FAILED(); }
+
+ if ( ! pass )
+ HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n",
+ fcn_name, failure_mssg);
+
+} /* check_fapl_mdc_api_errs() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: check_file_mdc_api_errs()
+ *
+ * Purpose: Verify that the file related MDC API calls reject input
+ * errors gracefully.
+ *
+ * Return: void
+ *
+ * Programmer: John Mainzer
+ * 4/19/04
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+check_file_mdc_api_errs(void)
+{
+ const char * fcn_name = "check_file_mdc_api_errs()";
+ char filename[512];
+ static char msg[128];
+ int i;
+ herr_t result;
+ hid_t file_id;
+ size_t max_size;
+ size_t min_clean_size;
+ size_t cur_size;
+ int32_t cur_num_entries;
+ double hit_rate;
+ H5AC_cache_config_t default_config = H5AC__DEFAULT_CACHE_CONFIG;
+ H5AC_cache_config_t scratch;
+
+ TESTING("MDC/FILE related API input errors");
+
+ pass = TRUE;
+
+ /* Create a file for test purposes, and veify that its metadata cache
+ * set to the default MDC configuration.
+ */
+
+ /* setup the file name */
+ if ( pass ) {
+
+ if ( h5_fixname(FILENAME[0], H5P_DEFAULT, filename, sizeof(filename))
+ == NULL ) {
+
+ pass = FALSE;
+ failure_mssg = "h5_fixname() failed.\n";
+ }
+ }
+
+ if ( pass ) {
+
+ file_id = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
+
+ if ( file_id < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fcreate() failed.\n";
+ }
+ }
+
+ validate_mdc_config(file_id, &default_config, TRUE, 1);
+
+
+ /* test H5Fget_mdc_config(). */
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fget_mdc_config(-1, &scratch);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_config() accepted invalid file_id.";
+ }
+ }
+
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fget_mdc_config(file_id, NULL);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_config() accepted NULL config_ptr.";
+ }
+ }
+
+ scratch.version = -1; /* a convenient, invalid value */
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fget_mdc_config(file_id, &scratch);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_config() accepted bad config version.";
+ }
+ }
+
+
+ /* test H5Fset_mdc_config() */
+
+ scratch.version = H5C__CURR_AUTO_SIZE_CTL_VER;
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fset_mdc_config(-1, &default_config);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() accepted bad invalid file_id.";
+ }
+ }
+
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fset_mdc_config(file_id, NULL);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fset_mdc_config() accepted NULL config_ptr.";
+ }
+ }
+
+ i = 0;
+ while ( ( pass ) && ( i < NUM_INVALID_CONFIGS ) )
+ {
+ H5E_BEGIN_TRY {
+ result = H5Fset_mdc_config(file_id, &(invalid_configs[i]));
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ HDsnprintf(msg, (size_t)128,
+ "H5Fset_mdc_config() accepted invalid_configs[%d].", i);
+ failure_mssg = msg;
+ }
+ i++;
+ }
+
+ /* verify that none of the above calls to H5Fset_mdc_config() changed
+ * the configuration in the FAPL.
+ */
+ validate_mdc_config(file_id, &default_config, TRUE, 2);
+
+
+ /* test H5Fget_mdc_hit_rate() */
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fget_mdc_hit_rate(-1, &hit_rate);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_hit_rate() accepted bad file_id.";
+ }
+ }
+
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fget_mdc_hit_rate(file_id, NULL);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_hit_rate() accepted NULL hit_rate_ptr.";
+ }
+ }
+
+
+ /* test H5Freset_mdc_hit_rate_stats() */
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Freset_mdc_hit_rate_stats(-1);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg =
+ "H5Freset_mdc_hit_rate_stats() accepted bad file_id.";
+ }
+ }
+
+
+ /* test H5Fget_mdc_size() */
+ if ( pass ) {
+
+ H5E_BEGIN_TRY {
+ result = H5Fget_mdc_size(-1, &max_size, &min_clean_size,
+ &cur_size, &cur_num_entries);
+ } H5E_END_TRY;
+
+ if ( result >= 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_size() accepted bad file_id.";
+ }
+ }
+
+ if ( pass ) {
+
+ if ( ( H5Fget_mdc_size(file_id, &max_size, NULL, NULL, NULL) < 0 ) ||
+ ( H5Fget_mdc_size(file_id, NULL, &min_clean_size,
+ NULL, NULL) < 0 ) ||
+ ( H5Fget_mdc_size(file_id, NULL, NULL, &cur_size, NULL) < 0 ) ||
+ ( H5Fget_mdc_size(file_id, NULL, NULL, NULL,
+ &cur_num_entries) < 0 ) ||
+ ( H5Fget_mdc_size(file_id, NULL, NULL, NULL, NULL) < 0 ) ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fget_mdc_size() failed to handle NULL params.";
+ }
+ }
+
+
+ /* close the file and delete it */
+ if ( pass ) {
+
+ if ( H5Fclose(file_id) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "H5Fclose() failed.\n";
+
+ } else if ( HDremove(filename) < 0 ) {
+
+ pass = FALSE;
+ failure_mssg = "HDremove() failed.\n";
+ }
+ }
+
+ if ( pass ) { PASSED(); } else { H5_FAILED(); }
+
+ if ( ! pass )
+ HDfprintf(stdout, "%s: failure_mssg = \"%s\".\n",
+ fcn_name, failure_mssg);
+
+} /* check_file_mdc_api_errs() */
+
+
+/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: Run tests on the cache code contained in H5C.c
@@ -17479,6 +20469,7 @@ check_auto_cache_resize_aux_fcns(void)
*
*-------------------------------------------------------------------------
*/
+
int
main(void)
{
@@ -17491,7 +20482,7 @@ main(void)
#else /* NDEBUG */
run_full_test = FALSE;
#endif /* NDEBUG */
-
+#if 1
smoke_check_1();
smoke_check_2();
smoke_check_3();
@@ -17500,7 +20491,8 @@ main(void)
smoke_check_6();
smoke_check_7();
smoke_check_8();
-
+#endif
+#if 1
write_permitted_check();
check_flush_cache();
check_flush_protected_err();
@@ -17515,6 +20507,15 @@ main(void)
check_auto_cache_resize_input_errs();
check_auto_cache_resize_aux_fcns();
+ check_fapl_mdc_api_calls();
+ check_file_mdc_api_calls();
+#endif
+ mdc_api_call_smoke_check();
+#if 1
+ check_fapl_mdc_api_errs();
+ check_file_mdc_api_errs();
+#endif
+
return(0);
} /* main() */