diff options
-rwxr-xr-x | bin/trace | 2 | ||||
-rw-r--r-- | src/H5AC.c | 518 | ||||
-rw-r--r-- | src/H5ACprivate.h | 60 | ||||
-rw-r--r-- | src/H5ACpublic.h | 243 | ||||
-rw-r--r-- | src/H5C.c | 470 | ||||
-rw-r--r-- | src/H5Cpkg.h | 1 | ||||
-rw-r--r-- | src/H5Cprivate.h | 34 | ||||
-rw-r--r-- | src/H5Cpublic.h | 14 | ||||
-rw-r--r-- | src/H5F.c | 337 | ||||
-rw-r--r-- | src/H5Fpkg.h | 6 | ||||
-rw-r--r-- | src/H5Fprivate.h | 8 | ||||
-rw-r--r-- | src/H5Fpublic.h | 13 | ||||
-rw-r--r-- | src/H5MPprivate.h | 7 | ||||
-rw-r--r-- | src/H5Pfapl.c | 150 | ||||
-rw-r--r-- | src/H5Ppublic.h | 13 | ||||
-rw-r--r-- | test/cache.c | 3005 |
16 files changed, 4620 insertions, 261 deletions
@@ -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", @@ -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 @@ -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 @@ -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() */ |