diff options
author | Mike McGreevy <mamcgree@hdfgroup.org> | 2008-08-08 22:01:29 (GMT) |
---|---|---|
committer | Mike McGreevy <mamcgree@hdfgroup.org> | 2008-08-08 22:01:29 (GMT) |
commit | a6edfcad19bc6124f71cb8dc76161cdbe74094e2 (patch) | |
tree | 2ceb03cb8a4b1c07e395d7b7708821af0d96618d /src/H5HFcache.c | |
parent | e36116f962b815ff485f2c964f99483a1af069b6 (diff) | |
download | hdf5-a6edfcad19bc6124f71cb8dc76161cdbe74094e2.zip hdf5-a6edfcad19bc6124f71cb8dc76161cdbe74094e2.tar.gz hdf5-a6edfcad19bc6124f71cb8dc76161cdbe74094e2.tar.bz2 |
[svn-r15454] Purpose: metadata cache client conversions
Description: converted the fractal heap header and indirect block metadata
cache clients over to use the new journaling cache callbacks.
Tested: kagiso, smirom
Diffstat (limited to 'src/H5HFcache.c')
-rw-r--r-- | src/H5HFcache.c | 850 |
1 files changed, 329 insertions, 521 deletions
diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 23bc28e..26e539d 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -75,15 +75,22 @@ static herr_t H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable); static herr_t H5HF_dtable_decode(H5F_t *f, const uint8_t **pp, H5HF_dtable_t *dtable); -/* Metadata cache (H5AC) callbacks */ -static H5HF_hdr_t *H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); -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); -static herr_t H5HF_cache_hdr_clear(H5F_t *f, H5HF_hdr_t *hdr, hbool_t destroy); -static herr_t H5HF_cache_hdr_size(const H5F_t *f, const H5HF_hdr_t *hdr, size_t *size_ptr); -static H5HF_indirect_t *H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); -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); -static herr_t H5HF_cache_iblock_clear(H5F_t *f, H5HF_indirect_t *iblock, hbool_t destroy); -static herr_t H5HF_cache_iblock_size(const H5F_t *f, const H5HF_indirect_t *iblock, size_t *size_ptr); +/* Metadata cache (H5AC2) callbacks */ +static void *H5HF_cache_hdr_deserialize(haddr_t addr, size_t len, + const void *image, const void *udata, hbool_t *dirty); +static herr_t H5HF_cache_hdr_serialize(const H5F_t *f, haddr_t addr, size_t len, + void *image, void *thing, unsigned *flags, haddr_t *new_addr, + size_t *new_len, void **new_image); +static herr_t H5HF_cache_hdr_free_icr(haddr_t addr, size_t len, void *thing); +static herr_t H5HF_cache_hdr_image_len(const void *thing, size_t *image_len_ptr); + +static void *H5HF_cache_iblock_deserialize(haddr_t addr, size_t len, + const void *image, const void *udata, hbool_t *dirty); +static herr_t H5HF_cache_iblock_serialize(const H5F_t * f, haddr_t addr, + size_t len, void *image, void *_thing, unsigned *flags, haddr_t *new_addr, + size_t *new_len, void **new_image); +static herr_t H5HF_cache_iblock_free_icr(haddr_t addr, size_t len, void *thing); + static H5HF_direct_t *H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_direct_t *dblock, unsigned UNUSED * flags_ptr); static herr_t H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy); @@ -93,24 +100,28 @@ static herr_t H5HF_cache_dblock_size(const H5F_t *f, const H5HF_direct_t *dblock /* Package Variables */ /*********************/ -/* H5HF header inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_FHEAP_HDR[1] = {{ - H5AC_FHEAP_HDR_ID, - (H5AC_load_func_t)H5HF_cache_hdr_load, - (H5AC_flush_func_t)H5HF_cache_hdr_flush, - (H5AC_dest_func_t)H5HF_cache_hdr_dest, - (H5AC_clear_func_t)H5HF_cache_hdr_clear, - (H5AC_size_func_t)H5HF_cache_hdr_size, +/* H5HF header inherits cache-like properties from H5AC2 */ +const H5AC2_class_t H5AC2_FHEAP_HDR[1] = {{ + H5AC2_FHEAP_HDR_ID, + "fractal heap header", + H5FD_MEM_FHEAP_HDR, + H5HF_cache_hdr_deserialize, + H5HF_cache_hdr_image_len, + H5HF_cache_hdr_serialize, + H5HF_cache_hdr_free_icr, + NULL, }}; -/* H5HF indirect block inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_FHEAP_IBLOCK[1] = {{ - H5AC_FHEAP_IBLOCK_ID, - (H5AC_load_func_t)H5HF_cache_iblock_load, - (H5AC_flush_func_t)H5HF_cache_iblock_flush, - (H5AC_dest_func_t)H5HF_cache_iblock_dest, - (H5AC_clear_func_t)H5HF_cache_iblock_clear, - (H5AC_size_func_t)H5HF_cache_iblock_size, +/* H5HF indirect block inherits cache-like properties from H5AC2 */ +const H5AC2_class_t H5AC2_FHEAP_IBLOCK[1] = {{ + H5AC2_FHEAP_IBLOCK_ID, + "fractal heap indirect block", + H5FD_MEM_FHEAP_IBLOCK, + H5HF_cache_iblock_deserialize, + NULL, + H5HF_cache_iblock_serialize, + H5HF_cache_iblock_free_icr, + NULL, }}; /* H5HF direct block inherits cache-like properties from H5AC */ @@ -239,67 +250,54 @@ H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable) /*------------------------------------------------------------------------- - * Function: H5HF_cache_hdr_load + * Function: H5HF_cache_hdr_deserialize * - * Purpose: Loads a fractal heap header from the disk. + * Purpose: Deserialize the data structure from disk. * - * Return: Success: Pointer to a new fractal heap - * - * Failure: NULL + * Return: Success: SUCCESS + * Failure: FAIL * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu * Feb 24 2006 * + * Changes: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 + * Converted from H5HF_cache_hdr_load + * *------------------------------------------------------------------------- */ -static H5HF_hdr_t * -H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2) +static void * +H5HF_cache_hdr_deserialize(haddr_t addr, size_t UNUSED len, + const void *image, const void *_udata, hbool_t UNUSED *dirty) { H5HF_hdr_t *hdr = NULL; /* Fractal heap info */ + H5HF_hdr_cache_ud_t *udata = (H5HF_hdr_cache_ud_t *)_udata; size_t size; /* Header size */ - 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 */ uint8_t heap_flags; /* Status flags for heap */ H5HF_hdr_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_load) -#ifdef QAK -HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); -#endif /* QAK */ + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_deserialize) /* Check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); + HDassert(image); /* Allocate space for the fractal heap data structure */ - if(NULL == (hdr = H5HF_hdr_alloc(f))) + if(NULL == (hdr = H5HF_hdr_alloc(udata->f))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* 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); - /* 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; + p = image; /* Magic number */ if(HDmemcmp(p, H5HF_HDR_MAGIC, (size_t)H5HF_SIZEOF_MAGIC)) @@ -323,22 +321,22 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* "Huge" object information */ UINT32DECODE(p, hdr->max_man_size); /* Max. size of "managed" objects */ - H5F_DECODE_LENGTH(f, p, hdr->huge_next_id); /* Next ID to use for "huge" object */ - H5F_addr_decode(f, &p, &hdr->huge_bt2_addr); /* Address of "huge" object tracker B-tree */ + H5F_DECODE_LENGTH(udata->f, p, hdr->huge_next_id); /* Next ID to use for "huge" object */ + H5F_addr_decode(udata->f, &p, &hdr->huge_bt2_addr); /* Address of "huge" object tracker B-tree */ /* "Managed" object free space information */ - H5F_DECODE_LENGTH(f, p, hdr->total_man_free); /* Internal free space in managed direct blocks */ - H5F_addr_decode(f, &p, &hdr->fs_addr); /* Address of free section header */ + H5F_DECODE_LENGTH(udata->f, p, hdr->total_man_free); /* Internal free space in managed direct blocks */ + H5F_addr_decode(udata->f, &p, &hdr->fs_addr); /* Address of free section header */ /* Heap statistics */ - H5F_DECODE_LENGTH(f, p, hdr->man_size); - H5F_DECODE_LENGTH(f, p, hdr->man_alloc_size); - H5F_DECODE_LENGTH(f, p, hdr->man_iter_off); - H5F_DECODE_LENGTH(f, p, hdr->man_nobjs); - H5F_DECODE_LENGTH(f, p, hdr->huge_size); - H5F_DECODE_LENGTH(f, p, hdr->huge_nobjs); - H5F_DECODE_LENGTH(f, p, hdr->tiny_size); - H5F_DECODE_LENGTH(f, p, hdr->tiny_nobjs); + H5F_DECODE_LENGTH(udata->f, p, hdr->man_size); + H5F_DECODE_LENGTH(udata->f, p, hdr->man_alloc_size); + H5F_DECODE_LENGTH(udata->f, p, hdr->man_iter_off); + H5F_DECODE_LENGTH(udata->f, p, hdr->man_nobjs); + H5F_DECODE_LENGTH(udata->f, p, hdr->huge_size); + H5F_DECODE_LENGTH(udata->f, p, hdr->huge_nobjs); + H5F_DECODE_LENGTH(udata->f, p, hdr->tiny_size); + H5F_DECODE_LENGTH(udata->f, p, hdr->tiny_nobjs); /* Managed objects' doubling-table info */ if(H5HF_dtable_decode(hdr->f, &p, &(hdr->man_dtable)) < 0) @@ -346,16 +344,17 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Sanity check */ /* (allow for checksum not decoded yet) */ - HDassert((size_t)(p - buf) == (size - H5HF_SIZEOF_CHKSUM)); + HDassert((size_t)(p - (const uint8_t *)image) == (size - H5HF_SIZEOF_CHKSUM)); /* Check for I/O filter information to decode */ if(hdr->filter_len > 0) { + size_t filter_info_off; /* Offset in header of filter information */ size_t filter_info_size; /* Size of filter information */ H5O_pline_t *pline; /* Pipeline information from the header on disk */ /* Compute the offset of the filter info in the header */ - filter_info_off = p - buf; + filter_info_off = p - (const uint8_t *)image; /* Compute the size of the extra filter information */ filter_info_size = hdr->sizeof_size /* Size of size for filtered root direct block */ @@ -365,26 +364,17 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Compute the heap header's size */ hdr->heap_size = size + filter_info_size; - /* Re-size current buffer */ - 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) */ - if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, (addr + filter_info_off), (filter_info_size + H5HF_SIZEOF_CHKSUM), dxpl_id, (buf + filter_info_off)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header's I/O pipeline filter info") - /* Point at correct offset in header for the filter information */ - p = buf + filter_info_off; + p = image + filter_info_off; /* Decode the size of a filtered root direct block */ - H5F_DECODE_LENGTH(f, p, hdr->pline_root_direct_size); + H5F_DECODE_LENGTH(udata->f, p, hdr->pline_root_direct_size); /* Decode the filter mask for a filtered root direct block */ UINT32DECODE(p, hdr->pline_root_direct_filter_mask); /* Decode I/O filter information */ - if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, dxpl_id, H5O_PLINE_ID, p))) + if(NULL == (pline = (H5O_pline_t *)H5O_msg_decode(hdr->f, udata->dxpl_id, H5O_PLINE_ID, p))) HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode I/O pipeline filters") p += hdr->filter_len; @@ -401,13 +391,13 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Compute checksum on entire header */ /* (including the filter information, if present) */ - computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + computed_chksum = H5_checksum_metadata(image, (size_t)(p - (const uint8_t *)image), 0); /* Metadata checksum */ UINT32DECODE(p, stored_chksum); /* Sanity check */ - HDassert((size_t)(p - buf) == hdr->heap_size); + HDassert((size_t)(p - (const uint8_t *)image) == hdr->heap_size); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -425,21 +415,54 @@ HDfprintf(stderr, "%s: hdr->fspace = %p\n", FUNC, hdr->fspace); done: /* 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); + (void)H5HF_cache_hdr_dest(hdr); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */ +} /* end H5HF_cache_hdr_deserialize() */ /*lint !e818 Can't make udata a pointer to const */ /*------------------------------------------------------------------------- - * Function: H5HF_cache_hdr_flush + * Function: H5HF_cache_hdr_image_len * - * Purpose: Flushes a dirty fractal heap header to disk. + * Purpose: Tell the metadata cache about the actual size + * of the fractal heap header * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure + * + * Programmer: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_cache_hdr_image_len(const void *thing, size_t *image_len_ptr) +{ + + const H5HF_hdr_t *hdr = (const H5HF_hdr_t *)thing; /* Fractal heap header */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_image_len) + + /* Check arguments */ + HDassert(hdr); + HDassert(image_len_ptr); + + /* Report the fractal heap header's prefix + I/O filter length */ + *image_len_ptr = H5HF_HEADER_SIZE(hdr) + hdr->filter_len; + + FUNC_LEAVE_NOAPI(SUCCEED) + +} /* end H5HF_cache_hdr_image_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_cache_hdr_serialize + * + * Purpose: Serialize the data structure for writing to disk. + * + * Return: Success: SUCCEED + * Failure: FAIL * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu @@ -450,246 +473,153 @@ done: * entry is resized or renamed as a result of the flush. * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. * + * Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 + * Converted from H5HF_cache_hdr_flush + * *------------------------------------------------------------------------- */ 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) +H5HF_cache_hdr_serialize(const H5F_t *f, haddr_t UNUSED addr, size_t UNUSED len, + void *image, void *_thing, unsigned *flags, haddr_t UNUSED *new_addr, + size_t UNUSED *new_len, void UNUSED **new_image) { - 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 */ + uint8_t *p; /* Pointer into raw data buffer */ + size_t size; /* Header size on disk */ + uint8_t heap_flags; /* Status flags for heap */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + H5HF_hdr_t *hdr = (H5HF_hdr_t *)_thing; /* fractal heap header */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_flush) -#ifdef QAK -HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); -#endif /* QAK */ + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_serialize) /* check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(hdr); + HDassert(image); + HDassert(flags); - if(hdr->cache_info.is_dirty) { - uint8_t *buf; /* Temporary raw data buffer */ - uint8_t *p; /* Pointer into raw data buffer */ - size_t size; /* Header size on disk */ - uint8_t heap_flags; /* Status flags for heap */ - uint32_t metadata_chksum; /* Computed metadata checksum value */ + /* Sanity check */ + HDassert(hdr->dirty); - /* Sanity check */ - HDassert(hdr->dirty); + /* Set the shared heap header's file context for this operation */ + hdr->f = f; - /* Set the shared heap header's file context for this operation */ - hdr->f = f; + /* Compute the size of the heap header on disk */ + size = hdr->heap_size; - /* 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") + /* Get temporary pointer to serialized header */ + p = image; - /* Compute the size of the heap header on disk */ - size = hdr->heap_size; + /* Magic number */ + HDmemcpy(p, H5HF_HDR_MAGIC, (size_t)H5HF_SIZEOF_MAGIC); + p += H5HF_SIZEOF_MAGIC; - /* 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") + /* Version # */ + *p++ = H5HF_HDR_VERSION; - /* Get temporary pointer to serialized header */ - p = buf; + /* General heap information */ + UINT16ENCODE(p, hdr->id_len); /* Heap ID length */ + UINT16ENCODE(p, hdr->filter_len); /* I/O filters' encoded length */ - /* Magic number */ - HDmemcpy(p, H5HF_HDR_MAGIC, (size_t)H5HF_SIZEOF_MAGIC); - p += H5HF_SIZEOF_MAGIC; + /* Heap status flags */ + /* (bit 0: "huge" object IDs have wrapped) */ + /* (bit 1: checksum direct blocks) */ + heap_flags = 0; + heap_flags |= (hdr->huge_ids_wrapped ? H5HF_HDR_FLAGS_HUGE_ID_WRAPPED : 0); + heap_flags |= (hdr->checksum_dblocks ? H5HF_HDR_FLAGS_CHECKSUM_DBLOCKS : 0); + *p++ = heap_flags; - /* Version # */ - *p++ = H5HF_HDR_VERSION; - - /* General heap information */ - UINT16ENCODE(p, hdr->id_len); /* Heap ID length */ - UINT16ENCODE(p, hdr->filter_len); /* I/O filters' encoded length */ - - /* Heap status flags */ - /* (bit 0: "huge" object IDs have wrapped) */ - /* (bit 1: checksum direct blocks) */ - heap_flags = 0; - heap_flags |= (hdr->huge_ids_wrapped ? H5HF_HDR_FLAGS_HUGE_ID_WRAPPED : 0); - heap_flags |= (hdr->checksum_dblocks ? H5HF_HDR_FLAGS_CHECKSUM_DBLOCKS : 0); - *p++ = heap_flags; - - /* "Huge" object information */ - UINT32ENCODE(p, hdr->max_man_size); /* Max. size of "managed" objects */ - H5F_ENCODE_LENGTH(f, p, hdr->huge_next_id); /* Next ID to use for "huge" object */ - H5F_addr_encode(f, &p, hdr->huge_bt2_addr); /* Address of "huge" object tracker B-tree */ - - /* "Managed" object free space information */ - H5F_ENCODE_LENGTH(f, p, hdr->total_man_free); /* Internal free space in managed direct blocks */ - H5F_addr_encode(f, &p, hdr->fs_addr); /* Address of free section header */ - - /* Heap statistics */ - H5F_ENCODE_LENGTH(f, p, hdr->man_size); - H5F_ENCODE_LENGTH(f, p, hdr->man_alloc_size); - H5F_ENCODE_LENGTH(f, p, hdr->man_iter_off); - H5F_ENCODE_LENGTH(f, p, hdr->man_nobjs); - H5F_ENCODE_LENGTH(f, p, hdr->huge_size); - H5F_ENCODE_LENGTH(f, p, hdr->huge_nobjs); - H5F_ENCODE_LENGTH(f, p, hdr->tiny_size); - H5F_ENCODE_LENGTH(f, p, hdr->tiny_nobjs); - - /* Managed objects' doubling-table info */ - if(H5HF_dtable_encode(hdr->f, &p, &(hdr->man_dtable)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "unable to encode managed obj. doubling table info") - - /* Check for I/O filter information to encode */ - if(hdr->filter_len > 0) { - /* Encode the size of a filtered root direct block */ - H5F_ENCODE_LENGTH(f, p, hdr->pline_root_direct_size); + /* "Huge" object information */ + UINT32ENCODE(p, hdr->max_man_size); /* Max. size of "managed" objects */ + H5F_ENCODE_LENGTH(f, p, hdr->huge_next_id); /* Next ID to use for "huge" object */ + H5F_addr_encode(f, &p, hdr->huge_bt2_addr); /* Address of "huge" object tracker B-tree */ - /* Encode the filter mask for a filtered root direct block */ - UINT32ENCODE(p, hdr->pline_root_direct_filter_mask); + /* "Managed" object free space information */ + H5F_ENCODE_LENGTH(f, p, hdr->total_man_free); /* Internal free space in managed direct blocks */ + H5F_addr_encode(f, &p, hdr->fs_addr); /* Address of free section header */ - /* Encode I/O filter information */ - if(H5O_msg_encode(hdr->f, H5O_PLINE_ID, FALSE, p, &(hdr->pline)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "can't encode I/O pipeline fiters") - p += hdr->filter_len; - } /* end if */ + /* Heap statistics */ + H5F_ENCODE_LENGTH(f, p, hdr->man_size); + H5F_ENCODE_LENGTH(f, p, hdr->man_alloc_size); + H5F_ENCODE_LENGTH(f, p, hdr->man_iter_off); + H5F_ENCODE_LENGTH(f, p, hdr->man_nobjs); + H5F_ENCODE_LENGTH(f, p, hdr->huge_size); + H5F_ENCODE_LENGTH(f, p, hdr->huge_nobjs); + H5F_ENCODE_LENGTH(f, p, hdr->tiny_size); + H5F_ENCODE_LENGTH(f, p, hdr->tiny_nobjs); - /* Compute metadata checksum */ - metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + /* Managed objects' doubling-table info */ + if(H5HF_dtable_encode(hdr->f, &p, &(hdr->man_dtable)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "unable to encode managed obj. doubling table info") - /* Metadata checksum */ - UINT32ENCODE(p, metadata_chksum); + /* Check for I/O filter information to encode */ + if(hdr->filter_len > 0) { + /* Encode the size of a filtered root direct block */ + H5F_ENCODE_LENGTH(f, p, hdr->pline_root_direct_size); - /* Write the heap header. */ - HDassert((size_t)(p - buf) == size); - 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") + /* Encode the filter mask for a filtered root direct block */ + UINT32ENCODE(p, hdr->pline_root_direct_filter_mask); - hdr->dirty = FALSE; - hdr->cache_info.is_dirty = FALSE; + /* Encode I/O filter information */ + if(H5O_msg_encode(hdr->f, H5O_PLINE_ID, FALSE, p, &(hdr->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "can't encode I/O pipeline fiters") + p += hdr->filter_len; } /* end if */ - if(destroy) - if(H5HF_cache_hdr_dest(f, hdr) < 0) - 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() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_hdr_dest - * - * Purpose: Destroys a fractal heap header in memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 24 2006 - * - *------------------------------------------------------------------------- - */ -/* ARGSUSED */ -herr_t -H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_hdr_t *hdr) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_dest) - - /* - * Check arguments. - */ - HDassert(hdr); - HDassert(hdr->rc == 0); - - /* Free the block size lookup table for the doubling table */ - H5HF_dtable_dest(&hdr->man_dtable); - - /* Release any I/O pipeline filter information */ - if(hdr->pline.nused) - H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline)); - - /* Free the shared info itself */ - H5FL_FREE(H5HF_hdr_t, hdr); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HF_cache_hdr_dest() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_hdr_clear - * - * Purpose: Mark a fractal heap header in memory as non-dirty. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 24 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_cache_hdr_clear(H5F_t *f, H5HF_hdr_t *hdr, hbool_t destroy) -{ - herr_t ret_value = SUCCEED; /* Return value */ + /* Compute metadata checksum */ + metadata_chksum = H5_checksum_metadata(image, (size_t)(p - (const uint8_t *)image), 0); - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_clear) + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); - /* - * Check arguments. - */ - HDassert(hdr); + /* Sanity check */ + HDassert((size_t)(p - (const uint8_t *)image) == size); - /* Reset the dirty flag. */ - hdr->cache_info.is_dirty = FALSE; + /* Reset the cache flags for this operation (metadata not resized or renamed) */ + *flags = 0; - if(destroy) - if(H5HF_cache_hdr_dest(f, hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap header") + /* Sanity check */ + HDassert((size_t)((const uint8_t *)p - (const uint8_t *)image) <= len); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_hdr_clear() */ +} /* H5HF_cache_hdr_serialize() */ /*------------------------------------------------------------------------- - * Function: H5HF_cache_hdr_size + * Function: H5HF_cache_hdr_free_icr * - * Purpose: Compute the size in bytes of a fractal heap header - * on disk, and return it in *size_ptr. On failure, - * the value of *size_ptr is undefined. + * Purpose: Destroy/release an "in core representation" of a data structure * - * Return: Non-negative on success/Negative on failure + * Return: Success: SUCCEED + * Failure: FAIL * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 24 2006 + * Programmer: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 * *------------------------------------------------------------------------- */ static herr_t -H5HF_cache_hdr_size(const H5F_t UNUSED *f, const H5HF_hdr_t *hdr, size_t *size_ptr) +H5HF_cache_hdr_free_icr(haddr_t UNUSED addr, size_t UNUSED len, void *thing) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_size) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_free_icr) - /* check arguments */ - HDassert(f); - HDassert(hdr); - HDassert(size_ptr); + /* Check arguments */ + HDassert(thing); - /* Set size value */ - *size_ptr = hdr->heap_size; + /* Destroy B-tree node */ + H5HF_cache_hdr_dest(thing); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_cache_hdr_size() */ +} /* end H5HF_cache_hdr_free_icr() */ /*------------------------------------------------------------------------- - * Function: H5HF_cache_iblock_load + * Function: H5HF_cache_iblock_deserialize * * Purpose: Loads a fractal heap indirect block from the disk. * @@ -701,18 +631,20 @@ H5HF_cache_hdr_size(const H5F_t UNUSED *f, const H5HF_hdr_t *hdr, size_t *size_p * koziol@ncsa.uiuc.edu * Feb 27 2006 * + * Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 + * Converted from H5HF_cache_iblock_load + * *------------------------------------------------------------------------- */ -static H5HF_indirect_t * -H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_par_info) +static void * +H5HF_cache_iblock_deserialize(haddr_t UNUSED addr, size_t UNUSED len, + const void *image, const void *_udata, hbool_t UNUSED *dirty) { H5HF_hdr_t *hdr; /* Shared fractal heap information */ - 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_iblock_cache_ud_t *udata = (H5HF_iblock_cache_ud_t *)_udata; /* user data for callback */ H5HF_indirect_t *iblock = NULL; /* Indirect block info */ - 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 */ @@ -720,26 +652,24 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows size_t u; /* Local index variable */ H5HF_indirect_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_load) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_deserialize) #ifdef QAK HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); #endif /* QAK */ /* Check arguments */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); - HDassert(par_info); + HDassert(image); /* Allocate space for the fractal heap indirect block */ if(NULL == (iblock = H5FL_CALLOC(H5HF_indirect_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t)); + HDmemset(&iblock->cache_info, 0, sizeof(H5AC2_info_t)); /* Get the pointer to the shared heap header */ - hdr = par_info->hdr; + hdr = udata->par_info->hdr; /* Set the shared heap header's file context for this operation */ - hdr->f = f; + hdr->f = udata->f; /* Share common heap information */ iblock->hdr = hdr; @@ -748,27 +678,14 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); /* Set block's internal information */ iblock->rc = 0; - iblock->nrows = *nrows; + iblock->nrows = *udata->nrows; 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); - - /* 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; + p = image; /* Magic number */ if(HDmemcmp(p, H5HF_IBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC)) @@ -780,13 +697,13 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); 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); + H5F_addr_decode(udata->f, &p, &heap_addr); if(H5F_addr_ne(heap_addr, hdr->heap_addr)) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") /* Address of parent block */ - iblock->parent = par_info->iblock; - iblock->par_entry = par_info->entry; + iblock->parent = udata->par_info->iblock; + iblock->par_entry = udata->par_info->entry; if(iblock->parent) { /* Share parent block */ if(H5HF_iblock_incr(iblock->parent) < 0) @@ -821,7 +738,7 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); iblock->filt_ents = NULL; for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { /* Decode child block address */ - H5F_addr_decode(f, &p, &(iblock->ents[u].addr)); + H5F_addr_decode(udata->f, &p, &(iblock->ents[u].addr)); /* Check for heap with I/O filters */ if(hdr->filter_len > 0) { @@ -831,7 +748,7 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); /* Decode extra information for direct blocks */ if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) { /* Size of filtered direct block */ - H5F_DECODE_LENGTH(f, p, iblock->filt_ents[u].size); + H5F_DECODE_LENGTH(udata->f, p, iblock->filt_ents[u].size); /* Sanity check */ /* (either both the address & size are defined or both are @@ -859,13 +776,13 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add HDassert(iblock->nchildren); /* indirect blocks w/no children should have been deleted */ /* Compute checksum on indirect block */ - computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + computed_chksum = H5_checksum_metadata(image, (size_t)(p - (const uint8_t *)image), 0); /* Metadata checksum */ UINT32DECODE(p, stored_chksum); /* Sanity check */ - HDassert((size_t)(p - buf) == iblock->size); + HDassert((size_t)(p - (const uint8_t *)image) == iblock->size); /* Verify checksum */ if(stored_chksum != computed_chksum) @@ -888,19 +805,19 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add /* Set return value */ ret_value = iblock; + /* Sanity check */ + HDassert((size_t)((const uint8_t *)p - (const uint8_t *)image) <= len); done: /* 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); + (void)H5HF_cache_iblock_dest(iblock); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_iblock_load() */ +} /* end H5HF_cache_iblock_deserialize() */ /*------------------------------------------------------------------------- - * Function: H5HF_cache_iblock_flush + * Function: H5HF_cache_iblock_serialize * * Purpose: Flushes a dirty fractal heap indirect block to disk. * @@ -916,16 +833,32 @@ done: * entry is resized or renamed as a result of the flush. * *flags_ptr is set to H5C_CALLBACK__NO_FLAGS_SET on entry. * + * Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 + * Converted from H5HF_cache_iblock_flush + * *------------------------------------------------------------------------- */ 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) + +H5HF_cache_iblock_serialize(const H5F_t *f, haddr_t UNUSED addr, + size_t UNUSED len, void *image, void *_thing, unsigned UNUSED *flags, + haddr_t UNUSED *new_addr, size_t UNUSED *new_len, + void UNUSED **new_image) { - 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 */ + H5HF_hdr_t *hdr; /* Shared fractal heap information */ + H5HF_indirect_t *iblock = (H5HF_indirect_t *)_thing; + uint8_t *p; /* Pointer into raw data buffer */ +#ifndef NDEBUG + unsigned nchildren = 0; /* Track # of children */ + unsigned max_child = 0; /* Track max. child entry used */ +#endif /* NDEBUG */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + size_t u; /* Local index variable */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_flush) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_serialize) #ifdef QAK HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); #endif /* QAK */ @@ -935,19 +868,8 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC HDassert(H5F_addr_defined(addr)); HDassert(iblock); - if(iblock->cache_info.is_dirty) { - H5HF_hdr_t *hdr; /* Shared fractal heap information */ - uint8_t *buf; /* Temporary buffer */ - uint8_t *p; /* Pointer into raw data buffer */ -#ifndef NDEBUG - unsigned nchildren = 0; /* Track # of children */ - unsigned max_child = 0; /* Track max. child entry used */ -#endif /* NDEBUG */ - uint32_t metadata_chksum; /* Computed metadata checksum value */ - size_t u; /* Local index variable */ - - /* Get the pointer to the shared heap header */ - hdr = iblock->hdr; + /* Get the pointer to the shared heap header */ + hdr = iblock->hdr; #ifdef QAK HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size); @@ -955,233 +877,119 @@ 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 */ - /* 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") + /* Set the shared heap header's file context for this operation */ + hdr->f = f; - /* Get temporary pointer to buffer for serialized indirect block */ - p = buf; + /* Get temporary pointer to buffer for serialized indirect block */ + p = image; - /* Magic number */ - HDmemcpy(p, H5HF_IBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC); - p += H5HF_SIZEOF_MAGIC; + /* Magic number */ + HDmemcpy(p, H5HF_IBLOCK_MAGIC, (size_t)H5HF_SIZEOF_MAGIC); + p += H5HF_SIZEOF_MAGIC; - /* Version # */ - *p++ = H5HF_IBLOCK_VERSION; + /* Version # */ + *p++ = H5HF_IBLOCK_VERSION; - /* Address of heap header for heap which owns this block */ - H5F_addr_encode(f, &p, hdr->heap_addr); + /* Address of heap header for heap which owns this block */ + H5F_addr_encode(f, &p, hdr->heap_addr); - /* Offset of block in heap */ - UINT64ENCODE_VAR(p, iblock->block_off, hdr->heap_off_size); + /* Offset of block in heap */ + UINT64ENCODE_VAR(p, iblock->block_off, hdr->heap_off_size); - /* Encode indirect block-specific fields */ - for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { + /* Encode indirect block-specific fields */ + for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { #ifdef QAK HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].addr); #endif /* QAK */ - /* Encode child block address */ - H5F_addr_encode(f, &p, iblock->ents[u].addr); + /* Encode child block address */ + H5F_addr_encode(f, &p, iblock->ents[u].addr); - /* Check for heap with I/O filters */ - if(hdr->filter_len > 0) { - /* Sanity check */ - HDassert(iblock->filt_ents); + /* Check for heap with I/O filters */ + if(hdr->filter_len > 0) { + /* Sanity check */ + HDassert(iblock->filt_ents); - /* Encode extra information for direct blocks */ - if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) { + /* Encode extra information for direct blocks */ + if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) { #ifdef QAK HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->filt_ents[u].size, iblock->filt_ents[u].filter_mask); #endif /* QAK */ - /* Sanity check */ - /* (either both the address & size are defined or both are - * not defined) - */ - HDassert((H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size) - || (!H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size == 0)); - - /* Size of filtered direct block */ - H5F_ENCODE_LENGTH(f, p, iblock->filt_ents[u].size); - - /* I/O filter mask for filtered direct block */ - UINT32ENCODE(p, iblock->filt_ents[u].filter_mask); - } /* end if */ - } /* end if */ - -#ifndef NDEBUG - /* Count child blocks */ - if(H5F_addr_defined(iblock->ents[u].addr)) { - nchildren++; - if(u > max_child) - max_child = u; - } /* end if */ -#endif /* NDEBUG */ - } /* end for */ + /* Sanity check */ + /* (either both the address & size are defined or both are + * not defined) + */ + HDassert((H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size) + || (!H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size == 0)); - /* Compute checksum */ - metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + /* Size of filtered direct block */ + H5F_ENCODE_LENGTH(f, p, iblock->filt_ents[u].size); - /* Metadata checksum */ - UINT32ENCODE(p, metadata_chksum); + /* I/O filter mask for filtered direct block */ + UINT32ENCODE(p, iblock->filt_ents[u].filter_mask); + } /* end if */ + } /* end if */ - /* Sanity check */ - HDassert((size_t)(p - buf) == iblock->size); #ifndef NDEBUG - HDassert(nchildren == iblock->nchildren); - HDassert(max_child == iblock->max_child); + /* Count child blocks */ + if(H5F_addr_defined(iblock->ents[u].addr)) { + nchildren++; + if(u > max_child) + max_child = u; + } /* end if */ #endif /* NDEBUG */ + } /* end for */ - /* Write the indirect block */ - 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") - - /* Reset dirty flags */ - iblock->cache_info.is_dirty = FALSE; - } /* end if */ - - if(destroy) - if(H5HF_cache_iblock_dest(f, iblock) < 0) - 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() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_iblock_dest - * - * Purpose: Destroys a fractal heap indirect block in memory. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 6 2006 - * - *------------------------------------------------------------------------- - */ -/* ARGSUSED */ -herr_t -H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_dest) - - /* - * Check arguments. - */ - HDassert(iblock); - HDassert(iblock->rc == 0); -#ifdef QAK -HDfprintf(stderr, "%s: Destroying indirect block\n", FUNC); -#endif /* QAK */ - - /* Set the shared heap header's file context for this operation */ - iblock->hdr->f = f; - - /* Decrement reference count on shared info */ - HDassert(iblock->hdr); - if(H5HF_hdr_decr(iblock->hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") - if(iblock->parent) - if(H5HF_iblock_decr(iblock->parent) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") - - /* Release entry tables */ - if(iblock->ents) - H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); - if(iblock->filt_ents) - H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents); - if(iblock->child_iblocks) - H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks); - - /* Free fractal heap indirect block info */ - H5FL_FREE(H5HF_indirect_t, iblock); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_iblock_dest() */ + /* Compute checksum */ + metadata_chksum = H5_checksum_metadata(image, (size_t)((const uint8_t *)p - (const uint8_t *)image), 0); - -/*------------------------------------------------------------------------- - * Function: H5HF_cache_iblock_clear - * - * Purpose: Mark a fractal heap indirect block in memory as non-dirty. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 6 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_cache_iblock_clear(H5F_t *f, H5HF_indirect_t *iblock, hbool_t destroy) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_clear) + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); - /* - * Check arguments. - */ - HDassert(iblock); + /* Reset the cache flags for this operation (metadata not resized or renamed) */ + *flags = 0; - /* Reset the dirty flag. */ - iblock->cache_info.is_dirty = FALSE; + /* Sanity check */ + HDassert((size_t)((const uint8_t *)p - (const uint8_t *)image) <= len); - if(destroy) - if(H5HF_cache_iblock_dest(f, iblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to destroy fractal heap indirect block") + /* Sanity check */ + HDassert((size_t)(p - (const uint8_t *)image) == iblock->size); +#ifndef NDEBUG + HDassert(nchildren == iblock->nchildren); + HDassert(max_child == iblock->max_child); +#endif /* NDEBUG */ done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_cache_iblock_clear() */ +} /* H5HF_cache_iblock_serialize() */ /*------------------------------------------------------------------------- - * Function: H5HF_cache_iblock_size + * Function: H5HF_cache_iblock_free_icr * - * Purpose: Compute the size in bytes of a fractal heap indirect block - * on disk, and return it in *size_ptr. On failure, - * the value of *size_ptr is undefined. + * Purpose: Destroy/release an "in core representation" of a data structure * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 6 2006 + * Return: Success: SUCCEED + * Failure: FAIL * + * Programmer: Mike McGreevy + * mcgreevy@hdfgroup.org + * July 25, 2008 + * *------------------------------------------------------------------------- */ static herr_t -H5HF_cache_iblock_size(const H5F_t UNUSED *f, const H5HF_indirect_t *iblock, size_t *size_ptr) +H5HF_cache_iblock_free_icr(haddr_t UNUSED addr, size_t UNUSED len, void *thing) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_size) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_free_icr) - /* check arguments */ - HDassert(iblock); - HDassert(size_ptr); + /* Check arguments */ + HDassert(thing); - /* Set size value */ - *size_ptr = iblock->size; + /* Destroy fractal heap indirect block */ + H5HF_cache_iblock_dest(thing); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_cache_iblock_size() */ +} /* H5HF_cache_iblock_free_icr() */ /*------------------------------------------------------------------------- |