[svn-r12598] Description:

- Migrate "direct block location" routine from H5HFman.c to H5HFdblock.c,
        which is a more appropriate location
    - Optimize performance of heap code by taking advantage of pinned
        indirect blocks and use them without putting a metadata cache
        protect/unprotect pair around them.
    - Other minor compiler warning cleanups and optimizations...

Tested On:
    FreeBSD/32 4.11 (sleipnir)
    Linux/64 2.4 (mir)
    Solaris/64 2.9 (shanti)
This commit is contained in:
Quincey Koziol 2006-08-18 21:42:18 -05:00
parent c83c6dd945
commit 5a7ef381b2
11 changed files with 475 additions and 190 deletions

View File

@ -680,6 +680,9 @@ HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr);
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/* Check for free space manager for heap */
/* (must occur before attempting to delete the heap, so indirect blocks
* will get unpinned)
*/
if(H5F_addr_defined(hdr->fs_addr)) {
#ifdef QAK
HDfprintf(stderr, "%s: hdr->fs_addr = %a\n", FUNC, hdr->fs_addr);

View File

@ -1164,6 +1164,20 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add
#endif /* QAK */
} /* end for */
/* Check if we have any indirect block children */
if(iblock->nrows > hdr->man_dtable.max_direct_rows) {
unsigned indir_rows; /* Number of indirect rows in this indirect block */
/* Compute the number of indirect rows for this indirect block */
indir_rows = iblock->nrows - hdr->man_dtable.max_direct_rows;
/* Allocate & initialize child indirect block pointer array */
if(NULL == (iblock->child_iblocks = H5FL_SEQ_CALLOC(H5HF_indirect_ptr_t, (size_t)(indir_rows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block entries")
} /* end if */
else
iblock->child_iblocks = NULL;
/* Sanity checks */
HDassert((size_t)(p - buf) == iblock->size);
HDassert(iblock->nchildren); /* indirect blocks w/no children should have been deleted */
@ -1372,6 +1386,8 @@ HDfprintf(stderr, "%s: Destroying indirect block\n", FUNC);
H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents);
if(iblock->filt_ents)
H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents);
if(iblock->child_iblocks)
H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks);
/* Free fractal heap indirect block info */
H5FL_FREE(H5HF_indirect_t, iblock);

View File

@ -508,6 +508,7 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
{
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 */
char temp_str[64]; /* Temporary string, for formatting */
size_t u, v; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@ -532,9 +533,9 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
/*
* Load the heap direct block
* Load the heap indirect block
*/
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, addr, nrows, NULL, 0, H5AC_READ)))
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 opening message */
@ -604,7 +605,7 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
"<none>");
done:
if(iblock && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, iblock, H5AC__NO_FLAGS_SET) < 0)
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")
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")

View File

