summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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() */