[svn-r22233] Description:

Correct several errors in fractal heap code: root indirect block was
getting pinned/protected more than once, "single" free space sections weren't
getting "re-parented" correctly when the heap transitioned between having a
root indirect block and a root direct block, and several related issues.  Also
cleaned up some warnings in library/tests.

Tested on:
    FreeBSD/32 8.2 (loyalty) w/gcc4.6, w/C++ & FORTRAN, in debug mode
    FreeBSD/64 8.2 (freedom) w/gcc4.6, w/C++ & FORTRAN, in debug mode
    Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
        w/C++ & FORTRAN, w/threadsafe, in debug mode
    Linux/64-amd64 2.6 (koala) w/Intel compilers, w/default API=1.6.x,
        w/C++ & FORTRAN, in production mode
    Mac OSX/64 10.7.3 (amazon) w/debug
This commit is contained in:
Quincey Koziol 2012-04-01 18:53:17 -05:00
parent 982f1ff8ff
commit 42306f8ed4
13 changed files with 616 additions and 165 deletions

View File

@ -155,7 +155,7 @@ typedef struct H5FS_stat_t {
} H5FS_stat_t;
/* Typedef for iteration operations */
typedef herr_t (*H5FS_operator_t)(const H5FS_section_info_t *sect,
typedef herr_t (*H5FS_operator_t)(H5FS_section_info_t *sect,
void *operator_data/*in,out*/);

View File

@ -2244,7 +2244,7 @@ H5FS_sect_assert(const H5FS_t *fspace)
hsize_t separate_obj; /* The number of separate objects managed */
FUNC_ENTER_NOAPI_NOINIT_NOERR
#ifndef QAK
#ifdef QAK
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", "H5FS_sect_assert", fspace->tot_sect_count);
#endif /* QAK */

View File

@ -156,9 +156,6 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
H5HF_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
#ifdef QAK
HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* QAK */
/*
* Check arguments.
@ -234,14 +231,8 @@ H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
HDassert(H5F_addr_defined(fh_addr));
/* Load the heap header into memory */
#ifdef QAK
HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
#endif /* QAK */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, fh_addr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap header")
#ifdef QAK
HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fspace);
#endif /* QAK */
/* Check for pending heap deletion */
if(hdr->pending_delete)
@ -361,9 +352,6 @@ H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size, const void *obj,
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
#ifdef QAK
HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size);
#endif /* QAK */
/* Sanity check */
HDassert(fh);
@ -406,9 +394,6 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'write once' managed blocks not su
} /* end else */
done:
#ifdef QAK
HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
#endif /* QAK */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_insert() */
@ -580,9 +565,6 @@ H5HF_write(H5HF_t *fh, hid_t dxpl_id, void *_id, hbool_t UNUSED *id_changed,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
#ifdef QAK
HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* QAK */
/*
* Check arguments.
@ -720,9 +702,6 @@ H5HF_remove(H5HF_t *fh, hid_t dxpl_id, const void *_id)
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
#ifdef QAK
HDfprintf(stderr, "%s: Called\n", FUNC);
#endif /* QAK */
/*
* Check arguments.
@ -814,17 +793,9 @@ H5HF_close(H5HF_t *fh, hid_t dxpl_id)
* a reference loop and the objects couldn't be removed from
* the metadata cache - QAK)
*/
#ifdef QAK
HDfprintf(stderr, "%s; fh->hdr->man_iter_off = %Hu\n", FUNC, fh->hdr->man_iter_off);
HDfprintf(stderr, "%s; fh->hdr->man_size = %Hu\n", FUNC, fh->hdr->man_size);
HDfprintf(stderr, "%s; fh->hdr->rc = %Zu\n", FUNC, fh->hdr->rc);
#endif /* QAK */
if(H5HF_man_iter_ready(&fh->hdr->next_block))
if(H5HF_man_iter_reset(&fh->hdr->next_block) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator")
#ifdef QAK
HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr->rc);
#endif /* QAK */
/* Shut down the huge object information */
/* (Can't put this in header "destroy" routine, because it has
@ -900,9 +871,6 @@ H5HF_delete(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr)
HDassert(H5F_addr_defined(fh_addr));
/* Lock the heap header into memory */
#ifdef QAK
HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
#endif /* QAK */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, fh_addr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")

View File

@ -352,7 +352,7 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_indir_found",
herr_t
H5HF_huge_bt2_indir_remove(const void *nrecord, void *_udata)
{
H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -570,7 +570,7 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_bt2_filt
herr_t
H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *_udata)
{
H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -759,7 +759,7 @@ H5HF_huge_bt2_filt_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED
herr_t
H5HF_huge_bt2_dir_remove(const void *nrecord, void *_udata)
{
H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -984,7 +984,7 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_bt2_filt_dir_
herr_t
H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *_udata)
{
H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */
H5HF_huge_remove_ud_t *udata = (H5HF_huge_remove_ud_t *)_udata; /* User callback data */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT

View File

@ -172,39 +172,31 @@ H5HF_dtable_debug(H5HF_dtable_t *dtable, FILE *stream, int indent, int fwidth)
/*-------------------------------------------------------------------------
* Function: H5HF_hdr_debug
* Function: H5HF_hdr_print
*
* Purpose: Prints debugging info about a fractal heap header.
* Purpose: Prints info about a fractal heap header.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Feb 24 2006
* koziol@hdfgroup.org
* Feb 23 2012
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
void
H5HF_hdr_print(const H5HF_hdr_t *hdr, hid_t dxpl_id, hbool_t dump_internal, FILE *stream, int indent, int fwidth)
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(hdr);
HDassert(stream);
HDassert(indent >= 0);
HDassert(fwidth >= 0);
/* Load the fractal heap header */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, addr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Header...\n", indent, "");
@ -277,10 +269,66 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
"Filter mask for root direct block:",
hdr->pline_root_direct_filter_mask);
} /* end if */
H5O_debug_id(H5O_PLINE_ID, f, dxpl_id, &(hdr->pline), stream,
H5O_debug_id(H5O_PLINE_ID, hdr->f, dxpl_id, &(hdr->pline), stream,
indent + 3, MAX(0, fwidth - 3));
} /* end if */
/* Print internal (runtime) information, if requested */
if(dump_internal) {
HDfprintf(stream, "%*sFractal Heap Header Internal Information:\n", indent, "");
/* Dump root iblock, if there is one */
HDfprintf(stream, "%*s%-*s %x\n", indent + 3, "", MAX(0, fwidth - 3),
"Root indirect block flags:",
hdr->root_iblock_flags);
HDfprintf(stream, "%*s%-*s %p\n", indent + 3, "", MAX(0, fwidth - 3),
"Root indirect block pointer:",
hdr->root_iblock);
if(hdr->root_iblock)
H5HF_iblock_print(hdr->root_iblock, dump_internal, stream, indent + 3, fwidth);
} /* end if */
FUNC_LEAVE_NOAPI_VOID
} /* end H5HF_hdr_print() */
/*-------------------------------------------------------------------------
* Function: H5HF_hdr_debug
*
* Purpose: Prints debugging info about a fractal heap header.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Feb 24 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/*
* Check arguments.
*/
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(stream);
HDassert(indent >= 0);
HDassert(fwidth >= 0);
/* Load the fractal heap header */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, addr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
/* Print the information about the heap's header */
H5HF_hdr_print(hdr, dxpl_id, FALSE, stream, indent, fwidth);
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
@ -303,9 +351,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5HF_dblock_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
H5HF_dblock_debug_cb(H5FS_section_info_t *_sect, void *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_debug_iter_ud1_t *udata = (H5HF_debug_iter_ud1_t *)_udata; /* User data for callbacks */
haddr_t sect_start, sect_end; /* Section's beginning and ending offsets */
haddr_t dblock_start, dblock_end; /* Direct block's beginning and ending offsets */
@ -501,51 +549,39 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_iblock_debug
* Function: H5HF_iblock_print
*
* Purpose: Prints debugging info about a fractal heap indirect block.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Mar 7 2006
* koziol@hdfgroup.org
* Feb 23 2012
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
int indent, int fwidth, haddr_t hdr_addr, unsigned nrows)
void
H5HF_iblock_print(const H5HF_indirect_t *iblock,
hbool_t dump_internal, FILE *stream, int indent, int fwidth)
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */
hbool_t did_protect; /* Whether we protected the indirect block or not */
const H5HF_hdr_t *hdr; /* Pointer to heap's header */
char temp_str[64]; /* Temporary string, for formatting */
size_t u, v; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(iblock);
HDassert(iblock->hdr);
HDassert(stream);
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(H5F_addr_defined(hdr_addr));
HDassert(nrows > 0);
/* Load the fractal heap header */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, hdr_addr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
/*
* Load the heap indirect block
*/
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, addr, nrows, NULL, 0, FALSE, H5AC_READ, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block")
/* Set up convenience variables */
hdr = iblock->hdr;
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Indirect Block...\n", indent, "");
@ -623,6 +659,75 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
"<none>");
/* Print internal (runtime) information, if requested */
if(dump_internal) {
HDfprintf(stream, "%*sFractal Indirect Block Internal Information:\n", indent, "");
/* Print general information */
HDfprintf(stream, "%*s%-*s %Zu\n", indent + 3, "", MAX(0, fwidth - 3),
"Reference count:",
iblock->rc);
/* Print parent's information */
HDfprintf(stream, "%*s%-*s %p\n", indent + 3, "", MAX(0, fwidth - 3),
"Parent indirect block address:",
iblock->parent);
if(iblock->parent)
H5HF_iblock_print(iblock->parent, TRUE, stream, indent + 6, fwidth);
} /* end if */
FUNC_LEAVE_NOAPI_VOID
} /* end H5HF_iblock_print() */
/*-------------------------------------------------------------------------
* Function: H5HF_iblock_debug
*
* Purpose: Prints debugging info about a fractal heap indirect block.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* Mar 7 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
int indent, int fwidth, haddr_t hdr_addr, unsigned nrows)
{
H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */
H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */
hbool_t did_protect; /* Whether we protected the indirect block or not */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
/*
* Check arguments.
*/
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(stream);
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(H5F_addr_defined(hdr_addr));
HDassert(nrows > 0);
/* Load the fractal heap header */
if(NULL == (hdr = H5HF_hdr_protect(f, dxpl_id, hdr_addr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap header")
/*
* Load the heap indirect block
*/
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, addr, nrows, NULL, 0, FALSE, H5AC_READ, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block")
/* Print the information about the heap's indirect block */
H5HF_iblock_print(iblock, FALSE, stream, indent, fwidth);
done:
if(iblock && H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap direct block")
@ -647,9 +752,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
H5HF_sects_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
H5HF_sects_debug_cb(H5FS_section_info_t *_sect, void *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_debug_iter_ud2_t *udata = (H5HF_debug_iter_ud2_t *)_udata; /* User data for callbacks */
herr_t ret_value = SUCCEED; /* Return value */

View File

@ -899,7 +899,7 @@ done:
herr_t
H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id)
{
H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */
H5HF_huge_remove_ud_t udata; /* User callback data for v2 B-tree remove call */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -1072,7 +1072,7 @@ done:
herr_t
H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
{
H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */
H5HF_huge_remove_ud_t udata; /* User callback data for v2 B-tree remove call */
H5B2_remove_t op; /* Callback for v2 B-tree removal */
herr_t ret_value = SUCCEED; /* Return value */

View File

@ -140,8 +140,17 @@ H5HF_iblock_pin(H5HF_indirect_t *iblock)
else {
/* Check for pinning the root indirect block */
if(iblock->block_off == 0) {
HDassert(iblock->hdr->root_iblock == NULL);
iblock->hdr->root_iblock = iblock;
/* Sanity check - shouldn't be recursively pinning root indirect block */
HDassert(0 == (iblock->hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PINNED));
/* Check if we should set the root iblock pointer */
if(0 == iblock->hdr->root_iblock_flags) {
HDassert(NULL == iblock->hdr->root_iblock);
iblock->hdr->root_iblock = iblock;
} /* end if */
/* Indicate that the root indirect block is pinned */
iblock->hdr->root_iblock_flags |= H5HF_ROOT_IBLOCK_PINNED;
} /* end if */
} /* end if */
@ -192,12 +201,21 @@ H5HF_iblock_unpin(H5HF_indirect_t *iblock)
par_iblock->child_iblocks[indir_idx] = NULL;
} /* end if */
else {
/* Check for unpinning the root indirect block */
/* Check for root indirect block */
if(iblock->block_off == 0) {
HDassert(iblock->hdr->root_iblock);
iblock->hdr->root_iblock = NULL;
/* Sanity check - shouldn't be recursively unpinning root indirect block */
HDassert(iblock->hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PINNED);
/* Check if we should reset the root iblock pointer */
if(H5HF_ROOT_IBLOCK_PINNED == iblock->hdr->root_iblock_flags) {
HDassert(NULL != iblock->hdr->root_iblock);
iblock->hdr->root_iblock = NULL;
} /* end if */
/* Indicate that the root indirect block is unpinned */
iblock->hdr->root_iblock_flags &= ~(H5HF_ROOT_IBLOCK_PINNED);
} /* end if */
} /* end if */
} /* end else */
/* Mark block as evictable again */
if(H5AC_unpin_entry(iblock) < 0)
@ -273,18 +291,23 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock)
/* Mark block as evictable again when no child blocks depend on it */
if(iblock->rc == 0) {
if(H5HF_iblock_unpin(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block")
H5HF_hdr_t *hdr; /* Fractal heap header */
haddr_t iblock_addr; /* Address of fractal heap */
hbool_t expunge_iblock = FALSE; /* Whether to expunge indirect block from heap */
/* Set up convenience variables */
hdr = iblock->hdr;
iblock_addr = iblock->addr;
if(iblock->nchildren == 0) {
/* Check for deleting root indirect block (and no root direct block) */
if(iblock->block_off == 0 && iblock->hdr->man_dtable.curr_root_rows > 0) {
if(iblock->block_off == 0 && hdr->man_dtable.curr_root_rows > 0) {
/* Reset root pointer information */
iblock->hdr->man_dtable.curr_root_rows = 0;
iblock->hdr->man_dtable.table_addr = HADDR_UNDEF;
hdr->man_dtable.curr_root_rows = 0;
hdr->man_dtable.table_addr = HADDR_UNDEF;
/* Reset header information back to "empty heap" state */
if(H5HF_hdr_empty(iblock->hdr) < 0)
if(H5HF_hdr_empty(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty")
} /* end if */
@ -297,8 +320,18 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock)
iblock->par_entry = 0;
} /* end if */
/* Mark indirect block for removal from the metadata cache */
expunge_iblock = TRUE;
} /* end if */
/* Unpin the indirect block */
if(H5HF_iblock_unpin(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block")
/* Check for expunging the indirect block from the metadata cache */
if(expunge_iblock) {
/* Evict the indirect block from the metadata cache */
if(H5AC_expunge_entry(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
if(H5AC_expunge_entry(hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, H5AC__FREE_FILE_SPACE_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove indirect block from cache")
} /* end if */
} /* end if */
@ -420,6 +453,10 @@ H5HF_man_iblock_root_create(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
hdr->pline_root_direct_filter_mask = 0;
} /* end if */
/* Scan free space sections to set any 'parent' pointers to new indirect block */
if(H5HF_space_create_root(hdr, dxpl_id, iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, FAIL, "can't set free space section info to new root indirect block")
/* Unlock first (previously the root) direct block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
@ -859,6 +896,11 @@ H5HF_man_iblock_root_revert(H5HF_indirect_t *root_iblock, hid_t dxpl_id)
if(H5HF_hdr_adjust_heap(hdr, (hsize_t)hdr->man_dtable.cparam.start_block_size, (hssize_t)hdr->man_dtable.row_tot_dblock_free[0]) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "can't increase space to cover root direct block")
/* Scan free space sections to reset any 'parent' pointers */
if(H5HF_space_revert_root(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRESET, FAIL, "can't reset free space section info")
done:
if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
@ -1126,11 +1168,20 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
else {
/* Check for root indirect block */
if(H5F_addr_eq(iblock_addr, hdr->man_dtable.table_addr)) {
/* Check for pointer to pinned indirect block in root */
if(hdr->root_iblock)
/* Check for valid pointer to pinned indirect block in root */
if(H5HF_ROOT_IBLOCK_PINNED == hdr->root_iblock_flags) {
/* Sanity check */
HDassert(NULL != hdr->root_iblock);
/* Return the pointer to the pinned root indirect block */
iblock = hdr->root_iblock;
else
} /* end if */
else {
/* Sanity check */
HDassert(NULL == hdr->root_iblock);
should_protect = TRUE;
} /* end else */
} /* end if */
else
should_protect = TRUE;
@ -1158,6 +1209,21 @@ H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
/* Set the indirect block's address */
iblock->addr = iblock_addr;
/* Check for root indirect block */
if(iblock->block_off == 0) {
/* Sanity check - shouldn't be recursively protecting root indirect block */
HDassert(0 == (hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PROTECTED));
/* Check if we should set the root iblock pointer */
if(0 == hdr->root_iblock_flags) {
HDassert(NULL == hdr->root_iblock);
hdr->root_iblock = iblock;
} /* end if */
/* Indicate that the root indirect block is protected */
hdr->root_iblock_flags |= H5HF_ROOT_IBLOCK_PROTECTED;
} /* end if */
/* Indicate that the indirect block was protected */
*did_protect = TRUE;
} /* end if */
@ -1202,6 +1268,21 @@ H5HF_man_iblock_unprotect(H5HF_indirect_t *iblock, hid_t dxpl_id,
/* Check if we previously protected this indirect block */
/* (as opposed to using an existing pointer to a pinned child indirect block) */
if(did_protect) {
/* Check for root indirect block */
if(iblock->block_off == 0) {
/* Sanity check - shouldn't be recursively unprotecting root indirect block */
HDassert(iblock->hdr->root_iblock_flags & H5HF_ROOT_IBLOCK_PROTECTED);
/* Check if we should reset the root iblock pointer */
if(H5HF_ROOT_IBLOCK_PROTECTED == iblock->hdr->root_iblock_flags) {
HDassert(NULL != iblock->hdr->root_iblock);
iblock->hdr->root_iblock = NULL;
} /* end if */
/* Indicate that the root indirect block is unprotected */
iblock->hdr->root_iblock_flags &= ~(H5HF_ROOT_IBLOCK_PROTECTED);
} /* end if */
/* Unprotect the indirect block */
if(H5AC_unprotect(iblock->hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, cache_flags) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
@ -1215,7 +1296,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_attach
*
* Purpose: Attach a block to an indirect block
* Purpose: Attach a child block (direct or indirect) to an indirect block
*
* Return: SUCCEED/FAIL
*
@ -1243,7 +1324,7 @@ H5HF_man_iblock_attach(H5HF_indirect_t *iblock, unsigned entry, haddr_t child_ad
if(H5HF_iblock_incr(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block")
/* Point at the direct block */
/* Point at the child block */
iblock->ents[entry].addr = child_addr;
/* Check for I/O filters on this heap */
@ -1280,7 +1361,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_detach
*
* Purpose: Detach a block from an indirect block
* Purpose: Detach a child block (direct or indirect) from an indirect block
*
* Return: SUCCEED/FAIL
*
@ -1293,6 +1374,7 @@ done:
herr_t
H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
{
unsigned row; /* Row for entry */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -1306,16 +1388,14 @@ H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
/* Reset address of entry */
iblock->ents[entry].addr = HADDR_UNDEF;
/* Compute row for entry */
row = entry / iblock->hdr->man_dtable.cparam.width;
/* Check for I/O filters on this heap */
if(iblock->hdr->filter_len > 0) {
unsigned row; /* Row for entry */
/* Sanity check */
HDassert(iblock->filt_ents);
/* Compute row for entry */
row = entry / iblock->hdr->man_dtable.cparam.width;
/* If this is a direct block, reset its initial size */
if(row < iblock->hdr->man_dtable.max_direct_rows) {
iblock->filt_ents[entry].size = 0;
@ -1323,6 +1403,24 @@ H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
} /* end if */
} /* end if */
/* Check for indirect block being detached */
if(row >= iblock->hdr->man_dtable.max_direct_rows) {
unsigned indir_idx; /* Index in parent's child iblock pointer array */
/* Sanity check */
HDassert(iblock->child_iblocks);
/* Compute index in child iblock pointer array */
indir_idx = entry - (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width);
/* Sanity check */
HDassert(iblock->child_iblocks[indir_idx]);
/* Reset pointer to child indirect block in parent */
iblock->child_iblocks[indir_idx] = NULL;
} /* end if */
/* Decrement the # of child blocks */
/* (If the number of children drop to 0, the indirect block will be
* removed from the heap when its ref. count drops to zero and the

View File

@ -174,6 +174,11 @@
#define H5HF_OP_MODIFY 0x0001 /* Operation will modify object */
#define H5HF_OP_FLAGS (H5HF_OP_MODIFY) /* Bit-wise OR of all op flags */
/* Flags for 'root_iblock_flags' field in header */
#define H5HF_ROOT_IBLOCK_PINNED 0x01
#define H5HF_ROOT_IBLOCK_PROTECTED 0x02
/****************************/
/* Package Private Typedefs */
/****************************/
@ -342,7 +347,8 @@ typedef struct H5HF_hdr_t {
hbool_t pending_delete; /* Heap is pending deletion */
uint8_t sizeof_size; /* Size of file sizes */
uint8_t sizeof_addr; /* Size of file addresses */
struct H5HF_indirect_t *root_iblock; /* Pointer to pinned root indirect block */
struct H5HF_indirect_t *root_iblock; /* Pointer to root indirect block */
unsigned root_iblock_flags; /* Flags to indicate whether root indirect block is pinned/protected */
H5FS_t *fspace; /* Free space list for objects in heap */
H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */
H5B2_t *huge_bt2; /* v2 B-tree handle for huge objects */
@ -457,14 +463,14 @@ typedef struct H5HF_huge_bt2_filt_dir_rec_t {
typedef struct {
H5HF_hdr_t *hdr; /* Fractal heap header */
hid_t dxpl_id; /* DXPL ID for operation */
} H5HF_sect_add_ud1_t;
} H5HF_sect_add_ud_t;
/* User data for v2 B-tree 'remove' callback on 'huge' objects */
typedef struct {
H5HF_hdr_t *hdr; /* Fractal heap header (in) */
hid_t dxpl_id; /* DXPL ID for operation (in) */
hsize_t obj_len; /* Length of object removed (out) */
} H5HF_huge_remove_ud1_t;
} H5HF_huge_remove_ud_t;
/* User data for fractal heap header cache client callback */
typedef struct H5HF_hdr_cache_ud_t {
@ -701,10 +707,14 @@ H5_DLL herr_t H5HF_tiny_op(H5HF_hdr_t *hdr, const uint8_t *id,
H5_DLL herr_t H5HF_tiny_remove(H5HF_hdr_t *fh, const uint8_t *id);
/* Debugging routines for dumping file structures */
H5_DLL void H5HF_hdr_print(const H5HF_hdr_t *hdr, hid_t dxpl_id,
hbool_t dump_internal, FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth, haddr_t hdr_addr, size_t nrec);
H5_DLL void H5HF_iblock_print(const H5HF_indirect_t *iblock, hbool_t dump_internal,
FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
FILE *stream, int indent, int fwidth, haddr_t hdr_addr, unsigned nrows);
@ -733,6 +743,9 @@ H5_DLL herr_t H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *node, unsigned flags);
H5_DLL htri_t H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request,
H5HF_free_section_t **node);
H5_DLL herr_t H5HF_space_revert_root(const H5HF_hdr_t *hdr, hid_t dxpl_id);
H5_DLL herr_t H5HF_space_create_root(const H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_indirect_t *root_iblock);
H5_DLL herr_t H5HF_space_size(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t *fs_size);
H5_DLL herr_t H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *node);

View File

@ -665,42 +665,6 @@ H5HF_sect_single_dblock_info(H5HF_hdr_t *hdr, hid_t dxpl_id,
HDassert(dblock_addr);
HDassert(dblock_size);
/* Check for section in first direct block of heap */
if(sect->sect_info.addr < hdr->man_dtable.cparam.start_block_size) {
/* Check for heap changing from direct <-> indirect root (or vice versa)
* while section was live.
*/
if(sect->u.single.parent) {
/* Check for heap converting from indirect root to direct root while section was live */
if(hdr->man_dtable.curr_root_rows == 0) {
/* Release hold on parent indirect block */
if(H5HF_iblock_decr(sect->u.single.parent) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
/* Reset parent information */
sect->u.single.parent = NULL;
sect->u.single.par_entry = 0;
} /* end if */
else {
/* Check for heap converting from indirect to direct and back
* to indirect again, which would indicate a different
* indirect root block would be used for the parent of
* this section and the actual root indirect block.
*/
if(H5HF_sect_single_locate_parent(hdr, dxpl_id, TRUE, sect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
} /* end else */
} /* end if */
else {
/* Check for heap converting from direct root to indirect root while section was live */
if(hdr->man_dtable.curr_root_rows != 0) {
/* Look up indirect block information for section */
if(H5HF_sect_single_locate_parent(hdr, dxpl_id, FALSE, sect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get section's parent info")
} /* end if */
} /* end else */
} /* end if */
/* Check for root direct block */
if(hdr->man_dtable.curr_root_rows == 0) {
/* Retrieve direct block info from heap header */
@ -860,7 +824,7 @@ H5HF_sect_single_add(H5FS_section_info_t *_sect, unsigned *flags, void *_udata)
*/
if(!(*flags & H5FS_ADD_DESERIALIZING)) {
H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Fractal heap free section */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
@ -992,7 +956,7 @@ H5HF_sect_single_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
{
H5HF_free_section_t *sect1 = (H5HF_free_section_t *)_sect1; /* Fractal heap free section */
H5HF_free_section_t *sect2 = (H5HF_free_section_t *)_sect2; /* Fractal heap free section */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
herr_t ret_value = SUCCEED; /* Return value */
@ -1050,7 +1014,7 @@ static htri_t
H5HF_sect_single_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Fractal heap free section */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
htri_t ret_value = FALSE; /* Return value */
@ -1105,7 +1069,7 @@ static herr_t
H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
{
H5HF_free_section_t **sect = (H5HF_free_section_t **)_sect; /* Fractal heap free section */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
H5HF_direct_t *dblock; /* Pointer to direct block for section */
@ -1814,7 +1778,7 @@ H5HF_sect_row_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
{
H5HF_free_section_t *sect1 = (H5HF_free_section_t *)_sect1; /* Fractal heap free section */
H5HF_free_section_t *sect2 = (H5HF_free_section_t *)_sect2; /* Fractal heap free section */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
herr_t ret_value = SUCCEED; /* Return value */
@ -1881,7 +1845,7 @@ static htri_t
H5HF_sect_row_can_shrink(const H5FS_section_info_t *_sect, void UNUSED *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Fractal heap free section */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
htri_t ret_value = FALSE; /* Return value */
@ -1919,7 +1883,7 @@ H5HF_sect_row_shrink(H5FS_section_info_t **_sect, void *_udata)
{
H5HF_free_section_t **sect = (H5HF_free_section_t **)_sect; /* Fractal heap free section */
H5HF_free_section_t *top_indir_sect; /* Top indirect section for row */
H5HF_sect_add_ud1_t *udata = (H5HF_sect_add_ud1_t *)_udata; /* User callback data */
H5HF_sect_add_ud_t *udata = (H5HF_sect_add_ud_t *)_udata; /* User callback data */
H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */
herr_t ret_value = SUCCEED; /* Return value */
@ -2161,7 +2125,7 @@ H5HF_sect_indirect_iblock_off(const H5HF_free_section_t *sect)
*
* Purpose: Get the "top" indirect section
*
* Return: Pointer to the top indirect sectin (can't fail)
* Return: Pointer to the top indirect section (can't fail)
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu

View File

@ -168,7 +168,7 @@ herr_t
H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
unsigned flags)
{
H5HF_sect_add_ud1_t udata; /* User data for free space manager 'add' */
H5HF_sect_add_ud_t udata; /* User data for free space manager 'add' */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@ -244,6 +244,185 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_space_find() */
/*-------------------------------------------------------------------------
* Function: H5HF_space_revert_root_cb
*
* Purpose: Callback routine from iterator, to reset 'parent' pointers in
* sections, when the heap is changing from having a root indirect
* block to a direct block.
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Feb 24 2012
*
*-------------------------------------------------------------------------
*/
static herr_t
H5HF_space_revert_root_cb(H5FS_section_info_t *_sect, void UNUSED *_udata)
{
H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(sect);
/* Only modify "live" single blocks... */
if(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE && sect->sect_info.state == H5FS_SECT_LIVE) {
/* Release hold on previous indirect block (we must have one) */
HDassert(sect->u.single.parent);
if(H5HF_iblock_decr(sect->u.single.parent) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on section's indirect block")
/* Reset parent information */
sect->u.single.parent = NULL;
sect->u.single.par_entry = 0;
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_space_revert_root_cb() */
/*-------------------------------------------------------------------------
* Function: H5HF_space_revert_root
*
* Purpose: Reset 'parent' pointers in sections, when the heap is
* changing from having a root indirect block to a direct block.
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Feb 23 2012
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_space_revert_root(const H5HF_hdr_t *hdr, hid_t dxpl_id)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(hdr);
/* Only need to scan the sections if the free space has been initialized */
if(hdr->fspace) {
/* Iterate over all sections, reseting the parent pointers in 'single' sections */
if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_revert_root_cb, NULL) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to reset parent pointers")
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_space_revert_root() */
/*-------------------------------------------------------------------------
* Function: H5HF_space_create_root_cb
*
* Purpose: Callback routine from iterator, to set 'parent' pointers in
* sections to newly created root indirect block, when the heap
* is changing from having a root direct block to an indirect block.
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Feb 24 2012
*
*-------------------------------------------------------------------------
*/
static herr_t
H5HF_space_create_root_cb(H5FS_section_info_t *_sect, void *_udata)
{
H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Section to dump info */
H5HF_indirect_t *root_iblock = (H5HF_indirect_t *)_udata; /* User data for callback */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(sect);
HDassert(root_iblock);
/* Sanity check sections */
/* (If we are switching from a direct block for the root block of the heap, */
/* there should only be 'single' type sections. -QAK) */
HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE);
/* Increment ref. count on new root indirect block */
if(H5HF_iblock_incr(root_iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on section's indirect block")
/* Set parent info ("live" section must _NOT_ have a parent right now) */
if(sect->sect_info.state == H5FS_SECT_SERIALIZED)
sect->sect_info.state = H5FS_SECT_LIVE; /* Mark "live" now */
else
HDassert(!sect->u.single.parent);
sect->u.single.parent = root_iblock;
sect->u.single.par_entry = 0;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_space_create_root_cb() */
/*-------------------------------------------------------------------------
* Function: H5HF_space_create_root
*
* Purpose: Set 'parent' pointers in sections to new indirect block, when
* the heap is changing from having a root direct block to a
* indirect block.
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Feb 24 2012
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_space_create_root(const H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *root_iblock)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/*
* Check arguments.
*/
HDassert(hdr);
HDassert(root_iblock);
/* Only need to scan the sections if the free space has been initialized */
if(hdr->fspace) {
/* Iterate over all sections, seting the parent pointers in 'single' sections to the new indirect block */
if(H5FS_sect_iterate(hdr->f, dxpl_id, hdr->fspace, H5HF_space_create_root_cb, root_iblock) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over sections to set parent pointers")
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_space_create_root() */
/*-------------------------------------------------------------------------
* Function: H5HF_space_size

View File

@ -1172,9 +1172,9 @@ HDfprintf(stderr, "%s: Leaving\n", FUNC);
*-------------------------------------------------------------------------
*/
static herr_t
H5MF_sects_cb(const H5FS_section_info_t *_sect, void *_udata)
H5MF_sects_cb(H5FS_section_info_t *_sect, void *_udata)
{
const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect;
H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect;
H5MF_sect_iter_ud_t *udata = (H5MF_sect_iter_ud_t *)_udata;
FUNC_ENTER_NOAPI_NOINIT_NOERR

View File

@ -99,9 +99,9 @@ typedef struct {
*-------------------------------------------------------------------------
*/
static herr_t
H5MF_sects_debug_cb(const H5FS_section_info_t *_sect, void *_udata)
H5MF_sects_debug_cb(H5FS_section_info_t *_sect, void *_udata)
{
const H5MF_free_section_t *sect = (const H5MF_free_section_t *)_sect; /* Section to dump info */
H5MF_free_section_t *sect = (H5MF_free_section_t *)_sect; /* Section to dump info */
H5MF_debug_iter_ud_t *udata = (H5MF_debug_iter_ud_t *)_udata; /* User data for callbacks */
herr_t ret_value = SUCCEED; /* Return value */

View File

@ -508,6 +508,7 @@ get_fill_size(const fheap_test_param_t *tparam)
case FHEAP_TEST_FILL_SINGLE:
return((size_t)0);
case FHEAP_TEST_FILL_N:
default:
HDassert(0 && "Unknown bulk fill type?!?");
} /* end switch */
@ -6453,7 +6454,7 @@ test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa
/* seed = (unsigned long)1155438845; */
HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
HDsrandom(seed);
HDsrandom((unsigned)seed);
/* Set heap ID to random (non-null) value */
heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN;
@ -7594,6 +7595,117 @@ error:
} H5E_END_TRY;
return(1);
} /* test_man_remove_three_larger() */
/*-------------------------------------------------------------------------
* Function: test_man_incr_insert_remove
*
* Purpose: Test incremental insert & removal of objects in heap
*
* Return: Success: 0
* Failure: 1
*
* Programmer: Quincey Koziol
* Sunday, April 1, 2012
*
*-------------------------------------------------------------------------
*/
static unsigned
test_man_incr_insert_remove(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[FHEAP_FILENAME_LEN]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
H5HF_t *fh = NULL; /* Fractal heap wrapper */
haddr_t fh_addr; /* Address of fractal heap */
unsigned char heap_id[100][MAX_HEAP_ID_LEN]; /* Heap ID for object inserted */
struct a_type_t1 {
char a[10];
char b[29];
} obj1, obj2; /* Objects to insert/remove */
size_t id_len; /* Size of fractal heap IDs */
fheap_heap_state_t state; /* State of fractal heap */
int i, j;
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
/* Create the file to work on */
if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
FAIL_STACK_ERROR
/* Get a pointer to the internal file object */
if(NULL == (f = (H5F_t *)H5I_object(file)))
STACK_ERROR
/* Ignore metadata tags in the file's cache */
if(H5AC_ignore_tags(f) < 0)
STACK_ERROR
/* Create absolute heap */
if(NULL == (fh = H5HF_create(f, dxpl, cparam)))
FAIL_STACK_ERROR
if(H5HF_get_id_len(fh, &id_len) < 0)
FAIL_STACK_ERROR
if(id_len > HEAP_ID_LEN)
FAIL_STACK_ERROR
if(H5HF_get_heap_addr(fh, &fh_addr) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
HDmemset(&state, 0, sizeof(fheap_heap_state_t));
if(check_stats(fh, &state))
FAIL_STACK_ERROR
/*
* Test incremental insert and removal
*/
TESTING("incremental object insertion and removal")
for(i = 0; i < 100; i++) {
sprintf(obj1.b, "%s%d", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", i);
for(j = 0; j < i; j++) {
sprintf(obj2.b, "%s%d", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", j);
if(H5HF_remove(fh, dxpl, heap_id[j]) < 0)
FAIL_STACK_ERROR
if(H5HF_insert(fh, dxpl, (sizeof(obj2)), &obj2, heap_id[j]) < 0)
FAIL_STACK_ERROR
} /* end for */
/* Check for closing & re-opening the heap */
if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0)
TEST_ERROR
/* Insert object */
HDmemset(heap_id[i], 0, id_len);
if(H5HF_insert(fh, dxpl, (sizeof(obj1)), &obj1, heap_id[i]) < 0)
FAIL_STACK_ERROR
} /* end for */
/* Close the fractal heap */
if(H5HF_close(fh, dxpl) < 0)
TEST_ERROR
/* Close the file */
if(H5Fclose(file) < 0)
TEST_ERROR
/* All tests passed */
PASSED()
return(0);
error:
H5E_BEGIN_TRY {
if(fh)
H5HF_close(fh, dxpl);
H5Fclose(file);
} H5E_END_TRY;
return(1);
} /* test_man_incr_insert_remove() */
#endif /* QAK */
#ifndef QAK
@ -15420,7 +15532,7 @@ test_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_pa
/* seed = (unsigned long)1156158635; */
HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
HDsrandom(seed);
HDsrandom((unsigned)seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
@ -15624,7 +15736,7 @@ test_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_te
/* seed = (unsigned long)1155181717; */
HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
HDsrandom(seed);
HDsrandom((unsigned)seed);
/* Loop over adding objects to the heap, until the size limit is reached */
total_obj_added = 0;
@ -15838,7 +15950,7 @@ test_write(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam)
filter_class.set_local = NULL;
filter_class.filter = test_write_filter;
if(H5Zregister(&filter_class) < 0) TEST_ERROR
if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_RESERVED + 43, 0, 0, NULL) < 0)
if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_RESERVED + 43, 0, (size_t)0, NULL) < 0)
FAIL_STACK_ERROR
test_write_filter_called = FALSE;
} /* end if */
@ -16292,6 +16404,7 @@ curr_test = FHEAP_TEST_NORMAL;
break;
/* An unknown test? */
case FHEAP_TEST_NTESTS:
default:
goto error;
} /* end switch */
@ -16340,6 +16453,7 @@ fill = FHEAP_TEST_FILL_LARGE;
break;
/* An unknown test? */
case FHEAP_TEST_FILL_N:
default:
goto error;
} /* end switch */
@ -16348,8 +16462,12 @@ fill = FHEAP_TEST_FILL_LARGE;
* Test fractal heap managed object insertion
*/
#ifndef QAK
/* "Weird" sized objects */
nerrors += test_man_insert_weird(fapl, &small_cparam, &tparam);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
#ifdef ALL_INSERT_TESTS
/* "Standard" sized objects, building from simple to complex heaps */
@ -16411,6 +16529,10 @@ HDfprintf(stderr, "Uncomment tests!\n");
nerrors += test_man_remove_three_larger(fapl, &small_cparam, &tparam);
tparam.del_dir = FHEAP_DEL_REVERSE;
nerrors += test_man_remove_three_larger(fapl, &small_cparam, &tparam);
/* Incremental insert & removal */
tparam.del_dir = FHEAP_DEL_FORWARD;
nerrors += test_man_incr_insert_remove(fapl, &small_cparam, &tparam);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
@ -16452,6 +16574,8 @@ tparam.drain_half = FHEAP_DEL_DRAIN_ALL;
nerrors += test_man_remove_2nd_indirect(fapl, &small_cparam, &tparam);
nerrors += test_man_remove_3rd_indirect(fapl, &small_cparam, &tparam);
} /* end else */
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
#ifndef QAK