diff options
author | John Mainzer <mainzer@hdfgroup.org> | 2005-04-28 16:40:07 (GMT) |
---|---|---|
committer | John Mainzer <mainzer@hdfgroup.org> | 2005-04-28 16:40:07 (GMT) |
commit | a9ba92287d48568c901ec906b8aaf32ff32076aa (patch) | |
tree | f79047eaf353389a61b3395bab0a169385a6824b /src | |
parent | 097185980325a30153ceb0090f128a8f4e873a77 (diff) | |
download | hdf5-a9ba92287d48568c901ec906b8aaf32ff32076aa.zip hdf5-a9ba92287d48568c901ec906b8aaf32ff32076aa.tar.gz hdf5-a9ba92287d48568c901ec906b8aaf32ff32076aa.tar.bz2 |
[svn-r10688] Purpose:
Add API calls allowing user control of the metadata cache.
Description:
Prior to this update, the metadata cache was not configurable
from outside the library.
Solution:
Add API calls allowing the user to configure the metadata cache
either at file open time, or for any open file. Also added calls
permitting the user to monitor cache size and hit rate. These
latter facilities are needed for "manual" cache size control
Platforms tested:
h5committested
Misc. update:
Diffstat (limited to 'src')
-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 |
14 files changed, 1615 insertions, 259 deletions
@@ -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*/, |