diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5FS.c | 23 | ||||
-rw-r--r-- | src/H5FSprivate.h | 1 | ||||
-rw-r--r-- | src/H5HFdblock.c | 32 | ||||
-rw-r--r-- | src/H5HFhdr.c | 141 | ||||
-rw-r--r-- | src/H5HFiblock.c | 59 | ||||
-rw-r--r-- | src/H5HFint.c | 15 | ||||
-rw-r--r-- | src/H5HFpkg.h | 4 | ||||
-rw-r--r-- | src/H5HFsection.c | 62 | ||||
-rw-r--r-- | src/H5HFtest.c | 32 |
9 files changed, 258 insertions, 111 deletions
@@ -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() */ + |