summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-05-27 13:10:28 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-05-27 13:10:28 (GMT)
commit037c318770490c07f23e30af26353b68dbf712c0 (patch)
treee1fb9a5233047824bc1405e099e8f85f2e8faf4b /src
parent6a183ca20ce41b70feae9a52a4e04913d276be34 (diff)
downloadhdf5-037c318770490c07f23e30af26353b68dbf712c0.zip
hdf5-037c318770490c07f23e30af26353b68dbf712c0.tar.gz
hdf5-037c318770490c07f23e30af26353b68dbf712c0.tar.bz2
[svn-r18910] Description:
Remove 'size' parameter from H5AC2_set()/H5C2_insert_entry(), to align better with trunk. Use the 'image_len' cache client callback to retrieve the size of an inserted entry. Also, add flags to the cache client class structure, to indicate several client behaviors: speculative loads & compressed storage on disk (which were previously dependent on the 'image_len' callback only being used to detect size changes during load (deserialize) operations). Tested on: Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in debug mode Mac OS X/32 10.6.3 (amazon) in debug mode Mac OS X/32 10.6.3 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'src')
-rw-r--r--src/H5AC.c98
-rw-r--r--src/H5ACprivate.h29
-rw-r--r--src/H5B.c11
-rw-r--r--src/H5B2.c9
-rw-r--r--src/H5B2cache.c162
-rw-r--r--src/H5B2int.c4
-rw-r--r--src/H5B2pkg.h1
-rw-r--r--src/H5Bcache.c40
-rw-r--r--src/H5C.c394
-rw-r--r--src/H5Cprivate.h17
-rw-r--r--src/H5F.c2
-rw-r--r--src/H5FD.c10
-rw-r--r--src/H5FDpublic.h7
-rw-r--r--src/H5FS.c13
-rw-r--r--src/H5FScache.c87
-rw-r--r--src/H5FSpkg.h5
-rw-r--r--src/H5FSsection.c2
-rw-r--r--src/H5Gnode.c112
-rw-r--r--src/H5HFcache.c85
-rw-r--r--src/H5HFdblock.c2
-rw-r--r--src/H5HFhdr.c2
-rw-r--r--src/H5HFiblock.c8
-rw-r--r--src/H5HFpkg.h15
-rw-r--r--src/H5HG.c4
-rwxr-xr-xsrc/H5HGcache.c65
-rw-r--r--src/H5HL.c28
-rw-r--r--src/H5HLcache.c48
-rw-r--r--src/H5O.c5
-rw-r--r--src/H5Ocache.c49
-rw-r--r--src/H5Ochunk.c2
-rw-r--r--src/H5Ocopy.c2
-rwxr-xr-xsrc/H5SM.c69
-rw-r--r--src/H5SMcache.c101
-rwxr-xr-xsrc/H5SMpkg.h34
-rw-r--r--src/H5SMtest.c1
-rw-r--r--src/H5private.h27
36 files changed, 903 insertions, 647 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index 4e79dfa..82b7bfe 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -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);
diff --git a/src/H5B.c b/src/H5B.c
index 4898835..f94bb0a 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -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
diff --git a/src/H5B2.c b/src/H5B2.c
index 0bbd7b8..dd182fb 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -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.
diff --git a/src/H5C.c b/src/H5C.c
index 0cedf4d..8ee5ec5 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -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);
diff --git a/src/H5F.c b/src/H5F.c
index f70f7ae..e563212 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -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);
diff --git a/src/H5FD.c b/src/H5FD.c
index 383d064..e2d567f 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -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
diff --git a/src/H5FS.c b/src/H5FS.c
index 8565d8b..8a41ee7 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -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)))
diff --git a/src/H5HG.c b/src/H5HG.c
index 7ce4101..d496bdb 100644
--- a/src/H5HG.c
+++ b/src/H5HG.c
@@ -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
diff --git a/src/H5HL.c b/src/H5HL.c
index 17861eb..37e154d 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -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
diff --git a/src/H5O.c b/src/H5O.c
index 74e194a..63fb0f4 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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;
diff --git a/src/H5SM.c b/src/H5SM.c
index 48d163c..e3b4b40 100755
--- a/src/H5SM.c
+++ b/src/H5SM.c
@@ -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[];