[svn-r13926] Description:

Add small interface to "wrap" a static buffer (usually on the stack), but
still allow for buffers larger than the static buffer to be allocated.  This
can eliminate _many_ short-lived buffer allocations in situations where the
buffer is a predictable size (or at least a "very likely" size).

    Also, some minor code cleanups, particularly in the SOHM caching code.

Tested on:
    Mac OS X/32 10.4.10 (amazon)
This commit is contained in:
Quincey Koziol 2007-06-28 22:12:45 -05:00
parent 58467956ba
commit cad9846d77
20 changed files with 1188 additions and 595 deletions

View File

@ -696,6 +696,8 @@
./src/H5TSprivate.h
./src/H5V.c
./src/H5Vprivate.h
./src/H5WB.c
./src/H5WBprivate.h
./src/H5Z.c
./src/H5Zdeflate.c
./src/H5Zfletcher32.c

View File

@ -42,6 +42,7 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared object header messages */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
@ -166,9 +167,6 @@ typedef struct H5A_bt2_ud_rmbi_t {
/* Local Variables */
/*******************/
/* Declare a free list to manage the serialized attribute information */
H5FL_BLK_DEFINE(ser_attr);
/*-------------------------------------------------------------------------
@ -410,8 +408,8 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
H5A_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
H5HF_t *fheap = NULL; /* Fractal heap handle for attributes */
H5HF_t *shared_fheap = NULL; /* Fractal heap handle for shared header messages */
H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing message */
void *attr_ptr = NULL; /* Pointer to serialized message */
unsigned mesg_flags = 0; /* Flags for storing message */
htri_t attr_sharable; /* Flag indicating attributes are sharable */
herr_t ret_value = SUCCEED; /* Return value */
@ -474,19 +472,20 @@ H5A_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_ainfo_t *ainfo, H5A_t *attr)
udata.id = attr->sh_loc.u.heap_id;
} /* end if */
else {
size_t attr_size; /* Size of serialized attribute in the heap */
void *attr_ptr; /* Pointer to serialized message */
size_t attr_size; /* Size of serialized attribute in the heap */
/* Find out the size of buffer needed for serialized message */
if((attr_size = H5O_msg_raw_size(f, H5O_ATTR_ID, FALSE, attr)) == 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get message size")
/* Allocate space for serialized message, if necessary */
if(attr_size > sizeof(attr_buf)) {
if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end if */
else
attr_ptr = attr_buf;
/* Wrap the local buffer for serialized attributes */
if(NULL == (wb = H5WB_wrap(attr_buf, sizeof(attr_buf))))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for attribute */
if(NULL == (attr_ptr = H5WB_actual(wb, attr_size)))
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of attribute or shared message */
if(H5O_msg_encode(f, H5O_ATTR_ID, FALSE, (unsigned char *)attr_ptr, attr) < 0)
@ -529,8 +528,8 @@ done:
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(attr_ptr && attr_ptr != attr_buf)
(void)H5FL_BLK_FREE(ser_attr, attr_ptr);
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_insert() */
@ -592,8 +591,8 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
{
H5A_dense_bt2_name_rec_t *record = (H5A_dense_bt2_name_rec_t *)_record; /* Record from B-tree */
H5A_bt2_od_wrt_t *op_data = (H5A_bt2_od_wrt_t *)_op_data; /* "op data" from v2 B-tree modify */
H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t attr_buf[H5A_ATTR_BUF_SIZE]; /* Buffer for serializing attribute */
void *attr_ptr = NULL; /* Pointer to serialized attribute */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_dense_write_bt2_cb)
@ -638,19 +637,20 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
*changed = TRUE;
} /* end if */
else {
size_t attr_size; /* Size of serialized attribute in the heap */
void *attr_ptr; /* Pointer to serialized message */
size_t attr_size; /* Size of serialized attribute in the heap */
/* Find out the size of buffer needed for serialized attribute */
if((attr_size = H5O_msg_raw_size(op_data->f, H5O_ATTR_ID, FALSE, op_data->attr)) == 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTGETSIZE, FAIL, "can't get attribute size")
/* Allocate space for serialized attribute, if necessary */
if(attr_size > sizeof(attr_buf)) {
if(NULL == (attr_ptr = H5FL_BLK_MALLOC(ser_attr, attr_size)))
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end if */
else
attr_ptr = attr_buf;
/* Wrap the local buffer for serialized attributes */
if(NULL == (wb = H5WB_wrap(attr_buf, sizeof(attr_buf))))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for attribute */
if(NULL == (attr_ptr = H5WB_actual(wb, attr_size)))
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of attribute */
if(H5O_msg_encode(op_data->f, H5O_ATTR_ID, FALSE, (unsigned char *)attr_ptr, op_data->attr) < 0)
@ -674,8 +674,8 @@ H5A_dense_write_bt2_cb(void *_record, void *_op_data, hbool_t *changed)
done:
/* Release resources */
if(attr_ptr && attr_ptr != attr_buf)
(void)H5FL_BLK_FREE(ser_attr, attr_ptr);
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5A_dense_write_bt2_cb() */

View File

@ -36,6 +36,8 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
@ -46,6 +48,9 @@
#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 */
@ -118,9 +123,6 @@ const H5AC_class_t H5AC_BT2_LEAF[1] = {{
/* Local Variables */
/*******************/
/* Declare a free list to manage B-tree header data to/from disk */
H5FL_BLK_DEFINE_STATIC(header_block);
/*-------------------------------------------------------------------------
@ -149,7 +151,9 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
size_t size; /* Header size */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
uint8_t *buf = NULL; /* Temporary buffer */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5B2_HDR_BUF_SIZE]; /* Buffer for header */
uint8_t *hdr; /* Pointer to header buffer */
uint8_t *p; /* Pointer into raw data buffer */
H5B2_t *ret_value; /* Return value */
@ -165,18 +169,23 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t));
/* Compute the size of the B-tree header on disk */
/* 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")
/* Compute the size of the serialized B-tree header on disk */
size = H5B2_HEADER_SIZE(f);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for header */
if(NULL == (hdr = H5WB_actual(wb, 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, size, dxpl_id, buf) < 0)
if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree header")
p = buf;
/* Get temporary pointer to serialized header */
p = hdr;
/* Magic number */
if(HDmemcmp(p, H5B2_HDR_MAGIC, (size_t)H5B2_SIZEOF_MAGIC))
@ -213,10 +222,10 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == size);
HDassert((size_t)(p - hdr) == size);
/* Compute checksum on entire header */
computed_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0);
computed_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@ -230,8 +239,9 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, vo
ret_value = bt2;
done:
if(buf)
(void)H5FL_BLK_FREE(header_block, buf);
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && bt2)
(void)H5B2_cache_hdr_dest(f, bt2);
@ -260,6 +270,8 @@ done:
static herr_t
H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B2_t *bt2, unsigned UNUSED * flags_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 */
FUNC_ENTER_NOAPI(H5B2_cache_hdr_flush, FAIL)
@ -271,7 +283,7 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
if (bt2->cache_info.is_dirty) {
H5B2_shared_t *shared; /* Shared B-tree information */
uint8_t *buf; /* Temporary raw data buffer */
uint8_t *hdr; /* Pointer to header buffer */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t metadata_chksum; /* Computed metadata checksum value */
@ -280,14 +292,19 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
HDassert(shared);
/* Compute the size of the B-tree header on disk */
/* 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")
/* Compute the size of the serialized B-tree header on disk */
size = H5B2_HEADER_SIZE(f);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for header */
if(NULL == (hdr = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, FAIL, "can't get actual buffer")
p = buf;
/* Get temporary pointer to serialized header */
p = hdr;
/* Magic number */
HDmemcpy(p, H5B2_HDR_MAGIC, (size_t)H5B2_SIZEOF_MAGIC);
@ -318,18 +335,16 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
H5F_ENCODE_LENGTH(f, p, bt2->root.all_nrec);
/* Compute metadata checksum */
metadata_chksum = H5_checksum_metadata(buf, (size - H5B2_SIZEOF_CHKSUM), 0);
metadata_chksum = H5_checksum_metadata(hdr, (size - H5B2_SIZEOF_CHKSUM), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the B-tree header. */
HDassert((size_t)(p - buf) == size);
if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
HDassert((size_t)(p - hdr) == size);
if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree header to disk")
(void)H5FL_BLK_FREE(header_block, buf);
bt2->cache_info.is_dirty = FALSE;
} /* end if */
@ -338,6 +353,10 @@ H5B2_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B
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() */

View File

@ -39,6 +39,7 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5Vprivate.h" /* Vector and array functions */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
@ -65,9 +66,6 @@
/* Package Variables */
/*********************/
/* Declare a free list to manage blocks of single datatype element data */
H5FL_BLK_DEFINE(type_elem);
/* Declare extern the free list to manage blocks of type conversion data */
H5FL_BLK_EXTERN(type_conv);
@ -174,7 +172,10 @@ herr_t
H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
const H5T_t *buf_type, const H5S_t *space, hid_t dxpl_id)
{
uint8_t *tconv_buf = NULL; /* Data type conv buffer */
H5WB_t *elem_wb = NULL; /* Wrapped buffer for element data */
uint8_t elem_buf[H5T_ELEM_BUF_SIZE]; /* Buffer for element data */
H5WB_t *bkg_elem_wb = NULL; /* Wrapped buffer for background data */
uint8_t bkg_elem_buf[H5T_ELEM_BUF_SIZE]; /* Buffer for background data */
uint8_t *bkg_buf = NULL; /* Background conversion buffer */
uint8_t *tmp_buf = NULL; /* Temp conversion buffer */
hid_t src_id = -1, dst_id = -1; /* Temporary type IDs */
@ -198,12 +199,18 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
/* If there's no fill value, just use zeros */
if(fill == NULL) {
/* Allocate space & initialize conversion buffer to zeros */
if(NULL == (tconv_buf = H5FL_BLK_CALLOC(type_elem, dst_type_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
void *elem_ptr; /* Pointer to element to use for fill value */
/* Wrap the local buffer for elements */
if(NULL == (elem_wb = H5WB_wrap(elem_buf, sizeof(elem_buf))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for element */
if(NULL == (elem_ptr = H5WB_actual_clear(elem_wb, dst_type_size)))
HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Fill the selection in the memory buffer */
if(H5S_select_fill(tconv_buf, dst_type_size, space, buf) < 0)
if(H5S_select_fill(elem_ptr, dst_type_size, space, buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTENCODE, FAIL, "filling selection failed")
} /* end if */
else {
@ -283,24 +290,38 @@ H5D_fill(const void *fill, const H5T_t *fill_type, void *buf,
/* Convert disk buffer into memory buffer */
if(!H5T_path_noop(tpath)) {
/* Allocate space for conversion buffer */
if(NULL == (tconv_buf = H5FL_BLK_MALLOC(type_elem, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
void *elem_ptr; /* Pointer to element to use for fill value */
void *bkg_ptr; /* Pointer to background element to use for fill value */
/* Wrap the local buffer for elements */
if(NULL == (elem_wb = H5WB_wrap(elem_buf, sizeof(elem_buf))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for element */
if(NULL == (elem_ptr = H5WB_actual(elem_wb, buf_size)))
HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Copy the user's data into the buffer for conversion */
HDmemcpy(tconv_buf, fill, src_type_size);
HDmemcpy(elem_ptr, fill, src_type_size);
/* If there's no VL type of data, do conversion first then fill the data into
* the memory buffer. */
if(H5T_path_bkg(tpath) && NULL == (bkg_buf = H5FL_BLK_CALLOC(type_elem, buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
if(H5T_path_bkg(tpath)) {
/* Wrap the local buffer for background elements */
if(NULL == (bkg_elem_wb = H5WB_wrap(bkg_elem_buf, sizeof(bkg_elem_buf))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for element */
if(NULL == (bkg_ptr = H5WB_actual_clear(bkg_elem_wb, buf_size)))
HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
} /* end if */
/* Perform datatype conversion */
if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
if(H5T_convert(tpath, src_id, dst_id, (size_t)1, (size_t)0, (size_t)0, elem_ptr, bkg_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCONVERT, FAIL, "data type conversion failed")
/* Point at temporary buffer */
fill_buf = tconv_buf;
/* Point at element buffer */
fill_buf = elem_ptr;
} /* end if */
else
fill_buf = fill;
@ -318,14 +339,12 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID")
if(tmp_buf)
H5FL_BLK_FREE(type_conv, tmp_buf);
if(tconv_buf)
H5FL_BLK_FREE(type_elem, tconv_buf);
if(bkg_buf) {
if(TRUE == H5T_detect_class(fill_type, H5T_VLEN))
H5FL_BLK_FREE(type_conv, bkg_buf);
else
H5FL_BLK_FREE(type_elem, bkg_buf);
} /* end if */
if(elem_wb && H5WB_unwrap(elem_wb) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
if(bkg_elem_wb && H5WB_unwrap(bkg_elem_wb) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
if(bkg_buf)
H5FL_BLK_FREE(type_conv, bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_fill() */

View File

@ -37,6 +37,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FSpkg.h" /* File free space */
#include "H5Vprivate.h" /* Vectors and arrays */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
@ -46,6 +47,9 @@
#define H5FS_HDR_VERSION 0 /* Header */
#define H5FS_SINFO_VERSION 0 /* Serialized sections */
/* Size of stack buffer for serialized headers */
#define H5FS_HDR_BUF_SIZE 256
/******************/
/* Local Typedefs */
@ -118,9 +122,6 @@ const H5AC_class_t H5AC_FSPACE_SINFO[1] = {{
/* Local Variables */
/*******************/
/* Declare a free list to manage free space header data to/from disk */
H5FL_BLK_DEFINE_STATIC(header_block);
/* Declare a free list to manage free space section data to/from disk */
H5FL_BLK_DEFINE_STATIC(sect_block);
@ -146,7 +147,9 @@ H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot,
H5FS_t *fspace = NULL; /* Free space header info */
const H5FS_prot_t *fs_prot = (const H5FS_prot_t *)_fs_prot; /* User data for protecting */
size_t size; /* Header size */
uint8_t *buf = NULL; /* Temporary buffer */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5FS_HDR_BUF_SIZE]; /* Buffer for header */
uint8_t *hdr; /* Pointer to header buffer */
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 */
@ -170,18 +173,22 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
/* Set free space manager's internal information */
fspace->addr = addr;
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the size of the free space header on disk */
size = H5FS_HEADER_SIZE(f);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for header */
if(NULL == (hdr = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
if(H5F_block_read(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, buf) < 0)
if(H5F_block_read(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_READERROR, NULL, "can't read free space header")
p = buf;
p = hdr;
/* Magic number */
if(HDmemcmp(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC))
@ -237,12 +244,12 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
H5F_DECODE_LENGTH(f, p, fspace->alloc_sect_size);
/* Compute checksum on indirect block */
computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
computed_chksum = H5_checksum_metadata(hdr, (size_t)(p - hdr), 0);
/* Metadata checksum */
UINT32DECODE(p, stored_chksum);
HDassert((size_t)(p - buf) == size);
HDassert((size_t)(p - hdr) == size);
/* Verify checksum */
if(stored_chksum != computed_chksum)
@ -252,8 +259,9 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
ret_value = fspace;
done:
if(buf)
H5FL_BLK_FREE(header_block, buf);
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_FSPACE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && fspace)
(void)H5FS_cache_hdr_dest(f, fspace);
@ -284,6 +292,8 @@ done:
static herr_t
H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_t *fspace, unsigned UNUSED * flags_ptr)
{
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5FS_HDR_BUF_SIZE]; /* Buffer for header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_hdr_flush)
@ -297,19 +307,24 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
HDassert(fspace);
if(fspace->cache_info.is_dirty) {
uint8_t *buf = NULL; /* Temporary raw data buffer */
uint8_t *p; /* Pointer into raw data buffer */
uint8_t *hdr; /* Pointer to header buffer */
uint8_t *p; /* Pointer into raw data buffer */
uint32_t metadata_chksum; /* Computed metadata checksum value */
size_t size; /* Header size on disk */
size_t size; /* Header size on disk */
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Compute the size of the free space header on disk */
size = H5FS_HEADER_SIZE(f);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for header */
if(NULL == (hdr = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_FSPACE, H5E_NOSPACE, FAIL, "can't get actual buffer")
p = buf;
/* Get temporary pointer to header */
p = hdr;
/* Magic number */
HDmemcpy(p, H5FS_HDR_MAGIC, (size_t)H5FS_SIZEOF_MAGIC);
@ -358,18 +373,16 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
H5F_ENCODE_LENGTH(f, p, fspace->alloc_sect_size);
/* Compute checksum */
metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0);
metadata_chksum = H5_checksum_metadata(hdr, (size_t)(p - hdr), 0);
/* Metadata checksum */
UINT32ENCODE(p, metadata_chksum);
/* Write the free space header. */
HDassert((size_t)(p - buf) == size);
if(H5F_block_write(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, buf) < 0)
HDassert((size_t)(p - hdr) == size);
if(H5F_block_write(f, H5FD_MEM_FSPACE_HDR, addr, size, dxpl_id, hdr) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space header to disk")
H5FL_BLK_FREE(header_block, buf);
fspace->cache_info.is_dirty = FALSE;
} /* end if */
@ -378,6 +391,10 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space header")
done:
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_FSPACE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_cache_hdr_flush() */

View File

@ -36,9 +36,9 @@
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
#include "H5Gpkg.h" /* Groups */
#include "H5MMprivate.h" /* Memory management */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
@ -252,9 +252,6 @@ typedef struct {
/* Local Variables */
/*******************/
/* Declare a free list to manage the serialized link information */
H5FL_BLK_DEFINE(ser_link);
/*-------------------------------------------------------------------------
@ -373,6 +370,7 @@ H5G_dense_insert(H5F_t *f, hid_t dxpl_id, const H5O_linfo_t *linfo,
H5G_bt2_ud_ins_t udata; /* User data for v2 B-tree insertion */
H5HF_t *fheap = NULL; /* Fractal heap handle */
size_t link_size; /* Size of serialized link in the heap */
H5WB_t *wb = NULL; /* Wrapped buffer for link data */
uint8_t link_buf[H5G_LINK_BUF_SIZE]; /* Buffer for serializing link */
void *link_ptr = NULL; /* Pointer to serialized link */
herr_t ret_value = SUCCEED; /* Return value */
@ -397,13 +395,13 @@ HDfprintf(stderr, "%s: linfo->name_bt2_addr = %a\n", FUNC, linfo->name_bt2_addr)
HDfprintf(stderr, "%s: HDstrlen(lnk->name) = %Zu, link_size = %Zu\n", FUNC, HDstrlen(lnk->name), link_size);
#endif /* QAK */
/* Allocate space for serialized link, if necessary */
if(link_size > sizeof(link_buf)) {
if(NULL == (link_ptr = H5FL_BLK_MALLOC(ser_link, link_size)))
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "memory allocation failed")
} /* end if */
else
link_ptr = link_buf;
/* Wrap the local buffer for serialized link */
if(NULL == (wb = H5WB_wrap(link_buf, sizeof(link_buf))))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for link */
if(NULL == (link_ptr = H5WB_actual(wb, link_size)))
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Create serialized form of link */
if(H5O_msg_encode(f, H5O_LINK_ID, FALSE, link_ptr, lnk) < 0)
@ -444,8 +442,8 @@ done:
/* Release resources */
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close fractal heap")
if(link_ptr && link_ptr != link_buf)
H5FL_BLK_FREE(ser_link, link_ptr);
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_dense_insert() */

View File

@ -39,6 +39,7 @@
#include "H5HLprivate.h" /* Local Heaps */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5WBprivate.h" /* Wrapped Buffers */
/* Private typedefs */
@ -67,6 +68,9 @@ typedef struct H5G_node_t {
#define H5G_NODE_VERS 1 /*symbol table node version number */
#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
/* Size of stack buffer for serialized nodes */
#define H5G_NODE_BUF_SIZE 512
/* PRIVATE PROTOTYPES */
static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf);
static size_t H5G_node_size(const H5F_t *f);
@ -142,9 +146,6 @@ H5FL_DEFINE_STATIC(H5G_node_t);
/* Declare a free list to manage sequences of H5G_entry_t's */
H5FL_SEQ_DEFINE_STATIC(H5G_entry_t);
/* Declare a free list to manage blocks of symbol node data */
H5FL_BLK_DEFINE_STATIC(symbol_node);
/* Declare a free list to manage the native key offset sequence information */
H5FL_SEQ_DEFINE_STATIC(size_t);
@ -346,65 +347,83 @@ H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_udata1
void UNUSED * _udata2)
{
H5G_node_t *sym = NULL;
size_t size = 0;
uint8_t *buf = NULL;
const uint8_t *p = NULL;
size_t size;
H5WB_t *wb = NULL; /* Wrapped buffer for node data */
uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
uint8_t *node; /* Pointer to node buffer */
const uint8_t *p;
H5G_node_t *ret_value; /*for error handling */
FUNC_ENTER_NOAPI_NOINIT(H5G_node_load);
FUNC_ENTER_NOAPI_NOINIT(H5G_node_load)
/*
* Check arguments.
*/
assert(f);
assert(H5F_addr_defined(addr));
assert(!_udata1);
assert(NULL == _udata2);
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(!_udata1);
HDassert(NULL == _udata2);
/*
* Initialize variables.
*/
/* Wrap the local buffer for serialized node info */
if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the size of the serialized symbol table node on disk */
size = H5G_node_size(f);
if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for symbol table node");
p=buf;
if(NULL == (sym = H5FL_CALLOC(H5G_node_t)) ||
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");
if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node");
/* Get a pointer to a buffer that's large enough for node */
if(NULL == (node = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read the serialized symbol table node. */
if(H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read symbol table node")
/* Get temporary pointer to serialized node */
p = node;
/* magic */
if(HDmemcmp(p, H5G_NODE_MAGIC, (size_t)H5G_NODE_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature");
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node signature")
p += 4;
/* version */
if(H5G_NODE_VERS != *p++)
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version");
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "bad symbol table node version")
/* reserved */
p++;
/* Allocate symbol table data structures */
if(NULL == (sym = H5FL_CALLOC(H5G_node_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
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")
/* number of symbols */
UINT16DECODE(p, sym->nsyms);
/* entries */
if(H5G_ent_decode_vec(f, &p, sym->entry, sym->nsyms) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries");
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, NULL, "unable to decode symbol table entries")
/* Set return value */
ret_value = sym;
done:
if(buf)
H5FL_BLK_FREE(symbol_node,buf);
if(!ret_value) {
if (sym)
if(H5G_node_dest(f, sym)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node");
}
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value)
if(sym && H5G_node_dest(f, sym) < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTFREE, NULL, "unable to destroy symbol table node")
FUNC_LEAVE_NOAPI(ret_value);
}
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_node_load() */
/*-------------------------------------------------------------------------
@ -443,65 +462,77 @@ done:
static herr_t
H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_t *sym, unsigned UNUSED * flags_ptr)
{
uint8_t *buf = NULL;
size_t size;
H5WB_t *wb = NULL; /* Wrapped buffer for node data */
uint8_t node_buf[H5G_NODE_BUF_SIZE]; /* Buffer for node */
unsigned u;
herr_t ret_value=SUCCEED; /* Return value */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush);
FUNC_ENTER_NOAPI_NOINIT(H5G_node_flush)
/*
* Check arguments.
*/
assert(f);
assert(H5F_addr_defined(addr));
assert(sym);
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(sym);
/*
* Look for dirty entries and set the node dirty flag.
*/
for (u = 0; u < sym->nsyms; u++)
if (sym->entry[u].dirty) {
for(u = 0; u < sym->nsyms; u++)
if(sym->entry[u].dirty) {
/* Set the node's dirty flag */
sym->cache_info.is_dirty = TRUE;
/* Reset the entry's dirty flag */
sym->entry[u].dirty=FALSE;
sym->entry[u].dirty = FALSE;
} /* end if */
/*
* Write the symbol node to disk.
*/
if (sym->cache_info.is_dirty) {
if(sym->cache_info.is_dirty) {
uint8_t *node; /* Pointer to node buffer */
size_t size;
/* Wrap the local buffer for serialized node info */
if(NULL == (wb = H5WB_wrap(node_buf, sizeof(node_buf))))
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Compute the size of the serialized symbol table node on disk */
size = H5G_node_size(f);
/* Allocate temporary buffer */
if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
/* Get a pointer to a buffer that's large enough for node */
if(NULL == (node = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "can't get actual buffer")
if (H5G_node_serialize(f, sym, size, buf) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTSERIALIZE, FAIL, "node serialization failed");
/* Serialize symbol table node into buffer */
if(H5G_node_serialize(f, sym, size, node) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTSERIALIZE, FAIL, "node serialization failed")
if (H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file");
H5FL_BLK_FREE(symbol_node,buf);
/* Write the serialized symbol table node. */
if(H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, node) < 0)
HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file")
/* Reset the node's dirty flag */
sym->cache_info.is_dirty = FALSE;
}
} /* end if */
/*
* Destroy the symbol node? This might happen if the node is being
* preempted from the cache.
*/
if (destroy) {
if(H5G_node_dest(f, sym)<0)
HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node");
}
if(destroy)
if(H5G_node_dest(f, sym) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to destroy symbol table node")
done:
FUNC_LEAVE_NOAPI(ret_value);
}
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_node_flush() */
/*-------------------------------------------------------------------------

View File

@ -39,6 +39,7 @@
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Vprivate.h" /* Vectors and arrays */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
@ -49,6 +50,12 @@
#define H5HF_DBLOCK_VERSION 0 /* Direct block */
#define H5HF_IBLOCK_VERSION 0 /* Indirect block */
/* Size of stack buffer for serialized headers */
#define H5HF_HDR_BUF_SIZE 512
/* Size of stack buffer for serialized indirect blocks */
#define H5HF_IBLOCK_BUF_SIZE 4096
/******************/
/* Local Typedefs */
@ -126,15 +133,9 @@ const H5AC_class_t H5AC_FHEAP_DBLOCK[1] = {{
/* Local Variables */
/*******************/
/* Declare a free list to manage heap header data to/from disk */
H5FL_BLK_DEFINE_STATIC(header_block);
/* Declare a free list to manage heap direct block data to/from disk */
H5FL_BLK_DEFINE(direct_block);
/* Declare a free list to manage heap indirect block data to/from disk */
H5FL_BLK_DEFINE_STATIC(indirect_block);
/*-------------------------------------------------------------------------
@ -257,7 +258,9 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap info */
size_t size; /* Header size */
uint8_t *buf = NULL; /* Temporary buffer */
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5HF_HDR_BUF_SIZE]; /* Buffer for header */
uint8_t *buf; /* Pointer to header buffer */
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 */
@ -280,17 +283,22 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
/* Set the heap header's address */
hdr->heap_addr = addr;
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the 'base' size of the fractal heap header on disk */
size = H5HF_HEADER_SIZE(hdr);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for serialized header */
if(NULL == (buf = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header")
/* Get temporary pointer to serialized header */
p = buf;
/* Magic number */
@ -300,7 +308,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
/* Version */
if(*p++ != H5HF_HDR_VERSION)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap header version")
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap header version")
/* General heap information */
UINT16DECODE(p, hdr->id_len); /* Heap ID length */
@ -358,8 +366,8 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
hdr->heap_size = size + filter_info_size;
/* Re-size current buffer */
if((buf = H5FL_BLK_REALLOC(header_block, buf, hdr->heap_size)) == NULL)
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't allocate space to decode I/O pipeline filters")
if(NULL == (buf = H5WB_actual(wb, hdr->heap_size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read in I/O filter information */
/* (and the checksum) */
@ -416,8 +424,9 @@ HDfprintf(stderr, "%s: hdr->fspace = %p\n", FUNC, hdr->fspace);
ret_value = hdr;
done:
if(buf)
buf = H5FL_BLK_FREE(header_block, buf);
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && hdr)
(void)H5HF_cache_hdr_dest(f, hdr);
@ -446,6 +455,8 @@ done:
static herr_t
H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_hdr_t *hdr, unsigned UNUSED * flags_ptr)
{
H5WB_t *wb = NULL; /* Wrapped buffer for header data */
uint8_t hdr_buf[H5HF_HDR_BUF_SIZE]; /* Buffer for header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_flush)
@ -471,13 +482,18 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
/* Set the shared heap 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_HEAP, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Compute the size of the heap header on disk */
size = hdr->heap_size;
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for serialized header */
if(NULL == (buf = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to serialized header */
p = buf;
/* Magic number */
@ -547,8 +563,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap header to disk")
buf = H5FL_BLK_FREE(header_block, buf);
hdr->dirty = FALSE;
hdr->cache_info.is_dirty = FALSE;
} /* end if */
@ -558,6 +572,10 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap header")
done:
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF_cache_hdr_flush() */
@ -692,7 +710,9 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
const unsigned *nrows = (const unsigned *)_nrows; /* # of rows in indirect block */
H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Shared parent information */
H5HF_indirect_t *iblock = NULL; /* Indirect block info */
uint8_t *buf = NULL; /* Temporary buffer */
H5WB_t *wb = NULL; /* Wrapped buffer for indirect block data */
uint8_t iblock_buf[H5HF_IBLOCK_BUF_SIZE]; /* Buffer for indirect block */
uint8_t *buf; /* Temporary buffer */
const uint8_t *p; /* Pointer into raw data buffer */
haddr_t heap_addr; /* Address of heap header in the file */
uint32_t stored_chksum; /* Stored metadata checksum value */
@ -732,18 +752,22 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr);
iblock->addr = addr;
iblock->nchildren = 0;
/* Wrap the local buffer for serialized indirect block */
if(NULL == (wb = H5WB_wrap(iblock_buf, sizeof(iblock_buf))))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute size of indirect block */
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
/* Allocate buffer to decode block */
/* XXX: Use free list factories? */
if((buf = H5FL_BLK_MALLOC(indirect_block, iblock->size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for serialized indirect block */
if(NULL == (buf = H5WB_actual(wb, iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read indirect block from disk */
if(H5F_block_read(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap indirect block")
/* Get temporary pointer to serialized indirect block */
p = buf;
/* Magic number */
@ -753,7 +777,7 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr);
/* Version */
if(*p++ != H5HF_IBLOCK_VERSION)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block version")
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap direct block version")
/* Address of heap that owns this block */
H5F_addr_decode(f, &p, &heap_addr);
@ -865,10 +889,9 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add
ret_value = iblock;
done:
/* Free buffer */
/* XXX: Keep buffer around? */
buf = H5FL_BLK_FREE(indirect_block, buf);
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && iblock)
(void)H5HF_cache_iblock_dest(f, iblock);
@ -898,6 +921,8 @@ done:
static herr_t
H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_indirect_t *iblock, unsigned UNUSED * flags_ptr)
{
H5WB_t *wb = NULL; /* Wrapped buffer for indirect block data */
uint8_t iblock_buf[H5HF_IBLOCK_BUF_SIZE]; /* Buffer for indirect block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_flush)
@ -912,7 +937,7 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC
if(iblock->cache_info.is_dirty) {
H5HF_hdr_t *hdr; /* Shared fractal heap information */
uint8_t *buf = NULL; /* Temporary buffer */
uint8_t *buf; /* Temporary buffer */
uint8_t *p; /* Pointer into raw data buffer */
#ifndef NDEBUG
unsigned nchildren = 0; /* Track # of children */
@ -923,21 +948,25 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC
/* Get the pointer to the shared heap header */
hdr = iblock->hdr;
/* Set the shared heap header's file context for this operation */
hdr->f = f;
/* Allocate buffer to encode block */
/* XXX: Use free list factories? */
#ifdef QAK
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size);
HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
HDfprintf(stderr, "%s: hdr->man_dtable.cparam.width = %u\n", FUNC, hdr->man_dtable.cparam.width);
#endif /* QAK */
if((buf = H5FL_BLK_MALLOC(indirect_block, iblock->size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Set the shared heap header's file context for this operation */
hdr->f = f;
/* Wrap the local buffer for serialized indirect block */
if(NULL == (wb = H5WB_wrap(iblock_buf, sizeof(iblock_buf))))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for serialized indirect block */
if(NULL == (buf = H5WB_actual(wb, iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to buffer for serialized indirect block */
p = buf;
/* Magic number */
@ -1013,9 +1042,6 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f
if(H5F_block_write(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap indirect block to disk")
/* Free buffer */
buf = H5FL_BLK_FREE(indirect_block, buf);
/* Reset dirty flags */
iblock->cache_info.is_dirty = FALSE;
} /* end if */
@ -1025,6 +1051,10 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap indirect block")
done:
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF_cache_iblock_flush() */
@ -1292,7 +1322,7 @@ HDfprintf(stderr, "%s: nbytes = %Zu, read_size = %Zu, read_buf = %p\n", FUNC, nb
/* Version */
if(*p++ != H5HF_DBLOCK_VERSION)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "wrong fractal heap direct block version")
HGOTO_ERROR(H5E_HEAP, H5E_VERSION, NULL, "wrong fractal heap direct block version")
/* Address of heap that owns this block (just for file integrity checks) */
H5F_addr_decode(f, &p, &heap_addr);

View File

@ -26,19 +26,29 @@
* the global heap.
*/
/****************/
/* Module Setup */
/****************/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
#include "H5Gprivate.h" /* Groups */
#include "H5HFprivate.h" /* Fractal heap */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
#include "H5SMprivate.h" /* Shared object header messages */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
/****************/
/* First version, with full symbol table entry as link for object header sharing */
#define H5O_SHARED_VERSION_1 1
@ -53,8 +63,31 @@
/* Size of stack buffer for serialized messages */
#define H5O_MESG_BUF_SIZE 128
/* Declare a free list to manage the serialized message information */
H5FL_BLK_DEFINE(ser_mesg);
/******************/
/* Local Typedefs */
/******************/
/********************/
/* Local Prototypes */
/********************/
/*********************/
/* Package Variables */
/*********************/
/*****************************/
/* Library Private Variables */
/*****************************/
/*******************/
/* Local Variables */
/*******************/
/*-------------------------------------------------------------------------
@ -63,10 +96,7 @@ H5FL_BLK_DEFINE(ser_mesg);
* Purpose: Reads a message referred to by a shared message.
*
* Return: Success: Ptr to message in native format. The message
* should be freed by calling H5O_msg_reset(). If
* MESG is a null pointer then the caller should
* also call H5MM_xfree() on the return value
* after calling H5O_msg_reset().
* should be freed by calling H5O_msg_reset().
*
* Failure: NULL
*
@ -81,8 +111,8 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
const H5O_msg_class_t *type)
{
H5HF_t *fheap = NULL;
H5WB_t *wb = NULL; /* Wrapped buffer for attribute data */
uint8_t mesg_buf[H5O_MESG_BUF_SIZE]; /* Buffer for deserializing messages */
uint8_t *buf = NULL; /* Pointer to raw message in heap */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_shared_read)
@ -100,8 +130,9 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
/* Check for implicit shared object header message */
if(shared->type == H5O_SHARE_TYPE_SOHM) {
haddr_t fheap_addr;
size_t buf_size;
haddr_t fheap_addr; /* Address of SOHM heap */
uint8_t *mesg_ptr; /* Pointer to raw message in heap */
size_t mesg_size; /* Size of message */
/* Retrieve the fractal heap address for shared messages */
if(H5SM_get_fheap_addr(f, dxpl_id, type->id, &fheap_addr) < 0)
@ -112,23 +143,23 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "unable to open fractal heap")
/* Get the size of the message in the heap */
if(H5HF_get_obj_len(fheap, dxpl_id, &(shared->u.heap_id), &buf_size) < 0)
if(H5HF_get_obj_len(fheap, dxpl_id, &(shared->u.heap_id), &mesg_size) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "can't get message size from fractal heap.")
/* Allocate space for serialized message, if necessary */
if(buf_size > sizeof(mesg_buf)) {
if(NULL == (buf = H5FL_BLK_MALLOC(ser_mesg, buf_size)))
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "memory allocation failed")
} /* end if */
else
buf = mesg_buf;
/* Wrap the local buffer for serialized message */
if(NULL == (wb = H5WB_wrap(mesg_buf, sizeof(mesg_buf))))
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for message */
if(NULL == (mesg_ptr = H5WB_actual(wb, mesg_size)))
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Retrieve the message from the heap */
if(H5HF_read(fheap, dxpl_id, &(shared->u.heap_id), buf) < 0)
if(H5HF_read(fheap, dxpl_id, &(shared->u.heap_id), mesg_ptr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "can't read message from fractal heap.")
/* Decode the message */
if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, buf)))
if(NULL == (ret_value = (type->decode)(f, dxpl_id, 0, mesg_ptr)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode shared message.")
} /* end if */
else {
@ -150,10 +181,10 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared,
done:
/* Release resources */
if(buf && buf != mesg_buf)
buf = H5FL_BLK_FREE(ser_mesg, buf);
if(fheap && H5HF_close(fheap, dxpl_id) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTFREE, NULL, "can't close fractal heap")
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_OHDR, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shared_read() */

View File

@ -69,13 +69,13 @@ static herr_t H5SM_write_mesg(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5SM_index_header_t *header, unsigned type_id, void *mesg,
unsigned *cache_flags_ptr);
static herr_t H5SM_decr_ref(void *record, void *op_data, hbool_t *changed);
static herr_t H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata);
static herr_t H5SM_delete_from_index(H5F_t *f, hid_t dxpl_id, H5O_t *open_oh,
H5SM_index_header_t *header, const H5O_shared_t * mesg,
unsigned *cache_flags, void ** /*out*/ encoded_mesg);
static herr_t H5SM_type_to_flag(unsigned type_id, unsigned *type_flag);
static herr_t H5SM_read_iter_op(H5O_t *oh, H5O_mesg_t *mesg, unsigned sequence,
hbool_t *oh_modified, void *_udata);
static herr_t H5SM_read_mesg_fh_cb(const void *obj, size_t obj_len, void *_udata);
static herr_t H5SM_read_mesg(H5F_t *f, const H5SM_sohm_t *mesg, H5HF_t *fheap,
H5O_t * open_oh, hid_t dxpl_id, size_t *encoding_size /*out*/,
void ** encoded_mesg /*out*/);
@ -101,6 +101,7 @@ H5FL_ARR_DEFINE(H5SM_sohm_t, H5O_SHMESG_MAX_LIST_SIZE);
/*******************/
/*-------------------------------------------------------------------------
* Function: H5SM_init
*

View File

@ -17,8 +17,9 @@
/* Module Setup */
/****************/
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
#define H5SM_PACKAGE /*suppress error about including H5SMpkg */
/***********/
/* Headers */
@ -28,157 +29,78 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5MMprivate.h" /* Memory management */
#include "H5SMpkg.h" /* Shared object header messages */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
/****************/
/* Size of stack buffer for serialized tables */
#define H5SM_TBL_BUF_SIZE 1024
/* Size of stack buffer for serialized list indices */
#define H5SM_LST_BUF_SIZE 1024
/******************/
/* Local Typedefs */
/******************/
/********************/
/* Local Prototypes */
/********************/
static herr_t H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table);
static H5SM_master_table_t *H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *table);
static herr_t H5SM_clear_table(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy);
static herr_t H5SM_dest_table(H5F_t *f, H5SM_master_table_t* table);
static herr_t H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr);
static herr_t H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list);
static H5SM_list_t *H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
static herr_t H5SM_clear_list(H5F_t *f, H5SM_list_t *list, hbool_t destroy);
static herr_t H5SM_dest_list(H5F_t *f, H5SM_list_t* list);
/* Metadata cache (H5AC) callbacks */
static H5SM_master_table_t *H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *table);
static herr_t H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table);
static herr_t H5SM_table_dest(H5F_t *f, H5SM_master_table_t* table);
static herr_t H5SM_table_clear(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy);
static herr_t H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_ptr);
static H5SM_list_t *H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata1, void *udata2);
static herr_t H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list);
static herr_t H5SM_list_dest(H5F_t *f, H5SM_list_t* list);
static herr_t H5SM_list_clear(H5F_t *f, H5SM_list_t *list, hbool_t destroy);
static herr_t H5SM_list_size(const H5F_t *f, const H5SM_list_t UNUSED *list, size_t *size_ptr);
/*********************/
/* Package Variables */
/*********************/
/* H5SM inherits cache-like properties from H5AC */
const H5AC_class_t H5AC_SOHM_TABLE[1] = {{
H5AC_SOHM_TABLE_ID,
(H5AC_load_func_t) H5SM_load_table,
(H5AC_flush_func_t) H5SM_flush_table,
(H5AC_dest_func_t) H5SM_dest_table,
(H5AC_clear_func_t)H5SM_clear_table,
(H5AC_size_func_t) H5SM_table_size,
(H5AC_load_func_t)H5SM_table_load,
(H5AC_flush_func_t)H5SM_table_flush,
(H5AC_dest_func_t)H5SM_table_dest,
(H5AC_clear_func_t)H5SM_table_clear,
(H5AC_size_func_t)H5SM_table_size,
}};
const H5AC_class_t H5AC_SOHM_LIST[1] = {{
H5AC_SOHM_LIST_ID,
(H5AC_load_func_t) H5SM_load_list,
(H5AC_flush_func_t) H5SM_flush_list,
(H5AC_dest_func_t) H5SM_dest_list,
(H5AC_clear_func_t)H5SM_clear_list,
(H5AC_size_func_t) H5SM_list_size,
H5AC_SOHM_LIST_ID,
(H5AC_load_func_t)H5SM_list_load,
(H5AC_flush_func_t)H5SM_list_flush,
(H5AC_dest_func_t)H5SM_list_dest,
(H5AC_clear_func_t)H5SM_list_clear,
(H5AC_size_func_t)H5SM_list_size,
}};
/* Declare a free list to manage data to/from disk */
H5FL_BLK_DEFINE_STATIC(shared_mesg_cache);
/*****************************/
/* Library Private Variables */
/*****************************/
/*******************/
/* Local Variables */
/*******************/
/*-------------------------------------------------------------------------
* Function: H5SM_flush_table
*
* Purpose: Flushes (and destroys) the table of Shared Object Header
* Message indexes.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: James Laird
* November 6, 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_flush_table(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table)
{
uint8_t *buf=NULL; /* Temporary buffer */
herr_t ret_value=SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5SM_flush_table)
/* check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(table);
if(table->cache_info.is_dirty) {
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t computed_chksum; /* Computed metadata checksum value */
int x; /* Counter variable */
/* Verify that we're writing version 0 of the table; this is the only
* version defined so far.
*/
HDassert(f->shared->sohm_vers == HDF5_SHAREDHEADER_VERSION);
/* Encode the master table and all of the index headers as one big blob */
size = H5SM_TABLE_SIZE(f) + (H5SM_INDEX_HEADER_SIZE(f) * table->num_indexes);
/* Allocate the buffer */
if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Encode the master table */
p = buf;
/* Encode magic number */
HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC);
p += H5SM_TABLE_SIZEOF_MAGIC;
/* Encode each index header */
for(x=0; x<table->num_indexes; ++x) {
*p++ = H5SM_LIST_VERSION; /* Encode version for this list. */
*p++ = table->indexes[x].index_type; /* Is message index a list or a B-tree? */
UINT16ENCODE(p, table->indexes[x].mesg_types); /* Type of messages in the index */
UINT32ENCODE(p, table->indexes[x].min_mesg_size); /* Minimum size of message to share */
UINT16ENCODE(p, table->indexes[x].list_max); /* List cutoff; fewer than this number and index becomes a list */
UINT16ENCODE(p, table->indexes[x].btree_min); /* B-tree cutoff; more than this number and index becomes a B-tree */
UINT16ENCODE(p, table->indexes[x].num_messages); /* Number of messages shared */
H5F_addr_encode(f, &p, table->indexes[x].index_addr); /* Address of the actual index */
H5F_addr_encode(f, &p, table->indexes[x].heap_addr); /* Address of the index's heap */
}
/* Compute checksum on buffer */
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
UINT32ENCODE(p, computed_chksum);
/* Write the table to disk */
HDassert((size_t)(p - buf) == size);
if(H5F_block_write(f, H5FD_MEM_SOHM_TABLE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
table->cache_info.is_dirty = FALSE;
} /* end if */
if(destroy)
if(H5SM_dest_table(f, table) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table")
done:
/* Free buffer if allocated */
if(buf)
buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_flush_table */
/*-------------------------------------------------------------------------
* Function: H5SM_load_table
* Function: H5SM_table_load
*
* Purpose: Loads the master table of Shared Object Header Message
* indexes.
@ -191,22 +113,24 @@ done:
*-------------------------------------------------------------------------
*/
static H5SM_master_table_t *
H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
H5SM_table_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
{
H5SM_master_table_t *table = NULL;
size_t table_size; /* Size of SOHM master table on disk */
uint8_t *buf=NULL; /* Reading buffer */
const uint8_t *p; /* Pointer into input buffer */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
uint8_t x; /* Counter variable for index headers */
size_t size; /* Size of SOHM master table on disk */
H5WB_t *wb = NULL; /* Wrapped buffer for table data */
uint8_t tbl_buf[H5SM_TBL_BUF_SIZE]; /* Buffer for table */
uint8_t *buf; /* Reading buffer */
const uint8_t *p; /* Pointer into input buffer */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
size_t x; /* Counter variable for index headers */
H5SM_master_table_t *ret_value;
FUNC_ENTER_NOAPI_NOINIT(H5SM_load_table)
FUNC_ENTER_NOAPI_NOINIT(H5SM_table_load)
/* Verify that we're reading version 0 of the table; this is the only
* version defined so far.
*/
* version defined so far.
*/
HDassert(f->shared->sohm_vers == HDF5_SHAREDHEADER_VERSION);
/* Allocate space for the master table in memory */
@ -220,25 +144,30 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
HDassert(addr != HADDR_UNDEF);
HDassert(table->num_indexes > 0);
/* Wrap the local buffer for serialized table info */
if(NULL == (wb = H5WB_wrap(tbl_buf, sizeof(tbl_buf))))
HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the size of the SOHM table header on disk. This is the "table" itself
* plus each index within the table
*/
table_size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
size = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
/* Allocate temporary buffer */
if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, table_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for serialized table */
if(NULL == (buf = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read header from disk */
if(H5F_block_read(f, H5FD_MEM_SOHM_TABLE, addr, table_size, dxpl_id, buf) < 0)
if(H5F_block_read(f, H5FD_MEM_SOHM_TABLE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM table")
/* Get temporary pointer to serialized table */
p = buf;
/* Check magic number */
if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM table signature");
p += H5SM_TABLE_SIZEOF_MAGIC;
if(HDmemcmp(p, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC))
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
@ -250,49 +179,68 @@ H5SM_load_table(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for SOHM indexes")
/* Read in the index headers */
for(x=0; x<table->num_indexes; ++x) {
if (H5SM_LIST_VERSION != *p++)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "bad shared message list version number")
for(x = 0; x < table->num_indexes; ++x) {
/* Verify correct version of index list */
if(H5SM_LIST_VERSION != *p++)
HGOTO_ERROR(H5E_FILE, H5E_VERSION, NULL, "bad shared message list version number")
table->indexes[x].index_type= *p++; /* type of the index (list or B-tree) */
/* Type of the index (list or B-tree) */
table->indexes[x].index_type= *p++;
/* Type of messages in the index */
UINT16DECODE(p, table->indexes[x].mesg_types);
/* Minimum size of message to share */
UINT32DECODE(p, table->indexes[x].min_mesg_size);
/* List cutoff; fewer than this number and index becomes a list */
UINT16DECODE(p, table->indexes[x].list_max);
/* B-tree cutoff; more than this number and index becomes a B-tree */
UINT16DECODE(p, table->indexes[x].btree_min);
/* Number of messages shared */
UINT16DECODE(p, table->indexes[x].num_messages);
/* Address of the actual index */
H5F_addr_decode(f, &p, &(table->indexes[x].index_addr));
/* Address of the index's heap */
H5F_addr_decode(f, &p, &(table->indexes[x].heap_addr));
}
} /* end for */
/* Read in checksum */
UINT32DECODE(p, stored_chksum);
/* Sanity check */
HDassert((size_t)(p - buf) == table_size);
HDassert((size_t)(p - buf) == size);
/* Compute checksum on entire header */
computed_chksum = H5_checksum_metadata(buf, (table_size - H5SM_SIZEOF_CHECKSUM), 0);
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table");
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message table")
/* Set return value */
ret_value = table;
done:
/* Free buffer if allocated */
if(buf)
buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && table)
(void)H5SM_table_dest(f, table);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_load_table */
} /* end H5SM_table_load() */
/*-------------------------------------------------------------------------
* Function: H5SM_clear_table
* Function: H5SM_table_flush
*
* Purpose: Mark this table as no longer being dirty.
* Purpose: Flushes (and destroys) the table of Shared Object Header
* Message indexes.
*
* Return: Non-negative on success/Negative on failure
*
@ -302,32 +250,106 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_clear_table(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy)
H5SM_table_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_master_table_t *table)
{
H5WB_t *wb = NULL; /* Wrapped buffer for table data */
uint8_t tbl_buf[H5SM_TBL_BUF_SIZE]; /* Buffer for table */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_clear_table)
FUNC_ENTER_NOAPI_NOINIT(H5SM_table_flush)
/*
* Check arguments.
*/
/* check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(table);
/* Reset the dirty flag. */
table->cache_info.is_dirty = FALSE;
if(table->cache_info.is_dirty) {
uint8_t *buf; /* Temporary buffer */
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 x; /* Counter variable */
/* Verify that we're writing version 0 of the table; this is the only
* version defined so far.
*/
HDassert(f->shared->sohm_vers == HDF5_SHAREDHEADER_VERSION);
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(tbl_buf, sizeof(tbl_buf))))
HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Encode the master table and all of the index headers as one big blob */
size = H5SM_TABLE_SIZE(f) + (H5SM_INDEX_HEADER_SIZE(f) * table->num_indexes);
/* Get a pointer to a buffer that's large enough for serialized table */
if(NULL == (buf = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to buffer for serialized table */
p = buf;
/* Encode magic number */
HDmemcpy(p, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC);
p += H5SM_SIZEOF_MAGIC;
/* Encode each index header */
for(x = 0; x < table->num_indexes; ++x) {
/* Version for this list. */
*p++ = H5SM_LIST_VERSION;
/* Is message index a list or a B-tree? */
*p++ = table->indexes[x].index_type;
/* Type of messages in the index */
UINT16ENCODE(p, table->indexes[x].mesg_types);
/* Minimum size of message to share */
UINT32ENCODE(p, table->indexes[x].min_mesg_size);
/* List cutoff; fewer than this number and index becomes a list */
UINT16ENCODE(p, table->indexes[x].list_max);
/* B-tree cutoff; more than this number and index becomes a B-tree */
UINT16ENCODE(p, table->indexes[x].btree_min);
/* Number of messages shared */
UINT16ENCODE(p, table->indexes[x].num_messages);
/* Address of the actual index */
H5F_addr_encode(f, &p, table->indexes[x].index_addr);
/* Address of the index's heap */
H5F_addr_encode(f, &p, table->indexes[x].heap_addr);
} /* end for */
/* Compute checksum on buffer */
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
UINT32ENCODE(p, computed_chksum);
/* Write the table to disk */
HDassert((size_t)(p - buf) == size);
if(H5F_block_write(f, H5FD_MEM_SOHM_TABLE, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
table->cache_info.is_dirty = FALSE;
} /* end if */
if(destroy)
if(H5SM_dest_table(f, table) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to delete SOHM master table")
if(H5SM_table_dest(f, table) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy sohm table")
done:
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_clear_table */
} /* end H5SM_table_flush() */
/*-------------------------------------------------------------------------
* Function: H5SM_dest_table
* Function: H5SM_table_dest
*
* Purpose: Frees memory used by the SOHM table.
*
@ -339,10 +361,11 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_dest_table(H5F_t UNUSED *f, H5SM_master_table_t* table)
H5SM_table_dest(H5F_t UNUSED *f, H5SM_master_table_t* table)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_dest_table)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_table_dest)
/* Sanity check */
HDassert(table);
HDassert(table->indexes);
@ -351,7 +374,43 @@ H5SM_dest_table(H5F_t UNUSED *f, H5SM_master_table_t* table)
H5FL_FREE(H5SM_master_table_t, table);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SM_dest_table */
} /* end H5SM_table_dest() */
/*-------------------------------------------------------------------------
* Function: H5SM_table_clear
*
* Purpose: Mark this table as no longer being dirty.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: James Laird
* November 6, 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_table_clear(H5F_t *f, H5SM_master_table_t *table, hbool_t destroy)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_table_clear)
/*
* Check arguments.
*/
HDassert(table);
/* Reset the dirty flag. */
table->cache_info.is_dirty = FALSE;
if(destroy)
if(H5SM_table_dest(f, table) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to delete SOHM master table")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_table_clear() */
/*-------------------------------------------------------------------------
@ -380,98 +439,11 @@ H5SM_table_size(const H5F_t *f, const H5SM_master_table_t *table, size_t *size_p
*size_ptr = H5SM_TABLE_SIZE(f) + (table->num_indexes * H5SM_INDEX_HEADER_SIZE(f));
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SM_table_size */
} /* end H5SM_table_size() */
/*-------------------------------------------------------------------------
* Function: H5SM_flush_list
*
* Purpose: Flush this list index.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: James Laird
* November 6, 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_flush_list(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list)
{
uint8_t *buf=NULL; /* Temporary buffer */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5SM_flush_list)
/* check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(list);
HDassert(list->header);
if (list->cache_info.is_dirty) {
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
uint32_t computed_chksum; /* Computed metadata checksum value */
hsize_t x;
hsize_t mesgs_written;
size = H5SM_LIST_SIZE(f, list->header->num_messages);
/* Allocate temporary buffer */
if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Encode the list */
p = buf;
/* Encode magic number */
HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC);
p += H5SM_LIST_SIZEOF_MAGIC;
/* Write messages from the messages array to disk */
mesgs_written = 0;
for(x=0; x<list->header->list_max && mesgs_written < list->header->num_messages; x++) {
if(list->messages[x].location != H5SM_NO_LOC) {
if(H5SM_message_encode(f, p, &(list->messages[x]))< 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk")
p+=H5SM_SOHM_ENTRY_SIZE(f);
++mesgs_written;
}
}
HDassert(mesgs_written == list->header->num_messages);
/* Compute checksum on buffer */
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
UINT32ENCODE(p, computed_chksum);
/* Write the list to disk */
HDassert((size_t)(p - buf) == size);
if(H5F_block_write(f, H5FD_MEM_SOHM_INDEX, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
list->cache_info.is_dirty = FALSE;
}
if(destroy)
if(H5SM_dest_list(f, list) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list")
done:
/* Free buffer if allocated */
if(buf)
buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_flush_list */
/*-------------------------------------------------------------------------
* Function: H5SM_load_list
* Function: H5SM_list_load
*
* Purpose: Loads a list of SOHM messages.
*
@ -483,20 +455,23 @@ done:
*-------------------------------------------------------------------------
*/
static H5SM_list_t *
H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *udata2)
H5SM_list_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *udata2)
{
H5SM_list_t *list; /* The SOHM list being read in */
H5SM_list_t *list; /* The SOHM list being read in */
H5SM_index_header_t *header = (H5SM_index_header_t *) udata2; /* Index header for this list */
size_t size; /* Size of SOHM list on disk */
uint8_t *buf = NULL; /* Reading buffer */
uint8_t *p; /* Pointer into input buffer */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
hsize_t x; /* Counter variable for messages in list */
H5SM_list_t *ret_value=NULL;
size_t size; /* Size of SOHM list on disk */
H5WB_t *wb = NULL; /* Wrapped buffer for list index data */
uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */
uint8_t *buf; /* Reading buffer */
uint8_t *p; /* Pointer into input buffer */
uint32_t stored_chksum; /* Stored metadata checksum value */
uint32_t computed_chksum; /* Computed metadata checksum value */
size_t x; /* Counter variable for messages in list */
H5SM_list_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_load_list)
FUNC_ENTER_NOAPI_NOINIT(H5SM_list_load)
/* Sanity check */
HDassert(header);
/* Allocate space for the SOHM list data structure */
@ -510,28 +485,33 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
list->header = header;
/* Wrap the local buffer for serialized list index info */
if(NULL == (wb = H5WB_wrap(lst_buf, sizeof(lst_buf))))
HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, NULL, "can't wrap buffer")
/* Compute the size of the SOHM list on disk */
size = H5SM_LIST_SIZE(f, header->num_messages);
/* Allocate temporary buffer */
if(NULL == (buf = H5FL_BLK_MALLOC(shared_mesg_cache, size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Get a pointer to a buffer that's large enough for serialized list index */
if(NULL == (buf = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, NULL, "can't get actual buffer")
/* Read list from disk */
if(H5F_block_read(f, H5FD_MEM_SOHM_INDEX, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_READERROR, NULL, "can't read SOHM list")
/* Get temporary pointer to serialized list index */
p = buf;
/* Check magic number */
if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature");
p += H5SM_LIST_SIZEOF_MAGIC;
if(HDmemcmp(p, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC))
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "bad SOHM list signature")
p += H5SM_SIZEOF_MAGIC;
/* Read messages into the list array */
for(x = 0; x < header->num_messages; x++)
{
for(x = 0; x < header->num_messages; x++) {
if(H5SM_message_decode(f, p, &(list->messages[x])) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message");
HGOTO_ERROR(H5E_SOHM, H5E_CANTLOAD, NULL, "can't decode shared message")
p += H5SM_SOHM_ENTRY_SIZE(f);
} /* end for */
@ -541,42 +521,38 @@ H5SM_load_list(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1,
/* Sanity check */
HDassert((size_t)(p - buf) == size);
/* Compute checksum on entire header */
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
/* Verify checksum */
if(stored_chksum != computed_chksum)
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list");
HGOTO_ERROR(H5E_SOHM, H5E_BADVALUE, NULL, "incorrect metadata checksum for shared message list")
/* Initialize the rest of the array */
for(x = header->num_messages; x < header->list_max; x++)
list->messages[x].location = H5SM_NO_LOC;
/* Set return value */
ret_value = list;
done:
/* Free buffer if allocated */
if(buf)
buf = H5FL_BLK_FREE(shared_mesg_cache, buf);
if(ret_value == NULL) {
if(list) {
if(list->messages)
H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
H5FL_FREE(H5SM_list_t, list);
} /* end if */
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && list) {
if(list->messages)
H5FL_ARR_FREE(H5SM_sohm_t, list->messages);
H5FL_FREE(H5SM_list_t, list);
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SM_load_list */
} /* end H5SM_list_load() */
/*-------------------------------------------------------------------------
* Function: H5SM_clear_list
* Function: H5SM_list_flush
*
* Purpose: Marks a list as not dirty.
* Purpose: Flush this list index.
*
* Return: Non-negative on success/Negative on failure
*
@ -586,31 +562,85 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_clear_list(H5F_t *f, H5SM_list_t *list, hbool_t destroy)
H5SM_list_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5SM_list_t *list)
{
H5WB_t *wb = NULL; /* Wrapped buffer for list index data */
uint8_t lst_buf[H5SM_LST_BUF_SIZE]; /* Buffer for list index */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_clear_list)
FUNC_ENTER_NOAPI_NOINIT(H5SM_list_flush)
/*
* Check arguments.
*/
/* check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(list);
HDassert(list->header);
/* Reset the dirty flag. */
list->cache_info.is_dirty = FALSE;
if(list->cache_info.is_dirty) {
uint8_t *buf; /* Temporary buffer */
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 */
/* Wrap the local buffer for serialized list index info */
if(NULL == (wb = H5WB_wrap(lst_buf, sizeof(lst_buf))))
HGOTO_ERROR(H5E_SOHM, H5E_CANTINIT, FAIL, "can't wrap buffer")
size = H5SM_LIST_SIZE(f, list->header->num_messages);
/* Get a pointer to a buffer that's large enough for serialized list index */
if(NULL == (buf = H5WB_actual(wb, size)))
HGOTO_ERROR(H5E_SOHM, H5E_NOSPACE, FAIL, "can't get actual buffer")
/* Get temporary pointer to buffer for serialized list index */
p = buf;
/* Encode magic number */
HDmemcpy(p, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC);
p += H5SM_SIZEOF_MAGIC;
/* Write messages from the messages array to disk */
mesgs_written = 0;
for(x = 0; x < list->header->list_max && mesgs_written < list->header->num_messages; x++) {
if(list->messages[x].location != H5SM_NO_LOC) {
if(H5SM_message_encode(f, p, &(list->messages[x])) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to write shared message to disk")
p+=H5SM_SOHM_ENTRY_SIZE(f);
++mesgs_written;
} /* end if */
} /* end for */
HDassert(mesgs_written == list->header->num_messages);
/* Compute checksum on buffer */
computed_chksum = H5_checksum_metadata(buf, (size - H5SM_SIZEOF_CHECKSUM), 0);
UINT32ENCODE(p, computed_chksum);
/* Write the list to disk */
HDassert((size_t)(p - buf) == size);
if(H5F_block_write(f, H5FD_MEM_SOHM_INDEX, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFLUSH, FAIL, "unable to save sohm table to disk")
list->cache_info.is_dirty = FALSE;
} /* end if */
if(destroy)
if(H5SM_dest_list(f, list) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy SOHM list")
if(H5SM_list_dest(f, list) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy list")
done:
/* Release resources */
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_SOHM, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value)
} /* end of H5SM_clear_list */
} /* end H5SM_list_flush() */
/*-------------------------------------------------------------------------
* Function: H5SM_dest_list
* Function: H5SM_list_dest
*
* Purpose: Frees all memory used by the list.
*
@ -622,9 +652,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_dest_list(H5F_t UNUSED *f, H5SM_list_t* list)
H5SM_list_dest(H5F_t UNUSED *f, H5SM_list_t* list)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_dest_list)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SM_list_dest)
HDassert(list);
HDassert(list->messages);
@ -634,7 +664,43 @@ H5SM_dest_list(H5F_t UNUSED *f, H5SM_list_t* list)
H5FL_FREE(H5SM_list_t, list);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SM_dest_list */
} /* end H5SM_list_dest() */
/*-------------------------------------------------------------------------
* Function: H5SM_list_clear
*
* Purpose: Marks a list as not dirty.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: James Laird
* November 6, 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
H5SM_list_clear(H5F_t *f, H5SM_list_t *list, hbool_t destroy)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5SM_list_clear)
/*
* Check arguments.
*/
HDassert(list);
/* Reset the dirty flag. */
list->cache_info.is_dirty = FALSE;
if(destroy)
if(H5SM_list_dest(f, list) < 0)
HGOTO_ERROR(H5E_SOHM, H5E_CANTFREE, FAIL, "unable to destroy SOHM list")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end of H5SM_list_clear() */
/*-------------------------------------------------------------------------
@ -664,7 +730,5 @@ H5SM_list_size(const H5F_t UNUSED *f, const H5SM_list_t *list, size_t *size_ptr)
*size_ptr = H5SM_LIST_SIZE(f, list->header->list_max);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SM_list_size */
} /* end H5SM_list_size() */

View File

@ -39,38 +39,55 @@
/****************************/
/* Package Macros */
/****************************/
#define H5SM_LIST_MAGIC "SMLI"
#define H5SM_LIST_SIZEOF_MAGIC 4
#define H5SM_TABLE_MAGIC "SMTB"
#define H5SM_TABLE_SIZEOF_MAGIC 4
/* Size of signature information (on disk) */
#define H5SM_SIZEOF_MAGIC 4
/* Shared Message signatures */
#define H5SM_TABLE_MAGIC "SMTB" /* Shared Message Table */
#define H5SM_LIST_MAGIC "SMLI" /* Shared Message List */
/* Size of checksum information (on disk) */
#define H5SM_SIZEOF_CHECKSUM 4
#define H5SM_HEAP_LOC_SIZE (4 /* Reference count */ \
+ sizeof(H5O_fheap_id_t)) /* size of heap ID on disk */
#define H5SM_HEAP_LOC_SIZE ( \
4 /* Reference count */ \
+ sizeof(H5O_fheap_id_t) /* size of heap ID on disk */ \
)
#define H5SM_OH_LOC_SIZE(f) (1 /* reserved (possible flags?) */ \
+ 1 /* message type ID */ \
+ 2 /* creation index of message in OH */ \
+ H5F_SIZEOF_ADDR(f)) /* address of OH */
#define H5SM_OH_LOC_SIZE(f) ( \
1 /* reserved (possible flags?) */ \
+ 1 /* message type ID */ \
+ 2 /* creation index of message in OH */ \
+ H5F_SIZEOF_ADDR(f) /* address of OH */ \
)
#define H5SM_SOHM_ENTRY_SIZE(f) (1 /* Message location */ \
+ 4 /* Hash value */ \
+ MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)))
#define H5SM_SOHM_ENTRY_SIZE(f) ( \
1 /* Message location */ \
+ 4 /* Hash value */ \
+ MAX(H5SM_HEAP_LOC_SIZE, H5SM_OH_LOC_SIZE(f)) /* Entry */ \
)
#define H5SM_TABLE_SIZE(f) ( H5SM_TABLE_SIZEOF_MAGIC \
+ H5SM_SIZEOF_CHECKSUM) /* Checksum */
#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 */ \
+ 2 /* Type of messages stored in the index */ \
+ 4 /* Minimum size of messages to share */ \
+ (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \
+ H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \
+ H5F_SIZEOF_ADDR(f)) /* Address of heap */
#define H5SM_INDEX_HEADER_SIZE(f) ( \
1 /* Whether index is a list or B-tree */ \
+ 1 /* Version of index format */ \
+ 2 /* Type of messages stored in the index */ \
+ 4 /* Minimum size of messages to share */ \
+ (3 * 2) /* B-tree cutoff, list cutoff, # of shared messages */ \
+ H5F_SIZEOF_ADDR(f) /* Location of list or B-tree */ \
+ H5F_SIZEOF_ADDR(f) /* Address of heap */ \
)
#define H5SM_LIST_SIZE(f, num_mesg) H5SM_LIST_SIZEOF_MAGIC \
+ (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) \
+ H5SM_SIZEOF_CHECKSUM /* Checksum */
#define H5SM_LIST_SIZE(f, num_mesg) ( \
H5SM_SIZEOF_MAGIC /* Signature */ \
+ (H5SM_SOHM_ENTRY_SIZE(f) * num_mesg) /* Message entries */ \
+ H5SM_SIZEOF_CHECKSUM /* Checksum */ \
)
#define H5SM_B2_NODE_SIZE 512
#define H5SM_B2_SPLIT_PERCENT 100
@ -168,7 +185,7 @@ struct H5SM_master_table_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
uint8_t num_indexes; /* Number of indexes */
unsigned num_indexes; /* Number of indexes */
H5SM_index_header_t *indexes; /* Array of num_indexes indexes */
};

View File

@ -29,6 +29,7 @@
#include "H5Iprivate.h" /* IDs */
#include "H5Spkg.h" /* Dataspaces */
#include "H5Vprivate.h" /* Vector and array functions */
#include "H5WBprivate.h" /* Wrapped Buffers */
/* Local functions */
#ifdef LATER
@ -37,8 +38,6 @@ static htri_t H5S_select_iter_has_next_block (const H5S_sel_iter_t *iter);
static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter);
#endif /* LATER */
/* Declare a free list to manage blocks of single datatype element data */
H5FL_BLK_EXTERN(type_elem);
/*--------------------------------------------------------------------------
@ -1437,9 +1436,11 @@ herr_t
H5S_select_fill(const void *_fill, size_t fill_size, const H5S_t *space, void *_buf)
{
H5S_sel_iter_t iter; /* Selection iteration info */
hbool_t iter_init=0; /* Selection iteration info has been initialized */
hbool_t iter_init = 0; /* Selection iteration info has been initialized */
H5WB_t *elem_wb = NULL; /* Wrapped buffer for element data */
uint8_t elem_buf[H5T_ELEM_BUF_SIZE]; /* Buffer for element data */
uint8_t *buf; /* Current location in buffer */
const void *fill=_fill; /* Alias for fill-value buffer */
const void *fill; /* Alias for fill-value buffer */
hssize_t nelmts; /* Number of elements in selection */
hsize_t off[H5D_IO_VECTOR_SIZE]; /* Array to store sequence offsets */
size_t len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */
@ -1457,10 +1458,17 @@ H5S_select_fill(const void *_fill, size_t fill_size, const H5S_t *space, void *_
assert(_buf);
/* Check if we need a temporary fill value buffer */
if(fill==NULL) {
if (NULL==(fill = H5FL_BLK_CALLOC(type_elem,fill_size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "fill value buffer allocation failed");
if(_fill == NULL) {
/* Wrap the local buffer for elements */
if(NULL == (elem_wb = H5WB_wrap(elem_buf, sizeof(elem_buf))))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't wrap buffer")
/* Get a pointer to a buffer that's large enough for element */
if(NULL == (fill = H5WB_actual_clear(elem_wb, fill_size)))
HGOTO_ERROR(H5E_DATASET, H5E_NOSPACE, FAIL, "can't get actual buffer")
} /* end if */
else
fill = _fill;
/* Initialize iterator */
if (H5S_select_iter_init(&iter, space, fill_size)<0)
@ -1495,15 +1503,11 @@ H5S_select_fill(const void *_fill, size_t fill_size, const H5S_t *space, void *_
} /* end while */
done:
/* Release selection iterator */
if(iter_init) {
if (H5S_SELECT_ITER_RELEASE(&iter)<0)
HDONE_ERROR (H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
} /* end if */
/* Release fill value, if allocated */
if(_fill==NULL && fill)
H5FL_BLK_FREE(type_elem, (void *)fill); /* casting away const OK - QAK */
/* Release resouces */
if(iter_init && H5S_SELECT_ITER_RELEASE(&iter) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator");
if(elem_wb && H5WB_unwrap(elem_wb) < 0)
HDONE_ERROR(H5E_DATASPACE, H5E_CLOSEERROR, FAIL, "can't close wrapped buffer")
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_select_fill() */

View File

@ -3163,8 +3163,7 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
int direction; /*direction of traversal */
size_t elmtno; /*element number counter */
unsigned u; /* local index variable */
void *bkg_buf=NULL; /*temporary background buffer */
size_t bkg_buf_size=0; /*size of background buffer in bytes */
void *bkg_buf = NULL; /*temporary background buffer */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5T_conv_array, FAIL)
@ -3239,10 +3238,12 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
/* Check if we need a background buffer for this conversion */
if(tpath->cdata.need_bkg) {
size_t bkg_buf_size; /*size of background buffer in bytes */
/* Allocate background buffer */
bkg_buf_size = src->shared->u.array.nelem * MAX(src->shared->size, dst->shared->size);
if((bkg_buf = H5FL_BLK_CALLOC(array_seq, bkg_buf_size)) == NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
if(NULL == (bkg_buf = H5FL_BLK_CALLOC(array_seq, bkg_buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion")
} /* end if */
/* Perform the actual conversion */
@ -3259,10 +3260,6 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
dp += dst_delta;
} /* end for */
/* Release the background buffer, if we have one */
if(bkg_buf != NULL)
H5FL_BLK_FREE(array_seq, bkg_buf);
/* Release the temporary datatype IDs used */
if(tsrc_id >= 0)
H5I_dec_ref(tsrc_id);
@ -3275,6 +3272,10 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
} /* end switch */
done:
/* Release the background buffer, if we have one */
if(bkg_buf)
H5FL_BLK_FREE(array_seq, bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_conv_array() */

View File

@ -30,6 +30,9 @@
#include "H5Gprivate.h" /* Groups */
#include "H5Rprivate.h" /* References */
/* Macro for size of temporary buffers to contain a single element */
#define H5T_ELEM_BUF_SIZE 256
/* Forward references of package typedefs */
typedef struct H5T_t H5T_t;
typedef struct H5T_stats_t H5T_stats_t;

291
src/H5WB.c Normal file
View File

@ -0,0 +1,291 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*-------------------------------------------------------------------------
*
* Created: H5WB.c
* Jun 26 2007
* Quincey Koziol <koziol@hdfgroup.org>
*
* Purpose: Implements the "wrapped buffer" code for wrapping
* an existing [staticly sized] buffer, in order to
* avoid lots of memory allocation calls.
*
*-------------------------------------------------------------------------
*/
/****************/
/* Module Setup */
/****************/
/***********/
/* Headers */
/***********/
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
#include "H5WBprivate.h" /* Wrapped Buffers */
/****************/
/* Local Macros */
/****************/
/******************/
/* Local Typedefs */
/******************/
/********************/
/* Package Typedefs */
/********************/
/* Typedef for buffer wrapper */
struct H5WB_t {
void *wrapped_buf; /* Pointer to wrapped buffer */
size_t wrapped_size; /* Size of wrapped buffer */
void *actual_buf; /* Pointer to actual buffer */
size_t actual_size; /* Size of actual buffer used */
size_t alloc_size; /* Size of actual buffer allocated */
};
/********************/
/* Local Prototypes */
/********************/
/*********************/
/* Package Variables */
/*********************/
/*****************************/
/* Library Private Variables */
/*****************************/
/*******************/
/* Local Variables */
/*******************/
/* Declare a free list to manage the H5WB_t struct */
H5FL_DEFINE_STATIC(H5WB_t);
/* Declare a free list to manage the extra buffer information */
H5FL_BLK_DEFINE_STATIC(extra_buf);
/*-------------------------------------------------------------------------
* Function: H5WB_wrap
*
* Purpose: Wraps an existing [possibly static] buffer
*
* Return: Pointer to buffer wrapper info on success
* NULL on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Jun 26 2007
*
*-------------------------------------------------------------------------
*/
H5WB_t *
H5WB_wrap(void *buf, size_t buf_size)
{
H5WB_t *wb = NULL; /* Wrapped buffer info */
H5WB_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5WB_wrap, NULL)
/*
* Check arguments.
*/
HDassert(buf);
HDassert(buf_size);
/* Create wrapped buffer info */
if(NULL == (wb = H5FL_MALLOC(H5WB_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for wrapped buffer info")
/* Wrap buffer given */
wb->wrapped_buf = buf;
wb->wrapped_size = buf_size;
/* No actual buffer yet */
wb->actual_buf = NULL;
wb->actual_size = 0;
wb->alloc_size = 0;
/* Set the return value */
ret_value = wb;
done:
/* Release resources on error */
if(!ret_value && wb)
(void)H5FL_FREE(H5WB_t, wb);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5WB_wrap() */
/*-------------------------------------------------------------------------
* Function: H5WB_actual
*
* Purpose: Get the pointer to an "actual" buffer, of at least a certain
* size.
*
* Return: Pointer to buffer pointer on success
* NULL on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Jun 26 2007
*
*-------------------------------------------------------------------------
*/
void *
H5WB_actual(H5WB_t *wb, size_t need)
{
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5WB_actual, NULL)
/*
* Check arguments.
*/
HDassert(wb);
HDassert(wb->wrapped_buf);
/* Check for previously allocated buffer */
if(wb->actual_buf && wb->actual_buf != wb->wrapped_buf) {
/* Sanity check */
HDassert(wb->actual_size > wb->wrapped_size);
/* Check if we can re-use existing buffer */
if(need <= wb->alloc_size)
HGOTO_DONE(wb->actual_buf)
/* Can't re-use existing buffer, free it and proceed */
else
wb->actual_buf = H5FL_BLK_FREE(extra_buf, wb->actual_buf);
} /* end if */
/* Check if size needed can be fulfilled with wrapped buffer */
if(need > wb->wrapped_size) {
/* Need to allocate new buffer */
if(NULL == (wb->actual_buf = H5FL_BLK_MALLOC(extra_buf, need)))
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, NULL, "memory allocation failed")
/* Remember size of buffer allocated */
wb->alloc_size = need;
} /* end if */
else {
/* Don't have to allocate a new buffer, use the wrapped one */
wb->actual_buf = wb->wrapped_buf;
wb->alloc_size = 0;
} /* end else */
/* Set the return value */
ret_value = wb->actual_buf;
done:
/* Remember size of buffer used, if we were successful */
if(ret_value)
wb->actual_size = need;
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5WB_actual() */
/*-------------------------------------------------------------------------
* Function: H5WB_actual_clear
*
* Purpose: Get the pointer to an "actual" buffer, of at least a certain
* size. Also, clear actual buffer to zeros.
*
* Return: Pointer to buffer pointer on success
* NULL on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Jun 26 2007
*
*-------------------------------------------------------------------------
*/
void *
H5WB_actual_clear(H5WB_t *wb, size_t need)
{
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5WB_actual_clear, NULL)
/*
* Check arguments.
*/
HDassert(wb);
HDassert(wb->wrapped_buf);
/* Get a pointer to an actual buffer */
if(NULL == (ret_value = H5WB_actual(wb, need)))
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, NULL, "memory allocation failed")
/* Clear the buffer */
HDmemset(ret_value, 0, need);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5WB_actual_clear() */
/*-------------------------------------------------------------------------
* Function: H5WB_unwrap
*
* Purpose: "unwrap" a wrapped buffer, releasing all resources used
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Jun 26 2007
*
*-------------------------------------------------------------------------
*/
herr_t
H5WB_unwrap(H5WB_t *wb)
{
FUNC_ENTER_NOAPI_NOFUNC(H5WB_unwrap)
/*
* Check arguments.
*/
HDassert(wb);
HDassert(wb->wrapped_buf);
/* Release any extra buffers allocated */
if(wb->actual_buf && wb->actual_buf != wb->wrapped_buf) {
/* Sanity check */
HDassert(wb->actual_size > wb->wrapped_size);
wb->actual_buf = H5FL_BLK_FREE(extra_buf, wb->actual_buf);
} /* end if */
/* Release the buffer wrapper info */
H5FL_FREE(H5WB_t, wb);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5WB_unwrap() */

64
src/H5WBprivate.h Normal file
View File

@ -0,0 +1,64 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*-------------------------------------------------------------------------
*
* Created: H5WBprivate.h
* Jun 26 2007
* Quincey Koziol <koziol@hdfgroup.org>
*
* Purpose: Private header for library accessible wrapped buffer routines.
*
*-------------------------------------------------------------------------
*/
#ifndef _H5WBprivate_H
#define _H5WBprivate_H
/* Include package's public header */
/* #include "H5WBpublic.h" */
/* Private headers needed by this file */
/**************************/
/* Library Private Macros */
/**************************/
/****************************/
/* Library Private Typedefs */
/****************************/
/* Wrapped buffer info (forward decl - defined in H5WB.c) */
typedef struct H5WB_t H5WB_t;
/*****************************/
/* Library-private Variables */
/*****************************/
/***************************************/
/* Library-private Function Prototypes */
/***************************************/
/* General routines for wrapped buffer operations */
H5_DLL H5WB_t *H5WB_wrap(void *buf, size_t buf_size);
H5_DLL void *H5WB_actual(H5WB_t *wb, size_t need);
H5_DLL void *H5WB_actual_clear(H5WB_t *wb, size_t need);
H5_DLL herr_t H5WB_unwrap(H5WB_t *wb);
#endif /* _H5WBprivate_H */

View File

@ -83,7 +83,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Tfixed.c \
H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5Z.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
H5Zscaleoffset.c H5Ztrans.c

View File

@ -114,7 +114,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \
H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tdeprec.lo \
H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \
H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \
H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo \
H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo H5WB.lo \
H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \
H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo
libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS)
@ -436,7 +436,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5Tfixed.c \
H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \
H5Torder.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5Z.c \
H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5WB.c H5Z.c \
H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \
H5Zscaleoffset.c H5Ztrans.c
@ -758,6 +758,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tstrpad.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tvlen.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5V.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5WB.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Z.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zdeflate.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Zfletcher32.Plo@am__quote@

View File

@ -445,14 +445,14 @@ main(int argc, char *argv[])
status = H5FS_sects_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, extra, extra2);
} else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5SM_TABLE_SIZEOF_MAGIC)) {
} else if(!HDmemcmp(sig, H5SM_TABLE_MAGIC, (size_t)H5SM_SIZEOF_MAGIC)) {
/*
* Debug shared message master table.
*/
status = H5SM_table_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, (unsigned) UFAIL, (unsigned) UFAIL);
} else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5SM_LIST_SIZEOF_MAGIC)) {
} else if(!HDmemcmp(sig, H5SM_LIST_MAGIC, (size_t)H5SM_SIZEOF_MAGIC)) {
/*
* Debug shared message list index.
*/