@ -489,6 +489,124 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_protect() */
/*-------------------------------------------------------------------------
* Function: H5HF_man_dblock_locate
*
* Purpose: Locate a direct block in a managed heap
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* May 8 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_man_dblock_locate(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t obj_off,
H5HF_indirect_t **ret_iblock, unsigned *ret_entry, hbool_t *ret_did_protect,
H5AC_protect_t rw)
{
haddr_t iblock_addr; /* Indirect block's address */
H5HF_indirect_t *iblock; /* Pointer to indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
unsigned row, col; /* Row & column for object's block */
unsigned entry; /* Entry of block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_locate)
#ifdef QAK
HDfprintf(stderr, "%s: obj_off = %Hu\n", FUNC, obj_off);
#endif /* QAK */
/*
* Check arguments.
*/
HDassert(hdr);
HDassert(hdr->man_dtable.curr_root_rows); /* Only works for heaps with indirect root block */
HDassert(ret_iblock);
HDassert(ret_did_protect);
/* Look up row & column for object */
if(H5HF_dtable_lookup(&hdr->man_dtable, obj_off, &row, &col) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
#ifdef QAK
HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
#endif /* QAK */
/* Set initial indirect block info */
iblock_addr = hdr->man_dtable.table_addr;
#ifdef QAK
HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
#endif /* QAK */
/* Lock root indirect block */
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, FALSE, rw, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Check for indirect block row */
while(row >= hdr->man_dtable.max_direct_rows) {
H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */
hbool_t new_did_protect; /* Whether we protected the indirect block or not */
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;
/* Compute indirect block's entry */
entry = (row * hdr->man_dtable.cparam.width) + col;
#ifdef QAK
HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry);
#endif /* QAK */
/* Locate child indirect block */
iblock_addr = iblock->ents[entry].addr;
/* Check if we need to (re-)create the child indirect block */
if(!H5F_addr_defined(iblock_addr)) {
if(H5HF_man_iblock_create(hdr, dxpl_id, iblock, entry, nrows, nrows, &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 child indirect block */
if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, nrows, iblock, entry, FALSE, rw, &new_did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Release the current indirect block */
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, cache_flags, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
/* Switch variables to use new indirect block */
iblock = new_iblock;
did_protect = new_did_protect;
#ifdef QAK
HDfprintf(stderr, "%s: iblock->addr = %a\n", FUNC, iblock->addr);
HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
#endif /* QAK */
/* Look up row & column in new indirect block for object */
if(H5HF_dtable_lookup(&hdr->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
#ifdef QAK
HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
#endif /* QAK */
} /* end while */
/* Set return parameters */
if(ret_entry)
*ret_entry = (row * hdr->man_dtable.cparam.width) + col;
*ret_iblock = iblock;
*ret_did_protect = did_protect;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_locate() */
/*-------------------------------------------------------------------------
* Function: H5HF_man_dblock_delete

View File

@ -1086,6 +1086,7 @@ HDfprintf(stderr, "%s: child_entry = %u\n", FUNC, child_entry);
} /* end if */
else {
H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
haddr_t new_iblock_addr; /* New indirect block's address */
#ifdef QAK
@ -1096,10 +1097,10 @@ HDfprintf(stderr, "%s: Allocating new child indirect block\n", FUNC);
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap indirect block")
/* Lock new indirect block */
if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, child_nrows, iblock, next_entry, H5AC_WRITE)))
if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, child_nrows, iblock, next_entry, FALSE, H5AC_WRITE, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Move iterator down one level */
/* Move iterator down one level (pins indirect block) */
if(H5HF_man_iter_down(&hdr->next_block, new_iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTNEXT, FAIL, "unable to advance current block iterator location")
@ -1119,7 +1120,7 @@ HDfprintf(stderr, "%s: Skipping rows in new child indirect block - new_entry = %
} /* end if */
/* Unprotect child indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock->addr, new_iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(new_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
} /* end else */
@ -1321,8 +1322,9 @@ 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 */
H5HF_indirect_t *child_iblock; /* Pointer to child indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
unsigned child_nrows; /* # of rows in child block */
#ifdef QAK
HDfprintf(stderr, "%s: Walking down into child block\n", FUNC);
@ -1331,7 +1333,7 @@ HDfprintf(stderr, "%s: Walking down into child block\n", FUNC);
child_nrows = H5HF_dtable_size_to_rows(&hdr->man_dtable, hdr->man_dtable.row_block_size[row]);
/* Lock child indirect block */
if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock->ents[curr_entry].addr, child_nrows, iblock, curr_entry, H5AC_WRITE)))
if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock->ents[curr_entry].addr, child_nrows, iblock, curr_entry, FALSE, H5AC_WRITE, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Set the current location of the iterator */
@ -1352,7 +1354,7 @@ 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)
if(H5HF_man_iblock_unprotect(child_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
/* Note that we walked down */

View File

@ -56,6 +56,8 @@
/********************/
/* Local Prototypes */
/********************/
static herr_t H5HF_iblock_pin(H5HF_indirect_t *iblock);
static herr_t H5HF_iblock_unpin(H5HF_indirect_t *iblock);
static herr_t H5HF_man_iblock_root_halve(H5HF_indirect_t *root_iblock, hid_t dxpl_id);
static herr_t H5HF_man_iblock_root_revert(H5HF_indirect_t *root_iblock, hid_t dxpl_id);
@ -73,6 +75,9 @@ H5FL_SEQ_DEFINE(H5HF_indirect_ent_t);
/* Declare a free list to manage the H5HF_indirect_filt_ent_t sequence information */
H5FL_SEQ_DEFINE(H5HF_indirect_filt_ent_t);
/* Declare a free list to manage the H5HF_indirect_t * sequence information */
H5FL_SEQ_DEFINE(H5HF_indirect_ptr_t);
/*****************************/
/* Library Private Variables */
@ -84,6 +89,122 @@ H5FL_SEQ_DEFINE(H5HF_indirect_filt_ent_t);
/*******************/
/*-------------------------------------------------------------------------
* Function: H5HF_iblock_pin
*
* Purpose: Pin an indirect block in memory
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Aug 17 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
H5HF_iblock_pin(H5HF_indirect_t *iblock)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_iblock_pin)
/* Sanity checks */
HDassert(iblock);
/* Mark block as un-evictable */
if(H5AC_pin_protected_entry(iblock->hdr->f, iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTPIN, FAIL, "unable to pin fractal heap indirect block")
/* If this indirect block has a parent, update it's child iblock pointer */
if(iblock->parent) {
H5HF_indirect_t *par_iblock = iblock->parent; /* Parent indirect block */
unsigned indir_idx; /* Index in parent's child iblock pointer array */
/* Sanity check */
HDassert(par_iblock->child_iblocks);
HDassert(iblock->par_entry >= (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width));
/* Compute index in parent's child iblock pointer array */
indir_idx = iblock->par_entry - (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width);
/* Set pointer to pinned indirect block in parent */
HDassert(par_iblock->child_iblocks[indir_idx] == NULL);
par_iblock->child_iblocks[indir_idx] = iblock;
} /* end if */
else {
/* Check for pinning the root indirect block */
if(iblock->block_off == 0) {
HDassert(iblock->hdr->root_iblock == NULL);
iblock->hdr->root_iblock = iblock;
} /* end if */
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_iblock_pin() */
/*-------------------------------------------------------------------------
* Function: H5HF_iblock_unpin
*
* Purpose: Unpin an indirect block in the metadata cache
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Aug 17 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
H5HF_iblock_unpin(H5HF_indirect_t *iblock)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_iblock_unpin)
/* Sanity check */
HDassert(iblock);
/* If this indirect block has a parent, reset it's child iblock pointer */
if(iblock->parent) {
H5HF_indirect_t *par_iblock = iblock->parent; /* Parent indirect block */
unsigned indir_idx; /* Index in parent's child iblock pointer array */
/* Sanity check */
HDassert(par_iblock->child_iblocks);
HDassert(iblock->par_entry >= (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width));
/* Compute index in parent's child iblock pointer array */
indir_idx = iblock->par_entry - (iblock->hdr->man_dtable.max_direct_rows
* iblock->hdr->man_dtable.cparam.width);
/* Reset pointer to pinned child indirect block in parent */
HDassert(par_iblock->child_iblocks[indir_idx]);
par_iblock->child_iblocks[indir_idx] = NULL;
} /* end if */
else {
/* Check for unpinning the root indirect block */
if(iblock->block_off == 0) {
HDassert(iblock->hdr->root_iblock);
iblock->hdr->root_iblock = NULL;
} /* end if */
} /* end if */
/* Mark block as evictable again */
if(H5AC_unpin_entry(iblock->hdr->f, iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_iblock_unpin() */
/*-------------------------------------------------------------------------
* Function: H5HF_iblock_incr
@ -105,12 +226,13 @@ H5HF_iblock_incr(H5HF_indirect_t *iblock)
FUNC_ENTER_NOAPI_NOINIT(H5HF_iblock_incr)
/* Sanity check */
/* Sanity checks */
HDassert(iblock);
HDassert(iblock->block_off == 0 || iblock->parent);
/* Mark block as un-evictable when a child block is depending on it */
if(iblock->rc == 0)
if(H5AC_pin_protected_entry(iblock->hdr->f, iblock) < 0)
if(H5HF_iblock_pin(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTPIN, FAIL, "unable to pin fractal heap indirect block")
/* Increment reference count on shared indirect block */
@ -160,7 +282,7 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
#ifdef QAK
HDfprintf(stderr, "%s: indirect block ref. count at zero, iblock->addr = %a\n", FUNC, iblock->addr);
#endif /* QAK */
if(H5AC_unpin_entry(iblock->hdr->f, iblock) < 0)
if(H5HF_iblock_unpin(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block")
if(iblock->nchildren == 0) {
@ -257,6 +379,7 @@ H5HF_man_iblock_root_create(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_si
haddr_t iblock_addr; /* Indirect block's address */
hsize_t acc_dblock_free; /* Accumulated free space in direct blocks */
hbool_t have_direct_block; /* Flag to indicate a direct block already exists */
hbool_t did_protect; /* Whether we protected the indirect block or not */
unsigned nrows; /* Number of rows for root indirect block */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@ -297,7 +420,7 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
/* Move current direct block (used as root) into new indirect block */
/* Lock new indirect block */
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, nrows, NULL, 0, H5AC_WRITE)))
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, nrows, NULL, 0, FALSE, H5AC_WRITE, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Check if there's already a direct block as root) */
@ -341,7 +464,7 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
/* Unprotect root indirect block (it's pinned by the iterator though) */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, H5AC__DIRTIED_FLAG) < 0)
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__DIRTIED_FLAG, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;
@ -504,7 +627,6 @@ HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, ib
/* Compute the number of direct rows for this indirect block */
dir_rows = MIN(iblock->nrows, hdr->man_dtable.max_direct_rows);
HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows);
HDassert(dir_rows > old_nrows);
/* Re-allocate filtered direct block entry array */
@ -518,6 +640,29 @@ HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows);
} /* end for */
} /* end if */
/* Check for needing to re-allocate child iblock pointer array */
if(iblock->nrows > hdr->man_dtable.max_direct_rows) {
unsigned indir_rows; /* Number of indirect rows in this indirect block */
unsigned old_indir_rows; /* Previous number of indirect rows in this indirect block */
/* Compute the number of direct rows for this indirect block */
indir_rows = iblock->nrows - hdr->man_dtable.max_direct_rows;
/* Re-allocate child indirect block array */
if(NULL == (iblock->child_iblocks = H5FL_SEQ_REALLOC(H5HF_indirect_ptr_t, iblock->child_iblocks, (size_t)(indir_rows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries")
/* Compute the previous # of indirect rows in this block */
if(old_nrows < hdr->man_dtable.max_direct_rows)
old_indir_rows = 0;
else
old_indir_rows = old_nrows - hdr->man_dtable.max_direct_rows;
/* Initialize new entries allocated */
for(u = (old_indir_rows * hdr->man_dtable.cparam.width); u < (indir_rows * hdr->man_dtable.cparam.width); u++)
iblock->child_iblocks[u] = NULL;
} /* end if */
/* Mark indirect block as dirty */
if(H5HF_iblock_dirty(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
@ -560,6 +705,7 @@ H5HF_man_iblock_root_halve(H5HF_indirect_t *iblock, hid_t dxpl_id)
haddr_t new_addr; /* New address of indirect block */
hsize_t acc_dblock_free; /* Accumulated free space in direct blocks */
unsigned max_child_row; /* Row for max. child entry */
unsigned old_nrows; /* Old # of rows */
unsigned new_nrows; /* New # of rows */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@ -604,6 +750,7 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
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 */
old_nrows = iblock->nrows;
iblock->nrows = new_nrows;
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
@ -622,7 +769,7 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr);
} /* end if */
/* Re-allocate child block entry array */
if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * hdr->man_dtable.cparam.width))))
if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries")
/* Check for needing to re-allocate filtered entry array */
@ -632,6 +779,23 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr);
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries")
} /* end if */
/* Check for needing to re-allocate child iblock pointer array */
if(old_nrows > hdr->man_dtable.max_direct_rows) {
/* Check for shrinking away child iblock pointer array */
if(iblock->nrows > hdr->man_dtable.max_direct_rows) {
unsigned indir_rows; /* Number of indirect rows in this indirect block */
/* Compute the number of direct rows for this indirect block */
indir_rows = iblock->nrows - hdr->man_dtable.max_direct_rows;
/* Re-allocate child indirect block array */
if(NULL == (iblock->child_iblocks = H5FL_SEQ_REALLOC(H5HF_indirect_ptr_t, iblock->child_iblocks, (size_t)(indir_rows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries")
} /* end if */
else
iblock->child_iblocks = H5FL_SEQ_FREE(H5HF_indirect_ptr_t, iblock->child_iblocks);
} /* end if */
/* Mark indirect block as dirty */
if(H5HF_iblock_dirty(iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
@ -883,6 +1047,20 @@ HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows);
else
iblock->filt_ents = NULL;
/* Check if we have any indirect block children */
if(iblock->nrows > hdr->man_dtable.max_direct_rows) {
unsigned indir_rows; /* Number of indirect rows in this indirect block */
/* Compute the number of indirect rows for this indirect block */
indir_rows = iblock->nrows - hdr->man_dtable.max_direct_rows;
/* Allocate & initialize child indirect block pointer array */
if(NULL == (iblock->child_iblocks = H5FL_SEQ_CALLOC(H5HF_indirect_ptr_t, (size_t)(indir_rows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries")
} /* end if */
else
iblock->child_iblocks = NULL;
/* Allocate space for the indirect block on disk */
if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
@ -909,7 +1087,7 @@ HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows);
iblock->nchildren = 0;
iblock->max_child = 0;
/* Cache the new fractal heap header */
/* Cache the new indirect block */
if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, iblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap indirect block to cache")
@ -926,7 +1104,6 @@ done:
* Function: H5HF_man_iblock_protect
*
* Purpose: Convenience wrapper around H5AC_protect on a indirect block
* (Use H5AC_unprotect to unprotect it for now)
*
* Return: Pointer to indirect block on success, NULL on failure
*
@ -939,10 +1116,11 @@ done:
H5HF_indirect_t *
H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
unsigned iblock_nrows, H5HF_indirect_t *par_iblock, unsigned par_entry,
H5AC_protect_t rw)
hbool_t must_protect, H5AC_protect_t rw, hbool_t *did_protect)
{
H5HF_parent_t par_info; /* Parent info for loading block */
H5HF_indirect_t *iblock; /* Indirect block from cache */
H5HF_indirect_t *iblock = NULL; /* Indirect block from cache */
hbool_t should_protect = FALSE; /* Whether we should protect the indirect block or not */
H5HF_indirect_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_protect)
@ -956,15 +1134,57 @@ HDfprintf(stderr, "%s: iblock_addr = %a, iblock_nrows = %u\n", FUNC, iblock_addr
HDassert(hdr);
HDassert(H5F_addr_defined(iblock_addr));
HDassert(iblock_nrows > 0);
HDassert(did_protect);
/* Set up parent info */
par_info.hdr = hdr;
par_info.iblock = par_iblock;
par_info.entry = par_entry;
/* Check if we are allow to use existing pinned iblock pointer */
if(!must_protect) {
/* Check for this block already being pinned */
if(par_iblock) {
unsigned indir_idx; /* Index in parent's child iblock pointer array */
/* Protect the indirect block */
if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, &par_info, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
/* Sanity check */
HDassert(par_iblock->child_iblocks);
HDassert(par_entry >= (hdr->man_dtable.max_direct_rows
* hdr->man_dtable.cparam.width));
/* Compute index in parent's child iblock pointer array */
indir_idx = par_entry - (hdr->man_dtable.max_direct_rows
* hdr->man_dtable.cparam.width);
/* Check for pointer to pinned indirect block in parent */
if(par_iblock->child_iblocks[indir_idx])
iblock = par_iblock->child_iblocks[indir_idx];
else
should_protect = TRUE;
} /* end if */
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)
iblock = hdr->root_iblock;
else
should_protect = TRUE;
} /* end if */
else
should_protect = TRUE;
} /* end else */
} /* end if */
/* Check for protecting indirect block */
if(must_protect || should_protect) {
/* Set up parent info */
par_info.hdr = hdr;
par_info.iblock = par_iblock;
par_info.entry = par_entry;
/* Protect the indirect block */
if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, &par_info, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
*did_protect = TRUE;
} /* end if */
else
*did_protect = FALSE;
/* Set the return value */
ret_value = iblock;
@ -973,6 +1193,45 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iblock_protect() */
/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_unprotect
*
* Purpose: Convenience wrapper around H5AC_unprotect on a indirect block
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@hdfgroup.org
* Aug 17 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_man_iblock_unprotect(H5HF_indirect_t *iblock, hid_t dxpl_id,
unsigned cache_flags, hbool_t did_protect)
{
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_unprotect)
/*
* Check arguments.
*/
HDassert(iblock);
/* Check if we previously protected this indirect block */
/* (as opposed to using an existing pointer to a pinned child indirect block) */
if(did_protect) {
/* 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")
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iblock_unprotect() */
/*-------------------------------------------------------------------------
* Function: H5HF_man_iblock_attach
@ -1209,6 +1468,7 @@ H5HF_man_iblock_delete(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr,
H5HF_indirect_t *iblock; /* Pointer to indirect block */
unsigned row, col; /* Current row & column in indirect block */
unsigned entry; /* Current entry in row */
hbool_t did_protect; /* Whether we protected the indirect block or not */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_delete)
@ -1224,8 +1484,10 @@ HDfprintf(stderr, "%s: iblock_addr = %a, iblock_nrows = %u\n", FUNC, iblock_addr
HDassert(iblock_nrows > 0);
/* Lock indirect block */
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, iblock_nrows, par_iblock, par_entry, H5AC_WRITE)))
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, iblock_nrows, par_iblock, par_entry, TRUE, H5AC_WRITE, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
HDassert(iblock->nchildren > 0);
HDassert(did_protect == TRUE);
/* Iterate over rows in this indirect block */
entry = 0;
@ -1277,7 +1539,7 @@ HDfprintf(stderr, "%s: iblock_addr = %a, iblock_nrows = %u\n", FUNC, iblock_addr
#endif /* NDEBUG */
/* Finished deleting indirect block in metadata cache */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0)
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG, did_protect) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;

View File

@ -169,6 +169,8 @@ HDfprintf(stderr, "%s: offset = %Hu\n", FUNC, offset);
*/
do {
hbool_t did_protect; /* Whether we protected the indirect block or not */
/* Walk down the rows in the doubling table until we've found the correct row for the next block */
for(row = 0; row < hdr->man_dtable.max_root_rows; row++)
if((offset >= hdr->man_dtable.row_block_off[row]) &&
@ -224,7 +226,7 @@ HDfprintf(stderr, "%s: biter->curr->entry = %u\n", FUNC, biter->curr->entry);
} /* end else */
/* Load indirect block for this context location */
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, iblock_nrows, iblock_parent, iblock_par_entry, H5AC_WRITE)))
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, iblock_nrows, iblock_parent, iblock_par_entry, FALSE, H5AC_WRITE, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Make indirect block the context for the current location */
@ -235,7 +237,7 @@ HDfprintf(stderr, "%s: biter->curr->entry = %u\n", FUNC, biter->curr->entry);
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared 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(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;

View File

@ -74,136 +74,6 @@
/*******************/
/*-------------------------------------------------------------------------
* Function: H5HF_man_locate_block
*
* Purpose: Locate a block in a managed heap
*
* Return: SUCCEED/FAIL
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
* May 8 2006
*
*-------------------------------------------------------------------------
*/
herr_t
H5HF_man_locate_block(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t obj_off,
hbool_t locate_indirect,
H5HF_indirect_t **ret_iblock, unsigned *ret_entry,
H5AC_protect_t rw)
{
haddr_t iblock_addr; /* Indirect block's address */
H5HF_indirect_t *iblock; /* Pointer to indirect block */
unsigned bot_row, top_row; /* Bottom & top acceptable rows */
unsigned row, col; /* Row & column for object's block */
unsigned entry; /* Entry of block */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_locate_block)
#ifdef QAK
HDfprintf(stderr, "%s: obj_off = %Hu\n", FUNC, obj_off);
#endif /* QAK */
/*
* Check arguments.
*/
HDassert(hdr);
HDassert(hdr->man_dtable.curr_root_rows); /* Only works for heaps with indirect root block */
/* Set up target bottom & top rows */
if(locate_indirect) {
bot_row = hdr->man_dtable.max_direct_rows;
top_row = hdr->man_dtable.max_direct_rows + H5V_log2_of2(hdr->man_dtable.cparam.width);
} /* end if */
else {
bot_row = 0;
top_row = hdr->man_dtable.max_direct_rows - 1;
} /* end else */
#ifdef QAK
HDfprintf(stderr, "%s: bot_row = %u, top_row = %u\n", FUNC, bot_row, top_row);
#endif /* QAK */
/* Look up row & column for object */
if(H5HF_dtable_lookup(&hdr->man_dtable, obj_off, &row, &col) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
#ifdef QAK
HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
#endif /* QAK */
/* Set initial indirect block info */
iblock_addr = hdr->man_dtable.table_addr;
#ifdef QAK
HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
#endif /* QAK */
/* Lock root indirect block */
if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, rw)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Check for indirect block row */
while(row < bot_row || row > top_row) {
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;
/* Compute indirect block's entry */
entry = (row * hdr->man_dtable.cparam.width) + col;
#ifdef QAK
HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry);
#endif /* QAK */
/* 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, cache_flags) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
/* Switch variables to use new indirect block */
iblock = new_iblock;
iblock_addr = new_iblock_addr;
#ifdef QAK
HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
#endif /* QAK */
/* Look up row & column in new indirect block for object */
if(H5HF_dtable_lookup(&hdr->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
#ifdef QAK
HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
#endif /* QAK */
} /* end while */
/* Set return parameters */
if(ret_entry)
*ret_entry = (row * hdr->man_dtable.cparam.width) + col;
*ret_iblock = iblock;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_locate_block() */
/*-------------------------------------------------------------------------
* Function: H5HF_man_insert
@ -316,10 +186,6 @@ HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
if(H5HF_sect_single_reduce(hdr, dxpl_id, sec_node, obj_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce single section node")
/* Reduce space available in heap */
if(H5HF_hdr_adj_free(hdr, -(ssize_t)obj_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for heap")
/* Encode the object in the block */
{
uint8_t *p; /* Temporary pointer to obj info in block */
@ -347,9 +213,9 @@ HDfprintf(stderr, "%s: obj_off = %Hu, obj_len = %Zu\n", FUNC, (dblock->block_off
/* Update statistics about heap */
hdr->man_nobjs++;
/* Mark heap header as modified */
if(H5HF_hdr_dirty(hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
/* Reduce space available in heap (marks header dirty) */
if(H5HF_hdr_adj_free(hdr, -(ssize_t)obj_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for heap")
done:
/* Release the direct block (marked as dirty) */
@ -418,10 +284,11 @@ HDfprintf(stderr, "%s: obj_off = %Hu, obj_len = %Zu\n", FUNC, obj_off, obj_len);
} /* end if */
else {
H5HF_indirect_t *iblock; /* Pointer to indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
unsigned entry; /* Entry of block */
/* Look up indirect block containing direct block */
if(H5HF_man_locate_block(hdr, dxpl_id, obj_off, FALSE, &iblock, &entry, H5AC_READ) < 0)
if(H5HF_man_dblock_locate(hdr, dxpl_id, obj_off, &iblock, &entry, &did_protect, H5AC_READ) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
#ifdef QAK
HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
@ -436,7 +303,7 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;
} /* end else */
@ -535,13 +402,14 @@ HDfprintf(stderr, "%s: direct root block\n", FUNC);
} /* end if */
else {
H5HF_indirect_t *iblock; /* Pointer to indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
unsigned entry; /* Entry of block */
#ifdef QAK
HDfprintf(stderr, "%s: indirect root block\n", FUNC);
#endif /* QAK */
/* Look up indirect block containing direct block */
if(H5HF_man_locate_block(hdr, dxpl_id, obj_off, FALSE, &iblock, &entry, H5AC_WRITE) < 0)
if(H5HF_man_dblock_locate(hdr, dxpl_id, obj_off, &iblock, &entry, &did_protect, H5AC_WRITE) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
#ifdef QAK
HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
@ -554,7 +422,7 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
/* Check for offset of invalid direct block */
if(!H5F_addr_defined(dblock_addr)) {
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, FAIL, "fractal heap ID not in allocated direct block")
@ -563,14 +431,14 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
/* Lock direct block */
if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, iblock, entry, H5AC_WRITE))) {
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
} /* end if */
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;
} /* end else */
@ -606,7 +474,7 @@ HDfprintf(stderr, "%s: blk_off = %Zu\n", FUNC, blk_off);
/* Update statistics about heap */
hdr->man_nobjs--;
/* Reduce space available in heap */
/* Increase space available in heap (marks header dirty) */
if(H5HF_hdr_adj_free(hdr, (ssize_t)obj_len) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for heap")

View File

@ -346,6 +346,7 @@ typedef struct H5HF_hdr_t {
H5F_t *f; /* Pointer to file for heap */
size_t sizeof_size; /* Size of file sizes */
size_t sizeof_addr; /* Size of file addresses */
struct H5HF_indirect_t *root_iblock; /* Pointer to pinned root indirect block */
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 */
hsize_t huge_max_id; /* Max. 'huge' heap ID before rolling 'huge' heap IDs over */
@ -376,16 +377,17 @@ struct H5HF_indirect_t {
H5AC_info_t cache_info;
/* Internal heap information (not stored) */
size_t rc; /* Reference count of child blocks */
size_t rc; /* Reference count of objects using this block */
H5HF_hdr_t *hdr; /* Shared heap header info */
struct H5HF_indirect_t *parent; /* Shared parent indirect block info */
unsigned par_entry; /* Entry in parent's table */
haddr_t addr; /* Address of this indirect block on disk */
size_t size; /* Size of indirect block on disk */
unsigned nrows; /* Total # of rows in indirect block */
unsigned max_rows; /* Max. # of rows in indirect block */
unsigned nchildren; /* Number of child blocks */
unsigned max_child; /* Max. offset used in child entries */
size_t size; /* Size of indirect block on disk */
struct H5HF_indirect_t **child_iblocks; /* Array of pointers to pinned child indirect blocks */
/* Stored values */
hsize_t block_off; /* Offset of the block within the heap's address space */
@ -521,6 +523,10 @@ H5FL_SEQ_EXTERN(H5HF_indirect_ent_t);
/* Declare a free list to manage the H5HF_indirect_filt_ent_t sequence information */
H5FL_SEQ_EXTERN(H5HF_indirect_filt_ent_t);
/* Declare a free list to manage the H5HF_indirect_t * sequence information */
typedef H5HF_indirect_t *H5HF_indirect_ptr_t;
H5FL_SEQ_EXTERN(H5HF_indirect_ptr_t);
/******************************/
/* Package Private Prototypes */
@ -575,8 +581,10 @@ H5_DLL herr_t H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id,
unsigned max_rows, haddr_t *addr_p);
H5_DLL H5HF_indirect_t *H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id,
haddr_t iblock_addr, unsigned iblock_nrows,
H5HF_indirect_t *par_iblock, unsigned par_entry,
H5AC_protect_t rw);
H5HF_indirect_t *par_iblock, unsigned par_entry, hbool_t must_protect,
H5AC_protect_t rw, hbool_t *did_protect);
H5_DLL herr_t H5HF_man_iblock_unprotect(H5HF_indirect_t *iblock, hid_t dxpl_id,
unsigned cache_flags, hbool_t did_protect);
H5_DLL herr_t H5HF_man_iblock_attach(H5HF_indirect_t *iblock, unsigned entry,
haddr_t dblock_addr);
H5_DLL herr_t H5HF_man_iblock_detach(H5HF_indirect_t *iblock, hid_t dxpl_id, unsigned entry);
@ -598,13 +606,13 @@ H5_DLL H5HF_direct_t *H5HF_man_dblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id,
haddr_t dblock_addr, size_t dblock_size,
H5HF_indirect_t *par_iblock, unsigned par_entry,
H5AC_protect_t rw);
H5_DLL herr_t H5HF_man_dblock_locate(H5HF_hdr_t *hdr, hid_t dxpl_id,
hsize_t obj_off, H5HF_indirect_t **par_iblock,
unsigned *par_entry, hbool_t *par_did_protect, H5AC_protect_t rw);
H5_DLL herr_t H5HF_man_dblock_delete(H5F_t *f, hid_t dxpl_id, haddr_t dblock_addr,
hsize_t dblock_size);
/* Managed object routines */
H5_DLL herr_t H5HF_man_locate_block(H5HF_hdr_t *hdr, hid_t dxpl_id,
hsize_t obj_off, hbool_t locate_indirect, H5HF_indirect_t **par_iblock,
unsigned *par_entry, H5AC_protect_t rw);
H5_DLL herr_t H5HF_man_insert(H5HF_hdr_t *fh, hid_t dxpl_id, size_t obj_size,
const void *obj, void *id);
H5_DLL herr_t H5HF_man_read(H5HF_hdr_t *fh, hid_t dxpl_id, const uint8_t *id,

View File

@ -571,8 +571,10 @@ H5HF_sect_single_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
sect->u.single.dblock_size = hdr->man_dtable.cparam.start_block_size;
} /* end if */
else {
hbool_t did_protect; /* Whether we protected the indirect block or not */
/* Look up indirect block containing direct blocks for range */
if(H5HF_man_locate_block(hdr, dxpl_id, sect->sect_info.addr, FALSE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
if(H5HF_man_dblock_locate(hdr, dxpl_id, sect->sect_info.addr, &sec_iblock, &sec_entry, &did_protect, H5AC_READ) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
/* Increment reference count on indirect block that free section is in */
@ -588,7 +590,7 @@ H5HF_sect_single_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
sect->u.single.dblock_size = hdr->man_dtable.row_block_size[sec_entry / hdr->man_dtable.cparam.width];
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, sec_iblock->addr, sec_iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(sec_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
sec_iblock = NULL;
} /* end else */
@ -2585,6 +2587,8 @@ HDfprintf(stderr, "%s: row_entries = %u\n", FUNC, row_entries);
/* Add an indirect section for each indirect block in the row */
for(v = 0; v < row_entries; v++) {
hbool_t did_protect; /* Whether we protected the indirect block or not */
/* Try to get the child section's indirect block, if it's available */
if(sect->sect_info.state == H5FS_SECT_LIVE) {
haddr_t child_iblock_addr; /* Child indirect block's address on disk */
@ -2598,7 +2602,7 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr);
/* If the child indirect block's address is defined, protect it */
if(H5F_addr_defined(child_iblock_addr)) {
if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_iblock_addr, child_nrows, sect->u.indirect.u.iblock, curr_entry, H5AC_WRITE)))
if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_iblock_addr, child_nrows, sect->u.indirect.u.iblock, curr_entry, FALSE, H5AC_WRITE, &did_protect)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
} /* end if */
else
@ -2621,7 +2625,7 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr);
/* If we have a valid child indirect block, release it now */
/* (will be pinned, if rows reference it) */
if(child_iblock)
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock->addr, child_iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(child_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
/* Attach child section to this section */
@ -2821,6 +2825,7 @@ static herr_t
H5HF_sect_indirect_revive_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect)
{
H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
hbool_t did_protect; /* Whether we protected the indirect block or not */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@ -2838,7 +2843,7 @@ H5HF_sect_indirect_revive_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_
HDfprintf(stderr, "%s: sect->sect_info.addr = %a\n", FUNC, sect->sect_info.addr);
HDfprintf(stderr, "%s: sect->u.indirect.u.iblock_off = %Hu\n", FUNC, sect->u.indirect.u.iblock_off);
#endif /* QAK */
if(H5HF_man_locate_block(hdr, dxpl_id, sect->sect_info.addr, FALSE, &sec_iblock, NULL, H5AC_READ) < 0)
if(H5HF_man_dblock_locate(hdr, dxpl_id, sect->sect_info.addr, &sec_iblock, NULL, &did_protect, H5AC_READ) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
/* Increment reference count on indirect block that free section is in */
@ -2853,7 +2858,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.u.iblock_off = %Hu\n", FUNC, sect->u.ind
sect->u.indirect.u.iblock->max_rows;
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, sec_iblock->addr, sec_iblock, H5AC__NO_FLAGS_SET) < 0)
if(H5HF_man_iblock_unprotect(sec_iblock, dxpl_id, H5AC__NO_FLAGS_SET, did_protect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
sec_iblock = NULL;

View File

@ -12488,7 +12488,7 @@ test_filtered_huge(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam
unsigned char obj_type; /* Type of storage for object */
fheap_heap_state_t state; /* State of fractal heap */
unsigned deflate_level; /* Deflation level */
unsigned old_actual_id_len; /* Old actual ID length */
unsigned old_actual_id_len = 0; /* Old actual ID length */
hbool_t huge_ids_direct; /* Are 'huge' objects directly acccessed? */
const char *base_desc = "insert 'huge' object into heap with I/O filters, then remove %s"; /* Test description */