summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5FS.c23
-rw-r--r--src/H5FSprivate.h1
-rw-r--r--src/H5HFdblock.c32
-rw-r--r--src/H5HFhdr.c141
-rw-r--r--src/H5HFiblock.c59
-rw-r--r--src/H5HFint.c15
-rw-r--r--src/H5HFpkg.h4
-rw-r--r--src/H5HFsection.c62
-rw-r--r--src/H5HFtest.c32
9 files changed, 258 insertions, 111 deletions
diff --git a/src/H5FS.c b/src/H5FS.c
index 5094405..1da16da 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -15,7 +15,7 @@
/* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* Tuesday, May 2, 2006
*
- * Purpose: File free space functions.
+ * Purpose: Free space tracking functions.
*
* Note: (Used to be in the H5HFflist.c file, prior to the date above)
*
@@ -2535,3 +2535,24 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_close() */
+herr_t
+H5FS_debug_test(const H5FS_t *fspace)
+{
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_debug_test)
+
+ HDfprintf(stderr, "%s: fspace->merge_list = %p\n", FUNC, fspace->merge_list);
+ if(fspace->merge_list) {
+ H5SL_node_t *merge_node;
+ H5FS_section_info_t *sect;
+
+ merge_node = H5SL_last(fspace->merge_list);
+ HDfprintf(stderr, "%s: last merge node = %p\n", FUNC, merge_node);
+ if(merge_node) {
+ sect = H5SL_item(merge_node);
+ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", FUNC, sect->size, sect->addr, sect->type);
+ } /* end if */
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+}
+
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index 4ce9d88..ada35e0 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -144,5 +144,6 @@ H5_DLL herr_t H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace);
H5_DLL herr_t H5FS_sect_debug(const H5FS_t *fspace, const H5FS_section_info_t *sect,
FILE *stream, int indent, int fwidth);
+H5_DLL herr_t H5FS_debug_test(const H5FS_t *fspace);
#endif /* _H5FSprivate_H */
diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c
index a4f1815..c8abfd4 100644
--- a/src/H5HFdblock.c
+++ b/src/H5HFdblock.c
@@ -217,6 +217,11 @@ H5HF_man_dblock_destroy(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_direct_t *dblock,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_destroy)
+#ifdef QAK
+HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
+HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size);
+HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
+#endif /* QAK */
/*
* Check arguments.
@@ -249,23 +254,23 @@ HDfprintf(stderr, "%s: root direct block\n", FUNC);
HDfprintf(stderr, "%s: root indirect block\n", FUNC);
#endif /* QAK */
- /* Detach from parent indirect block */
- if(H5HF_man_iblock_detach(dblock->parent, dxpl_id, dblock->par_entry) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't detach from parent indirect block")
- dblock->parent = NULL;
- dblock->par_entry = 0;
-
/* Adjust heap statistics */
hdr->man_alloc_size -= dblock->size;
#ifdef QAK
HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
+HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size);
+HDfprintf(stderr, "%s: dblock->parent->nchildren = %u\n", FUNC, dblock->parent->nchildren);
+HDfprintf(stderr, "%s: dblock->par_entry = %u\n", FUNC, dblock->par_entry);
HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
#endif /* QAK */
/* Check for this direct block being the highest in the heap */
if((dblock->block_off + dblock->size) == hdr->man_iter_off) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Reversing iterator\n", FUNC);
+#endif /* QAK */
/* Move 'next block' iterator backwards (may shrink heap) */
- if(H5HF_hdr_reverse_iter(hdr, dxpl_id) < 0)
+ if(H5HF_hdr_reverse_iter(hdr, dxpl_id, dblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reverse 'next block' iterator")
} /* end if */
#if 0
@@ -282,6 +287,12 @@ HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't create range section for direct block being destroyed")
} /* end else */
#endif /* 0 */
+
+ /* Detach from parent indirect block */
+ if(H5HF_man_iblock_detach(dblock->parent, dxpl_id, dblock->par_entry) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't detach from parent indirect block")
+ dblock->parent = NULL;
+ dblock->par_entry = 0;
} /* end else */
/* Release direct block's disk space */
@@ -292,7 +303,6 @@ HDfprintf(stderr, "%s: Before releasing direct block's space, dblock_addr = %a\n
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap direct block")
/* Remove direct block from metadata cache */
- /* (direct block "destroy" callback will be called by cache) */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
dblock = NULL;
@@ -380,10 +390,16 @@ HDfprintf(stderr, "%s: root direct block, dblock_addr = %a\n", FUNC, dblock_addr
unsigned next_entry; /* Iterator's next block entry */
size_t next_size; /* Size of next direct block to create */
+#ifdef QAK
+HDfprintf(stderr, "%s: before updating iterator\n", FUNC);
+#endif /* QAK */
/* Update iterator to reflect any previous increments as well as allow for requested direct block size */
if(H5HF_hdr_update_iter(hdr, dxpl_id, min_dblock_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUPDATE, FAIL, "unable to update block iterator")
+#ifdef QAK
+HDfprintf(stderr, "%s: after updating iterator\n", FUNC);
+#endif /* QAK */
/* Retrieve information about current iterator position */
if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, &next_entry, &iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to retrieve current block iterator location")
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c
index 5aefe7b..d5af3fe 100644
--- a/src/H5HFhdr.c
+++ b/src/H5HFhdr.c
@@ -869,6 +869,9 @@ HDfprintf(stderr, "%s: min_dblock_size = %Zu\n", FUNC, min_dblock_size);
/* Check for creating first indirect block */
if(hdr->man_dtable.curr_root_rows == 0) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Creating root direct block\n", FUNC);
+#endif /* QAK */
if(H5HF_man_iblock_root_create(hdr, dxpl_id, min_dblock_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "unable to create root indirect block")
} /* end if */
@@ -886,6 +889,7 @@ HDfprintf(stderr, "%s: searching root indirect block\n", FUNC);
min_dblock_row = H5HF_dtable_size_to_row(&hdr->man_dtable, min_dblock_size);
#ifdef QAK
HDfprintf(stderr, "%s: min_dblock_size = %Zu, min_dblock_row = %u\n", FUNC, min_dblock_size, min_dblock_row);
+HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
#endif /* QAK */
/* Initialize block iterator, if necessary */
@@ -905,6 +909,7 @@ HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
#ifdef QAK
HDfprintf(stderr, "%s: Check 1.0\n", FUNC);
HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock);
+HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row);
HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
@@ -940,6 +945,7 @@ HDfprintf(stderr, "%s: min_entry = %u, skip_entries = %u\n", FUNC, min_entry, sk
#ifdef QAK
HDfprintf(stderr, "%s: Check 2.0\n", FUNC);
HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock);
+HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row);
HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
@@ -949,7 +955,7 @@ HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
/* (walk up iterator) */
while(next_row >= iblock->nrows) {
#ifdef QAK
-HDfprintf(stderr, "%s: Off the end of a block\n", FUNC);
+HDfprintf(stderr, "%s: Off the end of a block, next_row = %u, iblock->nrows = %u\n", FUNC, next_row, iblock->nrows);
#endif /* QAK */
/* Check for needing to expand root indirect block */
if(iblock->parent == NULL) {
@@ -1145,9 +1151,12 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id)
+H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t dblock_addr)
{
H5HF_indirect_t *iblock; /* Indirect block where iterator is located */
+ unsigned curr_entry; /* Current entry for iterator */
+ hbool_t walked_down; /* Loop flag */
+ hbool_t walked_up; /* Loop flag */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_reverse_iter)
@@ -1163,71 +1172,91 @@ H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id)
if(H5HF_man_iter_start_offset(hdr, dxpl_id, &hdr->next_block, hdr->man_iter_off) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "unable to set block iterator location")
+ /* Walk backwards through heap, looking for direct block to place iterator after */
+
/* Get information about current iterator location */
- if(H5HF_man_iter_curr(&hdr->next_block, NULL, NULL, NULL, &iblock) < 0)
+ if(H5HF_man_iter_curr(&hdr->next_block, NULL, NULL, &curr_entry, &iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to retrieve current block iterator information")
#ifdef QAK
HDfprintf(stderr, "%s: iblock->nchildren = %u\n", FUNC, iblock->nchildren);
HDfprintf(stderr, "%s: iblock->parent = %p\n", FUNC, iblock->parent);
+HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry);
#endif /* QAK */
- /* Walk backwards through heap, looking for direct block to place iterator after */
+ /* Move current iterator position backwards once */
+ curr_entry--;
- /* Walk up the levels in the heap until we find an indirect block with children */
- while(iblock->nchildren == 0 && iblock->parent) {
- /* Move iterator to parent of current block */
- if(H5HF_man_iter_up(&hdr->next_block) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTNEXT, FAIL, "unable to advance current block iterator location")
+ /* Search backwards in the heap address space for direct block to latch onto */
+ do {
+ int tmp_entry; /* Temp. entry for iterator (use signed value to detect errors) */
- /* Detach from parent indirect block */
- if(H5HF_man_iblock_detach(iblock->parent, dxpl_id, iblock->par_entry) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't detach from parent indirect block")
- iblock->parent = NULL;
- iblock->par_entry = 0;
- } /* end while */
+ /* Reset loop flags */
+ walked_down = FALSE;
+ walked_up = FALSE;
- /* If there's children in this indirect block, walk backwards to find last child */
- if(iblock->nchildren) {
- unsigned curr_entry; /* Current entry for iterator */
- unsigned row; /* Row for entry */
- hbool_t walked_down; /* Loop flag */
+ /* Walk backwards through entries, until we find one that has a child */
+ /* (Skip direct block that will be deleted, if we find it) */
+ tmp_entry = curr_entry;
+#ifdef QAK
+HDfprintf(stderr, "%s: tmp_entry = %d\n", FUNC, tmp_entry);
+#endif /* QAK */
+ while(tmp_entry >= 0 &&
+ (H5F_addr_eq(iblock->ents[tmp_entry].addr, dblock_addr) ||
+ !H5F_addr_defined(iblock->ents[tmp_entry].addr)))
+ tmp_entry--;
+#ifdef QAK
+HDfprintf(stderr, "%s: check 2.0 - tmp_entry = %d\n", FUNC, tmp_entry);
+#endif /* QAK */
+ /* Check for no earlier blocks in this indirect block */
+ if(tmp_entry < 0) {
+ /* Check for parent of current indirect block */
+ if(iblock->parent) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Walking up a block\n", FUNC);
+#endif /* QAK */
+ /* Move iterator to parent of current block */
+ if(H5HF_man_iter_up(&hdr->next_block) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTNEXT, FAIL, "unable to move current block iterator location up")
- /* Get information about current iterator location */
- if(H5HF_man_iter_curr(&hdr->next_block, NULL, NULL, &curr_entry, NULL) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to retrieve current block iterator information")
+ /* Get information about current iterator location */
+ if(H5HF_man_iter_curr(&hdr->next_block, NULL, NULL, &curr_entry, &iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to retrieve current block iterator information")
#ifdef QAK
+HDfprintf(stderr, "%s: iblock->nchildren = %u\n", FUNC, iblock->nchildren);
+HDfprintf(stderr, "%s: iblock->parent = %p\n", FUNC, iblock->parent);
HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry);
#endif /* QAK */
- /* Move current iterator position backwards once */
- curr_entry--;
-
- /* Search backwards for direct block to latch onto */
- do {
- int tmp_entry; /* Temp. entry for iterator (use signed value to detect errors) */
-
- /* Reset loop flag */
- walked_down = FALSE;
+ /* Move current iterator position backwards once */
+ curr_entry--;
- /* Walk backwards through entries, until we find one that has a child */
- /* (Account for root indirect block shrinking) */
- tmp_entry = MIN(curr_entry, ((iblock->nrows * hdr->man_dtable.cparam.width) - 1));
-#ifdef QAK
-HDfprintf(stderr, "%s: tmp_entry = %d\n", FUNC, tmp_entry);
-HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
-#endif /* QAK */
- while(!H5F_addr_defined(iblock->ents[tmp_entry].addr)) {
- tmp_entry--;
- HDassert(tmp_entry >= 0);
- } /* end while */
+ /* Note that we walked up */
+ walked_up = TRUE;
+ } /* end if */
+ else {
#ifdef QAK
-HDfprintf(stderr, "%s: check 2.0 - tmp_entry = %d\n", FUNC, tmp_entry);
+HDfprintf(stderr, "%s: Heap empty\n", FUNC);
#endif /* QAK */
+ /* Reset header information back to "empty heap" state */
+ if(H5HF_hdr_empty(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty")
+ } /* end else */
+ } /* end if */
+ else {
+ unsigned row; /* Row for entry */
+
curr_entry = tmp_entry;
/* Check if entry is for a direct block */
row = curr_entry / hdr->man_dtable.cparam.width;
+#ifdef QAK
+HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry);
+HDfprintf(stderr, "%s: row = %u\n", FUNC, row);
+#endif /* QAK */
if(row < hdr->man_dtable.max_direct_rows) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Found direct block\n", FUNC);
+#endif /* QAK */
/* Increment entry to empty location */
curr_entry++;
@@ -1239,11 +1268,18 @@ HDfprintf(stderr, "%s: check 2.0 - tmp_entry = %d\n", FUNC, tmp_entry);
hdr->man_iter_off = iblock->block_off;
hdr->man_iter_off += hdr->man_dtable.row_block_off[curr_entry / hdr->man_dtable.cparam.width];
hdr->man_iter_off += hdr->man_dtable.row_block_size[curr_entry / hdr->man_dtable.cparam.width] * (curr_entry % hdr->man_dtable.cparam.width);
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
+HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry);
+#endif /* QAK */
} /* end if */
else {
H5HF_indirect_t *child_iblock; /* Pointer to child indirect block */
unsigned child_nrows; /* # of rows in child block */
+#ifdef QAK
+HDfprintf(stderr, "%s: Walking down into child block\n", FUNC);
+#endif /* QAK */
/* Compute # of rows in next child indirect block to use */
child_nrows = H5HF_dtable_size_to_rows(&hdr->man_dtable, hdr->man_dtable.row_block_size[row]);
@@ -1262,6 +1298,11 @@ HDfprintf(stderr, "%s: check 2.0 - tmp_entry = %d\n", FUNC, tmp_entry);
/* Update iterator location */
iblock = child_iblock;
curr_entry = (child_iblock->nrows * hdr->man_dtable.cparam.width) - 1;
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->nchildren = %u\n", FUNC, iblock->nchildren);
+HDfprintf(stderr, "%s: iblock->parent = %p\n", FUNC, iblock->parent);
+HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry);
+#endif /* QAK */
/* Unprotect child indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock->addr, child_iblock, H5AC__NO_FLAGS_SET) < 0)
@@ -1270,13 +1311,8 @@ HDfprintf(stderr, "%s: check 2.0 - tmp_entry = %d\n", FUNC, tmp_entry);
/* Note that we walked down */
walked_down = TRUE;
} /* end else */
- } while(walked_down);
- } /* end if */
- else {
- /* Reset header information back to "empty heap" state */
- if(H5HF_hdr_empty(hdr) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty")
- } /* end else */
+ } /* end else */
+ } while(walked_down || walked_up);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1314,6 +1350,9 @@ HDfprintf(stderr, "%s: Reseting heap header to empty\n", FUNC);
hdr->man_size = 0;
hdr->man_alloc_size = 0;
+ /* Reset the 'next block' iterator location */
+ hdr->man_iter_off = 0;
+
/* Reset the free space in direct blocks */
hdr->total_man_free = 0;
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index 652ae54..1fa7c35 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -165,6 +165,9 @@ HDfprintf(stderr, "%s: indirect block ref. count at zero, iblock->addr = %a\n",
* from cache.
*/
if(iblock->nchildren == 0) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Removing indirect block from cache, iblock->addr = %a\n", FUNC, iblock->addr);
+#endif /* QAK */
/* Check for deleting root indirect block (and no root direct block) */
if(iblock->block_off == 0 && iblock->hdr->man_dtable.curr_root_rows > 0) {
/* Reset root pointer information */
@@ -172,6 +175,19 @@ HDfprintf(stderr, "%s: indirect block ref. count at zero, iblock->addr = %a\n",
iblock->hdr->man_dtable.table_addr = HADDR_UNDEF;
} /* end if */
+ /* Detach from parent indirect block */
+ if(iblock->parent) {
+ /* Detach from parent indirect block */
+ if(H5HF_man_iblock_detach(iblock->parent, H5AC_dxpl_id, iblock->par_entry) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTATTACH, FAIL, "can't detach from parent indirect block")
+ iblock->parent = NULL;
+ iblock->par_entry = 0;
+ } /* end if */
+
+ /* Release space for indirect block on disk */
+ if(H5MF_xfree(iblock->hdr->f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block disk space")
+
/* Unlock indirect block with delete flag */
if(H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, tmp_iblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
@@ -382,7 +398,7 @@ H5HF_man_iblock_root_double(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_root_double)
#ifdef QAK
-HDfprintf(stderr, "%s: Extending root indirect block\n", FUNC);
+HDfprintf(stderr, "%s: Extending root indirect block, min_dblock_size = %Zu\n", FUNC, min_dblock_size);
#endif /* QAK */
/* Get "new block" iterator information */
@@ -392,9 +408,19 @@ HDfprintf(stderr, "%s: Extending root indirect block\n", FUNC);
/* Make certain the iterator is at the root indirect block */
HDassert(iblock->parent == NULL);
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
+#endif /* QAK */
+ HDassert(iblock->block_off == 0);
/* Keep this for later */
old_nrows = iblock->nrows;
+#ifdef QAK
+HDfprintf(stderr, "%s: old_nrows = %u\n", FUNC, old_nrows);
+HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry);
+HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row);
+HDfprintf(stderr, "%s: next_size = %Hu\n", FUNC, next_size);
+#endif /* QAK */
/* Check for skipping over direct block rows */
if(iblock->nrows < hdr->man_dtable.max_direct_rows && min_dblock_size > next_size) {
@@ -415,7 +441,7 @@ HDfprintf(stderr, "%s: Extending root indirect block\n", FUNC);
new_nrows = MAX(min_nrows, MIN(2 * iblock->nrows, iblock->max_rows));
#ifdef QAK
HDfprintf(stderr, "%s: min_nrows = %u, new_nrows = %u\n", FUNC, min_nrows, new_nrows);
-HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
+HDfprintf(stderr, "%s: iblock->nrows = %u, iblock->max_rows = %u\n", FUNC, iblock->nrows, iblock->max_rows);
HDfprintf(stderr, "%s: new_next_entry = %u\n", FUNC, new_next_entry);
#endif /* QAK */
@@ -659,6 +685,10 @@ HDfprintf(stderr, "%s: Reverting root indirect block\n", FUNC);
if(H5HF_hdr_reset_iter(hdr, (hsize_t)dblock_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator")
+ /* Extend heap to just cover first direct block */
+ if(H5HF_hdr_adjust_heap(hdr, (hsize_t)hdr->man_dtable.cparam.start_block_size, (hssize_t)hdr->man_dtable.row_dblock_free[0]) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "can't increase space to cover root direct block")
+
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")
@@ -826,7 +856,8 @@ HDfprintf(stderr, "%s: child_iblock->child_free_space = %Hu\n", FUNC, child_iblo
#ifdef QAK
HDfprintf(stderr, "%s: old_sec_node->u.indirect.indir_row = %u\n", FUNC, old_sec_node->u.indirect.indir_row);
HDfprintf(stderr, "%s: hdr->man_dtable.row_block_size[old_sec_node->u.indirect.indir_row] = %Hu\n", FUNC, hdr->man_dtable.row_block_size[old_sec_node->u.indirect.indir_row]);
-HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect_addr);
+HDfprintf(stderr, "%s: old_sec_node->sect_info.addr = %a\n", FUNC, old_sec_node->sect_info.addr);
+HDfprintf(stderr, "%s: dblock_entry = %u\n", FUNC, dblock_entry);
#endif /* QAK */
if(H5HF_man_dblock_create(dxpl_id, hdr, child_iblock, dblock_entry, &dblock_addr, &dblock_sec_node) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block")
@@ -1028,7 +1059,8 @@ H5HF_man_iblock_attach(H5HF_indirect_t *iblock, unsigned entry, haddr_t child_ad
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_attach)
#ifdef QAK
-HDfprintf(stderr, "%s: iblock = %p, entry = %u, child_addr = %a, iblock_nrows = %u\n", FUNC, iblock, entry, child_addr);
+HDfprintf(stderr, "%s: iblock = %p, entry = %u, child_addr = %a\n", FUNC, iblock, entry, child_addr);
+HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, iblock->block_off, iblock->nchildren);
#endif /* QAK */
/*
@@ -1036,6 +1068,7 @@ HDfprintf(stderr, "%s: iblock = %p, entry = %u, child_addr = %a, iblock_nrows =
*/
HDassert(iblock);
HDassert(H5F_addr_defined(child_addr));
+ HDassert(!H5F_addr_defined(iblock->ents[entry].addr));
/* Increment the reference count on this indirect block */
if(H5HF_iblock_incr(iblock) < 0)
@@ -1076,12 +1109,15 @@ done:
herr_t
H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry)
{
+#ifdef OLD_WAY
unsigned start_children; /* # of children of iblock when routine was entered */
+#endif /* OLD_WAY */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_detach)
#ifdef QAK
-HDfprintf(stderr, "%s: iblock = %p, entry = %u, dblock_addr = %a, iblock_nrows = %u\n", FUNC, iblock, entry, dblock_addr);
+HDfprintf(stderr, "%s: iblock = %p, entry = %u\n", FUNC, iblock, entry);
+HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, iblock->block_off, iblock->nchildren);
#endif /* QAK */
/*
@@ -1101,7 +1137,9 @@ HDfprintf(stderr, "%s: iblock = %p, entry = %u, dblock_addr = %a, iblock_nrows =
/* (Track the initial # of children before the block gets modified, because
* this routine is called recursively)
*/
+#ifdef OLD_WAY
start_children = iblock->nchildren;
+#endif /* OLD_WAY */
iblock->nchildren--;
/* Reduce the max. entry used, if necessary */
@@ -1138,13 +1176,6 @@ HDfprintf(stderr, "%s: iblock = %p, entry = %u, dblock_addr = %a, iblock_nrows =
} /* end if */
} /* end if */
- /* Free indirect block disk space, if it has no children (i.e. it's been deleted) */
- if(start_children == 1) {
- HDassert(iblock->nchildren == 0);
- if(H5MF_xfree(iblock->hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block disk space")
- } /* end if */
-
/* Mark indirect block as modified */
if(H5HF_iblock_dirty(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
@@ -1157,6 +1188,10 @@ HDfprintf(stderr, "%s: iblock = %p, entry = %u, dblock_addr = %a, iblock_nrows =
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't decrement reference count on shared indirect block")
done:
+#ifdef QAK
+HDfprintf(stderr, "%s: Leaving, ret_value = %d\n", FUNC, ret_value);
+HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, iblock->block_off, iblock->nchildren);
+#endif /* QAK */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iblock_detach() */
diff --git a/src/H5HFint.c b/src/H5HFint.c
index c374098..833bc0f 100644
--- a/src/H5HFint.c
+++ b/src/H5HFint.c
@@ -147,6 +147,7 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
haddr_t new_iblock_addr; /* New indirect block's address */
H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */
unsigned nrows; /* Number of rows in new indirect block */
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting parent indirect block */
/* Compute # of rows in child indirect block */
nrows = (H5V_log2_gen(hdr->man_dtable.row_block_size[row]) - hdr->man_dtable.first_row_bits) + 1;
@@ -160,12 +161,21 @@ HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry);
/* Locate child indirect block */
new_iblock_addr = iblock->ents[entry].addr;
+ /* Check if we need to (re-)create the child indirect block */
+ if(!H5F_addr_defined(new_iblock_addr)) {
+ if(H5HF_man_iblock_create(hdr, dxpl_id, iblock, entry, nrows, nrows, &new_iblock_addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap indirect block")
+
+ /* Indicate that the parent indirect block was modified */
+ cache_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+
/* Lock new indirect block */
if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, nrows, iblock, entry, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Release the current indirect block */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(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")
/* Switch variables to use new indirect block */
@@ -230,6 +240,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request);
/* Look for free space */
if((node_found = H5HF_space_find(hdr, dxpl_id, (hsize_t)request, sec_node)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
+#ifdef QAK
+HDfprintf(stderr, "%s: After H5HF_space_find(), node_found = %t\n", FUNC, node_found);
+#endif /* QAK */
/* If we didn't find a node, go create a direct block big enough to hold the requested block */
if(!node_found)
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index f2bcfc4..d5b4da0 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -402,7 +402,8 @@ H5_DLL herr_t H5HF_hdr_skip_blocks(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries);
H5_DLL herr_t H5HF_hdr_update_iter(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_size);
H5_DLL herr_t H5HF_hdr_inc_iter(H5HF_hdr_t *hdr, hsize_t adv_size, unsigned nentries);
-H5_DLL herr_t H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id);
+H5_DLL herr_t H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ haddr_t dblock_addr);
H5_DLL herr_t H5HF_hdr_reset_iter(H5HF_hdr_t *hdr, hsize_t curr_off);
H5_DLL herr_t H5HF_hdr_empty(H5HF_hdr_t *hdr);
@@ -533,6 +534,7 @@ H5_DLL unsigned H5HF_get_iblock_max_drows_test(const H5HF_t *fh, unsigned pos);
H5_DLL hsize_t H5HF_get_dblock_size_test(const H5HF_t *fh, unsigned row);
H5_DLL hsize_t H5HF_get_dblock_free_test(const H5HF_t *fh, unsigned row);
H5_DLL herr_t H5HF_get_id_off_test(const H5HF_t *fh, const void *id, hsize_t *obj_off);
+H5_DLL herr_t H5HF_debug_test(const H5HF_t *fh);
#endif /* H5HF_TESTING */
#endif /* _H5HFpkg_H */
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 48e2ddb..7fe557b 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -600,6 +600,11 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
if(H5HF_sect_range_from_single(hdr, sect1, dblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCONVERT, FAIL, "can't convert single section into range section")
+#ifdef QAK
+HDfprintf(stderr, "%s: sect1->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect1->sect_info.addr, sect1->sect_info.size, sect1->sect_info.type, (sect1->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
+HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect2->sect_info.addr, sect2->sect_info.size, sect2->sect_info.type, (sect2->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
+#endif /* QAK */
+
/* Destroy direct block */
if(H5HF_man_dblock_destroy(hdr, dxpl_id, dblock, dblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release direct block")
@@ -1134,6 +1139,10 @@ H5HF_sect_range_deserialize(const uint8_t *buf, haddr_t sect_addr,
if(NULL == (new_sect = H5HF_sect_node_new(H5HF_FSPACE_SECT_RANGE, sect_addr, sect_size, H5FS_SECT_SERIALIZED)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "allocation failed for direct block free list section")
+ /* Range's indirect block */
+ /* (Section needs to be "revived" before this is correct) */
+ new_sect->u.range.iblock = NULL;
+
/* Range's row */
UINT16DECODE(buf, new_sect->u.range.row);
@@ -1176,7 +1185,6 @@ H5HF_sect_range_can_merge(H5FS_section_info_t *_sect1,
H5HF_add_ud1_t *udata = (H5HF_add_ud1_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 */
- hsize_t sect2_off; /* Offset of second section in heap */
size_t dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); /* Direct block's overhead */
htri_t ret_value = FALSE; /* Return value */
@@ -1191,13 +1199,6 @@ H5HF_sect_range_can_merge(H5FS_section_info_t *_sect1,
HDfprintf(stderr, "%s: sect1->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect1->sect_info.addr, sect1->sect_info.size, sect1->sect_info.type, (sect1->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect2->sect_info.addr, sect2->sect_info.size, sect2->sect_info.type, (sect2->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
#endif /* QAK */
- /* Check to see if we should revive either section */
- if(sect1->sect_info.state != H5FS_SECT_LIVE)
- if(H5HF_sect_range_revive(hdr, dxpl_id, sect1) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section")
- if(sect2->sect_info.state != H5FS_SECT_LIVE)
- if(H5HF_sect_revive(hdr, dxpl_id, sect2) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive free section")
/* Check for special case of delayed conversion of 2nd section from
* single -> range section
@@ -1205,6 +1206,11 @@ HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect2->sec
if(sect2->sect_info.type == H5HF_FSPACE_SECT_SINGLE) {
size_t dblock_size; /* Section's direct block's size */
+ /* Check to see if we should revive the section */
+ if(sect2->sect_info.state != H5FS_SECT_LIVE)
+ if(H5HF_sect_revive(hdr, dxpl_id, sect2) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive free section")
+
/* Check for section occupying entire direct block */
dblock_size = sect2->u.single.dblock_size;
if((dblock_size - dblock_overhead) == sect2->sect_info.size) {
@@ -1236,6 +1242,7 @@ HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
#ifdef QAK
HDfprintf(stderr, "%s: sect1.u.range = {%p, %u, %u, %u}\n", FUNC, sect1->u.range.iblock, sect1->u.range.row, sect1->u.range.col, sect1->u.range.num_entries);
+HDfprintf(stderr, "%s: sect2.u.range = {%p, %u, %u, %u}\n", FUNC, sect2->u.range.iblock, sect2->u.range.row, sect2->u.range.col, sect2->u.range.num_entries);
#endif /* QAK */
/* Range section can only merge with other range sections */
@@ -1243,25 +1250,9 @@ HDfprintf(stderr, "%s: sect1.u.range = {%p, %u, %u, %u}\n", FUNC, sect1->u.range
HGOTO_DONE(FALSE)
#ifdef QAK
-HDfprintf(stderr, "%s: sect2.u.range = {%p, %u, %u, %u}\n", FUNC, sect2->u.range.iblock, sect2->u.range.row, sect2->u.range.col, sect2->u.range.num_entries);
-HDfprintf(stderr, "%s: sect2.u.range.iblock->nchildren = %u\n", FUNC, sect2->u.range.iblock->nchildren);
-#endif /* QAK */
-
- /* Check if second section is in indirect block that's being deleted */
- if(sect2->u.range.iblock->nchildren == 0)
- HGOTO_DONE(TRUE)
-
- /* Check if second section is past end of "next block" iterator */
- sect2_off = sect2->u.range.iblock->block_off;
- sect2_off += hdr->man_dtable.row_block_off[sect2->u.range.row];
- sect2_off += hdr->man_dtable.row_block_size[sect2->u.range.row] * sect2->u.range.col;
-#ifdef QAK
HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off);
-HDfprintf(stderr, "%s: sect2.u.range.iblock->block_off = %Hu\n", FUNC, sect2->u.range.iblock->block_off);
-HDfprintf(stderr, "%s: hdr->man_dtable.row_block_off[%u] = %Hu\n", FUNC, sect2->u.range.row, hdr->man_dtable.row_block_off[sect2->u.range.row]);
-HDfprintf(stderr, "%s: sect2_off = %Hu\n", FUNC, sect2_off);
#endif /* QAK */
- if(sect2_off > hdr->man_iter_off)
+ if(sect2->sect_info.addr >= hdr->man_iter_off)
HGOTO_DONE(TRUE)
/* Check if second section adjoins first section & is in the same row */
@@ -1307,10 +1298,8 @@ H5HF_sect_range_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
/* Check arguments. */
HDassert(sect1);
- HDassert(sect1->sect_info.state == H5FS_SECT_LIVE);
HDassert(sect1->sect_info.type == H5HF_FSPACE_SECT_RANGE);
HDassert(sect2);
- HDassert(sect2->sect_info.state == H5FS_SECT_LIVE);
HDassert(sect2->sect_info.type == H5HF_FSPACE_SECT_RANGE);
#ifdef QAK
@@ -1362,27 +1351,26 @@ static htri_t
H5HF_sect_range_can_shrink(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_add_ud1_t *udata = (H5HF_add_ud1_t *)_udata; /* User callback data */
+ H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */
htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_range_can_shrink)
/* Check arguments. */
HDassert(sect);
- HDassert(sect->sect_info.state == H5FS_SECT_LIVE);
+ HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_RANGE);
#ifdef QAK
HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_range_can_shrink", sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED"));
HDfprintf(stderr, "%s: sect->u.range = {%p, %u, %u, %u}\n", "H5HF_sect_range_can_shrink", sect->u.range.iblock, sect->u.range.row, sect->u.range.col, sect->u.range.num_entries);
-if(sect->u.range.iblock != NULL)
- HDfprintf(stderr, "%s: sect->u.range.iblock->nchildren = %u\n", "H5HF_sect_range_can_shrink", sect->u.range.iblock->nchildren);
#endif /* QAK */
- /* If section has no parent, it should go away */
- if(sect->u.range.iblock == NULL)
- HGOTO_DONE(TRUE)
-
- /* If section is in an indirect block with no children, it should go away */
- if(sect->u.range.iblock->nchildren == 0)
+ /* Check if section is past end of "next block" iterator */
+#ifdef QAK
+HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", "H5HF_sect_range_can_shrink", hdr->man_iter_off);
+#endif /* QAK */
+ if(sect->sect_info.addr >= hdr->man_iter_off)
HGOTO_DONE(TRUE)
done:
@@ -1415,7 +1403,7 @@ H5HF_sect_range_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
/* Check arguments. */
HDassert(sect);
HDassert(*sect);
- HDassert((*sect)->sect_info.state == H5FS_SECT_LIVE);
+ HDassert((*sect)->sect_info.type == H5HF_FSPACE_SECT_RANGE);
#ifdef QAK
HDfprintf(stderr, "%s: (*sect).sect_info = {%a, %Hu, %u}\n", FUNC, (*sect)->sect_info.addr, (*sect)->sect_info.size, (*sect)->sect_info.type);
diff --git a/src/H5HFtest.c b/src/H5HFtest.c
index 5e57af3..a3b524b 100644
--- a/src/H5HFtest.c
+++ b/src/H5HFtest.c
@@ -327,3 +327,35 @@ H5HF_get_id_off_test(const H5HF_t *fh, const void *_id, hsize_t *obj_off)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HF_get_id_off_test() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_debug_test
+ *
+ * Purpose: Debugging routine for testing
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 20, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_debug_test(const H5HF_t *fh)
+{
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_debug_test)
+
+ /* Check arguments. */
+ HDassert(fh);
+ HDassert(fh->hdr);
+
+ HDfprintf(stderr, "%s: fh->hdr->man_iter_off = %Hu\n", FUNC, fh->hdr->man_iter_off);
+ HDfprintf(stderr, "%s: fh->hdr->fspace = %p\n", FUNC, fh->hdr->fspace);
+ if(fh->hdr->fspace)
+ H5FS_debug_test(fh->hdr->fspace);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5HF_debug_test() */
+