summaryrefslogtreecommitdiffstats
path: root/src/H5HFint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5HFint.c')
-rw-r--r--src/H5HFint.c922
1 files changed, 523 insertions, 399 deletions
diff --git a/src/H5HFint.c b/src/H5HFint.c
index e25ad64..3fee747 100644
--- a/src/H5HFint.c
+++ b/src/H5HFint.c
@@ -76,28 +76,30 @@ struct H5HF_section_free_node_t {
/********************/
/* Doubling table routines */
-static herr_t H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable);
+static herr_t H5HF_dtable_init(H5HF_dtable_t *dtable);
static herr_t H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off,
unsigned *row, unsigned *col);
/* Shared heap header routines */
-static herr_t H5HF_shared_free(void *_shared);
+static herr_t H5HF_hdr_dirty(hid_t dxpl_id, H5HF_t *hdr);
/* Direct block routines */
static herr_t H5HF_dblock_section_node_free_cb(void *item, void UNUSED *key,
void UNUSED *op_data);
-static herr_t H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared,
- hid_t dxpl_id, size_t block_size, hsize_t block_off, haddr_t *addr_p);
-static herr_t H5HF_man_dblock_new(H5RC_t *fh_shared, hid_t dxpl_id,
+static herr_t H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr,
+ H5HF_indirect_t *par_iblock, unsigned par_entry, size_t block_size,
+ hsize_t block_off, haddr_t *addr_p);
+static herr_t H5HF_man_dblock_new(H5HF_t *fh, hid_t dxpl_id,
size_t request);
-static herr_t H5HF_man_dblock_adj_free(H5HF_direct_t *dblock, ssize_t amt);
+static herr_t H5HF_man_dblock_adj_free(hid_t dxpl_id, H5HF_direct_t *dblock, ssize_t amt);
/* Indirect block routines */
static herr_t H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock);
-static H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id,
+static herr_t H5HF_iblock_dirty(hid_t dxpl_id, H5HF_indirect_t *iblock);
+static H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5HF_t *fh, hid_t dxpl_id,
size_t min_dblock_size, haddr_t *addr_p, size_t *entry_p,
size_t *dblock_size);
-static herr_t H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
+static herr_t H5HF_man_iblock_create(H5HF_t *fh, hid_t dxpl_id,
hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p);
/*********************/
@@ -132,9 +134,6 @@ H5FL_SEQ_DEFINE(H5HF_indirect_ent_t);
/* Local Variables */
/*******************/
-/* Declare a free list to manage the H5HF_shared_t struct */
-H5FL_DEFINE_STATIC(H5HF_shared_t);
-
/*-------------------------------------------------------------------------
@@ -151,7 +150,7 @@ H5FL_DEFINE_STATIC(H5HF_shared_t);
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable)
+H5HF_dtable_init(H5HF_dtable_t *dtable)
{
hsize_t tmp_block_size; /* Temporary block size */
size_t u; /* Local index variable */
@@ -162,7 +161,6 @@ H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable)
/*
* Check arguments.
*/
- HDassert(shared);
HDassert(dtable);
/* Compute/cache some values */
@@ -232,25 +230,55 @@ H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off, unsigned *row, unsi
/*-------------------------------------------------------------------------
- * Function: H5HF_shared_alloc
+ * Function: H5HF_dtable_dest
*
- * Purpose: Allocate shared fractal heap info
+ * Purpose: Release information for doubling table
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Feb 27 2006
+ * Mar 27 2006
*
*-------------------------------------------------------------------------
*/
-H5HF_shared_t *
-H5HF_shared_alloc(H5F_t *f)
+herr_t
+H5HF_dtable_dest(H5HF_dtable_t *dtable)
{
- H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
- H5HF_shared_t *ret_value = NULL; /* Return value */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_dtable_dest)
- FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_alloc)
+ /*
+ * Check arguments.
+ */
+ HDassert(dtable);
+
+ /* Free the block size lookup table for the doubling table */
+ H5MM_xfree(dtable->row_block_size);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_dtable_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_alloc
+ *
+ * Purpose: Allocate shared fractal heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 21 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+H5HF_t *
+H5HF_alloc(H5F_t *f)
+{
+ H5HF_t *fh = NULL; /* Shared fractal heap header */
+ H5HF_t *ret_value = NULL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_alloc)
/*
* Check arguments.
@@ -258,95 +286,88 @@ H5HF_shared_alloc(H5F_t *f)
HDassert(f);
/* Allocate space for the shared information */
- if(NULL == (shared = H5FL_CALLOC(H5HF_shared_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared information")
+ if(NULL == (fh = H5FL_CALLOC(H5HF_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header")
/* Set the internal parameters for the heap */
- shared->f = f;
- shared->sizeof_size = H5F_SIZEOF_SIZE(f);
- shared->sizeof_addr = H5F_SIZEOF_ADDR(f);
+ fh->f = f;
+ fh->sizeof_size = H5F_SIZEOF_SIZE(f);
+ fh->sizeof_addr = H5F_SIZEOF_ADDR(f);
/* Set the return value */
- ret_value = shared;
+ ret_value = fh;
done:
if(!ret_value)
- if(shared)
- H5HF_shared_free(shared);
+ if(fh)
+ (void)H5HF_cache_hdr_dest(f, fh);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_shared_alloc() */
+} /* end H5HF_alloc() */
/*-------------------------------------------------------------------------
- * Function: H5HF_shared_own
+ * Function: H5HF_finish_init
*
- * Purpose: Have heap take ownership of the shared info
+ * Purpose: Finish initializing info in shared heap header
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Feb 27 2006
+ * Mar 21 2006
*
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_shared_own(H5HF_t *fh, H5HF_shared_t *shared)
+H5HF_finish_init(H5HF_t *fh)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_own)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_finish_init)
/*
* Check arguments.
*/
HDassert(fh);
- HDassert(shared);
/* Compute/cache some values */
- shared->ref_count_obj = (shared->ref_count_size > 0);
- shared->heap_off_size = H5HF_SIZEOF_OFFSET_BITS(shared->man_dtable.cparam.max_index);
- if(H5HF_dtable_init(shared, &shared->man_dtable) < 0)
+ fh->heap_off_size = H5HF_SIZEOF_OFFSET_BITS(fh->man_dtable.cparam.max_index);
+ if(H5HF_dtable_init(&fh->man_dtable) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize doubling table info")
/* Create the free-list structure for the heap */
- if(NULL == (shared->flist = H5HF_flist_create(shared->man_dtable.cparam.max_direct_size, H5HF_dblock_section_node_free_cb)))
+ if(NULL == (fh->flist = H5HF_flist_create(fh->man_dtable.cparam.max_direct_size, H5HF_dblock_section_node_free_cb)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free list info")
- /* Make shared heap info reference counted */
- if(NULL == (fh->shared = H5RC_create(shared, H5HF_shared_free)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap info")
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_shared_own() */
+} /* end H5HF_finish_init() */
/*-------------------------------------------------------------------------
- * Function: H5HF_shared_create
+ * Function: H5HF_init
*
- * Purpose: Allocate & create shared fractal heap info for new heap
+ * Purpose: Initialize shared fractal heap header for new heap
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Feb 24 2006
+ * Mar 21 2006
*
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam)
+H5HF_init(H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam)
{
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_init)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_init)
/*
* Check arguments.
*/
- HDassert(shared);
HDassert(fh);
HDassert(cparam);
@@ -361,71 +382,33 @@ H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t fh_addr, H5HF_create
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two")
if(cparam->managed.max_direct_size < cparam->standalone_size)
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not large enough to hold all managed blocks")
- if(cparam->managed.max_index > (8 * shared->sizeof_size) || cparam->managed.max_index == 0)
+ if(cparam->managed.max_index > (8 * fh->sizeof_size) || cparam->managed.max_index == 0)
HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two")
#endif /* NDEBUG */
/* Set the creation parameters for the heap */
- shared->heap_addr = fh_addr;
- shared->addrmap = cparam->addrmap;
- shared->standalone_size = cparam->standalone_size;
- shared->ref_count_size = cparam->ref_count_size;
- HDmemcpy(&(shared->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t));
+ fh->heap_addr = fh_addr;
+ fh->addrmap = cparam->addrmap;
+ fh->standalone_size = cparam->standalone_size;
+ HDmemcpy(&(fh->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t));
/* Set root table address */
- shared->man_dtable.table_addr = HADDR_UNDEF;
+ fh->man_dtable.table_addr = HADDR_UNDEF;
/* Note that the shared info is dirty (it's not written to the file yet) */
- shared->dirty = TRUE;
+ fh->dirty = TRUE;
/* Make shared heap info reference counted */
- if(H5HF_shared_own(fh, shared) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap info")
+ if(H5HF_finish_init(fh) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap header")
done:
if(ret_value < 0)
- if(shared)
- H5HF_shared_free(shared);
+ if(fh)
+ (void)H5HF_cache_hdr_dest(NULL, fh);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_shared_init() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_shared_free
- *
- * Purpose: Free shared fractal heap info
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Feb 24 2006
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5HF_shared_free(void *_shared)
-{
- H5HF_shared_t *shared = (H5HF_shared_t *)_shared;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_shared_free)
-
- /* Sanity check */
- HDassert(shared);
-
- /* Free the free list information for the heap */
- if(shared->flist)
- H5HF_flist_free(shared->flist);
-
- /* Free the block size lookup table for the doubling table */
- H5MM_xfree(shared->man_dtable.row_block_size);
-
- /* Free the shared info itself */
- H5FL_FREE(H5HF_shared_t, shared);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5HF_shared_free() */
+} /* end H5HF_init() */
/*-------------------------------------------------------------------------
@@ -444,7 +427,6 @@ H5HF_shared_free(void *_shared)
static herr_t
H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
{
- H5HF_shared_t *shared; /* Pointer to shared heap info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_inc_loc)
@@ -454,10 +436,6 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
*/
HDassert(iblock);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(iblock->shared);
- HDassert(shared);
-
/* Increment block entry */
iblock->next_entry++;
@@ -465,13 +443,14 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
iblock->next_col++;
/* Check for walking off end of column */
- if(iblock->next_col == shared->man_dtable.cparam.width) {
+ if(iblock->next_col == iblock->shared->man_dtable.cparam.width) {
/* Reset column */
iblock->next_col = 0;
/* Increment row & block size */
iblock->next_row++;
- iblock->next_size *= 2;
+ if(iblock->next_row > 1)
+ iblock->next_size *= 2;
/* Check for filling up indirect block */
if(iblock->next_row == iblock->max_rows) {
@@ -480,8 +459,7 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location")
/* Increment location for parent indirect block */
- iblock = H5RC_GET_OBJ(iblock->parent);
- if(H5HF_man_iblock_inc_loc(iblock) < 0)
+ if(H5HF_man_iblock_inc_loc(iblock->parent) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location")
} /* end if */
} /* end if */
@@ -489,10 +467,9 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock)
#ifdef QAK
HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row);
HDfprintf(stderr, "%s: iblock->next_col = %u\n", FUNC, iblock->next_col);
+HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry);
HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size);
#endif /* QAK */
- /* Mark heap header as modified */
- shared->dirty = TRUE;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -513,12 +490,12 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, hid_t dxpl_id,
+H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr, H5HF_indirect_t *par_iblock,
+ unsigned par_entry,
size_t block_size, hsize_t block_off, haddr_t *addr_p)
{
H5HF_direct_free_node_t *node; /* Pointer to free list node for block */
H5HF_section_free_node_t *sec_node; /* Pointer to free list section for block */
- H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_direct_t *dblock = NULL; /* Pointer to direct block */
size_t free_space; /* Free space in new block */
herr_t ret_value = SUCCEED; /* Return value */
@@ -528,8 +505,7 @@ H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, hid_t dxpl_id,
/*
* Check arguments.
*/
- HDassert(par_shared);
- HDassert(par_shared->shared);
+ HDassert(hdr);
HDassert(block_size > 0);
HDassert(addr_p);
@@ -543,26 +519,31 @@ H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, hid_t dxpl_id,
HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t));
/* Share common heap information */
- dblock->shared = par_shared->shared;
- H5RC_INC(dblock->shared);
-
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(dblock->shared);
- HDassert(shared);
+ dblock->shared = hdr;
+ if(H5HF_hdr_incr(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header")
/* Set info for direct block */
#ifdef QAK
HDfprintf(stderr, "%s: size = %Zu, block_off = %Hu\n", FUNC, block_size, block_off);
#endif /* QAK */
- dblock->parent = par_shared->parent;
- if(dblock->parent)
- H5RC_INC(dblock->parent);
- dblock->parent_entry = par_shared->parent_entry;
+ dblock->parent = par_iblock;
+ if(dblock->parent) {
+ if(H5HF_iblock_incr(par_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block")
+ dblock->par_addr = par_iblock->addr;
+ dblock->par_nrows = par_iblock->nrows;
+ } /* end if */
+ else {
+ dblock->par_addr = HADDR_UNDEF;
+ dblock->par_nrows = 0;
+ } /* end else */
+ dblock->par_entry = par_entry;
dblock->size = block_size;
dblock->block_off = block_off;
dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(block_size);
- dblock->free_list_head = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(shared, dblock);
- dblock->blk_free_space = par_shared->parent_free_space;
+ dblock->free_list_head = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock);
+ dblock->blk_free_space = 0; /* temporarily, this is modified later */
free_space = block_size - dblock->free_list_head;
/* Allocate buffer for block */
@@ -593,7 +574,7 @@ HDmemset(dblock->blk, 0, dblock->size);
dblock->free_list->first = node;
/* Allocate space for the header on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)block_size)))
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)block_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block")
/* Create free list section node */
@@ -605,31 +586,32 @@ HDmemset(dblock->blk, 0, dblock->size);
sec_node->block_size = block_size;
sec_node->sect_addr = *addr_p + node->my_offset;
/* (section size is "object size", without the metadata overhead) */
- sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock);
+ sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock);
/* Add new free space to the global list of space */
- if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
+ if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list")
/* Adjust free space to include new block's space */
- if(H5HF_man_dblock_adj_free(dblock, (ssize_t)free_space) < 0)
+ if(H5HF_man_dblock_adj_free(dxpl_id, dblock, (ssize_t)free_space) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for direct block & parents")
- /* Update shared heap info */
- shared->total_size += dblock->size;
- shared->man_size += dblock->size;
+ /* Update shared heap header */
+ hdr->total_size += dblock->size;
+ hdr->man_size += dblock->size;
/* Mark heap header as modified */
- shared->dirty = TRUE;
+ if(H5HF_hdr_dirty(dxpl_id, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
/* Cache the new fractal heap direct block */
- if(H5AC_set(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, *addr_p, dblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, *addr_p, dblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap direct block to cache")
done:
if(ret_value < 0)
if(dblock)
- (void)H5HF_cache_dblock_dest(shared->f, dblock);
+ (void)H5HF_cache_dblock_dest(hdr->f, dblock);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_create() */
@@ -681,7 +663,6 @@ herr_t
H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr)
{
H5HF_direct_free_head_t *head = NULL; /* Pointer to free list head for block */
- H5HF_shared_t *shared; /* Pointer to shared heap info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_build_freelist)
@@ -700,6 +681,7 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr)
if(dblock->free_list_head == 0)
head->first = NULL;
else {
+ H5HF_t *hdr; /* Pointer to shared heap header */
H5HF_section_free_node_t *sec_node; /* Pointer to free list section for block */
H5HF_direct_free_node_t *node = NULL; /* Pointer to free list node for block */
H5HF_direct_free_node_t *prev_node; /* Pointer to previous free list node for block */
@@ -709,8 +691,7 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr)
uint8_t *p; /* Temporary pointer to free node info */
/* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(dblock->shared);
- HDassert(shared);
+ hdr = dblock->shared;
/* Point to first node in free list */
p = dblock->blk + dblock->free_list_head;
@@ -744,10 +725,10 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr)
sec_node->block_size = dblock->size;
sec_node->sect_addr = dblock_addr + node->my_offset;
/* (section size is "object size", without the metadata overhead) */
- sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock);
+ sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock);
/* Add new free space to the global list of space */
- if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
+ if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list")
/* Set up trailing node pointer */
@@ -786,10 +767,10 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr)
sec_node->block_size = dblock->size;
sec_node->sect_addr = dblock_addr + node->my_offset;
/* (section size is "object size", without the metadata overhead) */
- sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock);
+ sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock);
/* Add new free space to the global list of space */
- if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
+ if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list")
/* Update trailing info */
@@ -824,11 +805,12 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_man_dblock_adj_free(H5HF_direct_t *dblock, ssize_t amt)
+H5HF_man_dblock_adj_free(hid_t dxpl_id, H5HF_direct_t *dblock, ssize_t amt)
{
- H5HF_shared_t *shared; /* Shared heap information */
+ H5HF_t *hdr; /* Shared heap information */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_dblock_adj_free)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_adj_free)
#ifdef QAK
HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt);
#endif /* QAK */
@@ -838,9 +820,8 @@ HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt);
*/
HDassert(dblock);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(dblock->shared);
- HDassert(shared);
+ /* Get the pointer to the shared heap header */
+ hdr = dblock->shared;
/* Adjust space available in block */
dblock->blk_free_space += amt;
@@ -850,44 +831,47 @@ HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt);
H5HF_indirect_t *iblock; /* Block's parent */
/* Get the pointer to the shared parent indirect block */
- iblock = H5RC_GET_OBJ(dblock->parent);
- HDassert(iblock);
+ iblock = dblock->parent;
/* Adjust this indirect block's child free space */
#ifdef QAK
HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_free", iblock->child_free_space);
#endif /* QAK */
- iblock->ents[dblock->parent_entry].free_space += amt;
+ iblock->ents[dblock->par_entry].free_space += amt;
iblock->child_free_space += amt;
/* Mark indirect block as dirty */
- iblock->dirty = TRUE;
+ if(H5HF_iblock_dirty(dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
/* Modify the free space in parent block(s) */
while(iblock->parent) {
- size_t parent_entry; /* Entry in parent */
+ size_t par_entry; /* Entry in parent */
/* Get the pointer to the shared parent indirect block */
- parent_entry = iblock->parent_entry;
- iblock = H5RC_GET_OBJ(iblock->parent);
+ par_entry = iblock->par_entry;
+ iblock = iblock->parent;
HDassert(iblock);
/* Adjust this indirect block's child free space */
- iblock->ents[parent_entry].free_space += amt;
+ iblock->ents[par_entry].free_space += amt;
iblock->child_free_space += amt;
/* Mark indirect block as dirty */
- iblock->dirty = TRUE;
+ if(H5HF_iblock_dirty(dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
} /* end while */
} /* end if */
- /* Update shared heap free space info */
- shared->total_man_free += amt;
+ /* Update shared heap free space header */
+ hdr->total_man_free += amt;
/* Mark heap header as modified */
- shared->dirty = TRUE;
+ if(H5HF_hdr_dirty(dxpl_id, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_dblock_adj_free() */
@@ -906,10 +890,8 @@ HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_f
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_man_dblock_new(H5RC_t *fh_shared, hid_t dxpl_id, size_t request)
+H5HF_man_dblock_new(H5HF_t *hdr, hid_t dxpl_id, size_t request)
{
- H5HF_parent_shared_t par_shared; /* Parent shared information */
- H5HF_shared_t *shared; /* Shared heap information */
haddr_t dblock_addr; /* Address of new direct block */
size_t dblock_size; /* Size of new direct block */
size_t min_dblock_size; /* Min. size of direct block to allocate */
@@ -923,52 +905,44 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request);
/*
* Check arguments.
*/
- HDassert(fh_shared);
+ HDassert(hdr);
HDassert(request > 0);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh_shared);
- HDassert(shared);
-
/* Compute the min. size of the direct block needed to fulfill the request */
- if(request < shared->man_dtable.cparam.start_block_size)
- min_dblock_size = shared->man_dtable.cparam.start_block_size;
+ if(request < hdr->man_dtable.cparam.start_block_size)
+ min_dblock_size = hdr->man_dtable.cparam.start_block_size;
else {
min_dblock_size = 2 * H5V_log2_gen((hsize_t)request);
- HDassert(min_dblock_size <= shared->man_dtable.cparam.max_direct_size);
+ HDassert(min_dblock_size <= hdr->man_dtable.cparam.max_direct_size);
} /* end else */
/* Adjust the size of block needed to fulfill request, with overhead */
#ifdef QAK
-HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(shared, shared->man_dtable.cparam.start_block_size));
-HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(shared, shared->man_dtable.cparam.start_block_size));
+HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(hdr, hdr->man_dtable.cparam.start_block_size));
+HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(hdr, hdr->man_dtable.cparam.start_block_size));
#endif /* QAK */
- if((min_dblock_size - request) < (H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(shared, min_dblock_size)
- + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(shared, min_dblock_size)))
+ if((min_dblock_size - request) < (H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(hdr, min_dblock_size)
+ + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(hdr, min_dblock_size)))
min_dblock_size *= 2;
#ifdef QAK
HDfprintf(stderr, "%s: min_dblock_size = %Zu\n", FUNC, min_dblock_size);
#endif /* QAK */
/* Check if this is the first block in the heap */
- if(!H5F_addr_defined(shared->man_dtable.table_addr)) {
+ if(!H5F_addr_defined(hdr->man_dtable.table_addr)) {
/* Create new direct block at corrent location*/
- dblock_size = shared->man_dtable.cparam.start_block_size;
- par_shared.shared = fh_shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = 0;
- if(H5HF_man_dblock_create(&par_shared, dxpl_id, dblock_size, shared->man_dtable.next_dir_block, &dblock_addr) < 0)
+ dblock_size = hdr->man_dtable.cparam.start_block_size;
+ if(H5HF_man_dblock_create(dxpl_id, hdr, NULL, 0, dblock_size, hdr->man_dtable.next_dir_block, &dblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block")
#ifdef QAK
HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
-HDfprintf(stderr, "%s: shared->man_dtable.next_dir_block = %Hu\n", FUNC, shared->man_dtable.next_dir_block);
+HDfprintf(stderr, "%s: hdr->man_dtable.next_dir_block = %Hu\n", FUNC, hdr->man_dtable.next_dir_block);
#endif /* QAK */
/* Point root at new direct block */
- shared->man_dtable.curr_root_rows = 0;
- shared->man_dtable.table_addr = dblock_addr;
+ hdr->man_dtable.curr_root_rows = 0;
+ hdr->man_dtable.table_addr = dblock_addr;
} /* end if */
/* Root entry already exists, go get indirect block for new direct block */
else {
@@ -977,19 +951,16 @@ HDfprintf(stderr, "%s: shared->man_dtable.next_dir_block = %Hu\n", FUNC, shared-
size_t dblock_entry; /* Direct entry for new direct block */
/* Find indirect block with room for block of correct size */
- if(NULL == (iblock = H5HF_man_iblock_place_dblock(fh_shared, dxpl_id, min_dblock_size, &iblock_addr, &dblock_entry, &dblock_size)))
+ if(NULL == (iblock = H5HF_man_iblock_place_dblock(hdr, dxpl_id, min_dblock_size, &iblock_addr, &dblock_entry, &dblock_size)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to locate indirect block with space for direct block")
#ifdef QAK
+HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
HDfprintf(stderr, "%s: dblock_entry = %Zu\n", FUNC, dblock_entry);
HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size);
#endif /* QAK */
/* Create new direct block at corrent location*/
- par_shared.shared = fh_shared;
- par_shared.parent = iblock->self;
- par_shared.parent_entry = dblock_entry;
- par_shared.parent_free_space = 0;
- if(H5HF_man_dblock_create(&par_shared, dxpl_id, dblock_size, shared->man_dtable.next_dir_block, &dblock_addr) < 0)
+ if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, dblock_entry, dblock_size, hdr->man_dtable.next_dir_block, &dblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block")
#ifdef QAK
@@ -1000,16 +971,17 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr);
iblock->ents[dblock_entry].addr = dblock_addr;
/* Mark indirect block as modified */
- iblock->dirty = TRUE;
+ if(H5HF_iblock_dirty(dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty")
/* Release the indirect block (marked as dirty) */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
} /* end else */
- /* Update shared info */
+ /* Update shared header */
/* XXX: This is going to cause problems when we support skipping blocks */
- shared->man_dtable.next_dir_block += dblock_size;
+ hdr->man_dtable.next_dir_block += dblock_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1031,10 +1003,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_man_find(H5RC_t *fh_shared, hid_t dxpl_id, size_t request,
+H5HF_man_find(H5HF_t *fh, hid_t dxpl_id, size_t request,
H5HF_section_free_node_t **sec_node/*out*/)
{
- H5HF_shared_t *shared; /* Shared heap information */
htri_t node_found; /* Whether an existing free list node was found */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1046,16 +1017,12 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request);
/*
* Check arguments.
*/
- HDassert(fh_shared);
+ HDassert(fh);
HDassert(request > 0);
HDassert(sec_node);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh_shared);
- HDassert(shared);
-
/* Look for free space in global free list */
- if((node_found = H5HF_flist_find(shared->flist, request, (void **)sec_node)) < 0)
+ if((node_found = H5HF_flist_find(fh->flist, request, (void **)sec_node)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block")
/* XXX: Make certain we've loaded all the direct blocks in the heap */
@@ -1063,12 +1030,12 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request);
/* If we didn't find a node, go make one big enough to hold the requested block */
if(!node_found) {
/* Allocate direct block big enough to hold requested size */
- if(H5HF_man_dblock_new(fh_shared, dxpl_id, request) < 0)
+ if(H5HF_man_dblock_new(fh, dxpl_id, request) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create fractal heap direct block")
/* Request space from the free list */
/* (Ought to be able to be filled, now) */
- if(H5HF_flist_find(shared->flist, request, (void **)sec_node) <= 0)
+ if(H5HF_flist_find(fh->flist, request, (void **)sec_node) <= 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block")
} /* end if */
HDassert(*sec_node);
@@ -1098,10 +1065,9 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_node,
+H5HF_man_insert(H5HF_t *hdr, hid_t dxpl_id, H5HF_section_free_node_t *sec_node,
size_t obj_size, const void *obj, void *id)
{
- H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_direct_t *dblock = NULL; /* Pointer to direct block to modify */
haddr_t dblock_addr; /* Direct block address */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1111,24 +1077,20 @@ H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_
/*
* Check arguments.
*/
- HDassert(fh_shared);
+ HDassert(hdr);
HDassert(obj_size > 0);
HDassert(obj);
HDassert(id);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh_shared);
- HDassert(shared);
-
/* Lock direct block */
dblock_addr = sec_node->block_addr;
- if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &sec_node->block_size, fh_shared, H5AC_WRITE)))
+ if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &sec_node->block_size, hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block")
/* Insert object into block */
/* Check for address mapping type */
- if(shared->addrmap == H5HF_ABSOLUTE) {
+ if(hdr->addrmap == H5HF_ABSOLUTE) {
H5HF_direct_free_node_t *node; /* Block's free list node */
uint8_t *p; /* Temporary pointer to obj info in block */
size_t obj_off; /* Offset of object within block */
@@ -1144,7 +1106,7 @@ H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_
node = node->next;
/* Compute full object size, with metadata for object */
- full_obj_size = obj_size + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock);
+ full_obj_size = obj_size + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock);
/* Sanity checks */
HDassert(dblock->blk_free_space >= full_obj_size);
@@ -1197,7 +1159,7 @@ H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_
sec_node->sect_size -= full_obj_size;
/* Re-insert section node onto global list */
- if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
+ if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list")
} /* end else */
@@ -1215,7 +1177,7 @@ HDfprintf(stderr, "%s: full_obj_size = %Zu\n", FUNC, full_obj_size);
HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size);
#endif /* QAK */
/* Reduce space available in parent block(s) */
- if(H5HF_man_dblock_adj_free(dblock, -(ssize_t)alloc_obj_size) < 0)
+ if(H5HF_man_dblock_adj_free(dxpl_id, dblock, -(ssize_t)alloc_obj_size) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for direct block & parents")
/* Encode the object in the block */
@@ -1229,10 +1191,6 @@ HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size);
/* Encode the free fragment size */
*p++ = free_frag_size;
- /* Encode a ref. count (of 1), if required */
- if(shared->ref_count_obj)
- UINT64ENCODE_VAR(p, 1, shared->ref_count_size);
-
/* Copy the object's data into the heap */
HDmemcpy(p, obj, obj_size);
p += obj_size;
@@ -1252,21 +1210,22 @@ HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size);
#ifdef QAK
HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off);
#endif /* QAK */
- UINT64ENCODE_VAR(id, (dblock->block_off + obj_off), shared->heap_off_size);
+ UINT64ENCODE_VAR(id, (dblock->block_off + obj_off), hdr->heap_off_size);
} /* end if */
else {
HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "inserting within mapped managed blocks not supported yet")
} /* end else */
/* Update statistics about heap */
- shared->nobjs++;
+ hdr->nobjs++;
/* Mark heap header as modified */
- shared->dirty = TRUE;
+ if(H5HF_hdr_dirty(dxpl_id, hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
done:
/* Release the direct block (marked as dirty) */
- if(dblock && H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG) < 0)
+ if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1287,10 +1246,8 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj)
+H5HF_man_read(H5HF_t *hdr, hid_t dxpl_id, hsize_t obj_off, void *obj)
{
- H5HF_parent_shared_t par_shared; /* Parent shared information */
- H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_direct_t *dblock; /* Pointer to direct block to query */
size_t blk_off; /* Offset of object in block */
uint8_t *p; /* Temporary pointer to obj info in block */
@@ -1304,27 +1261,18 @@ H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj)
/*
* Check arguments.
*/
- HDassert(fh_shared);
+ HDassert(hdr);
HDassert(obj_off > 0);
HDassert(obj);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh_shared);
- HDassert(shared);
-
/* Check for root direct block */
- if(shared->man_dtable.curr_root_rows == 0) {
+ if(hdr->man_dtable.curr_root_rows == 0) {
/* Set direct block info */
- par_shared.shared = fh_shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = shared->total_man_free;
-
- dblock_addr = shared->man_dtable.table_addr;
- dblock_size = shared->man_dtable.cparam.start_block_size;
+ dblock_addr = hdr->man_dtable.table_addr;
+ dblock_size = hdr->man_dtable.cparam.start_block_size;
/* Lock direct block */
- if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ)))
+ if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
} /* end if */
else {
@@ -1334,48 +1282,40 @@ H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj)
size_t entry; /* Entry of block */
/* Look up row & column for object */
- if(H5HF_dtable_lookup(&shared->man_dtable, obj_off, &row, &col) < 0)
+ 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 = shared->man_dtable.table_addr;
+ iblock_addr = hdr->man_dtable.table_addr;
/* Lock indirect block */
- par_shared.shared = fh_shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = shared->total_man_free;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_READ)))
+ if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Check for indirect block row */
- while(row >= shared->man_dtable.max_direct_rows) {
+ while(row >= hdr->man_dtable.max_direct_rows) {
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 */
/* Compute # of rows in child indirect block */
- nrows = (H5V_log2_gen(shared->man_dtable.row_block_size[row]) - shared->man_dtable.first_row_bits) + 1;
+ 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 * shared->man_dtable.cparam.width) + col;
+ entry = (row * hdr->man_dtable.cparam.width) + col;
/* Locate child indirect block */
new_iblock_addr = iblock->ents[entry].addr;
/* Lock new indirect block */
- par_shared.shared = fh_shared;
- par_shared.parent = iblock->self;
- par_shared.parent_entry = entry;
- par_shared.parent_free_space = iblock->ents[entry].free_space;
- if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_READ)))
+ if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
/* Release the current indirect block (possibly marked as dirty) */
- if(H5AC_unprotect(shared->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, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
/* Switch variables to use new indirect block */
@@ -1383,31 +1323,30 @@ HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col);
iblock_addr = new_iblock_addr;
/* Look up row & column in new indirect block for object */
- if(H5HF_dtable_lookup(&shared->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0)
+ 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 */
/* Compute direct block's entry */
- entry = (row * shared->man_dtable.cparam.width) + col;
+ entry = (row * hdr->man_dtable.cparam.width) + col;
#ifdef QAK
-HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->dblock_ents[entry].addr);
+HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr);
#endif /* QAK */
/* Set direct block info */
- par_shared.shared = fh_shared;
- par_shared.parent = iblock->self;
- par_shared.parent_entry = entry;
- par_shared.parent_free_space = iblock->ents[entry].free_space;
-
dblock_addr = iblock->ents[entry].addr;
- dblock_size = shared->man_dtable.row_block_size[row];
+ dblock_size = hdr->man_dtable.row_block_size[row];
/* Lock direct block */
- if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ)))
+ if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block")
/* Unlock indirect block */
- if(H5AC_unprotect(shared->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, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
iblock = NULL;
} /* end else */
@@ -1422,14 +1361,14 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->dblock_ents[entry].a
/* Decode the length */
UINT64DECODE_VAR(p, obj_size, dblock->blk_off_size);
- /* Skip over the free fragment size & ref count */
- p += 1 + (shared->ref_count_obj ? shared->ref_count_size : 0);
+ /* Skip over the free fragment size */
+ p++;
/* Copy the object's data into the heap */
HDmemcpy(obj, p, obj_size);
/* Unlock direct block */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ if(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")
dblock = NULL;
@@ -1439,46 +1378,248 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_iblock_free
+ * Function: H5HF_hdr_incr
*
- * Purpose: Free fractal heap indirect block
+ * Purpose: Increment reference count on shared heap header
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Mar 13 2006
+ * Mar 27 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_hdr_incr(H5HF_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_incr)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+/* XXX: When "un-evictable" feature is finished, mark the header as
+ * unevictable on the first block to share it. - QAK
+ */
+
+ /* Increment reference count on shared header */
+ hdr->rc++;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_hdr_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_decr
+ *
+ * Purpose: Decrement reference count on shared heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 27 2006
*
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_iblock_free(void *_iblock)
+H5HF_hdr_decr(H5HF_t *hdr)
{
- H5HF_indirect_t *iblock = (H5HF_indirect_t *)_iblock;
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_decr)
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_free)
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Decrement reference count on shared header */
+ hdr->rc--;
+
+/* XXX: When "un-evictable" feature is finished, mark the header as
+ * evictable when the ref. count drops to zero. - QAK
+ */
+/* XXX: Take this call out after "un-evictable" flag is working */
+ H5HF_cache_hdr_dest_real(hdr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_hdr_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_dirty
+ *
+ * Purpose: Mark heap header as dirty
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 27 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_hdr_dirty(hid_t dxpl_id, H5HF_t *hdr)
+{
+ H5HF_t *tmp_hdr; /* Temporary pointer to heap header */
+ hbool_t is_protected; /* Whether the indirect block is protected */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_dirty)
+#ifdef QAK
+HDfprintf(stderr, "%s: Marking heap header as dirty\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(hdr);
+
+/* XXX: When "un-evictable" feature is finished, just mark the header as dirty
+ * in the cache, instead of this protect -> unprotect kludge - QAK
+ */
+ /* Protect the header */
+ is_protected = hdr->cache_info.is_protected;
+ if(!is_protected) {
#ifdef QAK
-HDfprintf(stderr, "%s: Freeing indirect block\n", "H5HF_iblock_free");
+HDfprintf(stderr, "%s: hdr->heap_addr = %a\n", FUNC, hdr->heap_addr);
#endif /* QAK */
+ if(NULL == (tmp_hdr = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
+ HDassert(hdr == tmp_hdr);
+ } /* end if */
+
+ /* Set the dirty flags for the heap header */
+ hdr->dirty = TRUE;
+
+ /* Release the heap header (marked as dirty) */
+ if(!is_protected) {
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, tmp_hdr, H5AC__DIRTIED_FLAG) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_hdr_dirty() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_iblock_incr
+ *
+ * Purpose: Increment reference count on shared indirect block
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 27 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_iblock_incr(H5HF_indirect_t *iblock)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_incr)
+
+ /* Sanity check */
+ HDassert(iblock);
+
+/* XXX: When "un-evictable" feature is finished, mark the block as
+ * unevictable on the first block to share it. - QAK
+ */
+
+ /* Increment reference count on shared indirect block */
+ iblock->rc++;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_iblock_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_iblock_decr
+ *
+ * Purpose: Decrement reference count on shared indirect block
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 27 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_iblock_decr(H5HF_indirect_t *iblock)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_decr)
/* Sanity check */
HDassert(iblock);
- /* Decrement reference count on shared fractal heap info */
- if(iblock->shared)
- H5RC_DEC(iblock->shared);
- if(iblock->parent)
- H5RC_DEC(iblock->parent);
+ /* Decrement reference count on shared indirect block */
+ iblock->rc--;
- /* Release entry tables */
- if(iblock->ents)
- H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents);
+/* XXX: When "un-evictable" feature is finished, mark the block as
+ * evictable when the ref. count drops to zero. - QAK
+ */
+/* XXX: Take this call out after "un-evictable" flag is working */
+ H5HF_cache_iblock_dest_real(iblock);
- /* Free fractal heap indirect block info */
- H5FL_FREE(H5HF_indirect_t, iblock);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5HF_iblock_free() */
+} /* end H5HF_iblock_decr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_iblock_dirty
+ *
+ * Purpose: Mark indirect block as dirty
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 21 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_iblock_dirty(hid_t dxpl_id, H5HF_indirect_t *iblock)
+{
+ H5HF_indirect_t *tmp_iblock; /* Temporary pointer to indirect block */
+ hbool_t is_protected; /* Whether the indirect block is protected */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_iblock_dirty)
+#ifdef QAK
+HDfprintf(stderr, "%s: Marking indirect block as dirty\n", FUNC);
+#endif /* QAK */
+
+ /* Sanity check */
+ HDassert(iblock);
+
+/* XXX: When "un-evictable" feature is finished, just mark the block as dirty
+ * in the cache, instead of this protect -> unprotect kludge - QAK
+ */
+ /* Protect the indirect block */
+ is_protected = iblock->cache_info.is_protected;
+ if(!is_protected) {
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->addr = %a\n", FUNC, iblock->addr);
+#endif /* QAK */
+ if(NULL == (tmp_iblock = H5AC_protect(iblock->shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, &iblock->nrows, iblock->shared, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block")
+ HDassert(iblock == tmp_iblock);
+ } /* end if */
+
+ /* Set the dirty flags for the indirect block */
+ iblock->dirty = TRUE;
+
+ /* Release the indirect block (marked as dirty) */
+ if(!is_protected) {
+ if(H5AC_unprotect(iblock->shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, tmp_iblock, H5AC__DIRTIED_FLAG) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_iblock_dirty() */
/*-------------------------------------------------------------------------
@@ -1497,12 +1638,9 @@ HDfprintf(stderr, "%s: Freeing indirect block\n", "H5HF_iblock_free");
*-------------------------------------------------------------------------
*/
static H5HF_indirect_t *
-H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id,
- size_t min_dblock_size, haddr_t *addr_p, size_t *entry_p,
- size_t *dblock_size)
+H5HF_man_iblock_place_dblock(H5HF_t *hdr, hid_t dxpl_id, size_t min_dblock_size,
+ haddr_t *addr_p, size_t *entry_p, size_t *dblock_size)
{
- H5HF_parent_shared_t par_shared; /* Parent shared information */
- H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_indirect_t *iblock; /* Pointer to indirect block */
haddr_t iblock_addr; /* Indirect block's address */
H5HF_indirect_t *ret_value; /* Return value */
@@ -1512,16 +1650,12 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id,
/*
* Check arguments.
*/
- HDassert(fh_shared);
+ HDassert(hdr);
HDassert(min_dblock_size > 0);
HDassert(addr_p);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh_shared);
- HDassert(shared);
-
/* Check for creating first indirect block */
- if(shared->man_dtable.curr_root_rows == 0) {
+ if(hdr->man_dtable.curr_root_rows == 0) {
H5HF_direct_t *dblock; /* Pointer to direct block to query */
unsigned nrows; /* Number of rows for root indirect block */
@@ -1529,13 +1663,13 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id,
HDfprintf(stderr, "%s: creating first indirect block\n", FUNC);
#endif /* QAK */
/* Check for allocating entire root indirect block initially */
- if(shared->man_dtable.cparam.start_root_rows == 0)
- nrows = shared->man_dtable.max_root_rows;
+ if(hdr->man_dtable.cparam.start_root_rows == 0)
+ nrows = hdr->man_dtable.max_root_rows;
else
- nrows = shared->man_dtable.cparam.start_root_rows;
+ nrows = hdr->man_dtable.cparam.start_root_rows;
/* Allocate root indirect block */
- if(H5HF_man_iblock_create(fh_shared, dxpl_id, (hsize_t)0, nrows, shared->man_dtable.max_root_rows, &iblock_addr) < 0)
+ if(H5HF_man_iblock_create(hdr, dxpl_id, (hsize_t)0, nrows, hdr->man_dtable.max_root_rows, &iblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block")
#ifdef QAK
HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
@@ -1544,30 +1678,28 @@ 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 */
- par_shared.shared = fh_shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = 0;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, &par_shared, H5AC_WRITE)))
+ if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
/* Lock first (root) direct block */
- par_shared.parent_free_space = shared->total_man_free;
- if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.cparam.start_block_size, &par_shared, H5AC_READ)))
+ if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, &hdr->man_dtable.cparam.start_block_size, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block")
/* Point indirect block at direct block to add */
- iblock->ents[0].addr = shared->man_dtable.table_addr;
+ iblock->ents[0].addr = hdr->man_dtable.table_addr;
iblock->ents[0].free_space = dblock->blk_free_space;
iblock->child_free_space += dblock->blk_free_space;
/* Make direct block share parent indirect block */
- dblock->parent = iblock->self;
- dblock->parent_entry = 0;
- H5RC_INC(dblock->parent);
+ dblock->parent = iblock;
+ dblock->par_entry = 0;
+ dblock->par_addr = iblock->addr;
+ dblock->par_nrows = iblock->nrows;
+ if(H5HF_iblock_incr(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block")
/* Unlock first (root) direct block */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap direct block")
dblock = NULL;
@@ -1577,14 +1709,15 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr);
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location")
/* Mark indirect block as modified */
- iblock->dirty = TRUE;
+ if(H5HF_iblock_dirty(dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty")
/* Point heap header at new indirect block */
- shared->man_dtable.curr_root_rows = nrows;
- shared->man_dtable.table_addr = iblock_addr;
+ hdr->man_dtable.curr_root_rows = nrows;
+ hdr->man_dtable.table_addr = iblock_addr;
/* Mark heap header as modified */
- shared->dirty = TRUE;
+ hdr->dirty = TRUE;
} /* end if */
else {
#ifdef QAK
@@ -1592,12 +1725,8 @@ HDfprintf(stderr, "%s: searching root indirect block\n", FUNC);
#endif /* QAK */
/* Lock root indirect block */
- par_shared.shared = fh_shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = shared->total_man_free;
- iblock_addr = shared->man_dtable.table_addr;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE)))
+ iblock_addr = hdr->man_dtable.table_addr;
+ if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
#ifdef QAK
@@ -1611,7 +1740,7 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
/* Check for special case of second row, which has blocks the same size as first row */
if(iblock->next_row == 1)
- iblock->next_size = shared->man_dtable.cparam.start_block_size;
+ iblock->next_size = hdr->man_dtable.cparam.start_block_size;
/* Compute new # of rows in indirect block */
new_nrows = MIN(2 * iblock->nrows, iblock->max_rows);
@@ -1629,54 +1758,53 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows);
* QAK - 3/14/2006
*/
/* Free previous indirect block disk space */
- if(H5MF_xfree(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size)<0)
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size)<0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, NULL, "unable to free fractal heap indirect block")
/* Compute size of buffer needed for new indirect block */
iblock->nrows = new_nrows;
- iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock);
+ iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
/* Allocate space for the new indirect block on disk */
- if(HADDR_UNDEF == (new_addr = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for fractal heap indirect block")
/* Re-allocate direct block entry table */
- if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * shared->man_dtable.cparam.width))))
+ if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries")
/* Initialize new direct block entries */
- for(u = (iblock->next_row * shared->man_dtable.cparam.width);
- u < (iblock->nrows * shared->man_dtable.cparam.width);
+ for(u = (iblock->next_row * hdr->man_dtable.cparam.width);
+ u < (iblock->nrows * hdr->man_dtable.cparam.width);
u++) {
iblock->ents[u].addr = HADDR_UNDEF;
iblock->ents[u].free_space = 0;
} /* end for */
/* Mark indirect block as dirty */
- iblock->dirty = TRUE;
+ if(H5HF_iblock_dirty(dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty")
/* Release the indirect block (marked as dirty) */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block")
+ iblock = NULL;
/* Move object in cache */
- if(H5AC_rename(shared->f, H5AC_FHEAP_IBLOCK, iblock_addr, new_addr) < 0)
+ if(H5AC_rename(hdr->f, H5AC_FHEAP_IBLOCK, iblock_addr, new_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, NULL, "unable to move fractal heap root indirect block")
/* Update other shared header info */
- shared->man_dtable.curr_root_rows = new_nrows;
- shared->man_dtable.table_addr = iblock_addr = new_addr;
+ hdr->man_dtable.curr_root_rows = new_nrows;
+ hdr->man_dtable.table_addr = iblock_addr = new_addr;
/* Mark heap header as modified */
- shared->dirty = TRUE;
+ hdr->dirty = TRUE;
/* Lock root indirect block (again) */
- par_shared.shared = fh_shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = shared->total_man_free;
- if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE)))
+ if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
+ iblock->addr = iblock_addr;
} /* end if */
#ifdef QAK
@@ -1686,14 +1814,14 @@ HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size);
HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry);
#endif /* QAK */
/* Check for full direct block entries in current indirect block */
- while(iblock->next_row >= shared->man_dtable.max_direct_rows) {
+ while(iblock->next_row >= hdr->man_dtable.max_direct_rows) {
haddr_t new_iblock_addr; /* New indirect block's address */
H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */
unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */
unsigned nrows; /* Number of rows in new indirect block */
/* Compute # of rows in child indirect block */
- nrows = (H5V_log2_gen(iblock->next_size) - shared->man_dtable.first_row_bits) + 1;
+ nrows = (H5V_log2_gen(iblock->next_size) - hdr->man_dtable.first_row_bits) + 1;
#ifdef QAK
HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->next_size, nrows);
#endif /* QAK */
@@ -1704,32 +1832,28 @@ HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->nex
HDfprintf(stderr, "%s: Allocating new indirect block\n", FUNC);
#endif /* QAK */
/* Allocate new indirect block */
- if(H5HF_man_iblock_create(fh_shared, dxpl_id, shared->man_dtable.next_dir_block, nrows, nrows, &new_iblock_addr) < 0)
+ if(H5HF_man_iblock_create(hdr, dxpl_id, hdr->man_dtable.next_dir_block, nrows, nrows, &new_iblock_addr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block")
/* Lock new indirect block */
- par_shared.shared = fh_shared;
- par_shared.parent = iblock->self;
- par_shared.parent_entry = iblock->next_entry;
- par_shared.parent_free_space = 0;
- if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE)))
+ if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
-#ifdef QAK
-HDfprintf(stderr, "%s: new_iblock->next_row = %u\n", FUNC, new_iblock->next_row);
-HDfprintf(stderr, "%s: new_iblock->next_col = %u\n", FUNC, new_iblock->next_col);
-HDfprintf(stderr, "%s: new_iblock->next_size = %Zu\n", FUNC, new_iblock->next_size);
-HDfprintf(stderr, "%s: new_iblock->next_entry = %u\n", FUNC, new_iblock->next_entry);
-#endif /* QAK */
+
+ /* Set parent information */
+ HDassert(new_iblock->parent == NULL);
+ new_iblock->parent = iblock;
+ new_iblock->par_entry = iblock->next_entry;
+ new_iblock->par_nrows = iblock->nrows;
+ new_iblock->par_addr = iblock->addr;
+ if(H5HF_iblock_incr(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block")
/* Point current indirect block at new indirect block */
iblock->ents[iblock->next_entry].addr = new_iblock_addr;
- /* Increment location of next block from current indirect block */
- if(H5HF_man_iblock_inc_loc(iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location")
-
/* Mark current indirect block as modified */
- iblock->dirty = TRUE;
+ if(H5HF_iblock_dirty(dxpl_id, iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty")
/* Release the current indirect block (marked as dirty) */
hdr_flags |= H5AC__DIRTIED_FLAG;
@@ -1742,16 +1866,18 @@ HDfprintf(stderr, "%s: Descending existing indirect block\n", FUNC);
new_iblock_addr = iblock->ents[iblock->next_entry].addr;
/* Lock new indirect block */
- par_shared.shared = fh_shared;
- par_shared.parent = iblock->self;
- par_shared.parent_entry = iblock->next_entry;
- par_shared.parent_free_space = iblock->ents[iblock->next_entry].free_space;
- if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE)))
+ if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
} /* end else */
+#ifdef QAK
+HDfprintf(stderr, "%s: new_iblock->next_row = %u\n", FUNC, new_iblock->next_row);
+HDfprintf(stderr, "%s: new_iblock->next_col = %u\n", FUNC, new_iblock->next_col);
+HDfprintf(stderr, "%s: new_iblock->next_size = %Zu\n", FUNC, new_iblock->next_size);
+HDfprintf(stderr, "%s: new_iblock->next_entry = %u\n", FUNC, new_iblock->next_entry);
+#endif /* QAK */
/* Release the current indirect block (possibly marked as dirty) */
- if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, hdr_flags) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, hdr_flags) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block")
/* Switch variables to use new indirect block */
@@ -1804,10 +1930,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
+H5HF_man_iblock_create(H5HF_t *hdr, hid_t dxpl_id,
hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p)
{
- H5HF_shared_t *shared; /* Pointer to shared heap info */
H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */
size_t u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1817,7 +1942,7 @@ H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
/*
* Check arguments.
*/
- HDassert(fh_shared);
+ HDassert(hdr);
HDassert(nrows > 0);
HDassert(addr_p);
@@ -1831,23 +1956,19 @@ H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id,
HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t));
/* Share common heap information */
- iblock->shared = fh_shared;
- H5RC_INC(iblock->shared);
-
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(iblock->shared);
- HDassert(shared);
-
- /* Make a reference to this block */
- if(NULL == (iblock->self = H5RC_create(iblock, H5HF_iblock_free)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for indirect fractal heap block")
+ iblock->shared = hdr;
+ if(H5HF_hdr_incr(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header")
#ifdef QAK
HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows);
#endif /* QAK */
/* Set info for direct block */
+ iblock->rc = 0;
iblock->parent = NULL; /* Temporary, except for root indirect block */
- iblock->parent_entry = 0;
+ iblock->par_entry = 0;
+ iblock->par_nrows = 0;
+ iblock->par_addr = HADDR_UNDEF;
iblock->block_off = block_off;
iblock->child_free_space = 0;
iblock->nrows = nrows;
@@ -1855,44 +1976,47 @@ HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows);
iblock->next_col = 0;
iblock->next_row = 0;
iblock->next_entry = 0;
- iblock->next_size = shared->man_dtable.cparam.start_block_size;
+ iblock->next_size = hdr->man_dtable.cparam.start_block_size;
+ iblock->dirty = TRUE;
+ iblock->evicted = FALSE;
/* Compute size of buffer needed for indirect block */
- iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock);
+ iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
/* Allocate indirect block entry tables */
- if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * shared->man_dtable.cparam.width))))
+ if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * hdr->man_dtable.cparam.width))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries")
/* Initialize indirect block entry tables */
- for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) {
+ for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) {
iblock->ents[u].addr = HADDR_UNDEF;
iblock->ents[u].free_space = 0;
} /* end for */
/* Allocate space for the indirect block on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ 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")
+ iblock->addr = *addr_p;
/* XXX: Update indirect statistics when they are added */
#ifdef LATER
/* Update shared heap info */
- shared->total_man_free += dblock->blk_free_space;
- shared->total_size += dblock->size;
- shared->man_size += dblock->size;
+ hdr->total_man_free += dblock->blk_free_space;
+ hdr->total_size += dblock->size;
+ hdr->man_size += dblock->size;
/* Mark heap header as modified */
- shared->dirty = TRUE;
+ hdr->dirty = TRUE;
#endif /* LATER */
/* Cache the new fractal heap header */
- if(H5AC_set(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, iblock, H5AC__NO_FLAGS_SET) < 0)
+ 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")
done:
if(ret_value < 0)
if(iblock)
- (void)H5HF_cache_iblock_dest(shared->f, iblock);
+ (void)H5HF_cache_iblock_dest(hdr->f, iblock);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_man_iblock_create() */