summaryrefslogtreecommitdiffstats
path: root/src/H5B2cache.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2015-06-18 00:58:49 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2015-06-18 00:58:49 (GMT)
commitf30ab55f41296667eab0b273132ffc20c4323717 (patch)
tree2fd6a85b7c15e3505e308e21b41e67297cc58508 /src/H5B2cache.c
parent6e9e9e0dd200979642de8d2a2bce2f66f9728237 (diff)
downloadhdf5-f30ab55f41296667eab0b273132ffc20c4323717.zip
hdf5-f30ab55f41296667eab0b273132ffc20c4323717.tar.gz
hdf5-f30ab55f41296667eab0b273132ffc20c4323717.tar.bz2
[svn-r27237] Description:
Merge v3 metadata cache changes to trunk. Yay! :-) Tested on: MacOSX/64 10.10.3 (amazon) w/serial & parallel Linux/32 2.6.x (jam) w/serial & parallel (daily tested on branch)
Diffstat (limited to 'src/H5B2cache.c')
-rw-r--r--src/H5B2cache.c967
1 files changed, 424 insertions, 543 deletions
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index 3b30e02..64e304c 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -37,7 +37,6 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
-#include "H5MFprivate.h" /* File memory management */
#include "H5WBprivate.h" /* Wrapped Buffers */
@@ -50,9 +49,6 @@
#define H5B2_INT_VERSION 0 /* Internal node */
#define H5B2_LEAF_VERSION 0 /* Leaf node */
-/* Size of stack buffer for serialized headers */
-#define H5B2_HDR_BUF_SIZE 128
-
/******************/
/* Local Typedefs */
@@ -69,22 +65,32 @@
/********************/
/* Metadata cache callbacks */
-static H5B2_hdr_t *H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
-static herr_t H5B2__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_hdr_t *hdr, unsigned H5_ATTR_UNUSED * flags_ptr);
-static herr_t H5B2__cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr);
-static herr_t H5B2__cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy);
-static herr_t H5B2__cache_hdr_size(const H5F_t *f, const H5B2_hdr_t *hdr, size_t *size_ptr);
-static H5B2_internal_t *H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
-static herr_t H5B2__cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *i, unsigned H5_ATTR_UNUSED * flags_ptr);
-static herr_t H5B2__cache_internal_dest(H5F_t *f, H5B2_internal_t *internal);
-static herr_t H5B2__cache_internal_clear(H5F_t *f, H5B2_internal_t *i, hbool_t destroy);
-static herr_t H5B2__cache_internal_size(const H5F_t *f, const H5B2_internal_t *i, size_t *size_ptr);
-static H5B2_leaf_t *H5B2__cache_leaf_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *udata);
-static herr_t H5B2__cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *l, unsigned H5_ATTR_UNUSED * flags_ptr);
-static herr_t H5B2__cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf);
-static herr_t H5B2__cache_leaf_clear(H5F_t *f, H5B2_leaf_t *l, hbool_t destroy);
-static herr_t H5B2__cache_leaf_size(const H5F_t *f, const H5B2_leaf_t *l, size_t *size_ptr);
-
+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,
+ hbool_t *compressed_ptr, size_t *compressed_image_len_ptr);
+static herr_t H5B2__cache_hdr_serialize(const H5F_t *f, void *image, size_t len,
+ void *thing);
+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,
+ hbool_t *compressed_ptr, size_t *compressed_image_len_ptr);
+static herr_t H5B2__cache_int_serialize(const H5F_t *f, void *image, size_t len,
+ void *thing);
+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,
+ hbool_t *compressed_ptr, size_t *compressed_image_len_ptr);
+static herr_t H5B2__cache_leaf_serialize(const H5F_t *f, void *image, size_t len,
+ void *thing);
+static herr_t H5B2__cache_leaf_free_icr(void *thing);
/*********************/
/* Package Variables */
@@ -92,35 +98,53 @@ static herr_t H5B2__cache_leaf_size(const H5F_t *f, const H5B2_leaf_t *l, size_t
/* H5B2 inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_BT2_HDR[1] = {{
- H5AC_BT2_HDR_ID,
- (H5AC_load_func_t)H5B2__cache_hdr_load,
- (H5AC_flush_func_t)H5B2__cache_hdr_flush,
- (H5AC_dest_func_t)H5B2__cache_hdr_dest,
- (H5AC_clear_func_t)H5B2__cache_hdr_clear,
- (H5AC_notify_func_t)NULL,
- (H5AC_size_func_t)H5B2__cache_hdr_size,
+ H5AC_BT2_HDR_ID, /* Metadata client ID */
+ "v2 B-tree header", /* Metadata client name (for debugging) */
+ H5FD_MEM_BTREE, /* File space memory type for client */
+ H5AC__CLASS_NO_FLAGS_SET, /* Client class behavior flags */
+ H5B2__cache_hdr_get_load_size, /* 'get_load_size' callback */
+ H5B2__cache_hdr_deserialize, /* 'deserialize' callback */
+ H5B2__cache_hdr_image_len, /* 'image_len' callback */
+ NULL, /* 'pre_serialize' callback */
+ H5B2__cache_hdr_serialize, /* 'serialize' callback */
+ NULL, /* 'notify' callback */
+ H5B2__cache_hdr_free_icr, /* 'free_icr' callback */
+ NULL, /* 'clear' callback */
+ NULL, /* 'fsf_size' callback */
}};
/* H5B2 inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_BT2_INT[1] = {{
- H5AC_BT2_INT_ID,
- (H5AC_load_func_t)H5B2__cache_internal_load,
- (H5AC_flush_func_t)H5B2__cache_internal_flush,
- (H5AC_dest_func_t)H5B2__cache_internal_dest,
- (H5AC_clear_func_t)H5B2__cache_internal_clear,
- (H5AC_notify_func_t)NULL,
- (H5AC_size_func_t)H5B2__cache_internal_size,
+ H5AC_BT2_INT_ID, /* Metadata client ID */
+ "v2 B-tree internal node", /* Metadata client name (for debugging) */
+ H5FD_MEM_BTREE, /* File space memory type for client */
+ H5AC__CLASS_NO_FLAGS_SET, /* Client class behavior flags */
+ H5B2__cache_int_get_load_size, /* 'get_load_size' callback */
+ H5B2__cache_int_deserialize, /* 'deserialize' callback */
+ H5B2__cache_int_image_len, /* 'image_len' callback */
+ NULL, /* 'pre_serialize' callback */
+ H5B2__cache_int_serialize, /* 'serialize' callback */
+ NULL, /* 'notify' callback */
+ H5B2__cache_int_free_icr, /* 'free_icr' callback */
+ NULL, /* 'clear' callback */
+ NULL, /* 'fsf_size' callback */
}};
/* H5B2 inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_BT2_LEAF[1] = {{
- H5AC_BT2_LEAF_ID,
- (H5AC_load_func_t)H5B2__cache_leaf_load,
- (H5AC_flush_func_t)H5B2__cache_leaf_flush,
- (H5AC_dest_func_t)H5B2__cache_leaf_dest,
- (H5AC_clear_func_t)H5B2__cache_leaf_clear,
- (H5AC_notify_func_t)NULL,
- (H5AC_size_func_t)H5B2__cache_leaf_size,
+ H5AC_BT2_LEAF_ID, /* Metadata client ID */
+ "v2 B-tree leaf node", /* Metadata client name (for debugging) */
+ H5FD_MEM_BTREE, /* File space memory type for client */
+ H5AC__CLASS_NO_FLAGS_SET, /* Client class behavior flags */
+ H5B2__cache_leaf_get_load_size, /* 'get_load_size' callback */
+ H5B2__cache_leaf_deserialize, /* 'deserialize' callback */
+ H5B2__cache_leaf_image_len, /* 'image_len' callback */
+ NULL, /* 'pre_serialize' callback */
+ H5B2__cache_leaf_serialize, /* 'serialize' callback */
+ NULL, /* 'notify' callback */
+ H5B2__cache_leaf_free_icr, /* 'free_icr' callback */
+ NULL, /* 'clear' callback */
+ NULL, /* 'fsf_size' callback */
}};
@@ -136,7 +160,38 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_hdr_load
+ * Function: H5B2__cache_hdr_get_load_size
+ *
+ * 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 18, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B2__cache_hdr_get_load_size(const void *_udata, size_t *image_len)
+{
+ const H5B2_hdr_cache_ud_t *udata = (const H5B2_hdr_cache_ud_t *)_udata; /* User data for callback */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Check arguments */
+ HDassert(udata);
+ HDassert(image_len);
+
+ /* Set the image length size */
+ *image_len = H5B2_HEADER_SIZE_FILE(udata->f);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2__cache_hdr_get_load_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2__cache_hdr_deserialize
*
* Purpose: Loads a B-tree header from the disk.
*
@@ -149,8 +204,9 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
*
*-------------------------------------------------------------------------
*/
-static H5B2_hdr_t *
-H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
+static void *
+H5B2__cache_hdr_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
+ void *_udata, hbool_t H5_ATTR_UNUSED *dirty)
{
H5B2_hdr_t *hdr = NULL; /* B-tree header */
H5B2_hdr_cache_ud_t *udata = (H5B2_hdr_cache_ud_t *)_udata;
@@ -159,78 +215,59 @@ H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
uint16_t depth; /* Depth of B-tree */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
- H5WB_t *wb = NULL; /* Wrapped buffer for header data */
- uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
- uint8_t *buf; /* Pointer to header buffer */
- const uint8_t *p; /* Pointer into raw data buffer */
+ const uint8_t *image = (const uint8_t *)_image; /* Pointer into raw data buffer */
H5B2_hdr_t *ret_value; /* Return value */
FUNC_ENTER_STATIC
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
+ HDassert(image);
HDassert(udata);
/* Allocate new B-tree header and reset cache info */
if(NULL == (hdr = H5B2__hdr_alloc(udata->f)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "allocation failed for B-tree header")
- /* Wrap the local buffer for serialized header info */
- if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't wrap buffer")
-
- /* Get a pointer to a buffer that's large enough for header */
- if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->hdr_size)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "can't get actual buffer")
-
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")
-
- /* Get temporary pointer to serialized header */
- p = buf;
-
/* Magic number */
- if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ if(HDmemcmp(image, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree header signature")
- p += H5_SIZEOF_MAGIC;
+ image += H5_SIZEOF_MAGIC;
/* Version */
- if(*p++ != H5B2_HDR_VERSION)
+ if(*image++ != H5B2_HDR_VERSION)
HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree header version")
/* B-tree class */
- id = (H5B2_subid_t)*p++;
+ id = (H5B2_subid_t)*image++;
if(id >= H5B2_NUM_BTREE_ID)
HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
/* Node size (in bytes) */
- UINT32DECODE(p, cparam.node_size);
+ UINT32DECODE(image, cparam.node_size);
/* Raw key size (in bytes) */
- UINT16DECODE(p, cparam.rrec_size);
+ UINT16DECODE(image, cparam.rrec_size);
/* Depth of tree */
- UINT16DECODE(p, depth);
+ UINT16DECODE(image, depth);
/* Split & merge %s */
- cparam.split_percent = *p++;
- cparam.merge_percent = *p++;
+ cparam.split_percent = *image++;
+ cparam.merge_percent = *image++;
/* Root node pointer */
- H5F_addr_decode(udata->f, (const uint8_t **)&p, &(hdr->root.addr));
- UINT16DECODE(p, hdr->root.node_nrec);
- H5F_DECODE_LENGTH(udata->f, p, hdr->root.all_nrec);
+ H5F_addr_decode(udata->f, (const uint8_t **)&image, &(hdr->root.addr));
+ UINT16DECODE(image, hdr->root.node_nrec);
+ H5F_DECODE_LENGTH(udata->f, image, hdr->root.all_nrec);
/* Metadata checksum */
- UINT32DECODE(p, stored_chksum);
+ UINT32DECODE(image, stored_chksum);
/* Sanity check */
- HDassert((size_t)(p - (const uint8_t *)buf) == hdr->hdr_size);
+ HDassert((size_t)(image - (const uint8_t *)_image) == hdr->hdr_size);
/* Compute checksum on entire header */
- computed_chksum = H5_checksum_metadata(buf, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
+ computed_chksum = H5_checksum_metadata(_image, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@@ -242,131 +279,59 @@ H5B2__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't initialize B-tree header info")
/* Set the B-tree header's address */
- hdr->addr = addr;
+ hdr->addr = udata->addr;
+
+ /* Sanity check */
+ HDassert((size_t)(image - (const uint8_t *)_image) <= len);
/* Set return value */
ret_value = hdr;
done:
- /* Release resources */
- if(wb && H5WB_unwrap(wb) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && hdr)
if(H5B2__hdr_free(hdr) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, NULL, "can't release v2 B-tree header")
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
+} /* end H5B2__cache_hdr_deserialize() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_hdr_flush
+ * Function: H5B2__cache_hdr_image_len
*
- * Purpose: Flushes a dirty B-tree header to disk.
+ * Purpose: Compute the size of the data structure on disk.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 1 2005
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 20, 2010
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
- H5B2_hdr_t *hdr, unsigned H5_ATTR_UNUSED * flags_ptr)
+H5B2__cache_hdr_image_len(const void *_thing, size_t *image_len,
+ hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr)
{
- H5WB_t *wb = NULL; /* Wrapped buffer for header data */
- uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
- herr_t ret_value = SUCCEED; /* Return value */
+ const H5B2_hdr_t *hdr = (const H5B2_hdr_t *)_thing; /* Pointer to the B-tree header */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
HDassert(hdr);
+ HDassert(image_len);
- if(hdr->cache_info.is_dirty) {
- uint8_t *buf; /* Pointer to header buffer */
- uint8_t *p; /* Pointer into raw data buffer */
- uint32_t metadata_chksum; /* Computed metadata checksum value */
-
- /* Set the B-tree header's file context for this operation */
- hdr->f = f;
-
- /* Wrap the local buffer for serialized header info */
- if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't wrap buffer")
-
- /* Get a pointer to a buffer that's large enough for header */
- if(NULL == (buf = (uint8_t *)H5WB_actual(wb, hdr->hdr_size)))
- HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "can't get actual buffer")
-
- /* Get temporary pointer to serialized header */
- p = buf;
-
- /* Magic number */
- HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
- p += H5_SIZEOF_MAGIC;
-
- /* Version # */
- *p++ = H5B2_HDR_VERSION;
-
- /* B-tree type */
- *p++ = hdr->cls->id;
+ /* Set the image length size */
+ *image_len = hdr->hdr_size;
- /* Node size (in bytes) */
- UINT32ENCODE(p, hdr->node_size);
-
- /* Raw key size (in bytes) */
- UINT16ENCODE(p, hdr->rrec_size);
-
- /* Depth of tree */
- UINT16ENCODE(p, hdr->depth);
-
- /* Split & merge %s */
- H5_CHECK_OVERFLOW(hdr->split_percent, /* From: */ unsigned, /* To: */ uint8_t);
- *p++ = (uint8_t)hdr->split_percent;
- H5_CHECK_OVERFLOW(hdr->merge_percent, /* From: */ unsigned, /* To: */ uint8_t);
- *p++ = (uint8_t)hdr->merge_percent;
-
- /* Root node pointer */
- H5F_addr_encode(f, &p, hdr->root.addr);
- UINT16ENCODE(p, hdr->root.node_nrec);
- H5F_ENCODE_LENGTH(f, p, hdr->root.all_nrec);
-
- /* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(buf, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
-
- /* Metadata checksum */
- UINT32ENCODE(p, metadata_chksum);
-
- /* Write the B-tree header. */
- HDassert((size_t)(p - buf) == hdr->hdr_size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, hdr->hdr_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk")
-
- hdr->cache_info.is_dirty = FALSE;
- } /* end if */
-
- if(destroy)
- if(H5B2__cache_hdr_dest(f, hdr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
-
-done:
- /* Release resources */
- if(wb && H5WB_unwrap(wb) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2__cache_hdr_flush() */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2__cache_hdr_image_len() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_hdr_dest
+ * Function: H5B2__cache_hdr_serialize
*
- * Purpose: Destroys a B-tree header in memory.
+ * Purpose: Flushes a dirty B-tree header to disk.
*
* Return: Non-negative on success/Negative on failure
*
@@ -377,109 +342,132 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr)
+H5B2__cache_hdr_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
+ void *_thing)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5B2_hdr_t *hdr = (H5B2_hdr_t *)_thing; /* Pointer to the B-tree header */
+ uint8_t *image = (uint8_t *)_image; /* Pointer into raw data buffer */
+ uint32_t metadata_chksum; /* Computed metadata checksum value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
- /* Check arguments */
+ /* check arguments */
+ HDassert(f);
+ HDassert(image);
HDassert(hdr);
- HDassert(hdr->rc == 0);
- /* If we're going to free the space on disk, the address must be valid */
- HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr));
+ /* Magic number */
+ HDmemcpy(image, H5B2_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ image += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *image++ = H5B2_HDR_VERSION;
- /* Check for freeing file space for B-tree header */
- if(hdr->cache_info.free_file_space_on_destroy) {
- /* Release the space on disk */
- /* (XXX: Nasty usage of internal DXPL value! -QAK) */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)hdr->hdr_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header")
- } /* end if */
+ /* B-tree type */
+ *image++ = hdr->cls->id;
- /* Release B-tree header info */
- if(H5B2__hdr_free(hdr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header info")
+ /* Node size (in bytes) */
+ UINT32ENCODE(image, hdr->node_size);
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_hdr_dest() */
+ /* Raw key size (in bytes) */
+ UINT16ENCODE(image, hdr->rrec_size);
+
+ /* Depth of tree */
+ UINT16ENCODE(image, hdr->depth);
+
+ /* Split & merge %s */
+ H5_CHECK_OVERFLOW(hdr->split_percent, /* From: */ unsigned, /* To: */ uint8_t);
+ *image++ = (uint8_t)hdr->split_percent;
+ H5_CHECK_OVERFLOW(hdr->merge_percent, /* From: */ unsigned, /* To: */ uint8_t);
+ *image++ = (uint8_t)hdr->merge_percent;
+
+ /* Root node pointer */
+ H5F_addr_encode(f, &image, hdr->root.addr);
+ UINT16ENCODE(image, hdr->root.node_nrec);
+ H5F_ENCODE_LENGTH(f, image, hdr->root.all_nrec);
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(_image, (hdr->hdr_size - H5B2_SIZEOF_CHKSUM), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(image, metadata_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(image - (uint8_t *)_image) <= len);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5B2__cache_hdr_serialize() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_hdr_clear
+ * Function: H5B2__cache_hdr_free_icr
*
- * Purpose: Mark a B-tree header in memory as non-dirty.
+ * Purpose: Destroy/release an "in core representation" of a data
+ * structure
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 1 2005
+ * Programmer: Mike McGreevy
+ * mcgreevy@hdfgroup.org
+ * June 18, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_hdr_clear(H5F_t *f, H5B2_hdr_t *hdr, hbool_t destroy)
+H5B2__cache_hdr_free_icr(void *thing)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
- /*
- * Check arguments.
- */
- HDassert(hdr);
-
- /* Reset the dirty flag. */
- hdr->cache_info.is_dirty = FALSE;
+ /* Check arguments */
+ HDassert(thing);
- if(destroy)
- if(H5B2__cache_hdr_dest(f, hdr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree header")
+ /* Destroy v2 B-tree header */
+ if(H5B2__hdr_free((H5B2_hdr_t *)thing) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_hdr_clear() */
+} /* H5B2__cache_hdr_free_icr() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_hdr_size
+ * Function: H5B2__cache_int_get_load_size
*
- * Purpose: Compute the size in bytes of a B-tree header
- * on disk, and return it in *size_ptr. On failure,
- * the value of *size_ptr is undefined.
+ * Purpose: Compute the size of the data structure on disk.
*
- * Return: SUCCEED (Can't fail)
+ * Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
- * Feb 1 2005
+ * May 18, 2010
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_hdr_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_hdr_t *hdr, size_t *size_ptr)
+H5B2__cache_int_get_load_size(const void *_udata, size_t *image_len)
{
+ const H5B2_internal_cache_ud_t *udata = (const H5B2_internal_cache_ud_t *)_udata; /* User data for callback */
+
FUNC_ENTER_STATIC_NOERR
/* Check arguments */
- HDassert(f);
- HDassert(hdr);
- HDassert(size_ptr);
+ HDassert(udata);
+ HDassert(udata->hdr);
+ HDassert(image_len);
- /* Set size value */
- *size_ptr = hdr->hdr_size;
+ /* Set the image length size */
+ *image_len = udata->hdr->node_size;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5B2__cache_hdr_size() */
+} /* end H5B2__cache_int_get_load_size() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_internal_load
+ * Function: H5B2__cache_int_deserialize
*
- * Purpose: Loads a B-tree internal node from the disk.
+ * Purpose: Deserialize a B-tree internal node from the disk.
*
* Return: Success: Pointer to a new B-tree internal node.
* Failure: NULL
@@ -490,12 +478,13 @@ H5B2__cache_hdr_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_hdr_t *hdr, size_
*
*-------------------------------------------------------------------------
*/
-static H5B2_internal_t *
-H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
+static void *
+H5B2__cache_int_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
+ void *_udata, hbool_t H5_ATTR_UNUSED *dirty)
{
H5B2_internal_cache_ud_t *udata = (H5B2_internal_cache_ud_t *)_udata; /* Pointer to user data */
H5B2_internal_t *internal = NULL; /* Internal node read */
- const uint8_t *p; /* Pointer into raw data buffer */
+ const uint8_t *image = (const uint8_t *)_image; /* 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 stored_chksum; /* Stored metadata checksum value */
@@ -506,8 +495,7 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
FUNC_ENTER_STATIC
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
+ HDassert(image);
HDassert(udata);
/* Allocate new internal node and reset cache info */
@@ -515,9 +503,6 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemset(&internal->cache_info, 0, sizeof(H5AC_info_t));
- /* Set the B-tree header's file context for this operation */
- udata->hdr->f = f;
-
/* Increment ref. count on B-tree header */
if(H5B2__hdr_incr(udata->hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header")
@@ -525,23 +510,17 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
/* Share B-tree information */
internal->hdr = udata->hdr;
- /* Read header from disk */
- if(H5F_block_read(f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree internal node")
-
- p = udata->hdr->page;
-
/* Magic number */
- if(HDmemcmp(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ if(HDmemcmp(image, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree internal node signature")
- p += H5_SIZEOF_MAGIC;
+ image += H5_SIZEOF_MAGIC;
/* Version */
- if(*p++ != H5B2_INT_VERSION)
+ if(*image++ != H5B2_INT_VERSION)
HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree internal node version")
/* B-tree type */
- if(*p++ != (uint8_t)udata->hdr->cls->id)
+ if(*image++ != (uint8_t)udata->hdr->cls->id)
HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
/* Allocate space for the native keys in memory */
@@ -560,11 +539,11 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
native = internal->int_native;
for(u = 0; u < internal->nrec; u++) {
/* Decode record */
- if((udata->hdr->cls->decode)(p, native, udata->hdr->cb_ctx) < 0)
+ if((udata->hdr->cls->decode)(image, native, udata->hdr->cb_ctx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode B-tree record")
/* Move to next record */
- p += udata->hdr->rrec_size;
+ image += udata->hdr->rrec_size;
native += udata->hdr->cls->nrec_size;
} /* end for */
@@ -572,10 +551,10 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
int_node_ptr = internal->node_ptrs;
for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
/* Decode node pointer */
- H5F_addr_decode(udata->f, (const uint8_t **)&p, &(int_node_ptr->addr));
- UINT64DECODE_VAR(p, int_node_ptr->node_nrec, udata->hdr->max_nrec_size);
+ H5F_addr_decode(udata->f, (const uint8_t **)&image, &(int_node_ptr->addr));
+ UINT64DECODE_VAR(image, int_node_ptr->node_nrec, udata->hdr->max_nrec_size);
if(udata->depth > 1)
- UINT64DECODE_VAR(p, int_node_ptr->all_nrec, udata->hdr->node_info[udata->depth - 1].cum_max_nrec_size)
+ UINT64DECODE_VAR(image, int_node_ptr->all_nrec, udata->hdr->node_info[udata->depth - 1].cum_max_nrec_size)
else
int_node_ptr->all_nrec = int_node_ptr->node_nrec;
@@ -584,13 +563,13 @@ H5B2__cache_internal_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata)
} /* end for */
/* Compute checksum on internal node */
- computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
+ computed_chksum = H5_checksum_metadata(_image, (size_t)(image - (const uint8_t *)_image), 0);
/* Metadata checksum */
- UINT32DECODE(p, stored_chksum);
+ UINT32DECODE(image, stored_chksum);
/* Sanity check parsing */
- HDassert((size_t)(p - (const uint8_t *)udata->hdr->page) <= udata->hdr->node_size);
+ HDassert((size_t)(image - (const uint8_t *)_image) <= len);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@@ -605,224 +584,194 @@ done:
HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree internal node")
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2__cache_internal_load() */ /*lint !e818 Can't make udata a pointer to const */
+} /* H5B2__cache_int_deserialize() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_internal_flush
+ * Function: H5B2__cache_int_image_len
*
- * Purpose: Flushes a dirty B-tree internal node to disk.
+ * Purpose: Compute the size of the data structure on disk.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 3 2005
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 20, 2010
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_internal_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_internal_t *internal, unsigned H5_ATTR_UNUSED * flags_ptr)
+H5B2__cache_int_image_len(const void *_thing, size_t *image_len,
+ hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ const H5B2_internal_t *internal = (const H5B2_internal_t *)_thing; /* Pointer to the B-tree internal node */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
HDassert(internal);
HDassert(internal->hdr);
+ HDassert(image_len);
- if(internal->cache_info.is_dirty) {
- 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 */
-
- /* Set the B-tree header's file context for this operation */
- internal->hdr->f = f;
-
- p = internal->hdr->page;
-
- /* Magic number */
- HDmemcpy(p, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC);
- p += H5_SIZEOF_MAGIC;
-
- /* Version # */
- *p++ = H5B2_INT_VERSION;
-
- /* B-tree type */
- *p++ = internal->hdr->cls->id;
- HDassert((size_t)(p - internal->hdr->page) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
-
- /* Serialize records for internal node */
- native = internal->int_native;
- for(u = 0; u < internal->nrec; u++) {
- /* Encode record */
- if((internal->hdr->cls->encode)(p, native, internal->hdr->cb_ctx) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
-
- /* Move to next record */
- p += internal->hdr->rrec_size;
- native += internal->hdr->cls->nrec_size;
- } /* end for */
-
- /* Serialize node pointers for internal node */
- int_node_ptr = internal->node_ptrs;
- for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
- /* Encode node pointer */
- H5F_addr_encode(f, &p, int_node_ptr->addr);
- UINT64ENCODE_VAR(p, int_node_ptr->node_nrec, internal->hdr->max_nrec_size);
- if(internal->depth > 1)
- UINT64ENCODE_VAR(p, int_node_ptr->all_nrec, internal->hdr->node_info[internal->depth - 1].cum_max_nrec_size);
-
- /* Move to next node pointer */
- int_node_ptr++;
- } /* end for */
-
- /* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(internal->hdr->page, (size_t)(p - internal->hdr->page), 0);
-
- /* Metadata checksum */
- UINT32ENCODE(p, metadata_chksum);
-
- /* Write the B-tree internal node */
- HDassert((size_t)(p - internal->hdr->page) <= internal->hdr->node_size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, internal->hdr->node_size, dxpl_id, internal->hdr->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree internal node to disk")
+ /* Set the image length size */
+ *image_len = internal->hdr->node_size;
- internal->cache_info.is_dirty = FALSE;
- } /* end if */
-
- if(destroy)
- if(H5B2__cache_internal_dest(f, internal) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree internal node")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2__cache_internal_flush() */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2__cache_int_image_len() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_internal_dest
+ * Function: H5B2__cache_int_serialize
*
- * Purpose: Destroys a B-tree internal node in memory.
+ * Purpose: Serializes a B-tree internal node for writing to disk.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Feb 2 2005
+ * Feb 3 2005
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_internal_dest(H5F_t *f, H5B2_internal_t *internal)
+H5B2__cache_int_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
+ void *_thing)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5B2_internal_t *internal = (H5B2_internal_t *)_thing; /* Pointer to the B-tree internal node */
+ uint8_t *image = (uint8_t *)_image; /* 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 */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
- /* Check arguments */
+ /* check arguments */
HDassert(f);
+ HDassert(image);
HDassert(internal);
HDassert(internal->hdr);
- /* If we're going to free the space on disk, the address must be valid */
- HDassert(!internal->cache_info.free_file_space_on_destroy || H5F_addr_defined(internal->cache_info.addr));
+ /* Magic number */
+ HDmemcpy(image, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ image += H5_SIZEOF_MAGIC;
+
+ /* Version # */
+ *image++ = H5B2_INT_VERSION;
- /* Check for freeing file space for B-tree internal node */
- if(internal->cache_info.free_file_space_on_destroy) {
- /* Release the space on disk */
- /* (XXX: Nasty usage of internal DXPL value! -QAK) */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, internal->cache_info.addr, (hsize_t)internal->hdr->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree internal node")
- } /* end if */
+ /* B-tree type */
+ *image++ = internal->hdr->cls->id;
+ HDassert((size_t)(image - (uint8_t *)_image) == (H5B2_INT_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
- /* Release v2 b-tree internal node */
- if(H5B2__internal_free(internal) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree internal node")
+ /* Serialize records for internal node */
+ native = internal->int_native;
+ for(u = 0; u < internal->nrec; u++) {
+ /* Encode record */
+ if((internal->hdr->cls->encode)(image, native, internal->hdr->cb_ctx) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
+
+ /* Move to next record */
+ image += internal->hdr->rrec_size;
+ native += internal->hdr->cls->nrec_size;
+ } /* end for */
+
+ /* Serialize node pointers for internal node */
+ int_node_ptr = internal->node_ptrs;
+ for(u = 0; u < (unsigned)(internal->nrec + 1); u++) {
+ /* Encode node pointer */
+ H5F_addr_encode(f, &image, int_node_ptr->addr);
+ UINT64ENCODE_VAR(image, int_node_ptr->node_nrec, internal->hdr->max_nrec_size);
+ if(internal->depth > 1)
+ UINT64ENCODE_VAR(image, int_node_ptr->all_nrec, internal->hdr->node_info[internal->depth - 1].cum_max_nrec_size);
+
+ /* Move to next node pointer */
+ int_node_ptr++;
+ } /* end for */
+
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(_image, (size_t)(image - (uint8_t *)_image), 0);
+
+ /* Metadata checksum */
+ UINT32ENCODE(image, metadata_chksum);
+
+ /* Sanity check */
+ HDassert((size_t)(image - (uint8_t *)_image) <= len);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_internal_dest() */
+} /* H5B2__cache_int_serialize() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_internal_clear
+ * Function: H5B2__cache_int_free_icr
*
- * Purpose: Mark a B-tree internal node in memory as non-dirty.
+ * Purpose: Destroy/release an "in core representation" of a data
+ * structure
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
+ * Programmer: Mike McGreevy
+ * mcgreevy@hdfgroup.org
+ * June 18, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_internal_clear(H5F_t *f, H5B2_internal_t *internal, hbool_t destroy)
+H5B2__cache_int_free_icr(void *thing)
{
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
- /*
- * Check arguments.
- */
- HDassert(internal);
-
- /* Reset the dirty flag. */
- internal->cache_info.is_dirty = FALSE;
+ /* Check arguments */
+ HDassert(thing);
- if(destroy)
- if(H5B2__cache_internal_dest(f, internal) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree internal node")
+ /* Release v2 B-tree internal node */
+ if(H5B2__internal_free((H5B2_internal_t *)thing) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree internal node")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_internal_clear() */
+} /* H5B2__cache_int_free_icr() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_internal_size
+ * Function: H5B2__cache_leaf_get_load_size
*
- * Purpose: Compute the size in bytes of a B-tree internal node
- * on disk, and return it in *size_ptr. On failure,
- * the value of *size_ptr is undefined.
+ * Purpose: Compute the size of the data structure on disk.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 18, 2010
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_internal_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_internal_t *internal, size_t *size_ptr)
+H5B2__cache_leaf_get_load_size(const void *_udata, size_t *image_len)
{
+ const H5B2_leaf_cache_ud_t *udata = (const H5B2_leaf_cache_ud_t *)_udata; /* User data for callback */
+
FUNC_ENTER_STATIC_NOERR
/* Check arguments */
- HDassert(internal);
- HDassert(internal->hdr);
- HDassert(size_ptr);
+ HDassert(udata);
+ HDassert(udata->hdr);
+ HDassert(image_len);
- /* Set size value */
- *size_ptr = internal->hdr->node_size;
+ /* Set the image length size */
+ *image_len = udata->hdr->node_size;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5B2__cache_internal_size() */
+} /* end H5B2__cache_leaf_get_load_size() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_leaf_load
+ * Function: H5B2__cache_leaf_deserialize
*
- * Purpose: Loads a B-tree leaf from the disk.
+ * Purpose: Deserialize a B-tree leaf from the disk.
*
* Return: Success: Pointer to a new B-tree leaf node.
* Failure: NULL
@@ -833,12 +782,13 @@ H5B2__cache_internal_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_internal_t *
*
*-------------------------------------------------------------------------
*/
-static H5B2_leaf_t *
-H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, haddr_t addr, void *_udata)
+static void *
+H5B2__cache_leaf_deserialize(const void *_image, size_t H5_ATTR_UNUSED len,
+ void *_udata, hbool_t H5_ATTR_UNUSED *dirty)
{
H5B2_leaf_cache_ud_t *udata = (H5B2_leaf_cache_ud_t *)_udata;
H5B2_leaf_t *leaf = NULL; /* Pointer to lead node loaded */
- const uint8_t *p; /* Pointer into raw data buffer */
+ const uint8_t *image = (const uint8_t *)_image; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native keys */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
@@ -848,8 +798,7 @@ H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, haddr_t addr, void
FUNC_ENTER_STATIC
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
+ HDassert(image);
HDassert(udata);
/* Allocate new leaf node and reset cache info */
@@ -857,9 +806,6 @@ H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, haddr_t addr, void
HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed")
HDmemset(&leaf->cache_info, 0, sizeof(H5AC_info_t));
- /* Set the B-tree header's file context for this operation */
- udata->hdr->f = udata->f;
-
/* Increment ref. count on B-tree header */
if(H5B2__hdr_incr(udata->hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment ref. count on B-tree header")
@@ -867,23 +813,17 @@ H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, haddr_t addr, void
/* Share B-tree header information */
leaf->hdr = udata->hdr;
- /* Read header from disk */
- if(H5F_block_read(udata->f, H5FD_MEM_BTREE, addr, udata->hdr->node_size, dxpl_id, udata->hdr->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree leaf node")
-
- p = udata->hdr->page;
-
/* Magic number */
- if(HDmemcmp(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC))
+ if(HDmemcmp(image, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "wrong B-tree leaf node signature")
- p += H5_SIZEOF_MAGIC;
+ image += H5_SIZEOF_MAGIC;
/* Version */
- if(*p++ != H5B2_LEAF_VERSION)
+ if(*image++ != H5B2_LEAF_VERSION)
HGOTO_ERROR(H5E_BTREE, H5E_BADRANGE, NULL, "wrong B-tree leaf node version")
/* B-tree type */
- if(*p++ != (uint8_t)udata->hdr->cls->id)
+ if(*image++ != (uint8_t)udata->hdr->cls->id)
HGOTO_ERROR(H5E_BTREE, H5E_BADTYPE, NULL, "incorrect B-tree type")
/* Allocate space for the native keys in memory */
@@ -897,27 +837,30 @@ H5B2__cache_leaf_load(H5F_t H5_ATTR_UNUSED *f, hid_t dxpl_id, haddr_t addr, void
native = leaf->leaf_native;
for(u = 0; u < leaf->nrec; u++) {
/* Decode record */
- if((udata->hdr->cls->decode)(p, native, udata->hdr->cb_ctx) < 0)
+ if((udata->hdr->cls->decode)(image, native, udata->hdr->cb_ctx) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, NULL, "unable to decode B-tree record")
/* Move to next record */
- p += udata->hdr->rrec_size;
+ image += udata->hdr->rrec_size;
native += udata->hdr->cls->nrec_size;
} /* end for */
/* Compute checksum on leaf node */
- computed_chksum = H5_checksum_metadata(udata->hdr->page, (size_t)(p - (const uint8_t *)udata->hdr->page), 0);
+ computed_chksum = H5_checksum_metadata(_image, (size_t)(image - (const uint8_t *)_image), 0);
/* Metadata checksum */
- UINT32DECODE(p, stored_chksum);
+ UINT32DECODE(image, stored_chksum);
/* Sanity check parsing */
- HDassert((size_t)(p - (const uint8_t *)udata->hdr->page) <= udata->hdr->node_size);
+ HDassert((size_t)(image - (const uint8_t *)_image) <= udata->hdr->node_size);
/* Verify checksum */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_BTREE, H5E_BADVALUE, NULL, "incorrect metadata checksum for v2 leaf node")
+ /* Sanity check */
+ HDassert((size_t)(image - (const uint8_t *)_image) <= len);
+
/* Set return value */
ret_value = leaf;
@@ -927,96 +870,46 @@ done:
HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to destroy B-tree leaf node")
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2__cache_leaf_load() */ /*lint !e818 Can't make udata a pointer to const */
+} /* H5B2__cache_leaf_deserialize() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_leaf_flush
+ * Function: H5B2__cache_leaf_image_len
*
- * Purpose: Flushes a dirty B-tree leaf node to disk.
+ * Purpose: Compute the size of the data structure on disk.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * May 20, 2010
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_leaf_t *leaf, unsigned H5_ATTR_UNUSED * flags_ptr)
+H5B2__cache_leaf_image_len(const void *_thing, size_t *image_len,
+ hbool_t H5_ATTR_UNUSED *compressed_ptr, size_t H5_ATTR_UNUSED *compressed_image_len_ptr)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ const H5B2_leaf_t *leaf = (const H5B2_leaf_t *)_thing; /* Pointer to the B-tree leaf node */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* Check arguments */
- HDassert(f);
- HDassert(H5F_addr_defined(addr));
HDassert(leaf);
HDassert(leaf->hdr);
+ HDassert(image_len);
- if(leaf->cache_info.is_dirty) {
- 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 */
-
- /* Set the B-tree header's file context for this operation */
- leaf->hdr->f = f;
-
- p = leaf->hdr->page;
-
- /* magic number */
- HDmemcpy(p, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC);
- p += H5_SIZEOF_MAGIC;
-
- /* version # */
- *p++ = H5B2_LEAF_VERSION;
-
- /* b-tree type */
- *p++ = leaf->hdr->cls->id;
- HDassert((size_t)(p - leaf->hdr->page) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
+ /* Set the image length size */
+ *image_len = leaf->hdr->node_size;
- /* Serialize records for leaf node */
- native = leaf->leaf_native;
- for(u = 0; u < leaf->nrec; u++) {
- /* Encode record */
- if((leaf->hdr->cls->encode)(p, native, leaf->hdr->cb_ctx) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
-
- /* Move to next record */
- p += leaf->hdr->rrec_size;
- native += leaf->hdr->cls->nrec_size;
- } /* end for */
-
- /* Compute metadata checksum */
- metadata_chksum = H5_checksum_metadata(leaf->hdr->page, (size_t)(p - leaf->hdr->page), 0);
-
- /* Metadata checksum */
- UINT32ENCODE(p, metadata_chksum);
-
- /* Write the B-tree leaf node */
- HDassert((size_t)(p - leaf->hdr->page) <= leaf->hdr->node_size);
- if(H5F_block_write(f, H5FD_MEM_BTREE, addr, leaf->hdr->node_size, dxpl_id, leaf->hdr->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree leaf node to disk")
-
- leaf->cache_info.is_dirty = FALSE;
- } /* end if */
-
- if(destroy)
- if(H5B2__cache_leaf_dest(f, leaf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2__cache_leaf_flush() */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2__cache_leaf_image_len() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_leaf_dest
+ * Function: H5B2__cache_leaf_serialize
*
- * Purpose: Destroys a B-tree leaf node in memory.
+ * Purpose: Serializes a B-tree leaf node for writing to disk.
*
* Return: Non-negative on success/Negative on failure
*
@@ -1027,102 +920,90 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf)
+H5B2__cache_leaf_serialize(const H5F_t *f, void *_image, size_t H5_ATTR_UNUSED len,
+ void *_thing)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5B2_leaf_t *leaf = (H5B2_leaf_t *)_thing; /* Pointer to the B-tree leaf node */
+ uint8_t *image = (uint8_t *)_image; /* 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_STATIC
- /* Check arguments */
+ /* check arguments */
HDassert(f);
+ HDassert(image);
HDassert(leaf);
HDassert(leaf->hdr);
- /* If we're going to free the space on disk, the address must be valid */
- HDassert(!leaf->cache_info.free_file_space_on_destroy || H5F_addr_defined(leaf->cache_info.addr));
-
- /* Check for freeing file space for B-tree leaf node */
- if(leaf->cache_info.free_file_space_on_destroy) {
- /* Release the space on disk */
- /* (XXX: Nasty usage of internal DXPL value! -QAK) */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, H5AC_dxpl_id, leaf->cache_info.addr, (hsize_t)leaf->hdr->node_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree leaf node")
- } /* end if */
+ /* magic number */
+ HDmemcpy(image, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC);
+ image += H5_SIZEOF_MAGIC;
- /* Destroy v2 b-tree leaf node */
- if(H5B2__leaf_free(leaf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
+ /* version # */
+ *image++ = H5B2_LEAF_VERSION;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_leaf_dest() */
+ /* B-tree type */
+ *image++ = leaf->hdr->cls->id;
+ HDassert((size_t)(image - (uint8_t *)_image) == (H5B2_LEAF_PREFIX_SIZE - H5B2_SIZEOF_CHKSUM));
-
-/*-------------------------------------------------------------------------
- * Function: H5B2__cache_leaf_clear
- *
- * Purpose: Mark a B-tree leaf node in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5B2__cache_leaf_clear(H5F_t *f, H5B2_leaf_t *leaf, hbool_t destroy)
-{
- herr_t ret_value = SUCCEED;
+ /* Serialize records for leaf node */
+ native = leaf->leaf_native;
+ for(u = 0; u < leaf->nrec; u++) {
+ /* Encode record */
+ if((leaf->hdr->cls->encode)(image, native, leaf->hdr->cb_ctx) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree record")
- FUNC_ENTER_STATIC
+ /* Move to next record */
+ image += leaf->hdr->rrec_size;
+ native += leaf->hdr->cls->nrec_size;
+ } /* end for */
- /*
- * Check arguments.
- */
- HDassert(leaf);
+ /* Compute metadata checksum */
+ metadata_chksum = H5_checksum_metadata(_image, (size_t)((const uint8_t *)image - (const uint8_t *)_image), 0);
- /* Reset the dirty flag. */
- leaf->cache_info.is_dirty = FALSE;
+ /* Metadata checksum */
+ UINT32ENCODE(image, metadata_chksum);
- if(destroy)
- if(H5B2__cache_leaf_dest(f, leaf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
+ /* Sanity check */
+ HDassert((size_t)(image - (uint8_t *)_image) <= len);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2__cache_leaf_clear() */
+} /* H5B2__cache_leaf_serialize() */
/*-------------------------------------------------------------------------
- * Function: H5B2__cache_leaf_size
+ * Function: H5B2__cache_leaf_free_icr
*
- * Purpose: Compute the size in bytes of a B-tree leaf node
- * on disk, and return it in *size_ptr. On failure,
- * the value of *size_ptr is undefined.
+ * Purpose: Destroy/release an "in core representation" of a data
+ * structure
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 2 2005
+ * Programmer: Mike McGreevy
+ * mcgreevy@hdfgroup.org
+ * June 18, 2008
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2__cache_leaf_size(const H5F_t H5_ATTR_UNUSED *f, const H5B2_leaf_t *leaf, size_t *size_ptr)
+H5B2__cache_leaf_free_icr(void *thing)
{
- FUNC_ENTER_STATIC_NOERR
+ herr_t ret_value = SUCCEED; /* Return value */
- /* check arguments */
- HDassert(leaf);
- HDassert(leaf->hdr);
- HDassert(size_ptr);
+ FUNC_ENTER_STATIC
- /* Set size value */
- *size_ptr = leaf->hdr->node_size;
+ /* Check arguments */
+ HDassert(thing);
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5B2__cache_leaf_size() */
+ /* Destroy v2 B-tree leaf node */
+ if(H5B2__leaf_free((H5B2_leaf_t *)thing) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree leaf node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2__cache_leaf_free_icr() */