summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2012-04-01 23:53:17 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2012-04-01 23:53:17 (GMT)
commit42306f8ed4ade51a8629b9c5a159d1afac5f617f (patch)
treea503b4e463f3888709d893eae564898d899135bb
parent982f1ff8ff1687cc62e310c991c0d56929b271fd (diff)
downloadhdf5-42306f8ed4ade51a8629b9c5a159d1afac5f617f.zip
hdf5-42306f8ed4ade51a8629b9c5a159d1afac5f617f.tar.gz
hdf5-42306f8ed4ade51a8629b9c5a159d1afac5f617f.tar.bz2
[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
-rw-r--r--src/H5FSprivate.h2
-rw-r--r--src/H5FSsection.c2
-rw-r--r--src/H5HF.c32
-rw-r--r--src/H5HFbtree2.c8
-rw-r--r--src/H5HFdbg.c195
-rw-r--r--src/H5HFhuge.c4
-rw-r--r--src/H5HFiblock.c146
-rw-r--r--src/H5HFpkg.h19
-rw-r--r--src/H5HFsection.c52
-rw-r--r--src/H5HFspace.c181
-rw-r--r--src/H5MF.c4
-rw-r--r--src/H5MFdbg.c4
-rw-r--r--test/fheap.c132
13 files changed, 616 insertions, 165 deletions
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index ca7104c..f6a0034 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -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*/);
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index 914fa58..0f126c2 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -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 */
diff --git a/src/H5HF.c b/src/H5HF.c
index 9c911fd..a9750c9 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -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")
diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c
index 023344c..34b74d7 100644
--- a/src/H5HFbtree2.c
+++ b/src/H5HFbtree2.c
@@ -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
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index 4289c02..caaedc7 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -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 */
diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c
index 3bbd137..6f0b48e 100644
--- a/src/H5HFhuge.c
+++ b/src/H5HFhuge.c
@@ -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 */
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index 6c19b4f..342e228 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -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
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 2746302..498c45e 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -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);
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 38d9381..87fa069 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -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
diff --git a/src/H5HFspace.c b/src/H5HFspace.c
index cec9b3a..01330d3 100644
--- a/src/H5HFspace.c
+++ b/src/H5HFspace.c
@@ -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
@@ -246,6 +246,185 @@ done:
/*-------------------------------------------------------------------------
+ * 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
*
* Purpose: Query the size of the heap's free space info on disk
diff --git a/src/H5MF.c b/src/H5MF.c
index fce151e..f9ca256 100644
--- a/src/H5MF.c
+++ b/src/H5MF.c
@@ -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
diff --git a/src/H5MFdbg.c b/src/H5MFdbg.c
index bdc811f..d6fc5ce 100644
--- a/src/H5MFdbg.c
+++ b/src/H5MFdbg.c
@@ -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 */
diff --git a/test/fheap.c b/test/fheap.c
index 14cfbe8..e4aa137 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -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