diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2016-06-13 17:49:39 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2016-06-13 17:49:39 (GMT) |
commit | 7a9e13afdb134bafc070cf8bd2087a84fd0d2334 (patch) | |
tree | c16578adf13fb9312870afff86332ad190add859 /src | |
parent | 1db1d99883397d92dc6984841fecfc391c52676d (diff) | |
download | hdf5-7a9e13afdb134bafc070cf8bd2087a84fd0d2334.zip hdf5-7a9e13afdb134bafc070cf8bd2087a84fd0d2334.tar.gz hdf5-7a9e13afdb134bafc070cf8bd2087a84fd0d2334.tar.bz2 |
[svn-r30068] Description:
Bring metadata cache corking to trunk.
Tested on:
MacOSX/64 10.11.5 (amazon) w/serial, parallel & production
(h5committest forthcoming)
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/H5AC.c | 41 | ||||
-rw-r--r-- | src/H5ACmpio.c | 2 | ||||
-rw-r--r-- | src/H5ACprivate.h | 7 | ||||
-rw-r--r-- | src/H5C.c | 185 | ||||
-rw-r--r-- | src/H5Cpkg.h | 17 | ||||
-rw-r--r-- | src/H5Cprivate.h | 12 | ||||
-rw-r--r-- | src/H5Cquery.c | 3 | ||||
-rw-r--r-- | src/H5Ctag.c | 84 | ||||
-rw-r--r-- | src/H5Ctest.c | 159 | ||||
-rw-r--r-- | src/H5Dint.c | 8 | ||||
-rw-r--r-- | src/H5Gint.c | 8 | ||||
-rw-r--r-- | src/H5O.c | 122 | ||||
-rw-r--r-- | src/H5Opublic.h | 3 | ||||
-rw-r--r-- | src/H5T.c | 11 | ||||
-rw-r--r-- | src/H5err.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 |
17 files changed, 648 insertions, 19 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c7ae908..c0f934e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -87,6 +87,7 @@ set (H5C_SOURCES ${HDF5_SRC_DIR}/H5Cmpio.c ${HDF5_SRC_DIR}/H5Cquery.c ${HDF5_SRC_DIR}/H5Ctag.c + ${HDF5_SRC_DIR}/H5Ctest.c ) set (H5C_HDRS ${HDF5_SRC_DIR}/H5Cpkg.h @@ -741,6 +741,7 @@ H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status) hbool_t is_dirty; /* Entry @ addr is in the cache and dirty */ hbool_t is_protected; /* Entry @ addr is in the cache and protected */ hbool_t is_pinned; /* Entry @ addr is in the cache and pinned */ + hbool_t is_corked; hbool_t is_flush_dep_child; /* Entry @ addr is in the cache and is a flush dependency child */ hbool_t is_flush_dep_parent; /* Entry @ addr is in the cache and is a flush dependency parent */ herr_t ret_value = SUCCEED; /* Return value */ @@ -751,7 +752,7 @@ H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Bad param(s) on entry.") if(H5C_get_entry_status(f, addr, NULL, &in_cache, &is_dirty, - &is_protected, &is_pinned, &is_flush_dep_parent, &is_flush_dep_child) < 0) + &is_protected, &is_pinned, &is_corked, &is_flush_dep_parent, &is_flush_dep_child) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "H5C_get_entry_status() failed.") if(in_cache) { @@ -762,6 +763,8 @@ H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned *status) *status |= H5AC_ES__IS_PROTECTED; if(is_pinned) *status |= H5AC_ES__IS_PINNED; + if(is_corked) + *status |= H5AC_ES__IS_CORKED; if(is_flush_dep_parent) *status |= H5AC_ES__IS_FLUSH_DEP_PARENT; if(is_flush_dep_child) @@ -2505,6 +2508,42 @@ done: } /* H5AC_expunge_tag_type_metadata*/ + +/*------------------------------------------------------------------------- + * Function: H5AC_cork + * + * Purpose: To cork/uncork/get cork status for an object + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; Jan 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Sanity check */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->cache); + HDassert(H5F_addr_defined(obj_addr)); + HDassert(action == H5AC__SET_CORK || action == H5AC__UNCORK || action == H5AC__GET_CORKED); + + if(action == H5AC__GET_CORKED) + HDassert(corked); + + if(H5C_cork(f->shared->cache, obj_addr, action, corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Cannot perform the cork action") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5AC_cork() */ + #if H5AC_DO_TAGGING_SANITY_CHECKS /*------------------------------------------------------------------------- diff --git a/src/H5ACmpio.c b/src/H5ACmpio.c index db291cf..e33fc8e 100644 --- a/src/H5ACmpio.c +++ b/src/H5ACmpio.c @@ -1016,7 +1016,7 @@ H5AC__log_moved_entry(const H5F_t *f, haddr_t old_addr, haddr_t new_addr) /* get entry status, size, etc here */ if(H5C_get_entry_status(f, old_addr, &entry_size, &entry_in_cache, - &entry_dirty, NULL, NULL, NULL, NULL) < 0) + &entry_dirty, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't get entry status.") if(!entry_in_cache) HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "entry not in cache.") diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 4b00b3c..4d78938 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -138,6 +138,11 @@ typedef enum { #define H5AC__SERIALIZE_MOVED_FLAG H5C__SERIALIZE_MOVED_FLAG #define H5AC__SERIALIZE_COMPRESSED_FLAG H5C__SERIALIZE_COMPRESSED_FLAG +/* Cork actions: cork/uncork/get cork status of an object */ +#define H5AC__SET_CORK H5C__SET_CORK +#define H5AC__UNCORK H5C__UNCORK +#define H5AC__GET_CORKED H5C__GET_CORKED + /* Aliases for the "ring" type and values */ typedef H5C_ring_t H5AC_ring_t; #define H5AC_RING_INV H5C_RING_UNDEFINED @@ -318,6 +323,7 @@ H5_DLLVAR hid_t H5AC_rawdata_dxpl_id; #define H5AC_ES__IS_PINNED 0x0008 #define H5AC_ES__IS_FLUSH_DEP_PARENT 0x0010 #define H5AC_ES__IS_FLUSH_DEP_CHILD 0x0020 +#define H5AC_ES__IS_CORKED 0x0040 /* external function declarations: */ @@ -359,6 +365,7 @@ H5_DLL herr_t H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag); H5_DLL herr_t H5AC_flush_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id); H5_DLL herr_t H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag); H5_DLL herr_t H5AC_ignore_tags(const H5F_t *f); +H5_DLL herr_t H5AC_cork(H5F_t *f, haddr_t obj_addr, unsigned action, hbool_t *corked); H5_DLL herr_t H5AC_get_entry_ring(const H5F_t *f, haddr_t addr, H5AC_ring_t *ring); H5_DLL herr_t H5AC_set_ring(hid_t dxpl_id, H5AC_ring_t ring, H5P_genplist_t **dxpl, H5AC_ring_t *orig_ring); @@ -209,6 +209,9 @@ H5FL_DEFINE_STATIC(H5C_t); /* Declare extern free list to manage the H5C_collective_write_t struct */ H5FL_EXTERN(H5C_collective_write_t); +/* Declare a free list to manage corked object addresses */ +H5FL_DEFINE_STATIC(haddr_t); + /*------------------------------------------------------------------------- @@ -276,6 +279,11 @@ H5C_create(size_t max_cache_size, HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list.") } + if ( (cache_ptr->cork_list_ptr = H5SL_create(H5SL_TYPE_HADDR, NULL)) == NULL ) { + + HGOTO_ERROR(H5E_CACHE, H5E_CANTCREATE, NULL, "can't create skip list for corked object addresses.") + } + /* If we get this far, we should succeed. Go ahead and initialize all * the fields. */ @@ -451,6 +459,9 @@ done: if ( cache_ptr->slist_ptr != NULL ) H5SL_close(cache_ptr->slist_ptr); + if ( cache_ptr->cork_list_ptr != NULL ) + H5SL_close(cache_ptr->cork_list_ptr); + cache_ptr->magic = 0; cache_ptr = H5FL_FREE(H5C_t, cache_ptr); @@ -650,6 +661,34 @@ H5C_def_auto_resize_rpt_fcn(H5C_t * cache_ptr, /*------------------------------------------------------------------------- + * Function: H5C_free_cork_list_cb + * + * Purpose: Callback function to free the list of object addresses + * on the skip list. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5C_free_cork_list_cb(void *_item, void H5_ATTR_UNUSED *key, void H5_ATTR_UNUSED *op_data) +{ + haddr_t *addr = (haddr_t *)_item; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(addr); + + /* Release the item */ + addr = H5FL_FREE(haddr_t, addr); + + FUNC_LEAVE_NOAPI(0) +} /* H5C_free_cork_list_cb() */ + + +/*------------------------------------------------------------------------- * Function: H5C_dest * * Purpose: Flush all data to disk and destroy the cache. @@ -694,6 +733,11 @@ H5C_dest(H5F_t * f, hid_t dxpl_id) cache_ptr->slist_ptr = NULL; } /* end if */ + if(cache_ptr->cork_list_ptr != NULL) { + H5SL_destroy(cache_ptr->cork_list_ptr, H5C_free_cork_list_cb, NULL); + cache_ptr->cork_list_ptr = NULL; + } /* end if */ + /* Only display count of number of calls to H5C_get_entry_ptr_from_add() * if NDEBUG is undefined, and H5C_DO_SANITY_CHECKS is defined. Need * this as the print statement will upset windows, and we frequently @@ -1267,6 +1311,10 @@ H5C_insert_entry(H5F_t * f, if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag metadata entry") + /* Set the entry's cork status */ + if(H5C_cork(cache_ptr, entry_ptr->tag, H5C__GET_CORKED, &entry_ptr->is_corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Cannot retrieve entry's cork status") + entry_ptr->is_protected = FALSE; entry_ptr->is_read_only = FALSE; entry_ptr->ro_ref_count = 0; @@ -2241,6 +2289,10 @@ H5C_protect(H5F_t * f, if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Cannot tag metadata entry") + /* Set the entry's cork status */ + if(H5C_cork(cache_ptr, entry_ptr->tag, H5C__GET_CORKED, &entry_ptr->is_corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, NULL, "Cannot retrieve entry's cork status") + /* If the entry is very large, and we are configured to allow it, * we may wish to perform a flash cache size increase. */ @@ -3606,7 +3658,7 @@ H5C_dump_cache(H5C_t * cache_ptr, HDfprintf(stdout, "\n\nDump of metadata cache \"%s\".\n", cache_name); HDfprintf(stdout, - "Num: Addr: Len: Type: Prot: Pinned: Dirty:\n"); + "Num: Addr: Tag: Len: Type: Prot: Pinned: Dirty: Corked:\n"); i = 0; @@ -3626,14 +3678,16 @@ H5C_dump_cache(H5C_t * cache_ptr, HDassert( entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC ); HDfprintf(stdout, - "%s%d 0x%08llx 0x%3llx %2d %d %d %d\n", + "%s%d 0x%16llx 0x%3llx 0x%3llx %2d %d %d %d %d\n", cache_ptr->prefix, i, (long long)(entry_ptr->addr), + (long long)(entry_ptr->tag), (long long)(entry_ptr->size), (int)(entry_ptr->type->id), (int)(entry_ptr->is_protected), (int)(entry_ptr->is_pinned), - (int)(entry_ptr->is_dirty)); + (int)(entry_ptr->is_dirty), + (int)(entry_ptr->is_corked)); /* increment node_ptr before we delete its target */ node_ptr = H5SL_next(node_ptr); @@ -5423,6 +5477,8 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) && ( bytes_evicted < eviction_size_limit ) ) { + hbool_t corked = FALSE; + HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC); HDassert( ! (entry_ptr->is_protected) ); HDassert( ! (entry_ptr->is_read_only) ); @@ -5436,7 +5492,10 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } - if ( entry_ptr->is_dirty ) { + /* dirty corked entry is skipped */ + if(entry_ptr->is_corked && entry_ptr->is_dirty) + corked = TRUE; + else if ( entry_ptr->is_dirty ) { /* reset entries_removed_counter and * last_entry_removed_ptr prior to the call to @@ -5467,7 +5526,10 @@ H5C__autoadjust__ageout__evict_aged_out_entries(H5F_t * f, if ( prev_ptr != NULL ) { - if ( ( restart_scan ) + if(corked) /* dirty corked entry is skipped */ + entry_ptr = prev_ptr; + + else if ( ( restart_scan ) || ( prev_ptr->is_dirty != prev_is_dirty ) || @@ -8046,6 +8108,7 @@ H5C_make_space_in_cache(H5F_t * f, H5C_cache_entry_t * entry_ptr; H5C_cache_entry_t * prev_ptr; H5C_cache_entry_t * next_ptr; + int32_t num_corked_entries = 0; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -8102,7 +8165,13 @@ H5C_make_space_in_cache(H5F_t * f, prev_is_dirty = prev_ptr->is_dirty; } - if ( ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) && + if (entry_ptr->is_corked && entry_ptr->is_dirty) { + + /* Skip "dirty" corked entries. */ + ++num_corked_entries; + didnt_flush_entry = TRUE; + + } else if ( ( (entry_ptr->type)->id != H5C__EPOCH_MARKER_TYPE ) && ( ! entry_ptr->flush_in_progress ) ) { didnt_flush_entry = FALSE; @@ -8250,12 +8319,14 @@ H5C_make_space_in_cache(H5F_t * f, } #endif /* H5C_COLLECT_CACHE_STATS */ + + /* NEED: work on a better assert for corked entries */ HDassert( ( entries_examined > (2 * initial_list_len) ) || ( (cache_ptr->pl_size + cache_ptr->pel_size + cache_ptr->min_clean_size) > cache_ptr->max_cache_size ) || ( ( cache_ptr->clean_index_size + empty_space ) - >= cache_ptr->min_clean_size ) ); - + >= cache_ptr->min_clean_size ) || + ( ( num_corked_entries ))); #if H5C_MAINTAIN_CLEAN_AND_DIRTY_LRU_LISTS HDassert( ( entries_examined > (2 * initial_list_len) ) || @@ -8976,6 +9047,104 @@ done: /*------------------------------------------------------------------------- + * + * Function: H5C_cork + * + * Purpose: To cork/uncork/get cork status of an object depending on "action": + * H5C__SET_CORK: + * To cork the object + * Return error if the object is already corked + * H5C__UNCORK: + * To uncork the obejct + * Return error if the object is not corked + * H5C__GET_CORKED: + * To retrieve the cork status of an object in + * the parameter "corked" + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C_cork(H5C_t * cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked) +{ + haddr_t *ptr; /* Points to an address */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT + + /* Assertions */ + HDassert(cache_ptr != NULL); + HDassert(H5F_addr_defined(obj_addr)); + HDassert(action == H5C__SET_CORK || action == H5C__UNCORK || action == H5C__GET_CORKED); + + /* Search the list of corked object addresses in the cache */ + ptr = (haddr_t *)H5SL_search(cache_ptr->cork_list_ptr, &obj_addr); + + if(H5C__GET_CORKED == action) { + HDassert(corked); + if(ptr != NULL && *ptr == obj_addr) + *corked = TRUE; + else + *corked = FALSE; + } /* end if */ + else { + hbool_t is_corked; /* Cork status for an entry */ + + /* Sanity check */ + HDassert(H5C__SET_CORK == action || H5C__UNCORK == action); + + /* Perform appropriate action */ + if(H5C__SET_CORK == action) { + haddr_t *addr_ptr = NULL; /* Points to an address */ + + if(ptr != NULL && *ptr == obj_addr) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't cork an already corked object") + + /* Allocate address */ + if(NULL == (addr_ptr = H5FL_MALLOC(haddr_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Insert into the list */ + *addr_ptr = obj_addr; + if(H5SL_insert(cache_ptr->cork_list_ptr, addr_ptr, addr_ptr) < 0) { + addr_ptr = H5FL_FREE(haddr_t, addr_ptr); + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't insert address into cork list") + } /* end if */ + + /* Set the entry's cork status */ + is_corked = TRUE; + } /* end if */ + else { + if(ptr == NULL) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't uncork an object that is not corked ") + + /* Remove the object address from the list */ + ptr = (haddr_t *)H5SL_remove(cache_ptr->cork_list_ptr, &obj_addr); + if(ptr == NULL || *ptr != obj_addr) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Can't remove address from list") + + /* Free address */ + ptr = H5FL_FREE(haddr_t, ptr); + + /* Set the entry's cork status */ + is_corked = FALSE; + } /* end else */ + + /* Mark existing cache entries with tag (obj_addr) to the cork status */ + if(H5C__mark_tagged_entries_cork(cache_ptr, obj_addr, is_corked) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "can't mark cork status on entry") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C_cork() */ + + +/*------------------------------------------------------------------------- * Function: H5C__generate_image * * Purpose: Serialize an entry and generate its image. diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index d7da17b..fe2be2f 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -3482,6 +3482,11 @@ if ( ( (entry_ptr) == NULL ) || \ * to the slist since the last time this field was set to * zero. Note that this value can be negative. * + * cork_list_ptr: A skip list to track object addresses that are corked. + * When an entry is inserted or protected in the cache, + * the entry's associated object address (tag field) is + * checked against this skip list. If found, the entry + * is corked. * * When a cache entry is protected, it must be removed from the LRU * list(s) as it cannot be either flushed or evicted until it is unprotected. @@ -4111,6 +4116,8 @@ struct H5C_t { int64_t slist_size_increase; #endif /* H5C_DO_SANITY_CHECKS */ + H5SL_t * cork_list_ptr; /* list of corked object addresses */ + /* Fields for tracking protected entries */ int32_t pl_len; size_t pl_size; @@ -4260,6 +4267,9 @@ typedef struct H5C_collective_write_t { } H5C_collective_write_t; #endif /* H5_HAVE_PARALLEL */ +/* Define typedef for tagged cache entry iteration callbacks */ +typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx); + /*****************************/ /* Package Private Variables */ @@ -4277,6 +4287,8 @@ H5_DLLVAR const H5C_class_t H5C__epoch_marker_class; H5_DLL herr_t H5C__flush_single_entry(const H5F_t *f, hid_t dxpl_id, H5C_cache_entry_t *entry_ptr, unsigned flags, int64_t *entry_size_change_ptr, H5SL_t *collective_write_list); H5_DLL herr_t H5C__flush_marked_entries(H5F_t * f, hid_t dxpl_id); +H5_DLL int H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global, + H5C_tag_iter_cb_t cb, void *cb_ctx); /* Routines for operating on entry tags */ H5_DLL herr_t H5C__tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, @@ -4284,5 +4296,10 @@ H5_DLL herr_t H5C__tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, H5_DLL herr_t H5C__mark_tagged_entries_cork(H5C_t *cache_ptr, haddr_t obj_addr, hbool_t val); +/* Testing functions */ +#ifdef H5C_TESTING +H5_DLL herr_t H5C__verify_cork_tag_test(hid_t fid, haddr_t tag, hbool_t status); +#endif /* H5C_TESTING */ + #endif /* _H5Cpkg_H */ diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index e077cc0..0974384 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -232,6 +232,11 @@ #define H5C_DO_EXTREME_SANITY_CHECKS 0 #endif /* NDEBUG */ +/* Cork actions: cork/uncork/get cork status of an object */ +#define H5C__SET_CORK 0x1 +#define H5C__UNCORK 0x2 +#define H5C__GET_CORKED 0x4 + /* Note: The memory sanity checks aren't going to work until I/O filters are * changed to call a particular alloc/free routine for their buffers, * because the H5AC__SERIALIZE_RESIZED_FLAG set by the fractal heap @@ -1290,6 +1295,9 @@ typedef int H5C_ring_t; * The name is not particularly descriptive, but is retained * to avoid changes in existing code. * + * is_corked: Boolean flag indicating whether the cache entry associated + * with an object is corked or not corked. + * * is_dirty: Boolean flag indicating whether the contents of the cache * entry has been modified since the last time it was written * to disk. @@ -1614,6 +1622,7 @@ typedef struct H5C_cache_entry_t { const H5C_class_t * type; haddr_t tag; H5C_tag_globality_t globality; + hbool_t is_corked; hbool_t is_dirty; hbool_t dirtied; hbool_t is_protected; @@ -1983,7 +1992,7 @@ H5_DLL herr_t H5C_get_cache_size(H5C_t *cache_ptr, size_t *max_size_ptr, H5_DLL herr_t H5C_get_cache_hit_rate(H5C_t *cache_ptr, double *hit_rate_ptr); H5_DLL herr_t H5C_get_entry_status(const H5F_t *f, haddr_t addr, size_t *size_ptr, hbool_t *in_cache_ptr, hbool_t *is_dirty_ptr, - hbool_t *is_protected_ptr, hbool_t *is_pinned_ptr, + hbool_t *is_protected_ptr, hbool_t *is_pinned_ptr, hbool_t *is_corked_ptr, hbool_t *is_flush_dep_parent_ptr, hbool_t *is_flush_dep_child_ptr); H5_DLL herr_t H5C_get_evictions_enabled(const H5C_t *cache_ptr, hbool_t *evictions_enabled_ptr); H5_DLL void * H5C_get_aux_ptr(const H5C_t *cache_ptr); @@ -2017,6 +2026,7 @@ H5_DLL herr_t H5C_validate_resize_config(H5C_auto_size_ctl_t *config_ptr, H5_DLL herr_t H5C_ignore_tags(H5C_t *cache_ptr); H5_DLL hbool_t H5C_get_ignore_tags(const H5C_t *cache_ptr); H5_DLL herr_t H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag); +H5_DLL herr_t H5C_cork(H5C_t *cache_ptr, haddr_t obj_addr, unsigned action, hbool_t *corked); H5_DLL herr_t H5C_get_entry_ring(const H5F_t *f, haddr_t addr, H5C_ring_t *ring); #ifdef H5_HAVE_PARALLEL diff --git a/src/H5Cquery.c b/src/H5Cquery.c index 9cb92ba..a693ec2 100644 --- a/src/H5Cquery.c +++ b/src/H5Cquery.c @@ -229,6 +229,7 @@ H5C_get_entry_status(const H5F_t *f, hbool_t * is_dirty_ptr, hbool_t * is_protected_ptr, hbool_t * is_pinned_ptr, + hbool_t * is_corked_ptr, hbool_t * is_flush_dep_parent_ptr, hbool_t * is_flush_dep_child_ptr) { @@ -273,6 +274,8 @@ H5C_get_entry_status(const H5F_t *f, *is_protected_ptr = entry_ptr->is_protected; if(is_pinned_ptr != NULL) *is_pinned_ptr = entry_ptr->is_pinned; + if(is_corked_ptr != NULL) + *is_corked_ptr = entry_ptr->is_corked; if(is_flush_dep_parent_ptr != NULL) *is_flush_dep_parent_ptr = (entry_ptr->flush_dep_height > 0); if(is_flush_dep_child_ptr != NULL) diff --git a/src/H5Ctag.c b/src/H5Ctag.c index 6c26796..4748156 100644 --- a/src/H5Ctag.c +++ b/src/H5Ctag.c @@ -54,9 +54,6 @@ /* Local Typedefs */ /******************/ -/* Define cache entry iteration callback type */ -typedef int (*H5C_tag_iter_cb_t)(H5C_cache_entry_t *entry, void *ctx); - /* Typedef for tagged entry iterator callback context - retag tagged entries */ typedef struct { haddr_t dest_tag; /* New tag value for matching entries */ @@ -70,13 +67,16 @@ typedef struct { unsigned flags; /* Flags for expunging entry */ } H5C_tag_iter_ettm_ctx_t; +/* Typedef for tagged entry iterator callback context - mark corked */ +typedef struct { + hbool_t cork_val; /* Corked value */ +} H5C_tag_iter_cork_ctx_t; + /********************/ /* Local Prototypes */ /********************/ static herr_t H5C__mark_tagged_entries(H5C_t *cache_ptr, haddr_t tag); -static int H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global, - H5C_tag_iter_cb_t cb, void *cb_ctx); /*********************/ @@ -244,7 +244,7 @@ done: * *------------------------------------------------------------------------- */ -static int +int H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global, H5C_tag_iter_cb_t cb, void *cb_ctx) { @@ -252,7 +252,7 @@ H5C__iter_tagged_entries(H5C_t *cache, haddr_t tag, hbool_t match_global, int ret_value = H5_ITER_CONT; /* Return value */ /* Function enter macro */ - FUNC_ENTER_STATIC + FUNC_ENTER_PACKAGE /* Sanity checks */ HDassert(cache != NULL); @@ -630,3 +630,73 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* H5C_expunge_tag_type_metadata() */ + +/*------------------------------------------------------------------------- + * Function: H5C__mark_tagged_entries_cork_cb + * + * Purpose: The "is_corked" field to "val" for en entry + * + * Return: H5_ITER_ERROR if error is detected, H5_ITER_CONT otherwise. + * + * Programmer: Vailin Choi + * January 2014 + * + *------------------------------------------------------------------------- + */ +static int +H5C__mark_tagged_entries_cork_cb(H5C_cache_entry_t *entry, void *_ctx) +{ + H5C_tag_iter_cork_ctx_t *ctx = (H5C_tag_iter_cork_ctx_t *)_ctx; /* Get pointer to iterator context */ + + /* Function enter macro */ + FUNC_ENTER_STATIC_NOERR + + /* Santify checks */ + HDassert(entry); + HDassert(ctx); + + /* Set the entry's "corked" field to "val" */ + entry->is_corked = ctx->cork_val; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5C__mark_tagged_entries_cork_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5C__mark_tagged_entries_cork + * + * Purpose: To set the "is_corked" field to "val" for entries in cache + * with the entry's tag equals to "obj_addr". + * + * Return: FAIL if error is detected, SUCCEED otherwise. + * + * Programmer: Vailin Choi + * January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C__mark_tagged_entries_cork(H5C_t *cache, haddr_t obj_addr, hbool_t val) +{ + H5C_tag_iter_cork_ctx_t ctx; /* Context for iterator callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Function enter macro */ + FUNC_ENTER_PACKAGE + + /* Sanity checks */ + HDassert(cache); + HDassert(cache->magic == H5C__H5C_T_MAGIC); + + /* Construct context for iterator callbacks */ + ctx.cork_val = val; + + /* Iterate through entries, find each entry with the specified tag */ + /* and set the entry's "corked" field to "val" */ + if(H5C__iter_tagged_entries(cache, obj_addr, FALSE, H5C__mark_tagged_entries_cork_cb, &ctx) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "Iteration of tagged entries failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C__mark_tagged_entries_cork() */ + diff --git a/src/H5Ctest.c b/src/H5Ctest.c new file mode 100644 index 0000000..b049a75 --- /dev/null +++ b/src/H5Ctest.c @@ -0,0 +1,159 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Ctest.c + * June 7 2016 + * Quincey Koziol + * + * Purpose: Functions in this file support the metadata cache regression + * tests> + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#include "H5Cmodule.h" /* This source code file is part of the H5C module */ +#define H5C_TESTING /*suppress warning about H5C testing funcs*/ +#define H5F_FRIEND /*suppress error about including H5Fpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Cpkg.h" /* Cache */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* Files */ +#include "H5Iprivate.h" /* IDs */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Typedef for tagged entry iterator callback context - verify cork tag */ +typedef struct { + hbool_t status; /* Corked status */ +} H5C_tag_iter_vct_ctx_t; + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + + +/*------------------------------------------------------------------------- + * Function: H5C__verify_cork_tag_test_cb + * + * Purpose: Verify the cork status for an entry + * + * Return: SUCCEED on success, FAIL on error + * + * Programmer: Vailin Choi + * Feb 2014 + * + *------------------------------------------------------------------------- + */ +static int +H5C__verify_cork_tag_test_cb(H5C_cache_entry_t *entry, void *_ctx) +{ + H5C_tag_iter_vct_ctx_t *ctx = (H5C_tag_iter_vct_ctx_t *)_ctx; /* Get pointer to iterator context */ + int ret_value = H5_ITER_CONT; /* Return value */ + + /* Function enter macro */ + FUNC_ENTER_STATIC + + /* Santify checks */ + HDassert(entry); + HDassert(ctx); + + /* Verify corked status for entry */ + if(entry->is_corked != ctx->status) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, H5_ITER_ERROR, "bad cork status") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C__verify_cork_tag_test_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5C__verify_cork_tag_test + * + * Purpose: This routine verifies that all cache entries associated with + * the object tag are marked with the desired "cork" status. + * + * Return: SUCCEED on success, FAIL on error + * + * Programmer: Vailin Choi + * Feb 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5C__verify_cork_tag_test(hid_t fid, haddr_t tag, hbool_t status) +{ + H5F_t * f; /* File Pointer */ + H5C_t * cache; /* Cache Pointer */ + H5C_tag_iter_vct_ctx_t ctx; /* Context for iterator callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + /* Function enter macro */ + FUNC_ENTER_PACKAGE + + /* Get file pointer */ + if(NULL == (f = (H5F_t *)H5I_object_verify(fid, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file") + + /* Get cache pointer */ + cache = f->shared->cache; + + /* Construct context for iterator callbacks */ + ctx.status = status; + + /* Iterate through tagged entries in the cache */ + if(H5C__iter_tagged_entries(cache, tag, FALSE, H5C__verify_cork_tag_test_cb, &ctx) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADITER, FAIL, "iteration of tagged entries failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5C__verify_cork_tag_test() */ + diff --git a/src/H5Dint.c b/src/H5Dint.c index c68a355..a324873 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1776,6 +1776,7 @@ herr_t H5D_close(H5D_t *dataset) { hbool_t free_failed = FALSE; + hbool_t corked; /* Whether the dataset is corked or not */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -1885,6 +1886,13 @@ H5D_close(H5D_t *dataset) (H5O_msg_reset(H5O_FILL_ID, &dataset->shared->dcpl_cache.fill) < 0) || (H5O_msg_reset(H5O_EFL_ID, &dataset->shared->dcpl_cache.efl) < 0); + /* Uncork cache entries with object address tag */ + if(H5AC_cork(dataset->oloc.file, dataset->oloc.addr, H5AC__GET_CORKED, &corked) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") + if(corked) + if(H5AC_cork(dataset->oloc.file, dataset->oloc.addr, H5AC__UNCORK, NULL) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTUNCORK, FAIL, "unable to uncork an object") + /* * Release datatype, dataspace and creation property list -- there isn't * much we can do if one of these fails, so we just continue. diff --git a/src/H5Gint.c b/src/H5Gint.c index c78c87c..f5bccc3 100644 --- a/src/H5Gint.c +++ b/src/H5Gint.c @@ -472,6 +472,7 @@ done: herr_t H5G_close(H5G_t *grp) { + hbool_t corked; /* Whether the group is corked or not */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(FAIL) @@ -485,6 +486,13 @@ H5G_close(H5G_t *grp) if(0 == grp->shared->fo_count) { HDassert(grp != H5G_rootof(H5G_fileof(grp))); + /* Uncork cache entries with object address tag */ + if(H5AC_cork(grp->oloc.file, grp->oloc.addr, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") + if(corked) + if(H5AC_cork(grp->oloc.file, grp->oloc.addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTUNCORK, FAIL, "unable to uncork an object") + /* Remove the group from the list of opened objects in the file */ if(H5FO_top_decr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't decrement count for object") @@ -1101,6 +1101,120 @@ done: /*------------------------------------------------------------------------- + * Function: H5Odisable_mdc_flushes + * + * Purpose: To "cork" an object: + * --keep dirty entries assoicated with the object in the metadata cache + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi + * January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Odisable_mdc_flushes(hid_t object_id) +{ + H5O_loc_t *oloc; /* Object location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", object_id); + + /* Get the object's oloc */ + if(NULL == (oloc = H5O_get_loc(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + if(H5AC_cork(oloc->file, oloc->addr, H5AC__SET_CORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCORK, FAIL, "unable to cork an object") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Odisable_mdc_flushes() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oenable_mdc_flushes + * + * Purpose: To "uncork" an object + * --release keeping dirty entries associated with the object + * in the metadata cache + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi + * January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oenable_mdc_flushes(hid_t object_id) +{ + H5O_loc_t *oloc; /* Object location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE1("e", "i", object_id); + + /* Get the object's oloc */ + if(NULL == (oloc = H5O_get_loc(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + /* Set the value */ + if(H5AC_cork(oloc->file, oloc->addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork an object") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Oenable_mdc_flushes() */ + + +/*------------------------------------------------------------------------- + * Function: H5Oare_mdc_flushes_disabled + * + * Purpose: Retrieve the object's "cork" status in the parameter "are_disabled": + * TRUE if mdc flushes for the object is disabled + * FALSE if mdc flushes for the object is not disabled + * Return error if the parameter "are_disabled" is not supplied + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi + * January 2014 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled) +{ + H5O_loc_t *oloc; /* Object location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*b", object_id, are_disabled); + + /* Check args */ + + /* Get the object's oloc */ + if(NULL == (oloc = H5O_get_loc(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to get object location from ID") + if(!are_disabled) + HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "unable to get object location from ID") + + /* Get the cork status */ + if(H5AC_cork(oloc->file, oloc->addr, H5AC__GET_CORKED, are_disabled) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") + +done: + FUNC_LEAVE_API(ret_value) +} /* H5Oare_mdc_flushes_disabled() */ + + +/*------------------------------------------------------------------------- * Function: H5O_create * * Purpose: Creates a new object header. Allocates space for it and @@ -2224,6 +2338,7 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) H5O_t *oh = NULL; /* Object header information */ H5O_loc_t loc; /* Object location for object to delete */ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting object header */ + hbool_t corked; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_TAG(dxpl_id, addr, FAIL) @@ -2245,6 +2360,13 @@ H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr) if(H5O_delete_oh(f, dxpl_id, oh) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file") + /* Uncork cache entries with tag: addr */ + if(H5AC_cork(f, addr, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") + if(corked) + if(H5AC_cork(f, addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTUNCORK, FAIL, "unable to uncork an object") + /* Mark object header as deleted */ oh_flags = H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; diff --git a/src/H5Opublic.h b/src/H5Opublic.h index a7d386a..9debdbc 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -182,6 +182,9 @@ H5_DLL herr_t H5Ovisit_by_name(hid_t loc_id, const char *obj_name, H5_index_t idx_type, H5_iter_order_t order, H5O_iterate_t op, void *op_data, hid_t lapl_id); H5_DLL herr_t H5Oclose(hid_t object_id); +H5_DLL herr_t H5Odisable_mdc_flushes(hid_t object_id); +H5_DLL herr_t H5Oenable_mdc_flushes(hid_t object_id); +H5_DLL herr_t H5Oare_mdc_flushes_disabled(hid_t object_id, hbool_t *are_disabled); /* Symbols defined for compatibility with previous versions of the HDF5 API. * @@ -3612,6 +3612,17 @@ H5T_close(H5T_t *dt) dt->shared->fo_count--; if(dt->shared->state != H5T_STATE_OPEN || dt->shared->fo_count == 0) { + /* Uncork cache entries with object address tag for named datatype only */ + if(dt->shared->state == H5T_STATE_OPEN && dt->shared->fo_count == 0) { + hbool_t corked; /* Whether the named datatype is corked or not */ + + if(H5AC_cork(dt->oloc.file, dt->oloc.addr, H5AC__GET_CORKED, &corked) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve an object's cork status") + if(corked) + if(H5AC_cork(dt->oloc.file, dt->oloc.addr, H5AC__UNCORK, NULL) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTUNCORK, FAIL, "unable to uncork an object") + } /* end if */ + if(H5T__free(dt) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype"); diff --git a/src/H5err.txt b/src/H5err.txt index e0ebf5e..8219408 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -175,6 +175,8 @@ MINOR, CACHE, H5E_CANTRESIZE, Unable to resize a metadata cache entry MINOR, CACHE, H5E_CANTDEPEND, Unable to create a flush dependency MINOR, CACHE, H5E_CANTUNDEPEND, Unable to destroy a flush dependency MINOR, CACHE, H5E_CANTNOTIFY, Unable to notify object about action +MINOR, CACHE, H5E_CANTCORK, Unable to cork an object +MINOR, CACHE, H5E_CANTUNCORK, Unable to uncork an object # B-tree related errors MINOR, BTREE, H5E_NOTFOUND, Object not found diff --git a/src/Makefile.am b/src/Makefile.am index 1f3f00e..7facf9a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5AC.c \ H5B.c H5Bcache.c H5Bdbg.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ - H5C.c H5Cepoch.c H5Cquery.c H5Ctag.c \ + H5C.c H5Cepoch.c H5Cquery.c H5Ctag.c H5Ctest.c \ H5CS.c \ H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ |