diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5AC.c | 98 | ||||
-rw-r--r-- | src/H5ACprivate.h | 29 | ||||
-rw-r--r-- | src/H5B.c | 11 | ||||
-rw-r--r-- | src/H5B2.c | 9 | ||||
-rw-r--r-- | src/H5B2cache.c | 162 | ||||
-rw-r--r-- | src/H5B2int.c | 4 | ||||
-rw-r--r-- | src/H5B2pkg.h | 1 | ||||
-rw-r--r-- | src/H5Bcache.c | 40 | ||||
-rw-r--r-- | src/H5C.c | 394 | ||||
-rw-r--r-- | src/H5Cprivate.h | 17 | ||||
-rw-r--r-- | src/H5F.c | 2 | ||||
-rw-r--r-- | src/H5FD.c | 10 | ||||
-rw-r--r-- | src/H5FDpublic.h | 7 | ||||
-rw-r--r-- | src/H5FS.c | 13 | ||||
-rw-r--r-- | src/H5FScache.c | 87 | ||||
-rw-r--r-- | src/H5FSpkg.h | 5 | ||||
-rw-r--r-- | src/H5FSsection.c | 2 | ||||
-rw-r--r-- | src/H5Gnode.c | 112 | ||||
-rw-r--r-- | src/H5HFcache.c | 85 | ||||
-rw-r--r-- | src/H5HFdblock.c | 2 | ||||
-rw-r--r-- | src/H5HFhdr.c | 2 | ||||
-rw-r--r-- | src/H5HFiblock.c | 8 | ||||
-rw-r--r-- | src/H5HFpkg.h | 15 | ||||
-rw-r--r-- | src/H5HG.c | 4 | ||||
-rwxr-xr-x | src/H5HGcache.c | 65 | ||||
-rw-r--r-- | src/H5HL.c | 28 | ||||
-rw-r--r-- | src/H5HLcache.c | 48 | ||||
-rw-r--r-- | src/H5O.c | 5 | ||||
-rw-r--r-- | src/H5Ocache.c | 49 | ||||
-rw-r--r-- | src/H5Ochunk.c | 2 | ||||
-rw-r--r-- | src/H5Ocopy.c | 2 | ||||
-rwxr-xr-x | src/H5SM.c | 69 | ||||
-rw-r--r-- | src/H5SMcache.c | 101 | ||||
-rwxr-xr-x | src/H5SMpkg.h | 34 | ||||
-rw-r--r-- | src/H5SMtest.c | 1 | ||||
-rw-r--r-- | src/H5private.h | 27 |
36 files changed, 903 insertions, 647 deletions
@@ -159,10 +159,7 @@ static herr_t H5AC_log_flushed_entry_dummy(H5C_t * cache_ptr, static herr_t H5AC_log_inserted_entry(H5F_t * f, H5AC_t * cache_ptr, - H5AC_info_t * entry_ptr, - const H5AC_class_t * type, - haddr_t addr, - size_t size); + H5AC_info_t * entry_ptr); static herr_t H5AC_propagate_flushed_and_still_clean_entries_list(H5F_t * f, hid_t dxpl_id, @@ -1565,11 +1562,8 @@ done: */ herr_t H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, - size_t len, void *thing, unsigned int flags) + void *thing, unsigned int flags) { - herr_t result; - H5AC_info_t *info; - herr_t ret_value=SUCCEED; /* Return value */ #ifdef H5_HAVE_PARALLEL H5AC_aux_t * aux_ptr = NULL; #endif /* H5_HAVE_PARALLEL */ @@ -1578,6 +1572,7 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, size_t trace_entry_size = 0; FILE * trace_file_ptr = NULL; #endif /* H5AC__TRACE_FILE_ENABLED */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5AC_set, FAIL) @@ -1603,81 +1598,40 @@ H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, ( H5C_get_trace_file_ptr(f->shared->cache, &trace_file_ptr) >= 0) && ( trace_file_ptr != NULL ) ) { - sprintf(trace, "H5AC_set 0x%lx %ld %d 0x%x", + sprintf(trace, "H5AC_set 0x%lx %d 0x%x", (unsigned long)addr, - (long)len, type->id, flags); } #endif /* H5AC__TRACE_FILE_ENABLED */ - /* Get local copy of this information */ - info = (H5AC_info_t *)thing; - - info->addr = addr; - info->type = type; - info->is_protected = FALSE; - -#ifdef H5_HAVE_PARALLEL - if ( NULL != (aux_ptr = f->shared->cache->aux_ptr) ) { - - result = H5AC_log_inserted_entry(f, - f->shared->cache, - (H5AC_info_t *)thing, - type, - addr, - len); - - if ( result < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, \ - "H5AC_log_inserted_entry() failed.") - } - } -#endif /* H5_HAVE_PARALLEL */ - - result = H5C_insert_entry(f, - dxpl_id, - type, - addr, - len, - thing, - flags); - - if ( result < 0 ) { - + /* Insert entry into metadata cache */ + if(H5C_insert_entry(f, dxpl_id, type, addr, thing, flags) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C_insert_entry() failed") - } #if H5AC__TRACE_FILE_ENABLED - if ( trace_file_ptr != NULL ) { - + if(trace_file_ptr != NULL) { /* make note of the entry size */ trace_entry_size = ((H5C_cache_entry_t *)thing)->size; } #endif /* H5AC__TRACE_FILE_ENABLED */ #ifdef H5_HAVE_PARALLEL - if ( ( aux_ptr != NULL ) && - ( aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold ) ) { - - result = H5AC_propagate_flushed_and_still_clean_entries_list(f, - H5AC_noblock_dxpl_id, - f->shared->cache, - TRUE); - if ( result < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, \ - "Can't propagate clean entries list.") - } - } + if(NULL != (aux_ptr = f->shared->cache->aux_ptr)) { + if(H5AC_log_inserted_entry(f, f->shared->cache, (H5AC_info_t *)thing) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5AC_log_inserted_entry() failed") + + if(aux_ptr->dirty_bytes >= aux_ptr->dirty_bytes_threshold) { + if(H5AC_propagate_flushed_and_still_clean_entries_list(f, H5AC_noblock_dxpl_id, + f->shared->cache, TRUE) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTUNPROTECT, FAIL, "Can't propagate clean entries list") + } /* end if */ + } /* end if */ #endif /* H5_HAVE_PARALLEL */ done: - #if H5AC__TRACE_FILE_ENABLED - if ( trace_file_ptr != NULL ) { - + if(trace_file_ptr != NULL) { HDfprintf(trace_file_ptr, "%s %d %d\n", trace, (int)trace_entry_size, (int)ret_value); @@ -1685,7 +1639,6 @@ done: #endif /* H5AC__TRACE_FILE_ENABLED */ FUNC_LEAVE_NOAPI(ret_value) - } /* H5AC_set() */ @@ -4316,10 +4269,7 @@ done: static herr_t H5AC_log_inserted_entry(H5F_t * f, H5AC_t * cache_ptr, - H5AC_info_t * entry_ptr, - const H5AC_class_t * type, - haddr_t addr, - size_t size) + H5AC_info_t * entry_ptr) { herr_t ret_value = SUCCEED; /* Return value */ H5AC_aux_t * aux_ptr = NULL; @@ -4336,15 +4286,13 @@ H5AC_log_inserted_entry(H5F_t * f, HDassert( aux_ptr->magic == H5AC__H5AC_AUX_T_MAGIC ); HDassert( entry_ptr != NULL ); - HDassert( entry_ptr->addr == addr ); - HDassert( entry_ptr->type == type ); if ( aux_ptr->mpi_rank == 0 ) { HDassert( aux_ptr->d_slist_ptr != NULL ); HDassert( aux_ptr->c_slist_ptr != NULL ); - if ( H5SL_search(aux_ptr->d_slist_ptr, (void *)(&addr)) == NULL ) { + if ( H5SL_search(aux_ptr->d_slist_ptr, (void *)(&entry_ptr->addr)) == NULL ) { /* insert the address of the entry in the dirty entry list, and * add its size to the dirty_bytes count. @@ -4356,7 +4304,7 @@ H5AC_log_inserted_entry(H5F_t * f, } slist_entry_ptr->magic = H5AC__H5AC_SLIST_ENTRY_T_MAGIC; - slist_entry_ptr->addr = addr; + slist_entry_ptr->addr = entry_ptr->addr; if ( H5SL_insert(aux_ptr->d_slist_ptr, slist_entry_ptr, &(slist_entry_ptr->addr)) < 0 ) { @@ -4373,14 +4321,14 @@ H5AC_log_inserted_entry(H5F_t * f, "Inserted entry already in dirty slist.") } - if ( H5SL_search(aux_ptr->c_slist_ptr, (void *)(&addr)) != NULL ) { + if ( H5SL_search(aux_ptr->c_slist_ptr, (void *)(&entry_ptr->addr)) != NULL ) { HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ "Inserted entry in clean slist.") } } - aux_ptr->dirty_bytes += size; + aux_ptr->dirty_bytes += entry_ptr->size; #if H5AC_DEBUG_DIRTY_BYTES_CREATION aux_ptr->insert_dirty_bytes += size; diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index aa0ded9..78eaf83 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -94,30 +94,16 @@ typedef enum { /* * Class methods pertaining to caching. Each type of cached object will * have a constant variable with permanent life-span that describes how - * to cache the object. That variable will be of type H5AC_class_t and - * have the following required fields... - * - * LOAD: Loads an object from disk to memory. The function - * should allocate some data structure and return it. - * - * FLUSH: Writes some data structure back to disk. It would be - * wise for the data structure to include dirty flags to - * indicate whether it really needs to be written. This - * function is also responsible for freeing memory allocated - * by the LOAD method if the DEST argument is non-zero (by - * calling the DEST method). - * - * DEST: Just frees memory allocated by the LOAD method. - * - * CLEAR: Just marks object as non-dirty. - * - * SIZE: Report the size (on disk) of the specified cache object. - * Note that the space allocated on disk may not be contiguous. + * to cache the object. */ #define H5AC__SERIALIZE_RESIZED_FLAG H5C__SERIALIZE_RESIZED_FLAG #define H5AC__SERIALIZE_MOVED_FLAG H5C__SERIALIZE_MOVED_FLAG +#define H5AC__CLASS_NO_FLAGS_SET H5C__CLASS_NO_FLAGS_SET +#define H5AC__CLASS_SPECULATIVE_LOAD_FLAG H5C__CLASS_SPECULATIVE_LOAD_FLAG +#define H5AC__CLASS_COMPRESSED_FLAG H5C__CLASS_COMPRESSED_FLAG + typedef H5C_get_load_size_func_t H5AC_get_load_size_func_t; typedef H5C_deserialize_func_t H5AC_deserialize_func_t; typedef H5C_image_len_func_t H5AC_image_len_func_t; @@ -126,8 +112,7 @@ typedef H5C_free_icr_func_t H5AC_free_icr_func_t; typedef H5C_class_t H5AC_class_t; - - +/* Cache entry info */ typedef H5C_cache_entry_t H5AC_info_t; @@ -302,7 +287,7 @@ H5_DLL herr_t H5AC_end_transaction(hbool_t do_transaction, H5_DLL herr_t H5AC_get_entry_status(const H5F_t *f, haddr_t addr, unsigned * status_ptr); H5_DLL herr_t H5AC_set(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, - haddr_t addr, size_t len, void *thing, unsigned int flags); + haddr_t addr, void *thing, unsigned int flags); H5_DLL herr_t H5AC_pin_protected_entry(void *thing); H5_DLL void * H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr, void *udata, H5AC_protect_t rw); @@ -248,7 +248,7 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, /* * Cache the new B-tree node. */ - if(H5AC_set(f, dxpl_id, H5AC_BT, *addr_p, shared->sizeof_rnode, bt, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_BT, *addr_p, bt, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree root node to cache") #ifdef H5B_DEBUG H5B_assert(f, dxpl_id, *addr_p, shared->type, udata); @@ -705,15 +705,14 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, new_bt->nchildren = 2; new_bt->child[0] = old_root; - HDmemcpy(H5B_NKEY(new_bt,shared,0), lt_key, shared->type->sizeof_nkey); + HDmemcpy(H5B_NKEY(new_bt, shared, 0), lt_key, shared->type->sizeof_nkey); new_bt->child[1] = child; - HDmemcpy(H5B_NKEY(new_bt,shared,1), md_key, shared->type->sizeof_nkey); - - HDmemcpy(H5B_NKEY(new_bt,shared,2), rt_key, shared->type->sizeof_nkey); + HDmemcpy(H5B_NKEY(new_bt, shared, 1), md_key, shared->type->sizeof_nkey); + HDmemcpy(H5B_NKEY(new_bt, shared, 2), rt_key, shared->type->sizeof_nkey); /* Insert the modified copy of the old root into the file again */ - if(H5AC_set(f, dxpl_id, H5AC_BT, addr, shared->sizeof_rnode, new_bt, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_BT, addr, new_bt, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to flush old B-tree root node") #ifdef H5B_DEBUG @@ -124,6 +124,7 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, /* Assign internal information */ HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t)); + bt2->hdr_size = H5B2_HEADER_SIZE(f); bt2->root.addr = HADDR_UNDEF; bt2->root.node_nrec = 0; bt2->root.all_nrec = 0; @@ -133,11 +134,11 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared B-tree info") /* Allocate space for the header on disk */ - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(f)))) + if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)bt2->hdr_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree header") /* Cache the new B-tree node */ - if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, *addr_p, (size_t)H5B2_HEADER_SIZE(f), bt2, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, *addr_p, bt2, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree header to cache") done: @@ -1029,7 +1030,7 @@ H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes") /* Release space for B-tree node on disk */ - if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5B2_HEADER_SIZE(f))<0) + if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)bt2->hdr_size) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree header info") done: @@ -1282,7 +1283,7 @@ H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t add HDassert(shared); /* Add size of header to B-tree metadata total */ - *btree_size += H5B2_HEADER_SIZE(f); + *btree_size += bt2->hdr_size; /* Make copy of the root node pointer */ root_ptr = bt2->root; diff --git a/src/H5B2cache.c b/src/H5B2cache.c index 3f49f36..f8247aa 100644 --- a/src/H5B2cache.c +++ b/src/H5B2cache.c @@ -67,6 +67,7 @@ static herr_t H5B2_cache_hdr_get_load_size(const void *udata, size_t *image_len); static void *H5B2_cache_hdr_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5B2_cache_hdr_image_len(const void *thing, size_t *image_len); static herr_t H5B2_cache_hdr_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -75,6 +76,7 @@ static herr_t H5B2_cache_hdr_free_icr(void *thing); static herr_t H5B2_cache_int_get_load_size(const void *udata, size_t *image_len); static void *H5B2_cache_int_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5B2_cache_int_image_len(const void *thing, size_t *image_len); static herr_t H5B2_cache_int_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -83,6 +85,7 @@ static herr_t H5B2_cache_int_free_icr(void *thing); static herr_t H5B2_cache_leaf_get_load_size(const void *udata, size_t *image_len); static void *H5B2_cache_leaf_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5B2_cache_leaf_image_len(const void *thing, size_t *image_len); static herr_t H5B2_cache_leaf_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -97,9 +100,10 @@ const H5AC_class_t H5AC_BT2_HDR[1] = {{ H5AC_BT2_HDR_ID, "v2 b-tree header", H5FD_MEM_BTREE, + H5AC__CLASS_NO_FLAGS_SET, H5B2_cache_hdr_get_load_size, H5B2_cache_hdr_deserialize, - NULL, + H5B2_cache_hdr_image_len, H5B2_cache_hdr_serialize, H5B2_cache_hdr_free_icr, }}; @@ -109,9 +113,10 @@ const H5AC_class_t H5AC_BT2_INT[1] = {{ H5AC_BT2_INT_ID, "v2 b-tree internal node", H5FD_MEM_BTREE, + H5AC__CLASS_NO_FLAGS_SET, H5B2_cache_int_get_load_size, H5B2_cache_int_deserialize, - NULL, + H5B2_cache_int_image_len, H5B2_cache_int_serialize, H5B2_cache_int_free_icr, }}; @@ -121,9 +126,10 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{ H5AC_BT2_LEAF_ID, "v2 b-tree leaf node", H5FD_MEM_BTREE, + H5AC__CLASS_NO_FLAGS_SET, H5B2_cache_leaf_get_load_size, H5B2_cache_leaf_deserialize, - NULL, + H5B2_cache_leaf_image_len, H5B2_cache_leaf_serialize, H5B2_cache_leaf_free_icr, }}; @@ -194,7 +200,6 @@ H5B2_cache_hdr_deserialize(const void *image, size_t UNUSED len, size_t node_size, rrec_size; /* Size info for B-tree */ uint8_t split_percent, merge_percent; /* Split & merge %s for B-tree */ H5B2_t *bt2 = NULL; /* B-tree info */ - size_t size; /* Header size */ uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ const uint8_t *p; /* Pointer into raw data buffer */ @@ -212,7 +217,7 @@ H5B2_cache_hdr_deserialize(const void *image, size_t UNUSED len, HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t)); /* Compute the size of the serialized B-tree header on disk */ - size = H5B2_HEADER_SIZE(udata->f); + bt2->hdr_size = H5B2_HEADER_SIZE(udata->f); /* Get temporary pointer to serialized header */ p = (const uint8_t *)image; @@ -252,7 +257,7 @@ H5B2_cache_hdr_deserialize(const void *image, size_t UNUSED len, UINT32DECODE(p, stored_chksum); /* Compute checksum on entire header */ - computed_chksum = H5_checksum_metadata(image, (size - H5B2_SIZEOF_CHKSUM), 0); + computed_chksum = H5_checksum_metadata(image, (bt2->hdr_size - H5B2_SIZEOF_CHKSUM), 0); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -278,6 +283,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5B2_cache_hdr_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5B2_cache_hdr_image_len(const void *_thing, size_t *image_len) +{ + H5B2_t *bt2 = (H5B2_t *)_thing; /* Pointer to the B-tree header */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_hdr_image_len) + + /* Check arguments */ + HDassert(bt2); + HDassert(image_len); + + /* Set the image length size */ + *image_len = bt2->hdr_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B2_cache_hdr_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5B2_cache_hdr_serialize * * Purpose: Flushes a dirty B-tree header to disk. @@ -296,11 +332,10 @@ H5B2_cache_hdr_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, unsigned *flags, haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image) { - H5B2_t *bt2 = (H5B2_t *)_thing; /* Pointer to the b-tree header */ - H5B2_shared_t *shared; /* Shared B-tree information */ - uint8_t *p; /* Pointer into raw data buffer */ - size_t size; /* Header size on disk */ - uint32_t metadata_chksum; /* Computed metadata checksum value */ + H5B2_t *bt2 = (H5B2_t *)_thing; /* Pointer to the B-tree header */ + H5B2_shared_t *shared; /* Shared B-tree information */ + uint8_t *p; /* Pointer into raw data buffer */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_hdr_serialize) @@ -314,9 +349,6 @@ H5B2_cache_hdr_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared); HDassert(shared); - /* Compute the size of the serialized B-tree header on disk */ - size = H5B2_HEADER_SIZE(f); - /* Get temporary pointer to serialized header */ p = (uint8_t *)image; @@ -351,7 +383,7 @@ H5B2_cache_hdr_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, H5F_ENCODE_LENGTH(f, p, bt2->root.all_nrec); /* Compute metadata checksum */ - metadata_chksum = H5_checksum_metadata(image, (size - H5B2_SIZEOF_CHKSUM), 0); + metadata_chksum = H5_checksum_metadata(image, (bt2->hdr_size - H5B2_SIZEOF_CHKSUM), 0); /* Metadata checksum */ UINT32ENCODE(p, metadata_chksum); @@ -563,6 +595,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5B2_cache_int_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5B2_cache_int_image_len(const void *_thing, size_t *image_len) +{ + H5B2_internal_t *internal = (H5B2_internal_t *)_thing; /* Pointer to the B-tree internal node */ + H5B2_shared_t *shared; /* Shared B-tree information */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_int_image_len) + + /* Check arguments */ + HDassert(internal); + HDassert(image_len); + + /* Get the pointer to the shared B-tree info */ + shared = (H5B2_shared_t *)H5RC_GET_OBJ(internal->shared); + HDassert(shared); + + /* Set the image length size */ + *image_len = shared->node_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B2_cache_int_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5B2_cache_int_serialize * * Purpose: Serializes a B-tree internal node for writing to disk. @@ -581,13 +649,13 @@ H5B2_cache_int_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, unsigned *flags, haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image) { + H5B2_internal_t *internal = (H5B2_internal_t *)_thing; /* Pointer to the B-tree internal node */ H5B2_shared_t *shared; /* Shared B-tree information */ uint8_t *p; /* Pointer into raw data buffer */ uint8_t *native; /* Pointer to native record info */ H5B2_node_ptr_t *int_node_ptr; /* Pointer to node pointer info */ uint32_t metadata_chksum; /* Computed metadata checksum value */ unsigned u; /* Local index variable */ - H5B2_internal_t *internal = (H5B2_internal_t *)_thing; /* Pointer to the b-tree internal node */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_int_serialize) @@ -618,13 +686,13 @@ H5B2_cache_int_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, /* Serialize records for internal node */ native = internal->int_native; for(u = 0; u < internal->nrec; u++) { - /* Encode record */ - if((shared->type->encode)(f, p, native) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record") + /* Encode record */ + if((shared->type->encode)(f, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record") - /* Move to next record */ - p += shared->rrec_size; - native += shared->type->nrec_size; + /* Move to next record */ + p += shared->rrec_size; + native += shared->type->nrec_size; } /* end for */ /* Serialize node pointers for internal node */ @@ -835,6 +903,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5B2_cache_leaf_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5B2_cache_leaf_image_len(const void *_thing, size_t *image_len) +{ + H5B2_leaf_t *leaf = (H5B2_leaf_t *)_thing; /* Pointer to the B-tree leaf node */ + H5B2_shared_t *shared; /* Shared B-tree information */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_cache_leaf_image_len) + + /* Check arguments */ + HDassert(leaf); + HDassert(image_len); + + /* Get the pointer to the shared B-tree info */ + shared = (H5B2_shared_t *)H5RC_GET_OBJ(leaf->shared); + HDassert(shared); + + /* Set the image length size */ + *image_len = shared->node_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B2_cache_leaf_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5B2_cache_leaf_serialize * * Purpose: Serializes a B-tree leaf node for writing to disk. @@ -853,13 +957,13 @@ H5B2_cache_leaf_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, unsigned *flags, haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image) { - H5B2_shared_t *shared; /* Shared B-tree information */ - uint8_t *p; /* Pointer into raw data buffer */ - uint8_t *native; /* Pointer to native keys */ - uint32_t metadata_chksum; /* Computed metadata checksum value */ - H5B2_leaf_t *leaf = (H5B2_leaf_t *)_thing; /* Pointer to the b-tree leaf node */ - unsigned u; /* Local index variable */ - herr_t ret_value = SUCCEED; /* Return value */ + H5B2_leaf_t *leaf = (H5B2_leaf_t *)_thing; /* Pointer to the B-tree leaf node */ + H5B2_shared_t *shared; /* Shared B-tree information */ + uint8_t *p; /* Pointer into raw data buffer */ + uint8_t *native; /* Pointer to native keys */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5B2_cache_leaf_serialize) diff --git a/src/H5B2int.c b/src/H5B2int.c index a1532ca..d31231e 100644 --- a/src/H5B2int.c +++ b/src/H5B2int.c @@ -2010,7 +2010,7 @@ HDmemset(leaf->leaf_native, 0, shared->type->nrec_size * shared->node_info[0].ma HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree leaf node") /* Cache the new B-tree node */ - if(H5AC_set(f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, (size_t)shared->node_size, leaf, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree leaf to cache") done: @@ -2092,7 +2092,7 @@ HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (shared->node_info[de HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree internal node") /* Cache the new B-tree node */ - if(H5AC_set(f, dxpl_id, H5AC_BT2_INT, node_ptr->addr, (size_t)shared->node_size, internal, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_BT2_INT, node_ptr->addr, internal, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree internal node to cache") done: diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 21b6eee..f0bb2b5 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -188,6 +188,7 @@ typedef struct H5B2_t { /* Internal B-tree information */ H5B2_node_ptr_t root; /* Node pointer to root node in B-tree */ + size_t hdr_size; /* Size of the B-tree header on disk */ H5RC_t *shared; /* Ref-counted shared info */ } H5B2_t; diff --git a/src/H5Bcache.c b/src/H5Bcache.c index 0ed6916..f95fb69 100644 --- a/src/H5Bcache.c +++ b/src/H5Bcache.c @@ -57,6 +57,7 @@ static herr_t H5B_get_load_size(const void *udata, size_t *image_len); static void *H5B_deserialize( const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5B_image_len(const void *thing, size_t *image_len); static herr_t H5B_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -72,9 +73,10 @@ const H5AC_class_t H5AC_BT[1] = {{ H5AC_BT_ID, "v1 B-tree", H5FD_MEM_BTREE, + H5AC__CLASS_NO_FLAGS_SET, H5B_get_load_size, H5B_deserialize, - NULL, + H5B_image_len, H5B_serialize, H5B_free_icr, }}; @@ -227,6 +229,42 @@ done: /*------------------------------------------------------------------------- + * Function: H5B_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5B_image_len(const void *_thing, size_t *image_len) +{ + H5B_t *bt = (H5B_t *)_thing; /* Pointer to the B-tree node */ + H5B_shared_t *shared; /* Pointer to shared B-tree info */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_image_len) + + /* Check arguments */ + HDassert(bt); + HDassert(image_len); + + /* Get shared info for B-tree */ + shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); + HDassert(shared); + + /* Set the image length size */ + *image_len = shared->sizeof_rnode; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5B_serialize * * Purpose: Serialize the data structure for writing to disk. @@ -90,6 +90,16 @@ /* + * Private macros. + */ +#if H5C_DO_MEMORY_SANITY_CHECKS +#define H5C_IMAGE_EXTRA_SPACE 8 +#define H5C_IMAGE_SANITY_VALUE "DeadBeef" +#else /* H5C_DO_MEMORY_SANITY_CHECKS */ +#define H5C_IMAGE_EXTRA_SPACE 0 +#endif /* H5C_DO_MEMORY_SANITY_CHECKS */ + +/* * Private file-scope variables. */ @@ -199,6 +209,7 @@ const H5C_class_t epoch_marker_class = /* id = */ H5C__EPOCH_MARKER_TYPE, /* name = */ "epoch marker", /* mem_type = */ H5FD_MEM_DEFAULT, /* value doesn't matter */ + /* flags = */ H5AC__CLASS_NO_FLAGS_SET, /* get_load_size = */ &H5C_epoch_marker_get_load_size, /* deserialize = */ &H5C_epoch_marker_deserialize, /* image_len = */ &H5C_epoch_marker_image_len, @@ -2008,7 +2019,6 @@ H5C_insert_entry(H5F_t * f, hid_t dxpl_id, const H5C_class_t * type, haddr_t addr, - size_t len, void * thing, unsigned int flags) { @@ -2072,9 +2082,10 @@ H5C_insert_entry(H5F_t * f, /* not protected, so can't be dirtied */ entry_ptr->dirtied = FALSE; - entry_ptr->size = len; - - HDassert( entry_ptr->size < H5C_MAX_ENTRY_SIZE ); + /* Retrieve the size of the thing */ + if((type->image_len)(thing, &(entry_ptr->size)) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, "Can't get size of thing") + HDassert(entry_ptr->size > 0 && entry_ptr->size < H5C_MAX_ENTRY_SIZE); entry_ptr->in_slist = FALSE; @@ -2582,7 +2593,6 @@ H5C_mark_entry_dirty(void *thing) HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC); if ( entry_ptr->is_protected ) { - HDassert( ! ((entry_ptr)->is_read_only) ); /* set the dirtied flag */ @@ -7141,11 +7151,9 @@ H5C_flush_single_entry(const H5F_t * f, } /* Clear the dirty flag only, if requested */ - if ( clear_only ) { + if(clear_only) entry_ptr->is_dirty = FALSE; - } - else if ( entry_ptr->is_dirty ) - { + else if(entry_ptr->is_dirty) { /* The entry is dirty, and we are doing either a flush, * or a flush destroy. In either case, serialize the * entry and write it to disk. @@ -7155,61 +7163,35 @@ H5C_flush_single_entry(const H5F_t * f, * will have to touch up the cache to account for the * change(s). */ - #if H5C_DO_SANITY_CHECKS - if ( ( cache_ptr->check_write_permitted == NULL ) && - ( ! (cache_ptr->write_permitted) ) ) { - - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "Write when writes are always forbidden!?!?!") - } + if((cache_ptr->check_write_permitted == NULL) && !(cache_ptr->write_permitted)) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "Write when writes are always forbidden!?!?!") #endif /* H5C_DO_SANITY_CHECKS */ - if ( entry_ptr->image_ptr == NULL ) - { - entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size); - - if ( entry_ptr->image_ptr == NULL ) - { - - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \ - "memory allocation failed for on disk image buffer.") - } - } - - if ( ! ( entry_ptr->image_up_to_date ) ) { - - if ( entry_ptr->type->serialize(f, - dxpl_id, - entry_ptr->addr, - entry_ptr->size, - entry_ptr->image_ptr, - (void *)entry_ptr, - &serialize_flags, - &new_addr, - &new_len, - &new_image_ptr) != SUCCEED ) - { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "unable to serialize entry") - } - - if ( serialize_flags != 0 ) - { - + if(NULL == entry_ptr->image_ptr) { + if(NULL == (entry_ptr->image_ptr = H5MM_malloc(entry_ptr->size + H5C_IMAGE_EXTRA_SPACE))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for on disk image buffer") +#if H5C_DO_MEMORY_SANITY_CHECKS + HDmemcpy(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); +#endif /* H5C_DO_MEMORY_SANITY_CHECKS */ + } /* end if */ + + if(!(entry_ptr->image_up_to_date)) { + if(entry_ptr->type->serialize(f, dxpl_id, entry_ptr->addr, + entry_ptr->size, entry_ptr->image_ptr, (void *)entry_ptr, + &serialize_flags, &new_addr, &new_len, &new_image_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to serialize entry") + + if(serialize_flags != 0) { /* Check for unexpected flags from serialize callback */ if(serialize_flags & ~(H5C__SERIALIZE_RESIZED_FLAG | H5C__SERIALIZE_MOVED_FLAG)) HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unknown serialize flag(s)") - if ( destroy ) - { - if ( cache_ptr->mdj_enabled ) { - - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "move/resize on destroy when journaling enabled.") - } + /* Check for move/resize when journaling is enabled */ + if(cache_ptr->mdj_enabled) + HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, "move/resize when journaling enabled") + if(destroy) { /* We have already removed the entry from the * cache's data structures, so no need to update * them for the re-size and/or move. All we need @@ -7221,38 +7203,20 @@ H5C_flush_single_entry(const H5F_t * f, * size of the disk image of the entry, it must * deallocate the old image, and allocate a new. */ - if(serialize_flags & H5C__SERIALIZE_RESIZED_FLAG) { H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, \ - entry_ptr, \ - new_len) - - /* Check for resize+move */ - if(serialize_flags & H5C__SERIALIZE_MOVED_FLAG) { - H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, \ - entry_ptr) - entry_ptr->addr = new_addr; - } /* end if */ - + entry_ptr, new_len) entry_ptr->size = new_len; entry_ptr->image_ptr = new_image_ptr; } /* end if */ - else { - HDassert(serialize_flags & H5C__SERIALIZE_MOVED_FLAG); - H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, \ - entry_ptr) + /* Check for move */ + if(serialize_flags & H5C__SERIALIZE_MOVED_FLAG) { + H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, entry_ptr) entry_ptr->addr = new_addr; - } /* end else */ - } - else - { - if ( cache_ptr->mdj_enabled ) { - - HGOTO_ERROR(H5E_CACHE, H5E_SYSTEM, FAIL, \ - "move/resize on flush when journaling enabled."); - } - + } /* end if */ + } /* end if */ + else { /* The entry is not being destroyed, and thus has not * been removed from the cache's data structures. * @@ -7260,13 +7224,9 @@ H5C_flush_single_entry(const H5F_t * f, * re-size and/or move, we must also update the * cache data structures. */ - if(serialize_flags & H5C__SERIALIZE_RESIZED_FLAG) { - - H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE( \ - cache_ptr, \ - entry_ptr, \ - new_len) + H5C__UPDATE_STATS_FOR_ENTRY_SIZE_CHANGE(cache_ptr, \ + entry_ptr, new_len) /* The replacement policy code thinks the * entry is already clean, so modify is_dirty @@ -7274,18 +7234,6 @@ H5C_flush_single_entry(const H5F_t * f, */ entry_ptr->is_dirty = FALSE; - /* Check for resize+move */ - if(serialize_flags & H5C__SERIALIZE_MOVED_FLAG) { - H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, \ - entry_ptr) - - /* update the hash table for the move */ - H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr) - entry_ptr->addr = new_addr; - H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, \ - FAIL) - } /* end if */ - /* update the hash table for the size change*/ H5C__UPDATE_INDEX_FOR_SIZE_CHANGE( \ (cache_ptr), \ @@ -7313,40 +7261,37 @@ H5C_flush_single_entry(const H5F_t * f, entry_ptr->size = new_len; entry_ptr->image_ptr = new_image_ptr; } /* end if */ - else { - HDassert(serialize_flags & H5C__SERIALIZE_MOVED_FLAG); + /* Check for move */ + if(serialize_flags & H5C__SERIALIZE_MOVED_FLAG) { /* The replacement policy code thinks the * entry is already clean, so modify is_dirty * to meet this expectation. */ entry_ptr->is_dirty = FALSE; - H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, \ - entry_ptr) + H5C__UPDATE_STATS_FOR_MOVE(cache_ptr, entry_ptr) /* first update the hash table for the move */ H5C__DELETE_FROM_INDEX(cache_ptr, entry_ptr) entry_ptr->addr = new_addr; - H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, \ - FAIL) + H5C__INSERT_IN_INDEX(cache_ptr, entry_ptr, FAIL) /* finally, set is_dirty to TRUE again */ entry_ptr->is_dirty = TRUE; - } /* end else */ - } - } + } /* end if */ + } /* end else */ + } /* end if */ +#if H5C_DO_MEMORY_SANITY_CHECKS + HDassert(0 == HDmemcmp(((uint8_t *)entry_ptr->image_ptr) + entry_ptr->size, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE)); +#endif /* H5C_DO_MEMORY_SANITY_CHECKS */ entry_ptr->image_up_to_date = TRUE; - } + } /* end if */ /* now write the image to disk */ - if ( H5F_block_write(f, type_ptr->mem_type, entry_ptr->addr, - entry_ptr->size, dxpl_id, - entry_ptr->image_ptr) < 0 ) - { - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, \ - "Can't write image to file.") - } + if(H5F_block_write(f, type_ptr->mem_type, entry_ptr->addr, + entry_ptr->size, dxpl_id, entry_ptr->image_ptr) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't write image to file.") #ifdef H5_HAVE_PARALLEL /* note that we initialized the serialize_flags to 0, so if @@ -7472,12 +7417,12 @@ H5C_load_entry(H5F_t * f, haddr_t addr, void * udata) { - hbool_t dirty = FALSE; /* Flag indicating whether thing was dirtied during deserialize */ - void * image_ptr = NULL; /* Buffer for disk image */ - void * thing = NULL; /* Pointer to thing loaded */ - H5C_cache_entry_t * entry_ptr; /* Alias for thing loaded, as cache entry */ - size_t len; /* Size of image in file */ - void * ret_value; /* Return value */ + hbool_t dirty = FALSE; /* Flag indicating whether thing was dirtied during deserialize */ + void * image = NULL; /* Buffer for disk image */ + void * thing = NULL; /* Pointer to thing loaded */ + H5C_cache_entry_t * entry; /* Alias for thing loaded, as cache entry */ + size_t len; /* Size of image in file */ + void * ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5C_load_entry) @@ -7494,10 +7439,7 @@ H5C_load_entry(H5F_t * f, HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "can't retrieve image size") /* Check for possible speculative read off the end of the file */ - /* (Assume speculative reads will only occur if an image_len callback is defined) */ - if ( type->image_len ) - { - + if(type->flags & H5C__CLASS_SPECULATIVE_LOAD_FLAG) { haddr_t eoa; /* End-of-allocation in the file */ haddr_t base_addr; /* Base address of file data */ @@ -7510,93 +7452,88 @@ H5C_load_entry(H5F_t * f, HDassert(H5F_addr_defined(base_addr)); /* Check for bad address in general */ - if ( (addr + base_addr) > eoa ) - { - - HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, \ - "address of object past end of allocation") - - } + if((addr + base_addr) > eoa) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "address of object past end of allocation") /* Check if the amount of data to read will be past the eoa */ - if ( ( addr + base_addr + len ) > eoa ) - { - + if((addr + base_addr + len) > eoa) /* Trim down the length of the metadata */ len = (size_t)(eoa - (addr + base_addr)); + } /* end if */ - } - } - - image_ptr = H5MM_malloc(len); - - if ( image_ptr == NULL ) { - - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, \ - "memory allocation failed for on disk image buffer.") - } - - if ( H5F_block_read(f, type->mem_type, addr, len, dxpl_id, image_ptr) < 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't read image*") - } - - thing = type->deserialize(image_ptr, len, udata, &dirty); + /* Allocate the buffer for reading the on-disk entry image */ + if(NULL == (image = H5MM_malloc(len + H5C_IMAGE_EXTRA_SPACE))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "memory allocation failed for on disk image buffer.") +#if H5C_DO_MEMORY_SANITY_CHECKS + HDmemcpy(((uint8_t *)image) + len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); +#endif /* H5C_DO_MEMORY_SANITY_CHECKS */ - if ( thing == NULL ) { + /* Get the on-disk entry image */ + if(H5F_block_read(f, type->mem_type, addr, len, dxpl_id, image) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_READERROR, NULL, "Can't read image*") + /* Deserialize the on-disk image into the native memory form */ + if(NULL == (thing = type->deserialize(image, len, udata, &dirty))) HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't deserialize image") - } /* If the client's cache has an image_len callback, check it */ - if ( type->image_len ) - { - size_t new_len; - - if ( type->image_len(thing, &new_len) != SUCCEED ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "image_len() failed.\n"); - - } else if ( new_len == 0 ) { - - HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "new_len == 0\n") - } - else if ( new_len != len) - { - image_ptr = H5MM_realloc(image_ptr, new_len); - - if ( image_ptr == NULL ) { - - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, \ - "image_ptr null after H5MM_realloc().") - } - - /* If the thing's image needs to be bigger, free the thing - * and retry with new length - */ - if(new_len > len) { - if(type->free_icr(thing) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "free_icr callback failed.") - - if(H5F_block_read(f, type->mem_type, addr, new_len, dxpl_id, image_ptr) < 0) - HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't read image") + if(type->image_len) { + size_t new_len; /* New size of on-disk image */ + + /* Get the actual image size for the thing */ + if(type->image_len(thing, &new_len) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "can't retrieve image length") + else if(new_len == 0) + HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, NULL, "image length is 0") + else if(new_len != len) { + /* Check for size changing on non-speculatively loaded, non-compressed thing */ + if(type->flags & ~(H5C__CLASS_SPECULATIVE_LOAD_FLAG | H5C__CLASS_COMPRESSED_FLAG)) + HGOTO_ERROR(H5E_CACHE, H5E_UNSUPPORTED, NULL, "size of non-speculative, non-compressed object changed") + else { + void *new_image; /* Buffer for disk image */ + + /* Allocate differently sized buffer */ + if(NULL == (new_image = H5MM_realloc(image, new_len + H5C_IMAGE_EXTRA_SPACE))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTALLOC, NULL, "image null after H5MM_realloc()") + image = new_image; +#if H5C_DO_MEMORY_SANITY_CHECKS + HDmemcpy(((uint8_t *)image) + new_len, H5C_IMAGE_SANITY_VALUE, H5C_IMAGE_EXTRA_SPACE); +#endif /* H5C_DO_MEMORY_SANITY_CHECKS */ + + /* If the thing's image needs to be bigger for a speculatively + * loaded thing, free the thing and retry with new length + */ + if((type->flags & H5C__CLASS_SPECULATIVE_LOAD_FLAG) && new_len > len) { + /* Release previous (possibly partially initialized) thing */ + if(type->free_icr(thing) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "free_icr callback failed") - thing = type->deserialize(image_ptr, new_len, udata, &dirty); + /* Go get the on-disk image again */ + if(H5F_block_read(f, type->mem_type, addr, new_len, dxpl_id, image) < 0) + HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't read image") - if ( thing == NULL ) { + /* Deserialize on-disk image into native memory form again */ + if(NULL == (thing = type->deserialize(image, new_len, udata, &dirty))) + HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, "Can't deserialize image") - HGOTO_ERROR(H5E_CACHE, H5E_CANTLOAD, NULL, \ - "Can't deserialize image") - } +#ifndef NDEBUG + { + size_t new_new_len; - } + /* Get the actual image size for the thing again */ + type->image_len(thing, &new_new_len); + HDassert(new_new_len == new_len); + } +#endif /* NDEBUG */ + } /* end else */ + } /* end if */ /* Retain adjusted size */ len = new_len; - } - } + } /* end if */ + } /* end if */ - entry_ptr = (H5C_cache_entry_t *)thing; + entry = (H5C_cache_entry_t *)thing; /* In general, an entry should be clean just after it is loaded. * @@ -7618,51 +7555,58 @@ H5C_load_entry(H5F_t * f, */ HDassert( ( dirty == FALSE ) || ( type->id == 5 || type->id == 6) ); - HDassert( entry_ptr->size < H5C_MAX_ENTRY_SIZE ); + HDassert( entry->size < H5C_MAX_ENTRY_SIZE ); #ifndef NDEBUG - entry_ptr->magic = H5C__H5C_CACHE_ENTRY_T_MAGIC; + entry->magic = H5C__H5C_CACHE_ENTRY_T_MAGIC; #endif /* NDEBUG */ - entry_ptr->cache_ptr = f->shared->cache; - entry_ptr->addr = addr; - entry_ptr->size = len; - entry_ptr->image_ptr = image_ptr; - entry_ptr->image_up_to_date = TRUE; - entry_ptr->type = type; - entry_ptr->is_dirty = dirty; - entry_ptr->dirtied = FALSE; - entry_ptr->is_protected = FALSE; - entry_ptr->is_read_only = FALSE; - entry_ptr->ro_ref_count = 0; - entry_ptr->is_pinned = FALSE; - entry_ptr->in_slist = FALSE; - entry_ptr->flush_marker = FALSE; + entry->cache_ptr = f->shared->cache; + entry->addr = addr; + entry->size = len; + entry->image_ptr = image; + entry->image_up_to_date = TRUE; + entry->type = type; + entry->is_dirty = dirty; + entry->dirtied = FALSE; + entry->is_protected = FALSE; + entry->is_read_only = FALSE; + entry->ro_ref_count = 0; + entry->is_pinned = FALSE; + entry->in_slist = FALSE; + entry->flush_marker = FALSE; #ifdef H5_HAVE_PARALLEL - entry_ptr->clear_on_unprotect = FALSE; + entry->clear_on_unprotect = FALSE; #endif /* H5_HAVE_PARALLEL */ - entry_ptr->flush_in_progress = FALSE; - entry_ptr->destroy_in_progress = FALSE; + entry->flush_in_progress = FALSE; + entry->destroy_in_progress = FALSE; - entry_ptr->ht_next = NULL; - entry_ptr->ht_prev = NULL; + entry->ht_next = NULL; + entry->ht_prev = NULL; - entry_ptr->next = NULL; - entry_ptr->prev = NULL; + entry->next = NULL; + entry->prev = NULL; - entry_ptr->aux_next = NULL; - entry_ptr->aux_prev = NULL; + entry->aux_next = NULL; + entry->aux_prev = NULL; - entry_ptr->last_trans = 0; - entry_ptr->trans_next = NULL; - entry_ptr->trans_prev = NULL; + entry->last_trans = 0; + entry->trans_next = NULL; + entry->trans_prev = NULL; - H5C__RESET_CACHE_ENTRY_STATS(entry_ptr); + H5C__RESET_CACHE_ENTRY_STATS(entry); ret_value = thing; done: + /* Cleanup on error */ + if(NULL == ret_value) { + /* Release resources */ + if(thing && type->free_icr(thing) < 0) + HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, NULL, "free_icr callback failed") + if(image) + image = H5MM_xfree(image); + } /* end if */ FUNC_LEAVE_NOAPI(ret_value) - } /* H5C_load_entry() */ diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h index 6f53c4f..0f7d4fd 100644 --- a/src/H5Cprivate.h +++ b/src/H5Cprivate.h @@ -39,6 +39,15 @@ #define H5C_DO_SANITY_CHECKS 1 #define H5C_DO_EXTREME_SANITY_CHECKS 0 +/* 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 + * direct block serialize callback calls H5Z_pipeline(). When the I/O + * filters are changed, then we should implement "cache image alloc/free" + * routines that the fractal heap direct block (and global heap) serialize + * calls can use when resizing (and re-allocating) their image in the + * cache. -QAK */ +#define H5C_DO_MEMORY_SANITY_CHECKS 0 /* This sanity checking constant was picked out of the air. Increase * or decrease it if appropriate. Its purposes is to detect corrupt @@ -110,6 +119,8 @@ typedef struct H5C_t H5C_t; * mem_type: Instance of H5FD_mem_t, that is used to supply the * mem type passed into H5F_block_read(). * + * flags: Flags indicating class-specific behavior. + * * get_load_size: Pointer to the 'get load size' function. * * This function must be able to determing the size of a disk image for @@ -432,10 +443,15 @@ typedef herr_t (*H5C_serialize_func_t)(const H5F_t *f, typedef herr_t (*H5C_free_icr_func_t)(void *thing); +#define H5C__CLASS_NO_FLAGS_SET 0x0 +#define H5C__CLASS_SPECULATIVE_LOAD_FLAG 0x1 +#define H5C__CLASS_COMPRESSED_FLAG 0x2 + typedef struct H5C_class_t { int id; const char * name; H5FD_mem_t mem_type; + unsigned flags; H5C_get_load_size_func_t get_load_size; H5C_deserialize_func_t deserialize; H5C_image_len_func_t image_len; @@ -1422,7 +1438,6 @@ H5_DLL herr_t H5C_insert_entry(H5F_t * f, hid_t dxpl_id, const H5C_class_t * type, haddr_t addr, - size_t len, void * thing, unsigned int flags); @@ -875,7 +875,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get byte number for object size") if(H5P_get(plist, H5F_CRT_BTREE_RANK_NAME, &f->shared->btree_k[0]) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to get rank for btree internal nodes") - if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes)<0) + if(H5P_get(plist, H5F_CRT_SHMSG_NINDEXES_NAME, &f->shared->sohm_nindexes) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get number of SOHM indexes") HDassert(f->shared->sohm_nindexes < 255); @@ -2136,14 +2136,14 @@ H5FD_write(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, size_t si { size_t new_size; /* New size of the accumulator buffer */ size_t old_offset; /* Offset of old data within the accumulator buffer */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5FD_write, FAIL) - assert(file && file->cls); - assert(H5I_GENPROP_LST==H5I_get_type(dxpl_id)); - assert(TRUE==H5P_isa_class(dxpl_id,H5P_DATASET_XFER)); - assert(buf); + HDassert(file && file->cls); + HDassert(H5I_GENPROP_LST == H5I_get_type(dxpl_id)); + HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER)); + HDassert(buf); #ifndef H5_HAVE_PARALLEL /* Do not return early for Parallel mode since the I/O could be a */ diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index 89068c0..ea92649 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -89,13 +89,6 @@ typedef enum H5FD_mem_t { #define H5FD_MEM_SOHM_TABLE H5FD_MEM_OHDR #define H5FD_MEM_SOHM_INDEX H5FD_MEM_BTREE -/* Per discussion with Quincey, I'm mapping the metadata journaling - * configuration block to super. - * - * JRM -- 3/20/08 - */ -#define H5FD_MEM_MDJCONFIG H5FD_MEM_SUPER - /* * A free-list map which maps all types of allocation requests to a single * free list. This is useful for drivers that don't really care about @@ -120,11 +120,11 @@ HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, ncl /* * Allocate free space structure */ - if(NULL == (fspace = H5FS_new(nclasses, classes, cls_init_udata))) + if(NULL == (fspace = H5FS_new(f, nclasses, classes, cls_init_udata))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for free space free list") /* Allocate space for the free space header */ - if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)H5FS_HEADER_SIZE(f)))) + if(HADDR_UNDEF == (fspace->addr = H5MF_alloc(f, H5FD_MEM_FSPACE_HDR, dxpl_id, (hsize_t)fspace->hdr_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for free space header") *fs_addr = fspace->addr; @@ -136,7 +136,7 @@ HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, ncl fspace->max_sect_size = fs_create->max_sect_size; /* Cache the new free space header (pinned) */ - if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, H5FS_HEADER_SIZE(f), fspace, H5AC__PIN_ENTRY_FLAG) < 0) + if(H5AC_set(f, dxpl_id, H5AC_FSPACE_HDR, fspace->addr, fspace, H5AC__PIN_ENTRY_FLAG) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space header to cache") /* Set the return value */ @@ -309,7 +309,7 @@ HDfprintf(stderr, "%s: Done expunging free space section info from cache\n", FUN } /* end if */ /* Release header's disk space */ - if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, fs_addr, (hsize_t)H5FS_HEADER_SIZE(f))<0) + if(H5MF_xfree(f, H5FD_MEM_FSPACE_HDR, dxpl_id, fs_addr, (hsize_t)fspace->hdr_size) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to release free space header") /* Release the free space header */ @@ -431,7 +431,7 @@ done: *------------------------------------------------------------------------- */ H5FS_t * -H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[], +H5FS_new(const H5F_t *f, size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata) { H5FS_t *fspace; /* Free space manager */ @@ -472,6 +472,7 @@ H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[], /* Initialize non-zero information for new free space manager */ fspace->addr = HADDR_UNDEF; + fspace->hdr_size = H5FS_HEADER_SIZE(f); fspace->sect_addr = HADDR_UNDEF; /* Set return value */ @@ -508,7 +509,7 @@ H5FS_size(const H5F_t *f, const H5FS_t *fspace, hsize_t *meta_size) HDassert(meta_size); /* Get the free space size info */ - *meta_size += H5FS_HEADER_SIZE(f) + fspace->alloc_sect_size; + *meta_size += fspace->hdr_size + fspace->alloc_sect_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FS_size() */ diff --git a/src/H5FScache.c b/src/H5FScache.c index 8d3ae88..68addce 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -78,6 +78,7 @@ static herr_t H5FS_sinfo_serialize_node_cb(void *_item, void UNUSED *key, void * static herr_t H5FS_cache_hdr_get_load_size(const void *udata, size_t *image_len); static void *H5FS_cache_hdr_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5FS_cache_hdr_image_len(const void *thing, size_t *image_len); static herr_t H5FS_cache_hdr_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -86,6 +87,7 @@ static herr_t H5FS_cache_hdr_free_icr(void *thing); static herr_t H5FS_cache_sinfo_get_load_size(const void *udata, size_t *image_len); static void *H5FS_cache_sinfo_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5FS_cache_sinfo_image_len(const void *thing, size_t *image_len); static herr_t H5FS_cache_sinfo_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -101,9 +103,10 @@ const H5AC_class_t H5AC_FSPACE_HDR[1] = {{ H5AC_FSPACE_HDR_ID, "Free space header", H5FD_MEM_FSPACE_HDR, + H5AC__CLASS_NO_FLAGS_SET, H5FS_cache_hdr_get_load_size, H5FS_cache_hdr_deserialize, - NULL, + H5FS_cache_hdr_image_len, H5FS_cache_hdr_serialize, H5FS_cache_hdr_free_icr, }}; @@ -113,9 +116,10 @@ const H5AC_class_t H5AC_FSPACE_SINFO[1] = {{ H5AC_FSPACE_SINFO_ID, "Free space section info", H5FD_MEM_FSPACE_SINFO, + H5AC__CLASS_NO_FLAGS_SET, H5FS_cache_sinfo_get_load_size, H5FS_cache_sinfo_deserialize, - NULL, + H5FS_cache_sinfo_image_len, H5FS_cache_sinfo_serialize, H5FS_cache_sinfo_free_icr, }}; @@ -183,7 +187,6 @@ H5FS_cache_hdr_deserialize(const void *image, size_t UNUSED len, { H5FS_t *fspace = NULL; /* Free space header info */ H5FS_hdr_cache_ud_t *udata = (H5FS_hdr_cache_ud_t *)_udata; /* user data for callback */ - size_t size; /* Header size */ const uint8_t *p; /* Pointer into raw data buffer */ uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ @@ -197,15 +200,12 @@ H5FS_cache_hdr_deserialize(const void *image, size_t UNUSED len, HDassert(udata); /* Allocate a new free space manager */ - if(NULL == (fspace = H5FS_new(udata->fs_prot->nclasses, udata->fs_prot->classes, udata->fs_prot->cls_init_udata))) + if(NULL == (fspace = H5FS_new(udata->f, udata->fs_prot->nclasses, udata->fs_prot->classes, udata->fs_prot->cls_init_udata))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* Set free space manager's internal information */ fspace->addr = udata->addr; - /* Compute the size of the free space header on disk */ - size = H5FS_HEADER_SIZE(udata->f); - p = (const uint8_t *)image; /* Magic number */ @@ -288,6 +288,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5FS_cache_hdr_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FS_cache_hdr_image_len(const void *_thing, size_t *image_len) +{ + H5FS_t *fspace = (H5FS_t *)_thing; /* Pointer to free space header */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cache_hdr_image_len) + + /* Check arguments */ + HDassert(fspace); + HDassert(image_len); + + /* Set the image length size */ + *image_len = fspace->hdr_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FS_cache_hdr_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5FS_cache_hdr_serialize * * Purpose: Serializes the data structure for writing to disk. @@ -309,7 +340,6 @@ H5FS_cache_hdr_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, H5FS_t *fspace = (H5FS_t *)_thing; /* Pointer to free space header */ uint8_t *p; /* Pointer into raw data buffer */ uint32_t metadata_chksum; /* Computed metadata checksum value */ - size_t size; /* Header size on disk */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cache_hdr_serialize) @@ -319,9 +349,6 @@ H5FS_cache_hdr_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, HDassert(fspace); HDassert(flags); - /* Compute the size of the free space header on disk */ - size = H5FS_HEADER_SIZE(f); - /* Get temporary pointer to header */ p = (uint8_t *)image; @@ -713,6 +740,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5FS_cache_sinfo_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FS_cache_sinfo_image_len(const void *_thing, size_t *image_len) +{ + H5FS_sinfo_t *sinfo = (H5FS_sinfo_t *)_thing; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cache_sinfo_image_len) + + /* Check arguments */ + HDassert(sinfo); + HDassert(image_len); + + /* Set the image length size */ + *image_len = sinfo->fspace->alloc_sect_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FS_cache_sinfo_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5FS_cache_sinfo_serialize * * Purpose: Serialize the data structure for writing to disk. @@ -730,12 +788,12 @@ H5FS_cache_sinfo_serialize(const H5F_t * f, hid_t UNUSED dxpl_id, haddr_t UNUSED size_t UNUSED len, void *image, void *_thing, unsigned *flags, haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image) { - H5FS_sinfo_t * sinfo = (H5FS_sinfo_t *)_thing; + H5FS_sinfo_t *sinfo = (H5FS_sinfo_t *)_thing; /* Pointer to section info */ H5FS_iter_ud_t udata; /* User data for callbacks */ uint8_t *p; /* Pointer into raw data buffer */ uint32_t metadata_chksum; /* Computed metadata checksum value */ unsigned bin; /* Current bin we are on */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_serialize) @@ -751,8 +809,7 @@ H5FS_cache_sinfo_serialize(const H5F_t * f, hid_t UNUSED dxpl_id, haddr_t UNUSED if(H5F_addr_ne(addr, sinfo->fspace->sect_addr)) HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, FAIL, "incorrect address for free space sections") - /* Allocate temporary buffer */ - + /* Point to disk image buffer */ p = (uint8_t *)image; /* Magic number */ diff --git a/src/H5FSpkg.h b/src/H5FSpkg.h index a88958f..c87a9b8 100644 --- a/src/H5FSpkg.h +++ b/src/H5FSpkg.h @@ -181,6 +181,7 @@ struct H5FS_t { /* Computed/cached values */ haddr_t addr; /* Address of free space header on disk */ + size_t hdr_size; /* Size of free space header on disk */ H5FS_sinfo_t *sinfo; /* Section information */ /* Memory data structures (not stored directly) */ @@ -216,8 +217,8 @@ H5FL_EXTERN(H5FS_t); /******************************/ /* Free space manager header routines */ -H5_DLL H5FS_t *H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[], - void *cls_init_udata); +H5_DLL H5FS_t *H5FS_new(const H5F_t *f, size_t nclasses, + const H5FS_section_class_t *classes[], void *cls_init_udata); /* Free space section routines */ H5_DLL H5FS_sinfo_t *H5FS_sinfo_new(H5F_t *f, H5FS_t *fspace); diff --git a/src/H5FSsection.c b/src/H5FSsection.c index d370478..49a9bc1 100644 --- a/src/H5FSsection.c +++ b/src/H5FSsection.c @@ -222,7 +222,7 @@ HDfprintf(stderr, "%s: New section info, addr = %a, size = %Hu\n", FUNC, fspace- #endif /* QAK */ /* Cache the new free space section info (pinned) */ - if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, (size_t)fspace->alloc_sect_size, sinfo, H5AC__PIN_ENTRY_FLAG) < 0) + if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, sinfo, H5AC__PIN_ENTRY_FLAG) < 0) HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't add free space sections to cache") /* Mark free space header as dirty */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 67d3dff..6cbb9f6 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -59,25 +59,35 @@ typedef struct H5G_node_key_t { * table or group. */ typedef struct H5G_node_t { - H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ + H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ - unsigned nsyms; /*number of symbols */ - H5G_entry_t *entry; /*array of symbol table entries */ + size_t node_size; /* Size of node on disk */ + unsigned nsyms; /* Number of symbols */ + H5G_entry_t *entry; /* Array of symbol table entries */ } H5G_node_t; /* Private macros */ #define H5G_NODE_VERS 1 /*symbol table node version number */ -#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4) +/* Size of a symbol table node on disk */ +#define H5G_NODE_SIZE(f) ( \ + /* General metadata fields */ \ + H5G_NODE_SIZEOF_MAGIC \ + + 1 /* Version */ \ + + 1 /* Reserved */ \ + + 2 /* Number of symbols */ \ + \ + /* Entries */ \ + + ((2 * H5F_SYM_LEAF_K(f)) * H5G_SIZEOF_ENTRY(f)) \ + ) -/* PRIVATE PROTOTYPES */ -static size_t H5G_node_size_real(const H5F_t *f); /* Metadata cache callbacks */ static herr_t H5G_node_get_load_size(const void *udata, size_t *image_len); static void *H5G_node_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5G_node_image_len(const void *thing, size_t *image_len); static herr_t H5G_node_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -110,9 +120,10 @@ const H5AC_class_t H5AC_SNODE[1] = {{ H5AC_SNODE_ID, "symbol table node", H5FD_MEM_BTREE, + H5AC__CLASS_NO_FLAGS_SET, H5G_node_get_load_size, H5G_node_deserialize, - NULL, + H5G_node_image_len, H5G_node_serialize, H5G_node_free_icr, }}; @@ -273,31 +284,6 @@ H5G_node_debug_key(FILE *stream, int indent, int fwidth, const void *_key, /*------------------------------------------------------------------------- - * Function: H5G_node_size_real - * - * Purpose: Returns the total size of a symbol table node. - * - * Return: Success: Total size of the node in bytes. - * - * Failure: Never fails. - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 - * - *------------------------------------------------------------------------- - */ -static size_t -H5G_node_size_real(const H5F_t *f) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_size_real); - - FUNC_LEAVE_NOAPI(H5G_NODE_SIZEOF_HDR(f) + - (2 * H5F_SYM_LEAF_K(f)) * H5G_SIZEOF_ENTRY(f)); -} /* end H5G_node_size_real() */ - - -/*------------------------------------------------------------------------- * Function: H5G_node_free * * Purpose: Destroy a symbol table node in memory. @@ -356,7 +342,7 @@ H5G_node_get_load_size(const void *_udata, size_t *image_len) HDassert(image_len); /* Set the image length size */ - *image_len = H5G_node_size_real(f); + *image_len = H5G_NODE_SIZE(f); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5G_node_get_load_size() */ @@ -409,6 +395,7 @@ H5G_node_deserialize(const void *image, size_t UNUSED len, void *udata, /* Allocate symbol table data structures */ if(NULL == (sym = H5FL_CALLOC(H5G_node_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + sym->node_size = H5G_NODE_SIZE(f); if(NULL == (sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f))))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") @@ -435,6 +422,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_node_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_node_image_len(const void *_thing, size_t *image_len) +{ + H5G_node_t *sym = (H5G_node_t *)_thing; /* Pointer to the Symbol Table node */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_image_len) + + /* Check arguments */ + HDassert(sym); + HDassert(image_len); + + /* Set the image length size */ + *image_len = sym->node_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5G_node_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5G_node_serialize * * Purpose: Serialize the data structure for writing to disk. @@ -454,7 +472,6 @@ H5G_node_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, haddr_t UNUSED *new_addr, size_t UNUSED *new_len, void UNUSED **new_image) { H5G_node_t *sym = (H5G_node_t *)_thing; /* Pointer to the Symbol Table node */ - size_t size; /* Size of symbol table node in file */ uint8_t *p; /* Pointer into image buffer */ herr_t ret_value = SUCCEED; /* Return value */ @@ -481,14 +498,10 @@ H5G_node_serialize(const H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, /* number of symbols */ UINT16ENCODE(p, sym->nsyms); - /* Compute the size of the serialized symbol table node on disk */ - size = H5G_node_size_real(f); - HDassert(size); - /* entries */ if(H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't serialize") - HDmemset(p, 0, size - (size_t)(p - (uint8_t *)image)); + HDmemset(p, 0, sym->node_size - (size_t)(p - (uint8_t *)image)); /* Reset the cache flags for this operation (metadata not resized or renamed) */ *flags = 0; @@ -560,7 +573,6 @@ H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t UNUSED op, void *_lt_key, H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; H5G_node_t *sym = NULL; - hsize_t size = 0; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_node_create) @@ -573,15 +585,13 @@ H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t UNUSED op, void *_lt_key, if(NULL == (sym = H5FL_CALLOC(H5G_node_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - size = H5G_node_size_real(f); - HDassert(size); - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, size))) + sym->node_size = H5G_NODE_SIZE(f); + if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, sym->node_size))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space") if(NULL == ( sym->entry = H5FL_SEQ_CALLOC(H5G_entry_t, (size_t)(2 * H5F_SYM_LEAF_K(f))))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - H5_CHECK_OVERFLOW(size, /* vartype */hsize_t, /* casttype */size_t); - if(H5AC_set(f, dxpl_id, H5AC_SNODE, *addr_p, (size_t)size, sym, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_SNODE, *addr_p, sym, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to cache symbol table leaf node") /* * The left and right symbols in an empty tree are both the @@ -1126,7 +1136,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, *rt_key = *lt_key; *rt_key_changed = TRUE; sn->nsyms = 0; - if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size_real(f)) < 0 + if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)sn->node_size) < 0 || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG) < 0) { sn = NULL; HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node") @@ -1198,7 +1208,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/, *rt_key = *lt_key; *rt_key_changed = TRUE; sn->nsyms = 0; - if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size_real(f)) < 0 + if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)sn->node_size) < 0 || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG) < 0) { sn = NULL; HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node") @@ -1686,7 +1696,7 @@ done: /*------------------------------------------------------------------------- * Function: H5G_node_iterate_size * - * Purpose: This function gets called by H5B_iterate_btree_size() + * Purpose: This function gets called by H5B_iterate_helper() * to gather storage info for SNODs. * * Return: Non-negative on success/Negative on failure @@ -1708,10 +1718,10 @@ H5G_node_iterate_size(H5F_t *f, hid_t UNUSED dxpl_id, const void UNUSED *_lt_key HDassert(f); HDassert(stab_size); - *stab_size += H5G_node_size_real(f); + *stab_size += H5G_NODE_SIZE(f); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5G_btree_node_iterate() */ +} /* end H5G_node_iterate_size() */ /*------------------------------------------------------------------------- @@ -1771,7 +1781,7 @@ H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, "Dirty:", sn->cache_info.is_dirty ? "Yes" : "No"); fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Size of Node (in bytes):", (unsigned)H5G_node_size_real(f)); + "Size of Node (in bytes):", (unsigned)sn->node_size); fprintf(stream, "%*s%-*s %u of %u\n", indent, "", fwidth, "Number of Symbols:", sn->nsyms, (unsigned)(2 * H5F_SYM_LEAF_K(f))); diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 548c37f..a9a371b 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -83,6 +83,7 @@ static herr_t H5HF_cache_hdr_free_icr(void *thing); static herr_t H5HF_cache_iblock_get_load_size(const void *udata, size_t *image_len); static void *H5HF_cache_iblock_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5HF_cache_iblock_image_len(const void *thing, size_t *image_len_ptr); static herr_t H5HF_cache_iblock_serialize(const H5F_t * f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *_thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -91,6 +92,7 @@ static herr_t H5HF_cache_iblock_free_icr(void *thing); static herr_t H5HF_cache_dblock_get_load_size(const void *udata, size_t *image_len); static void *H5HF_cache_dblock_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5HF_cache_dblock_image_len(const void *thing, size_t *image_len_ptr); static herr_t H5HF_cache_dblock_serialize(const H5F_t * f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *_thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -106,6 +108,7 @@ const H5AC_class_t H5AC_FHEAP_HDR[1] = {{ H5AC_FHEAP_HDR_ID, "fractal heap header", H5FD_MEM_FHEAP_HDR, + H5AC__CLASS_SPECULATIVE_LOAD_FLAG, H5HF_cache_hdr_get_load_size, H5HF_cache_hdr_deserialize, H5HF_cache_hdr_image_len, @@ -118,9 +121,10 @@ const H5AC_class_t H5AC_FHEAP_IBLOCK[1] = {{ H5AC_FHEAP_IBLOCK_ID, "fractal heap indirect block", H5FD_MEM_FHEAP_IBLOCK, + H5AC__CLASS_NO_FLAGS_SET, H5HF_cache_iblock_get_load_size, H5HF_cache_iblock_deserialize, - NULL, + H5HF_cache_iblock_image_len, H5HF_cache_iblock_serialize, H5HF_cache_iblock_free_icr, }}; @@ -128,11 +132,12 @@ const H5AC_class_t H5AC_FHEAP_IBLOCK[1] = {{ /* H5HF direct block inherits cache-like properties from H5AC */ const H5AC_class_t H5AC_FHEAP_DBLOCK[1] = {{ H5AC_FHEAP_DBLOCK_ID, - "fractal head direct block", + "fractal heap direct block", H5FD_MEM_FHEAP_DBLOCK, + H5AC__CLASS_COMPRESSED_FLAG, H5HF_cache_dblock_get_load_size, H5HF_cache_dblock_deserialize, - NULL, + H5HF_cache_dblock_image_len, H5HF_cache_dblock_serialize, H5HF_cache_dblock_free_icr, }}; @@ -471,7 +476,7 @@ H5HF_cache_hdr_image_len(const void *thing, size_t *image_len_ptr) HDassert(image_len_ptr); /* Report the fractal heap header's prefix + I/O filter length */ - *image_len_ptr = H5HF_HEADER_SIZE(hdr) + hdr->filter_len; + *image_len_ptr = hdr->heap_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_cache_hdr_image_len() */ @@ -659,7 +664,7 @@ H5HF_cache_iblock_get_load_size(const void *_udata, size_t *image_len) HDassert(image_len); /* Set the image length size */ - *image_len = H5HF_IBLOCK_SIZE(udata->par_info->hdr, *udata->nrows); + *image_len = H5HF_MAN_INDIRECT_SIZE(udata->par_info->hdr, *udata->nrows); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_cache_iblock_get_load_size() */ @@ -721,7 +726,7 @@ H5HF_cache_iblock_deserialize(const void *image, size_t UNUSED len, iblock->nchildren = 0; /* Compute size of indirect block */ - iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock->nrows); /* Get temporary pointer to serialized indirect block */ p = (const uint8_t *)image; @@ -855,6 +860,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_cache_iblock_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_cache_iblock_image_len(const void *_thing, size_t *image_len) +{ + H5HF_indirect_t *iblock = (H5HF_indirect_t *)_thing; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_image_len) + + /* Check arguments */ + HDassert(iblock); + HDassert(image_len); + + /* Set the image length size */ + *image_len = iblock->size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_cache_iblock_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_cache_iblock_serialize * * Purpose: Flushes a dirty fractal heap indirect block to disk. @@ -1217,6 +1253,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_cache_dblock_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_cache_dblock_image_len(const void *_thing, size_t *image_len) +{ + H5HF_direct_t *dblock = (H5HF_direct_t *)_thing; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_dblock_image_len) + + /* Check arguments */ + HDassert(dblock); + HDassert(image_len); + + /* Set the image length size */ + *image_len = dblock->size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_cache_dblock_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_cache_dblock_serialize * * Purpose: Construct the on disk image of the target direct block @@ -1236,7 +1303,7 @@ H5HF_cache_dblock_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *new_len, void **new_image) { H5HF_hdr_t *hdr; /* Shared fractal heap information */ - H5HF_direct_t *dblock; + H5HF_direct_t *dblock = (H5HF_direct_t *)_thing; void * write_buf; /* Pointer to buffer to write out */ size_t write_size; /* Size of buffer to write out */ uint8_t * p; /* Pointer into raw data buffer */ @@ -1252,9 +1319,7 @@ H5HF_cache_dblock_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, HDassert(H5F_addr_defined(addr)); HDassert(len > 0); HDassert(image); - HDassert(_thing); - - dblock = (H5HF_direct_t *)_thing; + HDassert(dblock); HDassert(dblock->cache_info.is_dirty); HDassert(flags); diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c index 1c470b5..78af693 100644 --- a/src/H5HFdblock.c +++ b/src/H5HFdblock.c @@ -175,7 +175,7 @@ HDmemset(dblock->blk, 0, dblock->size); } /* end else */ /* Cache the new fractal heap direct block */ - if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock->size, dblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap direct block to cache") /* Increase the allocated heap size */ diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index 3370ae0..3189478 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -490,7 +490,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for fractal heap header") /* Cache the new fractal heap header */ - if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, (size_t)hdr->heap_size, hdr, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache") /* Set address of heap header to return */ diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 4d6d585..71c2573 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -551,7 +551,7 @@ H5HF_man_iblock_root_double(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si /* Compute size of buffer needed for new indirect block */ iblock->nrows = new_nrows; - iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock->nrows); /* Allocate space for the new indirect block on disk */ if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) @@ -710,7 +710,7 @@ H5HF_man_iblock_root_halve(H5HF_indirect_t *iblock, hid_t dxpl_id) /* Compute size of buffer needed for new indirect block */ old_nrows = iblock->nrows; iblock->nrows = new_nrows; - iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock->nrows); /* Allocate space for the new indirect block on disk */ if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) @@ -968,7 +968,7 @@ H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *par_iblo iblock->max_rows = max_rows; /* Compute size of buffer needed for indirect block */ - iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock->nrows); /* Allocate child block entry array */ if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) @@ -1033,7 +1033,7 @@ H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *par_iblo iblock->max_child = 0; /* Cache the new indirect block */ - if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, (size_t)iblock->size, iblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, iblock, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap indirect block to cache") done: diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index c7cbddc..c741ed0 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -178,7 +178,7 @@ ) /* Size of managed indirect block */ -#define H5HF_IBLOCK_SIZE(h, r) ( \ +#define H5HF_MAN_INDIRECT_SIZE(h, r) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE(TRUE) \ \ @@ -189,19 +189,6 @@ + (((r > (h)->man_dtable.max_direct_rows) ? (r - (h)->man_dtable.max_direct_rows) : 0) * (h)->man_dtable.cparam.width * (h)->sizeof_addr) /* Size of entries for indirect blocks */ \ ) -/* Size of managed indirect block */ -#define H5HF_MAN_INDIRECT_SIZE(h, i) ( \ - /* General metadata fields */ \ - H5HF_METADATA_PREFIX_SIZE(TRUE) \ - \ - /* Fractal heap managed, absolutely mapped indirect block specific fields */ \ - + (h)->sizeof_addr /* File address of heap owning the block */ \ - + (h)->heap_off_size /* Offset of the block in the heap */ \ - + (MIN((i)->nrows, (h)->man_dtable.max_direct_rows) * (h)->man_dtable.cparam.width * H5HF_MAN_INDIRECT_CHILD_DIR_ENTRY_SIZE(h)) /* Size of entries for direct blocks */ \ - + ((((i)->nrows > (h)->man_dtable.max_direct_rows) ? ((i)->nrows - (h)->man_dtable.max_direct_rows) : 0) * (h)->man_dtable.cparam.width * (h)->sizeof_addr) /* Size of entries for indirect blocks */ \ - ) - - /* Compute the # of bytes required to store an offset into a given buffer size */ #define H5HF_SIZEOF_OFFSET_BITS(b) (((b) + 7) / 8) #define H5HF_SIZEOF_OFFSET_LEN(l) H5HF_SIZEOF_OFFSET_BITS(H5V_log2_of2((unsigned)(l))) @@ -140,7 +140,7 @@ H5FL_BLK_DEFINE(gheap_chunk); *------------------------------------------------------------------------- */ static haddr_t -H5HG_create (H5F_t *f, hid_t dxpl_id, size_t size) +H5HG_create(H5F_t *f, hid_t dxpl_id, size_t size) { H5HG_heap_t *heap = NULL; uint8_t *p = NULL; @@ -227,7 +227,7 @@ HDmemset(heap->chunk, 0, size); } /* end else */ /* Add the heap to the cache */ - if(H5AC_set(f, dxpl_id, H5AC_GHEAP, addr, (size_t)size, heap, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_GHEAP, addr, heap, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "unable to cache global heap collection") ret_value = addr; diff --git a/src/H5HGcache.c b/src/H5HGcache.c index e92a712..0b146eb 100755 --- a/src/H5HGcache.c +++ b/src/H5HGcache.c @@ -85,6 +85,7 @@ const H5AC_class_t H5AC_GHEAP[1] = {{ H5AC_GHEAP_ID, "global heap", H5FD_MEM_GHEAP, + H5AC__CLASS_SPECULATIVE_LOAD_FLAG, H5HG_get_load_size, H5HG_deserialize, H5HG_image_len, @@ -320,6 +321,38 @@ done: /*------------------------------------------------------------------------- + * Function: H5HG_image_len + * + * Purpose: Tell the metadata cache about the actual size + * of the global heap + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 28, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HG_image_len(const void *thing, size_t *image_len_ptr) +{ + const H5HG_heap_t *heap = (const H5HG_heap_t *)thing; /* Global heap */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_image_len) + + /* Check arguments */ + HDassert(heap); + HDassert(image_len_ptr); + + /* Report the global heap's total size */ + *image_len_ptr = heap->size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HG_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5HG_serialize * * Purpose: Serialize the data structure for writing to disk. @@ -379,38 +412,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5HG_image_len - * - * Purpose: Tell the metadata cache about the actual size - * of the global heap - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Mike McGreevy - * mcgreevy@hdfgroup.org - * July 28, 2008 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HG_image_len(const void *thing, size_t *image_len_ptr) -{ - const H5HG_heap_t *heap = (const H5HG_heap_t *)thing; /* Global heap */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HG_image_len) - - /* Check arguments */ - HDassert(heap); - HDassert(image_len_ptr); - - /* Report the global heap's total size */ - *image_len_ptr = heap->size; - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HG_image_len() */ - - -/*------------------------------------------------------------------------- * Function: H5HG_free_icr * * Purpose: Destroy/release an "in core representation" of a data structure @@ -163,7 +163,7 @@ H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "memory allocation failed") /* Add to cache */ - if(H5AC_set(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, (size_t)total_size, prfx, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_LHEAP_PRFX, heap->prfx_addr, prfx, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to cache local heap prefix") /* Set address to return */ @@ -210,6 +210,7 @@ H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) H5HL_dblk_t *dblk; /* Local heap data block */ haddr_t old_addr; /* Old location of heap data block */ haddr_t new_addr; /* New location of heap data block */ + size_t old_heap_size; /* Old size of heap data block */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HL_dblk_realloc) @@ -220,8 +221,9 @@ H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) /* Release old space on disk */ old_addr = heap->dblk_addr; - H5_CHECK_OVERFLOW(heap->dblk_size, size_t, hsize_t); - if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->dblk_size) < 0) + old_heap_size = heap->dblk_size; + H5_CHECK_OVERFLOW(old_heap_size, size_t, hsize_t); + if(H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)old_heap_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't release old heap data?") /* Allocate new space on disk */ @@ -229,12 +231,16 @@ H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) if(HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_size))) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "unable to allocate file space for heap") + /* Update heap info*/ + heap->dblk_addr = new_addr; + heap->dblk_size = new_heap_size; + /* Check if heap data block actually moved in the file */ if(H5F_addr_eq(old_addr, new_addr)) { /* Check if heap data block is contiguous w/prefix */ if(heap->single_cache_obj) { /* Sanity check */ - HDassert(H5F_addr_eq(heap->prfx_addr + heap->prfx_size, heap->dblk_addr)); + HDassert(H5F_addr_eq(heap->prfx_addr + heap->prfx_size, old_addr)); HDassert(heap->prfx); /* Resize the heap prefix in the cache */ @@ -243,7 +249,7 @@ H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) } /* end if */ else { /* Sanity check */ - HDassert(H5F_addr_ne(heap->prfx_addr + heap->prfx_size, heap->dblk_addr)); + HDassert(H5F_addr_ne(heap->prfx_addr + heap->prfx_size, old_addr)); HDassert(heap->dblk); /* Resize the heap data block in the cache */ @@ -264,7 +270,7 @@ H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) HGOTO_ERROR(H5E_HEAP, H5E_CANTRESIZE, FAIL, "unable to resize heap prefix in cache") /* Insert data block into cache (pinned) */ - if(H5AC_set(f, dxpl_id, H5AC_LHEAP_DBLK, new_addr, (size_t)new_heap_size, dblk, H5AC__PIN_ENTRY_FLAG) < 0) + if(H5AC_set(f, dxpl_id, H5AC_LHEAP_DBLK, new_addr, dblk, H5AC__PIN_ENTRY_FLAG) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to cache local heap data block") dblk = NULL; @@ -285,11 +291,13 @@ H5HL_dblk_realloc(H5F_t *f, hid_t dxpl_id, H5HL_t *heap, size_t new_heap_size) } /* end else */ } /* end else */ - /* Update heap info*/ - heap->dblk_addr = new_addr; - heap->dblk_size = new_heap_size; - done: + if(ret_value < 0) { + /* Restore old heap address & size */ + heap->dblk_addr = old_addr; + heap->dblk_size = old_heap_size; + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HL_dblk_realloc() */ diff --git a/src/H5HLcache.c b/src/H5HLcache.c index 643d3d6..4f7a304 100644 --- a/src/H5HLcache.c +++ b/src/H5HLcache.c @@ -83,6 +83,7 @@ static herr_t H5HL_prfx_free_icr(void *thing); static herr_t H5HL_dblk_get_load_size(const void *_udata, size_t *image_len); static void *H5HL_dblk_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5HL_dblk_image_len(const void *thing, size_t *image_len_ptr); static herr_t H5HL_dblk_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -100,6 +101,7 @@ const H5AC_class_t H5AC_LHEAP_PRFX[1] = {{ H5AC_LHEAP_PRFX_ID, "local heap prefix", H5FD_MEM_LHEAP, + H5AC__CLASS_SPECULATIVE_LOAD_FLAG, H5HL_prfx_get_load_size, H5HL_prfx_deserialize, H5HL_prfx_image_len, @@ -114,9 +116,10 @@ const H5AC_class_t H5AC_LHEAP_DBLK[1] = {{ H5AC_LHEAP_DBLK_ID, "local heap data block", H5FD_MEM_LHEAP, + H5AC__CLASS_NO_FLAGS_SET, H5HL_dblk_get_load_size, H5HL_dblk_deserialize, - NULL, + H5HL_dblk_image_len, H5HL_dblk_serialize, H5HL_dblk_free_icr, }}; @@ -401,7 +404,7 @@ done: /*------------------------------------------------------------------------- * Function: H5HL_prfx_image_len * - * Purpose: Tell the metadata cache about the actual size of the object + * Purpose: Compute the size of the data structure on disk. * * Return: Non-negative on success/Negative on failure * @@ -412,22 +415,22 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HL_prfx_image_len(const void *thing, size_t *image_len_ptr) +H5HL_prfx_image_len(const void *_thing, size_t *image_len) { - const H5HL_prfx_t *prfx = (const H5HL_prfx_t *)thing; /* The local heap prefix */ + const H5HL_prfx_t *prfx = (const H5HL_prfx_t *)_thing; /* The local heap prefix */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_prfx_image_len) /* Check arguments */ HDassert(prfx); HDassert(prfx->heap); - HDassert(image_len_ptr); + HDassert(image_len); /* Report the local heap's size, including the data block, if it's contiguous w/prefix */ if(prfx->heap->single_cache_obj) - *image_len_ptr = prfx->heap->prfx_size + prfx->heap->dblk_size; + *image_len = prfx->heap->prfx_size + prfx->heap->dblk_size; else - *image_len_ptr = prfx->heap->prfx_size; + *image_len = prfx->heap->prfx_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HL_prfx_image_len() */ @@ -628,6 +631,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5HL_dblk_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HL_dblk_image_len(const void *_thing, size_t *image_len) +{ + const H5HL_dblk_t *dblk = (const H5HL_dblk_t *)_thing; /* Pointer to the local heap data block */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_dblk_image_len) + + /* Check arguments */ + HDassert(dblk); + HDassert(image_len); + + /* Set the image length size */ + *image_len = dblk->heap->dblk_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HL_dblk_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5HL_dblk_serialize * * Purpose: Serializes a 'in core' representation of data structure @@ -1186,7 +1186,7 @@ H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, hid_t ocpl_id, oh->mesg[0].chunkno = 0; /* Cache object header */ - if(H5AC_set(f, dxpl_id, H5AC_OHDR, oh_addr, (size_t)oh_size, oh, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_OHDR, oh_addr, oh, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header") oh = NULL; @@ -1681,6 +1681,9 @@ H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot) /* Check for any messages that were modified while being read in */ if(udata.common.mesgs_modified && prot != H5AC_WRITE) oh->mesgs_modified = TRUE; + + /* Reset the field that contained chunk 0's size during speculative load */ + oh->chunk0_size = 0; } /* end if */ /* Take care of loose ends for modifications made while bringing in the diff --git a/src/H5Ocache.c b/src/H5Ocache.c index 0955151..e1dc382 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -69,7 +69,7 @@ static herr_t H5O_cache_get_load_size(const void *_udata, size_t *image_len); static void *H5O_cache_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); -static herr_t H5O_cache_image_len(const void *thing, size_t *image_len_ptr); +static herr_t H5O_cache_image_len(const void *thing, size_t *image_len); static herr_t H5O_cache_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -78,6 +78,7 @@ static herr_t H5O_cache_free_icr(void *thing); static herr_t H5O_cache_chk_get_load_size(const void *_udata, size_t *image_len); static void *H5O_cache_chk_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5O_cache_chk_image_len(const void *thing, size_t *image_len); static herr_t H5O_cache_chk_serialize(const H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -106,6 +107,7 @@ const H5AC_class_t H5AC_OHDR[1] = {{ H5AC_OHDR_ID, "object header", H5FD_MEM_OHDR, + H5AC__CLASS_SPECULATIVE_LOAD_FLAG, H5O_cache_get_load_size, H5O_cache_deserialize, H5O_cache_image_len, @@ -118,9 +120,10 @@ const H5AC_class_t H5AC_OHDR_CHK[1] = {{ H5AC_OHDR_CHK_ID, "object header chunk", H5FD_MEM_OHDR, + H5AC__CLASS_NO_FLAGS_SET, H5O_cache_chk_get_load_size, H5O_cache_chk_deserialize, - NULL, + H5O_cache_chk_image_len, H5O_cache_chk_serialize, H5O_cache_chk_free_icr, }}; @@ -365,7 +368,7 @@ done: /*------------------------------------------------------------------------- * Function: H5O_cache_image_len * - * Purpose: Tell the metadata cache about the actual size of the object + * Purpose: Compute the size of the data structure on disk. * * Return: Non-negative on success/Negative on failure * @@ -376,7 +379,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_cache_image_len(const void *thing, size_t *image_len_ptr) +H5O_cache_image_len(const void *thing, size_t *image_len) { const H5O_t *oh = (const H5O_t *)thing; /* The object header */ @@ -384,10 +387,13 @@ H5O_cache_image_len(const void *thing, size_t *image_len_ptr) /* Check arguments */ HDassert(oh); - HDassert(image_len_ptr); + HDassert(image_len); /* Report the object header's prefix+first chunk length */ - *image_len_ptr = H5O_SIZEOF_HDR(oh) + oh->chunk0_size; + if(oh->chunk0_size) + *image_len = H5O_SIZEOF_HDR(oh) + oh->chunk0_size; + else + *image_len = oh->chunk[0].size; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_cache_image_len() */ @@ -673,6 +679,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5O_cache_chk_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_cache_chk_image_len(const void *_thing, size_t *image_len) +{ + const H5O_chunk_proxy_t *chk_proxy = (const H5O_chunk_proxy_t *)_thing; /* Pointer to the object header chunk proxy */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_cache_chk_image_len) + + /* Check arguments */ + HDassert(chk_proxy); + HDassert(image_len); + + /* Set the image length size */ + *image_len = chk_proxy->oh->chunk[chk_proxy->chunkno].size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5O_cache_chk_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5O_cache_chk_serialize * * Purpose: Serializes an object header chunk diff --git a/src/H5Ochunk.c b/src/H5Ochunk.c index ee321e8..bc0f718 100644 --- a/src/H5Ochunk.c +++ b/src/H5Ochunk.c @@ -114,7 +114,7 @@ H5O_chunk_add(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned idx) chk_proxy->chunkno = idx; /* Insert the chunk proxy into the cache */ - if(H5AC_set(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, oh->chunk[idx].size, chk_proxy, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_OHDR_CHK, oh->chunk[idx].addr, chk_proxy, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header chunk") chk_proxy = NULL; diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c index a95495f..07a7c9c 100644 --- a/src/H5Ocopy.c +++ b/src/H5Ocopy.c @@ -719,7 +719,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, } /* end if */ /* Insert destination object header in cache */ - if(H5AC_set(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, (size_t)dst_oh_size, oh_dst, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header") oh_dst = NULL; @@ -123,14 +123,12 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d H5O_shmesg_table_t sohm_table; /* SOHM message for superblock extension */ H5SM_master_table_t *table = NULL; /* SOHM master table for file */ haddr_t table_addr = HADDR_UNDEF; /* Address of SOHM master table in file */ - unsigned num_indexes; /* Number of SOHM indices */ unsigned list_max, btree_min; /* Phase change limits for SOHM indices */ unsigned index_type_flags[H5O_SHMESG_MAX_NINDEXES]; /* Messages types stored in each index */ unsigned minsizes[H5O_SHMESG_MAX_NINDEXES]; /* Message size sharing threshhold for each index */ unsigned type_flags_used; /* Message type flags used, for sanity checking */ - hsize_t table_size; /* Size of SOHM master table in file */ unsigned x; /* Local index variable */ - herr_t ret_value = SUCCEED; + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5SM_init, NULL) @@ -141,36 +139,35 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* Initialize master table */ if(NULL == (table = H5FL_MALLOC(H5SM_master_table_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for SOHM table") + table->num_indexes = f->shared->sohm_nindexes; + table->table_size = H5SM_TABLE_SIZE(f); /* Get information from fcpl */ - if(H5P_get(fc_plist, H5F_CRT_SHMSG_NINDEXES_NAME, &num_indexes)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of indexes") - if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, &index_type_flags)<0) + if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_TYPES_NAME, &index_type_flags) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM type flags") - if(H5P_get(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &list_max)<0) + if(H5P_get(fc_plist, H5F_CRT_SHMSG_LIST_MAX_NAME, &list_max) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM list maximum") - if(H5P_get(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &btree_min)<0) + if(H5P_get(fc_plist, H5F_CRT_SHMSG_BTREE_MIN_NAME, &btree_min) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM btree minimum") if(H5P_get(fc_plist, H5F_CRT_SHMSG_INDEX_MINSIZE_NAME, &minsizes) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get SOHM message min sizes") /* Verify that values are valid */ - if(num_indexes > H5O_SHMESG_MAX_NINDEXES) + if(table->num_indexes > H5O_SHMESG_MAX_NINDEXES) HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "number of indexes in property list is too large") /* Check that type flags weren't duplicated anywhere */ type_flags_used = 0; - for(x = 0; x < num_indexes; ++x) { + for(x = 0; x < table->num_indexes; ++x) { if(index_type_flags[x] & type_flags_used) HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "the same shared message type flag is assigned to more than one index") type_flags_used |= index_type_flags[x]; } /* end for */ - /* Set version and number of indexes in table and in superblock. + /* Check that number of indexes in table and in superblock make sense. * Right now we just use one byte to hold the number of indexes. */ - HDassert(num_indexes < 256); - table->num_indexes = num_indexes; + HDassert(table->num_indexes < 256); /* Check that list and btree cutoffs make sense. There can't be any * values greater than the list max but less than the btree min; the @@ -187,8 +184,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d /* Initialize all of the indexes, but don't allocate space for them to * hold messages until we actually need to write to them. */ - for(x = 0; x < table->num_indexes; x++) - { + for(x = 0; x < table->num_indexes; x++) { table->indexes[x].btree_min = btree_min; table->indexes[x].list_max = list_max; table->indexes[x].mesg_types = index_type_flags[x]; @@ -202,15 +198,17 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d table->indexes[x].index_type = H5SM_LIST; else table->indexes[x].index_type = H5SM_BTREE; + + /* Compute the size of a list index for this SOHM index */ + table->indexes[x].list_size = H5SM_LIST_SIZE(f, list_max); } /* end for */ /* Allocate space for the table on disk */ - table_size = (hsize_t) H5SM_TABLE_SIZE(f) + (hsize_t) (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); - if(HADDR_UNDEF == (table_addr = H5MF_alloc(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_size))) + if(HADDR_UNDEF == (table_addr = H5MF_alloc(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table->table_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for SOHM table") /* Cache the new table */ - if(H5AC_set(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, (size_t)table_size, table, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, table, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "can't add SOHM table to cache") /* Record the address of the master table in the file */ @@ -232,7 +230,7 @@ H5SM_init(H5F_t *f, H5P_genplist_t * fc_plist, const H5O_loc_t *ext_loc, hid_t d done: if(ret_value < 0) { if(table_addr != HADDR_UNDEF) - H5MF_xfree(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_addr, (hsize_t)H5SM_TABLE_SIZE(f)); + H5MF_xfree(f, H5FD_MEM_SOHM_TABLE, dxpl_id, table_addr, (hsize_t)table->table_size); if(table != NULL) table = H5FL_FREE(H5SM_master_table_t, table); } /* end if */ @@ -359,7 +357,6 @@ H5SM_type_shared(H5F_t *f, unsigned type_id, hid_t dxpl_id) /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_READ))) HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") @@ -413,7 +410,6 @@ H5SM_get_fheap_addr(H5F_t *f, hid_t dxpl_id, unsigned type_id, haddr_t *fheap_ad /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_READ))) @@ -541,7 +537,6 @@ done: static herr_t H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, hbool_t delete_heap) { - hsize_t list_size; /* Size of list on disk */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5SM_delete_index) @@ -553,8 +548,7 @@ H5SM_delete_index(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id, hbool_t HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove list index from cache") /* Free the file space used */ - list_size = H5SM_LIST_SIZE(f, header->list_max); - if(H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, header->index_addr, list_size) < 0) + if(H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, header->index_addr, header->list_size) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to free shared message list") } /* end if */ else { @@ -605,7 +599,6 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) { H5SM_list_t *list = NULL; /* List of messages */ hsize_t x; /* Counter variable */ - hsize_t size = 0; /* Size of list on disk */ size_t num_entries; /* Number of messages to create in list */ haddr_t addr = HADDR_UNDEF; /* Address of the list on disk */ haddr_t ret_value; @@ -618,26 +611,24 @@ H5SM_create_list(H5F_t *f, H5SM_index_header_t *header, hid_t dxpl_id) num_entries = header->list_max; /* Allocate list in memory */ - if((list = H5FL_MALLOC(H5SM_list_t)) == NULL) + if(NULL == (list = H5FL_MALLOC(H5SM_list_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") - if((list->messages = (H5SM_sohm_t *)H5FL_ARR_MALLOC(H5SM_sohm_t, num_entries)) == NULL) + if(NULL == (list->messages = (H5SM_sohm_t *)H5FL_ARR_CALLOC(H5SM_sohm_t, num_entries))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") /* Initialize messages in list */ - HDmemset(list->messages, 0, sizeof(H5SM_sohm_t) * num_entries); - for(x=0; x<num_entries; x++) + for(x = 0; x < num_entries; x++) list->messages[x].location = H5SM_NO_LOC; /* Point list at header passed in */ list->header = header; /* Allocate space for the list on disk */ - size = H5SM_LIST_SIZE(f, num_entries); - if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_SOHM_INDEX, dxpl_id, size))) + if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_SOHM_INDEX, dxpl_id, header->list_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for SOHM list") /* Put the list into the cache */ - if(H5AC_set(f, dxpl_id, H5AC_SOHM_LIST, addr, (size_t)size, list, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_SOHM_LIST, addr, list, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, HADDR_UNDEF, "can't add SOHM list to cache") /* Set return value */ @@ -651,7 +642,7 @@ done: list = H5FL_FREE(H5SM_list_t, list); } /* end if */ if(addr != HADDR_UNDEF) - H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, addr, size); + H5MF_xfree(f, H5FD_MEM_SOHM_INDEX, dxpl_id, addr, header->list_size); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -910,7 +901,6 @@ H5SM_can_share(H5F_t *f, hid_t dxpl_id, H5SM_master_table_t *table, /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); if(NULL == (my_table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_READ))) HGOTO_ERROR(H5E_SOHM, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") @@ -1020,7 +1010,6 @@ H5SM_try_share(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, unsigned type_id, /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_WRITE))) @@ -1404,7 +1393,6 @@ H5SM_delete(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh, H5O_shared_t *sh_mesg) /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_WRITE))) @@ -1837,7 +1825,6 @@ H5SM_get_info(const H5O_loc_t *ext_loc, H5P_genplist_t *fc_plist, hid_t dxpl_id) /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Read the rest of the SOHM table information from the cache */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, shared->sohm_addr, &cache_udata, H5AC_READ))) @@ -2068,7 +2055,6 @@ H5SM_get_refcount(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Set up user data for callback */ tbl_cache_udata.f = f; - tbl_cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &tbl_cache_udata, H5AC_READ))) @@ -2457,7 +2443,6 @@ H5SM_table_debug(H5F_t *f, hid_t dxpl_id, haddr_t table_addr, /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, table_addr, &cache_udata, H5AC_READ))) @@ -2619,15 +2604,13 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_READ))) HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, FAIL, "unable to load SOHM master table") /* Get SOHM header size */ - finfo->sohm.hdr_size = (hsize_t) H5SM_TABLE_SIZE(f) + - (hsize_t)(table->num_indexes * H5SM_INDEX_HEADER_SIZE(f)); + finfo->sohm.hdr_size = (hsize_t)table->table_size; /* Loop over all the indices for shared messages */ for(u = 0; u < table->num_indexes; u++) { @@ -2638,7 +2621,7 @@ H5SM_ih_size(H5F_t *f, hid_t dxpl_id, H5F_info_t *finfo) HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "can't retrieve B-tree storage info") } /* end if */ else if(table->indexes[u].index_type == H5SM_LIST) - finfo->sohm.msgs_info.index_size += H5SM_LIST_SIZE(f, table->indexes[u].list_max); + finfo->sohm.msgs_info.index_size += table->indexes[u].list_size; /* Check for heap for this index */ if(H5F_addr_defined(table->indexes[u].heap_addr)) { diff --git a/src/H5SMcache.c b/src/H5SMcache.c index 3e9bbe6..f518399 100644 --- a/src/H5SMcache.c +++ b/src/H5SMcache.c @@ -51,6 +51,7 @@ static herr_t H5SM_table_get_load_size(const void *_udata, size_t *image_len); static void *H5SM_table_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5SM_table_image_len(const void *thing, size_t *image_len); static herr_t H5SM_table_serialize(const H5F_t * f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -59,6 +60,7 @@ static herr_t H5SM_table_free_icr(void *thing); static herr_t H5SM_list_get_load_size(const void *_udata, size_t *image_len); static void *H5SM_list_deserialize(const void *image, size_t len, void *udata, hbool_t *dirty); +static herr_t H5SM_list_image_len(const void *thing, size_t *image_len); static herr_t H5SM_list_serialize(const H5F_t * f, hid_t dxpl_id, haddr_t addr, size_t len, void *image, void *thing, unsigned *flags, haddr_t *new_addr, size_t *new_len, void **new_image); @@ -73,9 +75,10 @@ const H5AC_class_t H5AC_SOHM_TABLE[1] = {{ H5AC_SOHM_TABLE_ID, "shared object header message", H5FD_MEM_SOHM_TABLE, + H5AC__CLASS_NO_FLAGS_SET, H5SM_table_get_load_size, H5SM_table_deserialize, - NULL, + H5SM_table_image_len, H5SM_table_serialize, H5SM_table_free_icr, }}; @@ -84,9 +87,10 @@ const H5AC_class_t H5AC_SOHM_LIST[1] = {{ H5AC_SOHM_LIST_ID, "shared object header message", H5FD_MEM_SOHM_INDEX, + H5AC__CLASS_NO_FLAGS_SET, H5SM_list_get_load_size, H5SM_list_deserialize, - NULL, + H5SM_list_image_len, H5SM_list_serialize, H5SM_list_free_icr, }}; @@ -128,7 +132,7 @@ H5SM_table_get_load_size(const void *_udata, size_t *image_len) HDassert(image_len); /* Set the image length size */ - *image_len = udata->table_size; + *image_len = H5SM_TABLE_SIZE(udata->f); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM_table_get_load_size() */ @@ -174,6 +178,7 @@ H5SM_table_deserialize(const void *image, size_t UNUSED len, void *_udata, /* Read number of indexes and version from file superblock */ table->num_indexes = udata->f->shared->sohm_nindexes; + table->table_size = H5SM_TABLE_SIZE(udata->f); HDassert(table->num_indexes > 0); @@ -185,11 +190,6 @@ H5SM_table_deserialize(const void *image, size_t UNUSED len, void *_udata, HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature") p += H5SM_SIZEOF_MAGIC; - /* Don't count the checksum in the table size yet, since it comes after - * all of the index headers - */ - HDassert((size_t)(p - (const uint8_t *)image) == H5SM_TABLE_SIZE(udata->f) - H5SM_SIZEOF_CHECKSUM); - /* Allocate space for the index headers in memory*/ if(NULL == (table->indexes = (H5SM_index_header_t *)H5FL_ARR_MALLOC(H5SM_index_header_t, (size_t)table->num_indexes))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes") @@ -223,6 +223,9 @@ H5SM_table_deserialize(const void *image, size_t UNUSED len, void *_udata, /* Address of the index's heap */ H5F_addr_decode(udata->f, &p, &(table->indexes[x].heap_addr)); + + /* Compute the size of a list index for this SOHM index */ + table->indexes[x].list_size = H5SM_LIST_SIZE(udata->f, table->indexes[x].list_max); } /* end for */ /* Read in checksum */ @@ -254,6 +257,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5SM_table_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5SM_table_image_len(const void *_thing, size_t *image_len) +{ + const H5SM_master_table_t *table = (const H5SM_master_table_t *)_thing; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_table_image_len) + + /* Check arguments */ + HDassert(table); + HDassert(image_len); + + /* Set the image length size */ + *image_len = table->table_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM_table_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5SM_table_serialize * * Purpose: Serialize the data structure for writing to disk. @@ -335,7 +369,7 @@ H5SM_table_serialize(const H5F_t * f, hid_t UNUSED dxlp_id, haddr_t UNUSED addr, *flags = 0; /* Sanity check */ - HDassert((size_t)((const uint8_t *)p - (const uint8_t *)image) <= len); + HDassert((size_t)(p - (uint8_t *)image) == len); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM_table_serialize() */ @@ -399,7 +433,7 @@ H5SM_list_get_load_size(const void *_udata, size_t *image_len) HDassert(image_len); /* Set the image length size */ - *image_len = H5SM_LIST_SIZE(udata->f, udata->header->list_max); + *image_len = udata->header->list_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5SM_list_get_load_size() */ @@ -424,7 +458,6 @@ H5SM_list_deserialize(const void *image, size_t UNUSED len, void *_udata, { H5SM_list_t *list; /* The SOHM list being read in */ H5SM_list_cache_ud_t *udata = (H5SM_list_cache_ud_t *)_udata; /* User data for callback */ - size_t size; /* Size of SOHM list on disk */ const uint8_t *p; /* Pointer into input buffer */ uint32_t stored_chksum; /* Stored metadata checksum value */ uint32_t computed_chksum; /* Computed metadata checksum value */ @@ -447,9 +480,6 @@ H5SM_list_deserialize(const void *image, size_t UNUSED len, void *_udata, list->header = udata->header; - /* Compute the size of the SOHM list on disk */ - size = H5SM_LIST_SIZE(udata->f, udata->header->num_messages); - /* Get temporary pointer to serialized list index */ p = (const uint8_t *)image; @@ -471,11 +501,8 @@ H5SM_list_deserialize(const void *image, size_t UNUSED len, void *_udata, /* Sanity check */ HDassert((size_t)(p - (const uint8_t *)image) <= len); - /* Sanity check */ - HDassert((size_t)(p - (const uint8_t *)image) == size); - /* Compute checksum on entire header */ - computed_chksum = H5_checksum_metadata(image, (size - H5SM_SIZEOF_CHECKSUM), 0); + computed_chksum = H5_checksum_metadata(image, ((size_t)(p - (const uint8_t *)image) - H5SM_SIZEOF_CHECKSUM), 0); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -501,6 +528,37 @@ done: /*------------------------------------------------------------------------- + * Function: H5SM_list_image_len + * + * Purpose: Compute the size of the data structure on disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 20 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5SM_list_image_len(const void *_thing, size_t *image_len) +{ + const H5SM_list_t *list = (const H5SM_list_t *)_thing; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_list_image_len) + + /* Check arguments */ + HDassert(list); + HDassert(image_len); + + /* Set the image length size */ + *image_len = list->header->list_size; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5SM_list_image_len() */ + + +/*------------------------------------------------------------------------- * Function: H5SM_list_serialize * * Purpose: Serialize the data structure for writing to disk. @@ -520,7 +578,6 @@ H5SM_list_serialize(const H5F_t * f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, { H5SM_list_t *list = (H5SM_list_t *)_thing; uint8_t *p; /* Pointer into raw data buffer */ - size_t size; /* Header size on disk */ uint32_t computed_chksum; /* Computed metadata checksum value */ size_t mesgs_written; /* Number of messages written to list */ size_t x; /* Local index variable */ @@ -534,8 +591,6 @@ H5SM_list_serialize(const H5F_t * f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, HDassert(list); HDassert(list->header); - size = H5SM_LIST_SIZE(f, list->header->num_messages); - /* Get temporary pointer to buffer for serialized list index */ p = (uint8_t *)image; @@ -557,14 +612,14 @@ H5SM_list_serialize(const H5F_t * f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr, HDassert(mesgs_written == list->header->num_messages); /* Compute checksum on buffer */ - computed_chksum = H5_checksum_metadata(image, (size - H5SM_SIZEOF_CHECKSUM), 0); + computed_chksum = H5_checksum_metadata(image, (size_t)(p - (uint8_t *)image), 0); UINT32ENCODE(p, computed_chksum); /* Reset the cache flags for this operation (metadata not resize or renamed) */ *flags = 0; /* Sanity check */ - HDassert((size_t)((const uint8_t *)p - (const uint8_t *)image) <= len); + HDassert((size_t)(p - (uint8_t *)image) <= len); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5SMpkg.h b/src/H5SMpkg.h index d3566dc..3a16847 100755 --- a/src/H5SMpkg.h +++ b/src/H5SMpkg.h @@ -69,11 +69,6 @@ + MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)) /* Entry */ \ ) -#define H5SM_TABLE_SIZE(f) ( \ - H5SM_SIZEOF_MAGIC /* Signature */ \ - + H5SM_SIZEOF_CHECKSUM /* Checksum */ \ - ) - #define H5SM_INDEX_HEADER_SIZE(f) ( \ 1 /* Whether index is a list or B-tree */ \ + 1 /* Version of index format */ \ @@ -84,10 +79,26 @@ + H5F_SIZEOF_ADDR(f) /* Address of heap */ \ ) +/* Format overhead for all SOHM tree metadata in the file */ +#define H5SM_METADATA_PREFIX_SIZE ( \ + H5SM_SIZEOF_MAGIC /* Signature */ \ + + H5SM_SIZEOF_CHECKSUM /* Checksum */ \ + ) + +#define H5SM_TABLE_SIZE(f) ( \ + /* General metadata fields */ \ + H5SM_METADATA_PREFIX_SIZE \ + \ + /* Indices */ \ + + ((f)->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)) \ + ) + #define H5SM_LIST_SIZE(f, num_mesg) ( \ - H5SM_SIZEOF_MAGIC /* Signature */ \ - + (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) /* Message entries */ \ - + H5SM_SIZEOF_CHECKSUM /* Checksum */ \ + /* General metadata fields */ \ + H5SM_METADATA_PREFIX_SIZE \ + \ + /* Message entries */ \ + + (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) \ ) #define H5SM_B2_NODE_SIZE 512 @@ -161,6 +172,7 @@ typedef enum { /* Typedef for a SOHM index header */ typedef struct { +/* Stored */ unsigned mesg_types; /* Bit flag vector of message types */ size_t min_mesg_size; /* number of messages being tracked */ size_t list_max; /* >= this many messages, index with a B-tree */ @@ -169,6 +181,9 @@ typedef struct { H5SM_index_type_t index_type; /* Is the index a list or a B-tree? */ haddr_t index_addr; /* Address of the actual index (list or B-tree) */ haddr_t heap_addr; /* Address of the fheap used to store shared messages */ + +/* Not stored */ + size_t list_size; /* Size of list index on disk */ } H5SM_index_header_t; /* Typedef for a SOHM list */ @@ -180,12 +195,12 @@ typedef struct { H5SM_sohm_t *messages; /* Actual list, stored as an array */ } H5SM_list_t; - /* Typedef for shared object header message master table */ struct H5SM_master_table_t { /* Information for H5AC cache functions, _must_ be first field in structure */ H5AC_info_t cache_info; + size_t table_size; /* Size of table on disk */ unsigned num_indexes; /* Number of indexes */ H5SM_index_header_t *indexes; /* Array of num_indexes indexes */ }; @@ -224,7 +239,6 @@ typedef struct { /* Callback info for loading a shared message table index into the cache */ typedef struct H5SM_table_cache_ud_t { H5F_t *f; /* File that shared message index stored as a table is in */ - size_t table_size; /* Size of SOHM master table in file */ } H5SM_table_cache_ud_t; /* Callback info for loading a shared message list index into the cache */ diff --git a/src/H5SMtest.c b/src/H5SMtest.c index 67140dd..1c9ec62 100644 --- a/src/H5SMtest.c +++ b/src/H5SMtest.c @@ -96,7 +96,6 @@ H5SM_get_mesg_count_test(H5F_t *f, hid_t dxpl_id, unsigned type_id, /* Set up user data for callback */ cache_udata.f = f; - cache_udata.table_size = H5SM_TABLE_SIZE(f) + (f->shared->sohm_nindexes * H5SM_INDEX_HEADER_SIZE(f)); /* Look up the master SOHM table */ if(NULL == (table = (H5SM_master_table_t *)H5AC_protect(f, dxpl_id, H5AC_SOHM_TABLE, f->shared->sohm_addr, &cache_udata, H5AC_READ))) diff --git a/src/H5private.h b/src/H5private.h index 3ba6efd..1b595b4 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1551,34 +1551,7 @@ H5_DLL double H5_trace(const double *calltime, const char *func, const char *typ /* `S' is the name of a function which is being tested to check if its */ /* an API function */ -#if 0 #define H5_IS_API(S) ('_'!=S[2] && '_'!=S[3] && (!S[4] || '_'!=S[4])) -#else -/* -#define H5_IS_API(S) ('_'!=S[2] && '_'!=S[3] && (!S[4] || '_'!=S[4]) && \ - (!S[5] || ('_'!=S[5] && (S[4]>='a' && S[4]<='z')))) -*/ -#define H5_IS_API(S) ( ( 'H' == S[0] ) \ - && \ - ( '5' == S[1] ) \ - && \ - ( ( islower(S[2]) ) \ - || \ - ( ( ( isupper(S[2]) ) || ( isdigit(S[2]) ) ) \ - && \ - ( islower(S[3]) ) \ - ) \ - || \ - ( ( ( isupper(S[2]) ) || ( isdigit(S[2]) ) ) \ - && \ - ( ( isupper(S[3]) ) || ( isdigit(S[3]) ) ) \ - && \ - ( islower(S[4]) ) \ - ) \ - ) \ - ) - -#endif /* global library version information string */ extern char H5_lib_vers_info_g[]; |