diff options
Diffstat (limited to 'src/H5HFiblock.c')
-rw-r--r-- | src/H5HFiblock.c | 228 |
1 files changed, 74 insertions, 154 deletions
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 1fa7c35..f48b4c2 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -112,6 +112,10 @@ H5HF_iblock_incr(H5HF_indirect_t *iblock) /* Increment reference count on shared indirect block */ iblock->rc++; +#ifdef QAK +HDfprintf(stderr, "%s: iblock->addr = %a, iblock->rc = %Zu\n", FUNC, iblock->addr, iblock->rc); +HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off); +#endif /* QAK */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -143,6 +147,10 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock) /* Decrement reference count on shared indirect block */ iblock->rc--; +#ifdef QAK +HDfprintf(stderr, "%s: iblock->addr = %a, iblock->rc = %Zu\n", FUNC, iblock->addr, iblock->rc); +HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off); +#endif /* QAK */ /* Mark block as evictable again when no child blocks depend on it */ if(iblock->rc == 0) { @@ -350,11 +358,11 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl /* Compute free space in direct blocks referenced from entries in root indirect block */ acc_dblock_free = 0; for(u = 0; u < nrows; u++) - acc_dblock_free += hdr->man_dtable.row_dblock_free[u] * hdr->man_dtable.cparam.width; + acc_dblock_free += hdr->man_dtable.row_tot_dblock_free[u] * hdr->man_dtable.cparam.width; /* Account for potential initial direct block */ if(have_direct_block) - acc_dblock_free -= hdr->man_dtable.row_dblock_free[0]; + acc_dblock_free -= hdr->man_dtable.row_tot_dblock_free[0]; /* Extend heap to cover new root indirect block */ if(H5HF_hdr_adjust_heap(hdr, hdr->man_dtable.row_block_off[nrows], (hssize_t)acc_dblock_free) < 0) @@ -487,7 +495,7 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr); unsigned row = u / hdr->man_dtable.cparam.width; /* Row for current entry */ iblock->ents[u].addr = HADDR_UNDEF; - acc_dblock_free += hdr->man_dtable.row_dblock_free[row]; + acc_dblock_free += hdr->man_dtable.row_tot_dblock_free[row]; } /* end for */ /* Mark indirect block as dirty */ @@ -580,7 +588,7 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); /* Compute free space in rows to delete */ acc_dblock_free = 0; for(u = new_nrows; u < iblock->nrows; u++) - acc_dblock_free += hdr->man_dtable.row_dblock_free[u] * hdr->man_dtable.cparam.width; + acc_dblock_free += hdr->man_dtable.row_tot_dblock_free[u] * hdr->man_dtable.cparam.width; /* Compute size of buffer needed for new indirect block */ iblock->nrows = new_nrows; @@ -686,7 +694,7 @@ HDfprintf(stderr, "%s: Reverting root indirect block\n", FUNC); 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) + 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") done: @@ -698,80 +706,10 @@ done: /*------------------------------------------------------------------------- - * Function: H5HF_man_iblock_alloc_range - * - * Purpose: Allocate a "single" section for an object, out of a "range" - * section - * - * Note: Creates necessary direct & indirect blocks - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 28 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5HF_man_iblock_alloc_range(H5HF_hdr_t *hdr, hid_t dxpl_id, - H5HF_free_section_t **sec_node) -{ - H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */ - haddr_t dblock_addr; /* Direct block's address */ - H5HF_free_section_t *dblock_sec_node = NULL; /* Pointer to direct block's section node */ - H5HF_free_section_t *old_sec_node = *sec_node; /* Pointer to old section node */ - unsigned cur_entry; /* Current entry in indirect block */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_alloc_range) - - /* - * Check arguments. - */ - HDassert(hdr); - HDassert(sec_node && *sec_node); - - /* Check for serialized section */ - if(old_sec_node->sect_info.state == H5FS_SECT_SERIALIZED) { - /* Revive range section */ - if(H5HF_sect_range_revive(hdr, dxpl_id, old_sec_node) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTREVIVE, FAIL, "can't revive range section") - } /* end if */ - - /* Compute info about range */ - cur_entry = (old_sec_node->u.range.row * hdr->man_dtable.cparam.width) + old_sec_node->u.range.col; - - /* Get a pointer to the indirect block covering the range */ - iblock = old_sec_node->u.range.iblock; - HDassert(iblock); - -#ifdef QAK -HDfprintf(stderr, "%s: cur_entry = %u\n", FUNC, cur_entry); -HDfprintf(stderr, "%s: old_sec_node->u.range.num_entries = %u\n", FUNC, old_sec_node->u.range.num_entries); -#endif /* QAK */ - /* Create direct block of appropriate size */ - if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, cur_entry, &dblock_addr, &dblock_sec_node) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block") - - /* Reduce (& possibly re-add) 'range' section */ - if(H5HF_sect_range_reduce(hdr, dxpl_id, old_sec_node) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce indirect section node") - - /* Point 'sec_node' at new direct block section node */ - *sec_node = dblock_sec_node; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_man_iblock_alloc_range() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_man_iblock_alloc_indirect + * Function: H5HF_man_iblock_alloc_indirect2 * - * Purpose: Allocate a "single" section for an object, out of an - * "indirect" section, possibly creating "range" section as a - * byproduct. + * Purpose: Allocate a "single" section for an object, out of a + * "row" section. * * Note: Creates necessary direct & indirect blocks * @@ -779,110 +717,70 @@ done: * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu - * Apr 4 2006 + * July 6 2006 * *------------------------------------------------------------------------- */ herr_t -H5HF_man_iblock_alloc_indirect(H5HF_hdr_t *hdr, hid_t dxpl_id, - H5HF_free_section_t **sec_node) +H5HF_man_iblock_alloc_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t **sec_node) { H5HF_indirect_t *iblock; /* Pointer to indirect block */ - H5HF_indirect_t *child_iblock; /* Pointer to child indirect block */ - haddr_t child_iblock_addr; /* Address of child indirect block */ - haddr_t dblock_addr; /* New direct block's address */ - H5HF_free_section_t *dblock_sec_node = NULL; /* Pointer to direct block's section node */ H5HF_free_section_t *old_sec_node = *sec_node; /* Pointer to old indirect section node */ - unsigned curr_entry; /* Current entry in indirect block */ - unsigned dblock_entry; /* Entry of direct block in child indirect block */ + unsigned dblock_entry; /* Entry for direct block */ + hbool_t iblock_held = FALSE; /* Flag to indicate that indirect block is held */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_alloc_indirect) + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_alloc_row) /* * Check arguments. */ HDassert(hdr); - HDassert(sec_node && *sec_node); + HDassert(sec_node && old_sec_node); + HDassert(old_sec_node->u.row.row < hdr->man_dtable.max_direct_rows); /* Check for serialized section */ if(old_sec_node->sect_info.state == H5FS_SECT_SERIALIZED) { /* Revive indirect section */ - if(H5HF_sect_indirect_revive(hdr, dxpl_id, old_sec_node) < 0) + if(H5HF_sect_row_revive(hdr, dxpl_id, old_sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTREVIVE, FAIL, "can't revive indirect section") } /* end if */ - /* Compute info about range */ - curr_entry = (old_sec_node->u.indirect.row * hdr->man_dtable.cparam.width) + old_sec_node->u.indirect.col; - /* Get a pointer to the indirect block covering the section */ - iblock = old_sec_node->u.indirect.iblock; + if(NULL == (iblock = H5HF_sect_row_get_iblock(old_sec_node))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't retrieve indirect block for row section") #ifdef QAK -HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry); HDfprintf(stderr, "%s: iblock->addr = %a\n", FUNC, iblock->addr); HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off); HDfprintf(stderr, "%s: iblock->parent = %p\n", FUNC, iblock->parent); -HDfprintf(stderr, "%s: iblock->ents[curr_entry].addr = %a\n", FUNC, iblock->ents[curr_entry].addr); -HDfprintf(stderr, "%s: old_sec_node->u.indirect.indir_nrows = %u\n", FUNC, old_sec_node->u.indirect.indir_nrows); -HDfprintf(stderr, "%s: old_sec_node->u.indirect.num_entries = %u\n", FUNC, old_sec_node->u.indirect.num_entries); +HDfprintf(stderr, "%s: iblock->rc = %Zu\n", FUNC, iblock->rc); #endif /* QAK */ - /* Check if indirect block for this indirect section has already been created */ - if(H5F_addr_defined(iblock->ents[curr_entry].addr)) { - /* Look up existing child indirect block */ - child_iblock_addr = iblock->ents[curr_entry].addr; - if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_iblock_addr, old_sec_node->u.indirect.indir_nrows, iblock, curr_entry, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") - } /* end if */ - else { - /* Create child indirect block */ - if(H5HF_man_iblock_create(hdr, dxpl_id, iblock, curr_entry, old_sec_node->u.indirect.indir_nrows, old_sec_node->u.indirect.indir_nrows, &child_iblock_addr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap indirect block") - - /* Lock new child indirect block */ - if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_iblock_addr, old_sec_node->u.indirect.indir_nrows, iblock, curr_entry, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") -#ifdef QAK -HDfprintf(stderr, "%s: child_iblock->child_free_space = %Hu\n", FUNC, child_iblock->child_free_space); -#endif /* QAK */ - } /* end else */ + /* Hold indirect block in memory, until direct block can point to it */ + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + iblock_held = TRUE; - /* Compute entry for new direct block in child indirect block */ - dblock_entry = old_sec_node->u.indirect.indir_row * hdr->man_dtable.cparam.width; + /* Reduce (& possibly re-add) 'row' section */ + if(H5HF_sect_row_reduce(hdr, dxpl_id, old_sec_node, &dblock_entry) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce row section node") - /* Create direct block of correct size */ - /* (creates a 'single' free space section also) */ + /* Create direct block & single section */ #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_info.addr = %a\n", FUNC, old_sec_node->sect_info.addr); -HDfprintf(stderr, "%s: dblock_entry = %u\n", FUNC, dblock_entry); +HDfprintf(stderr, "%s: Allocating direct block, 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) + if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, dblock_entry, NULL, sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block") - /* Create "range" section for other direct blocks in row of child indirect block */ - if(H5HF_sect_range_add(hdr, dxpl_id, (child_iblock->block_off + hdr->man_dtable.row_block_off[old_sec_node->u.indirect.indir_row] - + hdr->man_dtable.row_block_size[old_sec_node->u.indirect.indir_row]), - old_sec_node->sect_info.size, child_iblock, old_sec_node->u.indirect.indir_row, - 1, hdr->man_dtable.cparam.width - 1) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create range section for indirect block's free space") - - /* Reduce (& possibly re-add) 'indirect' section */ - if(H5HF_sect_indirect_reduce(hdr, dxpl_id, old_sec_node) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce indirect section node") - - /* Release the child indirect block (marked as dirty) */ - if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock_addr, child_iblock, H5AC__DIRTIED_FLAG) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") - - /* Point 'sec_node' at new direct block section node */ - *sec_node = dblock_sec_node; - done: + /* Release hold on indirect block */ + if(iblock_held) + if(H5HF_iblock_decr(iblock) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't decrement reference count on shared indirect block") + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_man_iblock_alloc_indirect() */ +} /* end H5HF_man_iblock_alloc_row() */ /*------------------------------------------------------------------------- @@ -1109,9 +1007,6 @@ 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) @@ -1134,12 +1029,6 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, * removed from the heap when it's ref. count drops to zero and the * metadata cache calls the indirect block destructor) */ - /* (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 */ @@ -1195,3 +1084,34 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_iblock_detach() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iblock_entry_addr + * + * Purpose: Retrieve the address of an indirect block's child + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * July 10 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iblock_entry_addr(H5HF_indirect_t *iblock, unsigned entry, haddr_t *child_addr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iblock_entry_addr) + + /* + * Check arguments. + */ + HDassert(iblock); + HDassert(child_addr); + + /* Reset address of entry */ + *child_addr = iblock->ents[entry].addr; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_man_iblock_entry_addr() */ + |