summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5HF.c46
-rw-r--r--src/H5HFcache.c482
-rw-r--r--src/H5HFdbg.c121
-rw-r--r--src/H5HFint.c922
-rw-r--r--src/H5HFpkg.h198
-rw-r--r--src/H5HFprivate.h2
-rw-r--r--src/H5HFstat.c21
-rw-r--r--src/H5HFtest.c18
8 files changed, 1020 insertions, 790 deletions
diff --git a/src/H5HF.c b/src/H5HF.c
index feb88be..33a1959 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -99,7 +99,6 @@ herr_t
H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p)
{
H5HF_t *fh = NULL; /* The new fractal heap header information */
- H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_create, FAIL)
@@ -111,26 +110,17 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p)
HDassert(cparam);
HDassert(addr_p);
- /*
- * Allocate file and memory data structures.
- */
- if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fractal heap header")
-
- /* Reset the metadata cache info for the heap header */
- HDmemset(&fh->cache_info, 0, sizeof(H5AC_info_t));
-
- /* Allocate & basic initialization for the shared info struct */
- if(NULL == (shared = H5HF_shared_alloc(f)))
+ /* Allocate & basic initialization for the shared header */
+ if(NULL == (fh = H5HF_alloc(f)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for shared heap info")
/* Allocate space for the header on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(shared))))
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(fh))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap header")
- /* Initialize shared fractal heap info */
- if(H5HF_shared_init(shared, fh, *addr_p, cparam) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared fractal heap info")
+ /* Initialize shared fractal heap header */
+ if(H5HF_init(fh, *addr_p, cparam) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't initialize shared fractal heap header")
/* Cache the new fractal heap header */
if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, *addr_p, fh, H5AC__NO_FLAGS_SET) < 0)
@@ -165,7 +155,6 @@ H5HF_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size,
const void *obj, void *id/*out*/)
{
H5HF_t *fh = NULL; /* The fractal heap header information */
- H5HF_shared_t *shared; /* Shared fractal heap information */
unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */
herr_t ret_value = SUCCEED;
@@ -189,34 +178,30 @@ HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size);
if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/* Check if object is large enough to be standalone */
- if(size >= shared->standalone_size) {
+ if(size >= fh->standalone_size) {
HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "standalone blocks not supported yet")
} /* end if */
else {
/* Check if we are in "append only" mode, or if there's enough room for the object */
- if(shared->write_once) {
+ if(fh->write_once) {
HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'write once' managed blocks not supported yet")
} /* end if */
else {
H5HF_section_free_node_t *sec_node; /* Pointer to free space section */
/* Find free space in heap */
- if(H5HF_man_find(fh->shared, dxpl_id, size, &sec_node) < 0)
+ if(H5HF_man_find(fh, dxpl_id, size, &sec_node) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate space in fractal heap")
/* Use free space for allocating object */
- if(H5HF_man_insert(fh->shared, dxpl_id, sec_node, size, obj, id) < 0)
+ if(H5HF_man_insert(fh, dxpl_id, sec_node, size, obj, id) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate space for object in fractal heap")
} /* end else */
} /* end else */
/* Check for making header dirty */
- if(shared->dirty)
+ if(fh->dirty)
hdr_flags |= H5AC__DIRTIED_FLAG;
done:
@@ -245,7 +230,6 @@ H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_id,
void *obj/*out*/)
{
H5HF_t *fh = NULL; /* The fractal heap header information */
- H5HF_shared_t *shared; /* Shared fractal heap information */
const uint8_t *id = (const uint8_t *)_id; /* Object ID */
hsize_t obj_off; /* Object's offset in heap */
herr_t ret_value = SUCCEED;
@@ -266,12 +250,8 @@ H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_id,
if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/* Decode the offset within the heap */
- UINT64DECODE_VAR(id, obj_off, shared->heap_off_size);
+ UINT64DECODE_VAR(id, obj_off, fh->heap_off_size);
#ifdef QAK
HDfprintf(stderr, "%s: obj_off = %Hu\n", FUNC, obj_off);
#endif /* QAK */
@@ -282,7 +262,7 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "standalone blocks not supported ye
} /* end if */
else {
/* Read object from managed heap blocks */
- if(H5HF_man_read(fh->shared, dxpl_id, obj_off, obj) < 0)
+ if(H5HF_man_read(fh, dxpl_id, obj_off, obj) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't read object from fractal heap")
} /* end else */
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index 1fd3b51..ab6ea76 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -259,7 +259,6 @@ static H5HF_t *
H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
{
H5HF_t *fh = NULL; /* Fractal heap info */
- H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
size_t size; /* Header size */
uint8_t *buf = NULL; /* Temporary buffer */
const uint8_t *p; /* Pointer into raw data buffer */
@@ -267,23 +266,23 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
H5HF_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5HF_cache_hdr_load, NULL)
+#ifdef QAK
+HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr);
+#endif /* QAK */
/* Check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
/* Allocate space for the fractal heap data structure */
- if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
+ if(NULL == (fh = H5HF_alloc(f)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemset(&fh->cache_info, 0, sizeof(H5AC_info_t));
- /* Allocate & basic initialization for the shared info struct */
- if(NULL == (shared = H5HF_shared_alloc(f)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for shared heap info")
- shared->heap_addr = addr;
+ /* Set the heap header's address */
+ fh->heap_addr = addr;
/* Compute the size of the fractal heap header on disk */
- size = H5HF_HEADER_SIZE(shared);
+ size = H5HF_HEADER_SIZE(fh);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
@@ -316,36 +315,33 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap header")
/* Heap address mapping */
- shared->addrmap = *p++;
+ fh->addrmap = *p++;
HDassert(H5HF_ABSOLUTE == 0);
- if(shared->addrmap > H5HF_MAPPED)
+ if(fh->addrmap > H5HF_MAPPED)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect fractal heap address mapping")
/* Min. size of standalone objects */
- UINT32DECODE(p, shared->standalone_size);
-
- /* Size of ref. count for objects in heap */
- shared->ref_count_size = *p++;
+ UINT32DECODE(p, fh->standalone_size);
/* Internal management information */
- H5F_DECODE_LENGTH(f, p, shared->total_man_free);
- H5F_DECODE_LENGTH(f, p, shared->total_std_free);
+ H5F_DECODE_LENGTH(f, p, fh->total_man_free);
+ H5F_DECODE_LENGTH(f, p, fh->total_std_free);
/* Statistics information */
- H5F_DECODE_LENGTH(f, p, shared->total_size);
- H5F_DECODE_LENGTH(f, p, shared->man_size);
- H5F_DECODE_LENGTH(f, p, shared->std_size);
- H5F_DECODE_LENGTH(f, p, shared->nobjs);
+ H5F_DECODE_LENGTH(f, p, fh->total_size);
+ H5F_DECODE_LENGTH(f, p, fh->man_size);
+ H5F_DECODE_LENGTH(f, p, fh->std_size);
+ H5F_DECODE_LENGTH(f, p, fh->nobjs);
/* Managed objects' doubling-table info */
- if(H5HF_dtable_decode(shared->f, &p, &(shared->man_dtable)) < 0)
+ if(H5HF_dtable_decode(fh->f, &p, &(fh->man_dtable)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, NULL, "unable to encode managed obj. doubling table info")
HDassert((size_t)(p - buf) == size);
/* Make shared heap info reference counted */
- if(H5HF_shared_own(fh, shared) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create ref-count wrapper for shared fractal heap info")
+ if(H5HF_finish_init(fh) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create ref-count wrapper for shared fractal heap header")
/* Set return value */
ret_value = fh;
@@ -376,30 +372,28 @@ done:
static herr_t
H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_t *fh)
{
- H5HF_shared_t *shared; /* Shared fractal heap information */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_cache_hdr_flush, FAIL)
+#ifdef QAK
+HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy);
+#endif /* QAK */
/* check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
HDassert(fh);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
if(fh->cache_info.is_dirty) {
uint8_t *buf = NULL; /* Temporary raw data buffer */
uint8_t *p; /* Pointer into raw data buffer */
size_t size; /* Header size on disk */
/* Sanity check */
- HDassert(shared->dirty);
+ HDassert(fh->dirty);
/* Compute the size of the heap header on disk */
- size = H5HF_HEADER_SIZE(shared);
+ size = H5HF_HEADER_SIZE(fh);
/* Allocate temporary buffer */
if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL)
@@ -424,26 +418,23 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H
p += 4;
/* Heap address mapping */
- *p++ = shared->addrmap;
+ *p++ = fh->addrmap;
/* Min. size of standalone objects */
- UINT32ENCODE(p, shared->standalone_size);
-
- /* Size of ref. count for objects in heap */
- *p++ = shared->ref_count_size;
+ UINT32ENCODE(p, fh->standalone_size);
/* Internal management information */
- H5F_ENCODE_LENGTH(f, p, shared->total_man_free);
- H5F_ENCODE_LENGTH(f, p, shared->total_std_free);
+ H5F_ENCODE_LENGTH(f, p, fh->total_man_free);
+ H5F_ENCODE_LENGTH(f, p, fh->total_std_free);
/* Statistics information */
- H5F_ENCODE_LENGTH(f, p, shared->total_size);
- H5F_ENCODE_LENGTH(f, p, shared->man_size);
- H5F_ENCODE_LENGTH(f, p, shared->std_size);
- H5F_ENCODE_LENGTH(f, p, shared->nobjs);
+ H5F_ENCODE_LENGTH(f, p, fh->total_size);
+ H5F_ENCODE_LENGTH(f, p, fh->man_size);
+ H5F_ENCODE_LENGTH(f, p, fh->std_size);
+ H5F_ENCODE_LENGTH(f, p, fh->nobjs);
/* Managed objects' doubling-table info */
- if(H5HF_dtable_encode(shared->f, &p, &(shared->man_dtable)) < 0)
+ if(H5HF_dtable_encode(fh->f, &p, &(fh->man_dtable)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "unable to encode managed obj. doubling table info")
/* Write the heap header. */
@@ -453,7 +444,7 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H
H5FL_BLK_FREE(header_block, buf);
- shared->dirty = FALSE;
+ fh->dirty = FALSE;
fh->cache_info.is_dirty = FALSE;
} /* end if */
@@ -467,6 +458,47 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_cache_hdr_dest_real
+ *
+ * Purpose: Destroys a fractal heap header in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Feb 24 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_cache_hdr_dest_real(H5HF_t *fh)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_dest_real)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(fh);
+/* XXX: Take out this goofy routine, after metadata cache is supporting
+ * "un-evictable" flag
+ */
+ if(fh->rc == 0 && fh->evicted == TRUE) {
+ /* Free the free list information for the heap */
+ if(fh->flist)
+ H5HF_flist_free(fh->flist);
+
+ /* Free the block size lookup table for the doubling table */
+ H5HF_dtable_dest(&fh->man_dtable);
+
+ /* Free the shared info itself */
+ H5FL_FREE(H5HF_t, fh);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_cache_hdr_dest_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_cache_hdr_dest
*
* Purpose: Destroys a fractal heap header in memory.
@@ -489,13 +521,17 @@ H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_t *fh)
* Check arguments.
*/
HDassert(fh);
-
- /* Decrement reference count on shared fractal heap info */
- if(fh->shared)
- H5RC_DEC(fh->shared);
-
- /* Free fractal heap header info */
- H5FL_FREE(H5HF_t, fh);
+/* XXX: Enable this after the metadata cache supports the "un-evictable" flag */
+/* HDassert(fh->rc == 0); */
+/* XXX: Take out this goofy 'if' statement, after metadata cache is supporting
+ * "un-evictable" flag
+ */
+/* XXX: Take out 'evicted' flag after "un-evictable" flag is working */
+ fh->evicted = TRUE;
+/* XXX: Take out this goofy routine, after metadata cache is supporting
+ * "un-evictable" flag
+ */
+ H5HF_cache_hdr_dest_real(fh);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5HF_cache_hdr_dest() */
@@ -556,8 +592,6 @@ done:
static herr_t
H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr)
{
- H5HF_shared_t *shared; /* Shared fractal heap information */
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_size)
/* check arguments */
@@ -565,12 +599,8 @@ H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr)
HDassert(fh);
HDassert(size_ptr);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/* Set size value */
- *size_ptr = H5HF_HEADER_SIZE(shared);
+ *size_ptr = H5HF_HEADER_SIZE(fh);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HF_cache_hdr_size() */
@@ -592,11 +622,10 @@ H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr)
*-------------------------------------------------------------------------
*/
static H5HF_direct_t *
-H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_par_shared)
+H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_hdr)
{
const size_t *size = (const size_t *)_size; /* Size of block */
- H5HF_parent_shared_t *par_shared = (H5HF_parent_shared_t *)_par_shared; /* Shared direct block information */
- H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
+ H5HF_t *hdr = (H5HF_t *)_hdr; /* Shared heap header information */
H5HF_direct_t *dblock = NULL; /* Direct block info */
const uint8_t *p; /* Pointer into raw data buffer */
haddr_t heap_addr; /* Address of heap header in the file */
@@ -608,7 +637,7 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
/* Check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
- HDassert(par_shared);
+ HDassert(hdr);
/* Allocate space for the fractal heap direct block */
if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t)))
@@ -616,19 +645,9 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
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);
-
- /* Share common parent [indirect] block information */
- dblock->parent = par_shared->parent;
- if(dblock->parent)
- H5RC_INC(dblock->parent);
- dblock->parent_entry = par_shared->parent_entry;
- dblock->blk_free_space = (size_t)par_shared->parent_free_space;
+ dblock->shared = hdr;
+ if(H5HF_hdr_incr(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header")
/* Set block's internal information */
dblock->size = *size;
@@ -668,11 +687,48 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size,
/* Address of heap that owns this block (skip) */
H5F_addr_decode(f, &p, &heap_addr);
- if(H5F_addr_ne(heap_addr, shared->heap_addr))
+ if(H5F_addr_ne(heap_addr, hdr->heap_addr))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block")
+ /* Address of parent block */
+ H5F_addr_decode(f, &p, &dblock->par_addr);
+ UINT16DECODE(p, dblock->par_entry);
+ UINT16DECODE(p, dblock->par_nrows);
+ if(H5F_addr_defined(dblock->par_addr)) {
+ H5HF_indirect_t *iblock; /* Pointer to parent indirect block */
+
+ /* Check for direct block as a child of the root indirect block
+ * and retrieve the # of rows in the root indirect block from
+ * the shared heap header, because the root indirect block can
+ * change size.
+ */
+ if(H5F_addr_eq(iblock->par_addr, hdr->man_dtable.table_addr))
+ dblock->par_nrows = hdr->man_dtable.curr_root_rows;
+
+ /* Protect parent indirect block */
+ if(NULL == (iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, dblock->par_addr, &dblock->par_nrows, hdr, hdr->mode)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
+
+ /* Share parent block */
+ dblock->parent = iblock;
+ if(H5HF_iblock_incr(iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block")
+
+ /* Retrieve this block's free space from parent */
+ dblock->blk_free_space = iblock->ents[dblock->par_entry].free_space;
+
+ /* Release the indirect block */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, dblock->par_addr, iblock, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block")
+ } /* end if */
+ else {
+ /* Direct block is linked directly from heap header */
+ dblock->parent = NULL;
+ dblock->blk_free_space = hdr->total_man_free;
+ } /* end else */
+
/* Offset of heap within the heap's address space */
- UINT64DECODE_VAR(p, dblock->block_off, shared->heap_off_size);
+ UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size);
/* Offset of free list head */
/* (Defer deserializing the whole free list until we actually need to modify it) */
@@ -715,12 +771,11 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
HDassert(dblock);
if(dblock->cache_info.is_dirty) {
- H5HF_shared_t *shared; /* Shared fractal heap information */
- uint8_t *p; /* Pointer into raw data buffer */
+ H5HF_t *hdr; /* Shared fractal heap information */
+ uint8_t *p; /* Pointer into raw data buffer */
- /* 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;
p = dblock->blk;
@@ -741,20 +796,25 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
p += 4;
/* Address of heap header for heap which owns this block */
- H5F_addr_encode(f, &p, shared->heap_addr);
+ H5F_addr_encode(f, &p, hdr->heap_addr);
+
+ /* Info for parent block of this block */
+ H5F_addr_encode(f, &p, dblock->par_addr);
+ UINT16ENCODE(p, dblock->par_entry);
+ UINT16ENCODE(p, dblock->par_nrows);
/* Offset of block in heap */
- UINT64ENCODE_VAR(p, dblock->block_off, shared->heap_off_size);
+ UINT64ENCODE_VAR(p, dblock->block_off, hdr->heap_off_size);
/* Check for (currently) unsupported address mapping */
- if(shared->addrmap != H5HF_ABSOLUTE)
+ if(hdr->addrmap != H5HF_ABSOLUTE)
HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "encoding mapped direct blocks not supported currently")
/* Offset of free list head */
UINT64ENCODE_VAR(p, dblock->free_list_head, dblock->blk_off_size);
/* Sanity check */
- HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(shared, dblock));
+ HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock));
/* Check for dirty free list */
if(dblock->free_list && dblock->free_list->dirty) {
@@ -824,7 +884,9 @@ done:
herr_t
H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_dblock_dest)
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_dest)
/*
* Check arguments.
@@ -832,10 +894,12 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock)
HDassert(dblock);
/* Decrement reference count on shared fractal heap info */
- if(dblock->shared)
- H5RC_DEC(dblock->shared);
+ HDassert(dblock->shared);
+ if(H5HF_hdr_decr(dblock->shared) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
if(dblock->parent)
- H5RC_DEC(dblock->parent);
+ if(H5HF_iblock_decr(dblock->parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
/* Check for free list & free it, if necessary */
if(dblock->free_list) {
@@ -864,7 +928,8 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock)
/* Free fractal heap direct block info */
H5FL_FREE(H5HF_direct_t, dblock);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_cache_dblock_dest() */
@@ -955,11 +1020,10 @@ H5HF_cache_dblock_size(const H5F_t UNUSED *f, const H5HF_direct_t *dblock, size_
*-------------------------------------------------------------------------
*/
static H5HF_indirect_t *
-H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_par_shared)
+H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_hdr)
{
const unsigned *nrows = (const unsigned *)_nrows; /* # of rows in indirect block */
- H5HF_parent_shared_t *par_shared = (H5HF_parent_shared_t *)_par_shared; /* Shared direct block information */
- H5HF_shared_t *shared = NULL; /* Shared fractal heap information */
+ H5HF_t *hdr = (H5HF_t *)_hdr; /* Shared header information */
H5HF_indirect_t *iblock = NULL; /* Indirect block info */
uint8_t *buf = NULL; /* Temporary buffer */
const uint8_t *p; /* Pointer into raw data buffer */
@@ -969,11 +1033,14 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
H5HF_indirect_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5HF_cache_iblock_load, NULL)
+#ifdef QAK
+HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr);
+#endif /* QAK */
/* Check arguments */
HDassert(f);
HDassert(H5F_addr_defined(addr));
- HDassert(par_shared);
+ HDassert(hdr);
/* Allocate space for the fractal heap indirect block */
if(NULL == (iblock = H5FL_MALLOC(H5HF_indirect_t)))
@@ -981,33 +1048,19 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t));
/* Share common heap information */
- iblock->shared = par_shared->shared;
- H5RC_INC(iblock->shared);
-
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(iblock->shared);
- HDassert(shared);
-
- /* Share common parent [indirect] block information */
- iblock->parent = par_shared->parent;
- if(iblock->parent)
- H5RC_INC(iblock->parent);
- iblock->parent_entry = par_shared->parent_entry;
- iblock->child_free_space = par_shared->parent_free_space;
-
- /* Make a reference to this block */
- if(NULL == (iblock->self = H5RC_create(iblock, H5HF_iblock_free)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "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, NULL, "can't increment reference count on shared heap header")
/* Set block's internal information */
+ iblock->rc = 0;
iblock->nrows = *nrows;
- if(!iblock->parent)
- iblock->max_rows = shared->man_dtable.max_root_rows;
- else
- iblock->max_rows = *nrows;
+ iblock->addr = addr;
+ iblock->dirty = FALSE;
+ iblock->evicted = FALSE;
/* Compute size of indirect block */
- iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock);
+ iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
/* Allocate buffer to decode block */
/* XXX: Use free list factories? */
@@ -1042,33 +1095,77 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows
/* Address of heap that owns this block */
H5F_addr_decode(f, &p, &heap_addr);
- if(H5F_addr_ne(heap_addr, shared->heap_addr))
+ if(H5F_addr_ne(heap_addr, hdr->heap_addr))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block")
+ /* Address of parent block */
+ H5F_addr_decode(f, &p, &iblock->par_addr);
+ UINT16DECODE(p, iblock->par_entry);
+ UINT16DECODE(p, iblock->par_nrows);
+ if(H5F_addr_defined(iblock->par_addr)) {
+ H5HF_indirect_t *tmp_iblock; /* Pointer to parent indirect block */
+
+ /* Check for indirect block as a child of the root indirect block
+ * and retrieve the # of rows in the root indirect block from
+ * the shared heap header, because the root indirect block can
+ * change size.
+ */
+ if(H5F_addr_eq(iblock->par_addr, hdr->man_dtable.table_addr))
+ iblock->par_nrows = hdr->man_dtable.curr_root_rows;
+
+ /* Protect parent indirect block */
+ if(NULL == (tmp_iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->par_addr, &iblock->par_nrows, hdr, hdr->mode)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block")
+
+ /* Share parent block */
+ iblock->parent = tmp_iblock;
+ if(H5HF_iblock_incr(tmp_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block")
+
+ /* Retrieve this block's free space from parent */
+ iblock->child_free_space = tmp_iblock->ents[iblock->par_entry].free_space;
+
+ /* Release the indirect block */
+ if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->par_addr, tmp_iblock, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block")
+ tmp_iblock = NULL;
+
+ /* Set max. # of rows in this block */
+ iblock->max_rows = iblock->nrows;
+ } /* end if */
+ else {
+ /* Direct block is linked directly from heap header */
+ iblock->parent = NULL;
+ iblock->child_free_space = hdr->total_man_free;
+
+ /* Set max. # of rows in this block */
+ iblock->max_rows = hdr->man_dtable.max_root_rows;
+ } /* end else */
+
/* Offset of heap within the heap's address space */
- UINT64DECODE_VAR(p, iblock->block_off, shared->heap_off_size);
+ UINT64DECODE_VAR(p, iblock->block_off, hdr->heap_off_size);
/* Offset of next entry to allocate within this block */
UINT32DECODE(p, iblock->next_entry);
/* Compute next block column, row & size */
- iblock->next_col = iblock->next_entry % shared->man_dtable.cparam.width;
- iblock->next_row = iblock->next_entry / shared->man_dtable.cparam.width;
- iblock->next_size = shared->man_dtable.row_block_size[iblock->next_row];
+ iblock->next_col = iblock->next_entry % hdr->man_dtable.cparam.width;
+ iblock->next_row = iblock->next_entry / hdr->man_dtable.cparam.width;
+ iblock->next_size = hdr->man_dtable.row_block_size[iblock->next_row];
/* Allocate & decode indirect block entry tables */
HDassert(iblock->nrows > 0);
- 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, NULL, "memory allocation failed for direct entries")
- for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) {
+ for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) {
/* Decode block address */
H5F_addr_decode(f, &p, &(iblock->ents[u].addr));
/* Decode direct & indirect blocks differently */
- if(u < (shared->man_dtable.max_direct_rows * shared->man_dtable.cparam.width))
- UINT32DECODE_VAR(p, iblock->ents[u].free_space, shared->man_dtable.max_dir_blk_off_size)
+ if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width))
+ UINT32DECODE_VAR(p, iblock->ents[u].free_space, hdr->man_dtable.max_dir_blk_off_size)
else
- UINT64DECODE_VAR(p, iblock->ents[u].free_space, shared->heap_off_size)
+ UINT64DECODE_VAR(p, iblock->ents[u].free_space, hdr->heap_off_size)
} /* end for */
/* Sanity check */
@@ -1108,6 +1205,9 @@ H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_cache_iblock_flush, FAIL)
+#ifdef QAK
+HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy);
+#endif /* QAK */
/* check arguments */
HDassert(f);
@@ -1115,20 +1215,16 @@ H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr,
HDassert(iblock);
if(iblock->cache_info.is_dirty) {
- H5HF_shared_t *shared; /* Shared fractal heap information */
- uint8_t *buf = NULL; /* Temporary buffer */
- uint8_t *p; /* Pointer into raw data buffer */
- size_t u; /* Local index variable */
+ H5HF_t *hdr; /* Shared fractal heap information */
+ uint8_t *buf = NULL; /* Temporary buffer */
+ uint8_t *p; /* Pointer into raw data buffer */
+ size_t u; /* Local index variable */
/* Sanity check */
HDassert(iblock->dirty);
-#ifdef QAK
-HDfprintf(stderr, "%s: Flushing indirect block\n", FUNC);
-#endif /* QAK */
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(iblock->shared);
- HDassert(shared);
+ /* Get the pointer to the shared heap header */
+ hdr = iblock->shared;
/* Allocate buffer to encode block */
/* XXX: Use free list factories? */
@@ -1136,7 +1232,7 @@ HDfprintf(stderr, "%s: Flushing indirect block\n", FUNC);
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size);
HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off);
-HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->man_dtable.cparam.width);
+HDfprintf(stderr, "%s: hdr->man_dtable.cparam.width = %u\n", FUNC, hdr->man_dtable.cparam.width);
#endif /* QAK */
if((buf = H5FL_BLK_MALLOC(indirect_block, iblock->size)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
@@ -1160,24 +1256,32 @@ HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->ma
p += 4;
/* Address of heap header for heap which owns this block */
- H5F_addr_encode(f, &p, shared->heap_addr);
+ H5F_addr_encode(f, &p, hdr->heap_addr);
+
+ /* Info for parent block of this block */
+ H5F_addr_encode(f, &p, iblock->par_addr);
+ UINT16ENCODE(p, iblock->par_entry);
+ UINT16ENCODE(p, iblock->par_nrows);
/* Offset of block in heap */
- UINT64ENCODE_VAR(p, iblock->block_off, shared->heap_off_size);
+ UINT64ENCODE_VAR(p, iblock->block_off, hdr->heap_off_size);
/* Next block entry to allocate from */
UINT32ENCODE(p, iblock->next_entry);
/* Encode indirect block-specific fields */
- for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) {
+ for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) {
+#ifdef QAK
+HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a, %Hu}\n", FUNC, u, iblock->ents[u].addr, iblock->ents[u].free_space);
+#endif /* QAK */
/* Encode block address */
H5F_addr_encode(f, &p, iblock->ents[u].addr);
/* Encode direct & indirect blocks differently */
- if(u < (shared->man_dtable.max_direct_rows * shared->man_dtable.cparam.width))
- UINT32ENCODE_VAR(p, iblock->ents[u].free_space, shared->man_dtable.max_dir_blk_off_size)
+ if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width))
+ UINT32ENCODE_VAR(p, iblock->ents[u].free_space, hdr->man_dtable.max_dir_blk_off_size)
else
- UINT64ENCODE_VAR(p, iblock->ents[u].free_space, shared->heap_off_size)
+ UINT64ENCODE_VAR(p, iblock->ents[u].free_space, hdr->heap_off_size)
} /* end for */
/* Sanity check */
@@ -1190,6 +1294,8 @@ HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->ma
/* Free buffer */
H5FL_BLK_FREE(indirect_block, buf);
+ /* Reset dirty flags */
+ iblock->dirty = FALSE;
iblock->cache_info.is_dirty = FALSE;
} /* end if */
@@ -1203,6 +1309,58 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_cache_iblock_dest_real
+ *
+ * Purpose: Destroys a fractal heap indirect block in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 6 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_cache_iblock_dest_real(H5HF_indirect_t *iblock)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_dest_real)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(iblock);
+#ifdef QAK
+HDfprintf(stderr, "%s: Destroying indirect block\n", "H5HF_cache_iblock_dest");
+#endif /* QAK */
+/* XXX: Take out this goofy routine, after metadata cache is supporting
+ * "un-evictable" flag
+ */
+ if(iblock->rc == 0 && iblock->evicted) {
+ /* Decrement reference count on shared info */
+ HDassert(iblock->shared);
+ if(H5HF_hdr_decr(iblock->shared) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
+ if(iblock->parent)
+ if(H5HF_iblock_decr(iblock->parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
+
+ /* Release entry tables */
+ if(iblock->ents)
+ H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents);
+
+ /* Free fractal heap indirect block info */
+ H5FL_FREE(H5HF_indirect_t, iblock);
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_cache_iblock_dest_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_cache_iblock_dest
*
* Purpose: Destroys a fractal heap indirect block in memory.
@@ -1219,34 +1377,28 @@ done:
herr_t
H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_dest)
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_dest)
/*
* Check arguments.
*/
HDassert(iblock);
+/* XXX: Enable this after the metadata cache supports the "un-evictable" flag */
+/* HDassert(iblock->rc == 0); */
#ifdef QAK
HDfprintf(stderr, "%s: Destroying indirect block\n", "H5HF_cache_iblock_dest");
#endif /* QAK */
-
- /* Decrement reference count on self */
- /* (let ref-counting API's callback for the block perform all cleanup) */
-/* XXX: This should actually free all the indirect block info, since this
- * routine should not get called until the block has no dependents (once
- * the "un-evictable" flag is in the metadata cache)
+/* XXX: Take out 'evicted' flag after "un-evictable" flag is working */
+ iblock->evicted = TRUE;
+/* XXX: Take out this goofy routine, after metadata cache is supporting
+ * "un-evictable" flag
*/
-/* XXX: Once the "un-evictable" flag is working in the metadata cache, can
- * get rid of the "self" field and make a wrapper when creating the parent
- * info for each "child" block, which will make the indirect block
- * un-evictable as well as create the initial ref-counted object.
- */
-/* XXX: Once the "un-evictable" flag is working in the metadata cache, the
- * ref-counted 'free' callback should just make the indirect block
- * evictable again.
- */
- H5RC_DEC(iblock->self);
+ ret_value = H5HF_cache_iblock_dest_real(iblock);
- FUNC_LEAVE_NOAPI(SUCCEED)
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_cache_iblock_dest() */
@@ -1305,18 +1457,12 @@ done:
static herr_t
H5HF_cache_iblock_size(const H5F_t UNUSED *f, const H5HF_indirect_t *iblock, size_t *size_ptr)
{
- H5HF_shared_t *shared; /* Shared fractal heap information */
-
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_size)
/* check arguments */
HDassert(iblock);
HDassert(size_ptr);
- /* Get the pointer to the shared heap info */
- shared = H5RC_GET_OBJ(iblock->shared);
- HDassert(shared);
-
/* Set size value */
*size_ptr = iblock->size;
diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c
index 43a6064..8ad9949 100644
--- a/src/H5HFdbg.c
+++ b/src/H5HFdbg.c
@@ -165,7 +165,6 @@ herr_t
H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
{
H5HF_t *fh = NULL; /* Fractal heap header info */
- H5HF_shared_t *shared; /* Shared fractal heap information */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_hdr_debug, FAIL)
@@ -185,10 +184,6 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Header...\n", indent, "");
@@ -197,37 +192,33 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
*/
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Heap address mapping method:",
- ((shared->addrmap) == H5HF_ABSOLUTE ? "Absolute" :
- ((shared->addrmap) == H5HF_MAPPED ? "Mapped" :
+ ((fh->addrmap) == H5HF_ABSOLUTE ? "Absolute" :
+ ((fh->addrmap) == H5HF_MAPPED ? "Mapped" :
"Unknown!")));
HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth,
"Min. size of standalone object:",
- (unsigned long)shared->standalone_size);
- HDfprintf(stream, "%*s%-*s %u%s\n", indent, "", fwidth,
- "Ref. count size:",
- (unsigned)shared->ref_count_size,
- (shared->ref_count_size == 0 ? " (ref. count not stored)" : ""));
+ (unsigned long)fh->standalone_size);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Total free space in managed blocks:",
- shared->total_man_free);
+ fh->total_man_free);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Total # of free entries for standalone blocks:",
- shared->total_std_free);
+ fh->total_std_free);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Total data block size:",
- shared->total_size);
+ fh->total_size);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Total managed space data block size:",
- shared->man_size);
+ fh->man_size);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Total standalone space data block size:",
- shared->std_size);
+ fh->std_size);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Number of objects in heap:",
- shared->nobjs);
+ fh->nobjs);
HDfprintf(stream, "%*sManaged Objects Doubling-Table Info...\n", indent, "");
- H5HF_dtable_debug(&shared->man_dtable, stream, indent + 3, MAX(0, fwidth -3));
+ H5HF_dtable_debug(&fh->man_dtable, stream, indent + 3, MAX(0, fwidth -3));
done:
if(fh && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, addr, fh, H5AC__NO_FLAGS_SET) < 0)
@@ -254,11 +245,9 @@ herr_t
H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
int indent, int fwidth, haddr_t hdr_addr, size_t block_size)
{
- H5HF_t *fh = NULL; /* Fractal heap header info */
+ H5HF_t *hdr = NULL; /* Fractal heap header info */
H5HF_direct_t *dblock = NULL; /* Fractal heap direct block info */
- H5HF_parent_shared_t par_shared; /* Parent shared information */
H5HF_direct_free_node_t *node; /* Pointer to free list node for block */
- H5HF_shared_t *shared; /* Shared fractal heap information */
size_t blk_prefix_size; /* Size of prefix for block */
unsigned node_count = 0; /* Number of free space nodes */
size_t amount_free = 0; /* Amount of free space in block */
@@ -283,21 +272,13 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
/*
* Load the fractal heap header.
*/
- if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/*
* Load the heap direct block
*/
- par_shared.shared = fh->shared;
- par_shared.parent = NULL;
- par_shared.parent_entry = 0;
- par_shared.parent_free_space = 0;
- if(NULL == (dblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, &block_size, &par_shared, H5AC_READ)))
+ if(NULL == (dblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, &block_size, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap direct block")
/* Check for valid free list */
@@ -306,11 +287,6 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, FAIL, "can't decode free list for block")
HDassert(dblock->free_list);
- /* Release the heap header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, fh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
- fh = NULL;
-
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Direct Block...\n", indent, "");
@@ -319,11 +295,20 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
*/
HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
"Address of fractal heap that owns this block:",
- shared->heap_addr);
+ hdr->heap_addr);
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Parent address:",
+ dblock->par_addr);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Parent entry:",
+ dblock->par_entry);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Parent # of rows:",
+ dblock->par_nrows);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Offset of direct block in heap:",
dblock->block_off);
- blk_prefix_size = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(shared, dblock);
+ blk_prefix_size = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of block header:",
blk_prefix_size);
@@ -388,6 +373,8 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
done:
if(dblock && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, dblock, H5AC__NO_FLAGS_SET) < 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")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_dblock_debug() */
@@ -410,9 +397,7 @@ herr_t
H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
int indent, int fwidth, haddr_t hdr_addr, unsigned nrows)
{
- H5HF_t *fh = NULL; /* Fractal heap header info */
- H5HF_shared_t *shared; /* Shared fractal heap information */
- H5HF_parent_shared_t par_shared; /* Parent shared information */
+ H5HF_t *hdr = NULL; /* Fractal heap header info */
H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */
size_t dblock_size; /* Current direct block size */
char temp_str[64]; /* Temporary string, for formatting */
@@ -435,28 +420,15 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
/*
* Load the fractal heap header.
*/
- if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/*
* Load the heap direct 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(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, &nrows, &par_shared, H5AC_READ)))
+ if(NULL == (iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, &nrows, hdr, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block")
- /* Release the heap header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, fh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header")
- fh = NULL;
-
/* Print opening message */
HDfprintf(stream, "%*sFractal Heap Indirect Block...\n", indent, "");
@@ -465,7 +437,16 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
*/
HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
"Address of fractal heap that owns this block:",
- shared->heap_addr);
+ hdr->heap_addr);
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Parent address:",
+ iblock->par_addr);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Parent entry:",
+ iblock->par_entry);
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Parent # of rows:",
+ iblock->par_nrows);
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
"Offset of indirect block in heap:",
iblock->block_off);
@@ -483,7 +464,7 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
iblock->max_rows);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Max direct block rows:",
- shared->man_dtable.max_direct_rows);
+ hdr->man_dtable.max_direct_rows);
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
"Next block column:",
iblock->next_col);
@@ -496,15 +477,15 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
/* Print the entry tables */
HDfprintf(stream, "%*sDirect Block Entries (address, free space):\n", indent, "");
- for(u = 0; u < shared->man_dtable.max_direct_rows && u < iblock->nrows; u++) {
- sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)shared->man_dtable.row_block_size[u]);
+ for(u = 0; u < hdr->man_dtable.max_direct_rows && u < iblock->nrows; u++) {
+ sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)hdr->man_dtable.row_block_size[u]);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
- for(v = 0; v < shared->man_dtable.cparam.width; v++) {
- size_t off = (u * shared->man_dtable.cparam.width) + v;
+ for(v = 0; v < hdr->man_dtable.cparam.width; v++) {
+ size_t off = (u * hdr->man_dtable.cparam.width) + v;
sprintf(temp_str, "Col #%u:", (unsigned)v);
- HDfprintf(stream, "%*s%-*s %8a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6),
+ HDfprintf(stream, "%*s%-*s %9a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6),
temp_str,
iblock->ents[off].addr,
iblock->ents[off].free_space);
@@ -512,16 +493,16 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
dblock_size *= 2;
} /* end for */
HDfprintf(stream, "%*sIndirect Block Entries:\n", indent, "");
- if(iblock->nrows > shared->man_dtable.max_direct_rows) {
- for(u = shared->man_dtable.max_direct_rows; u < iblock->nrows; u++) {
+ if(iblock->nrows > hdr->man_dtable.max_direct_rows) {
+ for(u = hdr->man_dtable.max_direct_rows; u < iblock->nrows; u++) {
sprintf(temp_str, "Row #%u:", (unsigned)u);
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
- for(v = 0; v < shared->man_dtable.cparam.width; v++) {
- size_t off = (u * shared->man_dtable.cparam.width) + v;
+ for(v = 0; v < hdr->man_dtable.cparam.width; v++) {
+ size_t off = (u * hdr->man_dtable.cparam.width) + v;
sprintf(temp_str, "Col #%u:", (unsigned)v);
- HDfprintf(stream, "%*s%-*s %8a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6),
+ HDfprintf(stream, "%*s%-*s %9a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6),
temp_str,
iblock->ents[off].addr,
iblock->ents[off].free_space);
@@ -536,6 +517,8 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
done:
if(iblock && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, iblock, H5AC__NO_FLAGS_SET) < 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")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_iblock_debug() */
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() */
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 175b521..cede8c9 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -57,82 +57,87 @@
)
/* Size of doubling-table information */
-#define H5HF_DTABLE_INFO_SIZE(s) ( \
+#define H5HF_DTABLE_INFO_SIZE(h) ( \
2 /* Width of table (i.e. # of columns) */ \
- + (s)->sizeof_size /* Starting block size */ \
- + (s)->sizeof_size /* Maximum direct block size */ \
+ + (h)->sizeof_size /* Starting block size */ \
+ + (h)->sizeof_size /* Maximum direct block size */ \
+ 2 /* Max. size of heap (log2 of actual value - i.e. the # of bits) */ \
+ 2 /* Starting # of rows in root indirect block */ \
- + (s)->sizeof_addr /* File address of table managed */ \
+ + (h)->sizeof_addr /* File address of table managed */ \
+ 2 /* Current # of rows in root indirect block */ \
- + (s)->sizeof_size /* Next direct block's heap offset */ \
+ + (h)->sizeof_size /* Next direct block's heap offset */ \
)
/* Size of the fractal heap header on disk */
-#define H5HF_HEADER_SIZE(s) ( \
+#define H5HF_HEADER_SIZE(h) ( \
/* General metadata fields */ \
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap header specific fields */ \
- + 1 /* Address mapping */ \
+ + 1 /* Address mapping mode */ \
+ 4 /* Min. size of standalone object */ \
- + 1 /* Size of ref. count for objects */ \
- + (s)->sizeof_size /* Total man. free space */ \
- + (s)->sizeof_size /* Total std. free entries */ \
- + (s)->sizeof_size /* Total size of heap */ \
- + (s)->sizeof_size /* Size of man. space in heap */ \
- + (s)->sizeof_size /* Size of std. space in heap */ \
- + (s)->sizeof_size /* Number of objects in heap */ \
- + H5HF_DTABLE_INFO_SIZE(s) /* Size of managed obj. doubling-table info */ \
+ + (h)->sizeof_size /* Total man. free space */ \
+ + (h)->sizeof_size /* Total std. free entries */ \
+ + (h)->sizeof_size /* Total size of heap */ \
+ + (h)->sizeof_size /* Size of man. space in heap */ \
+ + (h)->sizeof_size /* Size of std. space in heap */ \
+ + (h)->sizeof_size /* Number of objects in heap */ \
+ + H5HF_DTABLE_INFO_SIZE(h) /* Size of managed obj. doubling-table info */ \
)
/* Size of free space description in an absolute managed direct block */
#define H5HF_MAN_ABS_DIRECT_FREE_NODE_SIZE(d) (2 * (d)->blk_off_size)
/* Size of header for each object in an absolute managed direct block */
-#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(s, o) ( \
+#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(h, o) ( \
H5HF_SIZEOF_OFFSET_LEN(o) /* Length of object in block */ \
+ 1 /* Free space fragment length */ \
- + (s)->ref_count_size /* Ref. count of object in block */ \
)
-#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(s, d) ( \
+#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(h, d) ( \
(d)->blk_off_size /* Length of object in block */ \
+ 1 /* Free space fragment length */ \
- + (s)->ref_count_size /* Ref. count of object in block */ \
)
/* Size of overhead for a direct block */
-#define H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(s, o) ( \
+#define H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(h, o) ( \
/* General metadata fields */ \
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap managed, absolutely mapped direct block specific fields */ \
- + (s)->sizeof_addr /* File address of heap owning the block */ \
- + (s)->heap_off_size /* Offset of the block in the heap */ \
- + H5HF_SIZEOF_OFFSET_LEN(o) /* Total free space in a block */ \
+ + (h)->sizeof_addr /* File address of heap owning the block */ \
+ + (h)->sizeof_addr /* File address of parent block */ \
+ + 2 /* Entry within parent block */ \
+ + 2 /* # of rows for parent block */ \
+ + (h)->heap_off_size /* Offset of the block in the heap */ \
+ H5HF_SIZEOF_OFFSET_LEN(o) /* Offset of first descriptor in free list */ \
)
-#define H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(s, d) ( \
+#define H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(h, d) ( \
/* General metadata fields */ \
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap managed, absolutely mapped direct block specific fields */ \
- + (s)->sizeof_addr /* File address of heap owning the block */ \
- + (s)->heap_off_size /* Offset of the block in the heap */ \
+ + (h)->sizeof_addr /* File address of heap owning the block */ \
+ + (h)->sizeof_addr /* File address of parent block */ \
+ + 2 /* Entry within parent block */ \
+ + 2 /* # of rows for parent block */ \
+ + (h)->heap_off_size /* Offset of the block in the heap */ \
+ (d)->blk_off_size /* Offset of first descriptor in free list */ \
)
/* Size of managed indirect block (absolute & mapped) */
-#define H5HF_MAN_INDIRECT_SIZE(s, i) ( \
+#define H5HF_MAN_INDIRECT_SIZE(h, i) ( \
/* General metadata fields */ \
H5HF_METADATA_PREFIX_SIZE \
\
/* Fractal heap managed, absolutely mapped indirect block specific fields */ \
- + (s)->sizeof_addr /* File address of heap owning the block */ \
- + (s)->heap_off_size /* Offset of the block in the heap */ \
+ + (h)->sizeof_addr /* File address of heap owning the block */ \
+ + (h)->sizeof_addr /* File address of parent block */ \
+ + 2 /* Entry within parent block */ \
+ + 2 /* # of rows for parent block */ \
+ + (h)->heap_off_size /* Offset of the block in the heap */ \
+ 4 /* Next block entry to allocate from */ \
- + (MIN((i)->nrows, (s)->man_dtable.max_direct_rows) * (s)->man_dtable.cparam.width * ((s)->sizeof_addr + (s)->man_dtable.max_dir_blk_off_size)) /* Size of entries for direct blocks */ \
- + ((((i)->nrows > (s)->man_dtable.max_direct_rows) ? ((i)->nrows - (s)->man_dtable.max_direct_rows) : 0) * (s)->man_dtable.cparam.width * ((s)->sizeof_addr + (s)->heap_off_size)) /* Size of entries for indirect blocks */ \
+ + (MIN((i)->nrows, (h)->man_dtable.max_direct_rows) * (h)->man_dtable.cparam.width * ((h)->sizeof_addr + (h)->man_dtable.max_dir_blk_off_size)) /* Size of entries for direct blocks */ \
+ + ((((i)->nrows > (h)->man_dtable.max_direct_rows) ? ((i)->nrows - (h)->man_dtable.max_direct_rows) : 0) * (h)->man_dtable.cparam.width * ((h)->sizeof_addr + (h)->heap_off_size)) /* Size of entries for indirect blocks */ \
)
@@ -175,10 +180,14 @@ typedef struct H5HF_freelist_t H5HF_freelist_t;
/* Fractal heap free list section info (forward decl - defined in H5HFint.c) */
typedef struct H5HF_section_free_node_t H5HF_section_free_node_t;
-/* Each fractal heap has certain information that can be shared across all
- * the instances of blocks in that fractal heap.
+/* The fractal heap header information */
+/* (Each fractal heap header has certain information that is shared across all
+ * the instances of blocks in that fractal heap)
*/
-typedef struct H5HF_shared_t {
+typedef struct H5HF_t {
+ /* Information for H5AC cache functions, _must_ be first field in structure */
+ H5AC_info_t cache_info;
+
/* Shared internal information (varies during lifetime of heap) */
hsize_t total_man_free; /* Total amount of free space in managed blocks */
hsize_t total_std_free; /* Total # of free standalone ID entries */
@@ -190,8 +199,11 @@ typedef struct H5HF_shared_t {
hsize_t nobjs; /* Number of objects in heap */
/* Cached/computed values (not stored in header) */
+ size_t rc; /* Reference count of child blocks */
hbool_t dirty; /* Shared info is modified */
+ hbool_t evicted; /* Shared info is evicted from cache */
haddr_t heap_addr; /* Address of heap header in the file */
+ H5AC_protect_t mode; /* Access mode for heap */
H5F_t *f; /* Pointer to file for heap */
size_t sizeof_size; /* Size of file sizes */
size_t sizeof_addr; /* Size of file addresses */
@@ -205,23 +217,49 @@ typedef struct H5HF_shared_t {
/* Information set by user */
H5HF_addrmap_t addrmap; /* Type of address mapping */
uint32_t standalone_size; /* Size of object to store standalone */
- unsigned char ref_count_size; /* Size of ref. count for objects (only for heaps w/ref. counted objects) */
/* Information derived from user parameters (not stored in header) */
unsigned char heap_off_size; /* Size of heap offsets (in bytes) */
- hbool_t ref_count_obj; /* Are objects in the heap ref. counted? */
+ hbool_t debug_objs; /* Is the heap storing objects in 'debug' format */
hbool_t have_io_filter; /* Does the heap have I/O filters for the direct blocks? */
hbool_t write_once; /* Is heap being written in "write once" mode? */
-} H5HF_shared_t;
+} H5HF_t;
-/* The fractal heap header information */
-typedef struct H5HF_t {
+/* Indirect block entry */
+typedef struct H5HF_indirect_ent_t {
+ haddr_t addr; /* Direct block's address */
+ hsize_t free_space; /* Amount of free space in block pointed to */
+/* XXX: Will need space for block size, for blocks with I/O filters */
+} H5HF_indirect_ent_t;
+
+/* Fractal heap indirect block */
+typedef struct H5HF_indirect_t {
/* Information for H5AC cache functions, _must_ be first field in structure */
H5AC_info_t cache_info;
- /* Internal fractal heap information */
- H5RC_t *shared; /* Ref-counted shared info */
-} H5HF_t;
+ /* Internal heap information */
+ size_t rc; /* Reference count of child blocks */
+ hbool_t dirty; /* Info is modified */
+ hbool_t evicted; /* Info is evicted from cache */
+ H5HF_t *shared; /* Shared heap header info */
+ struct H5HF_indirect_t *parent; /* Shared parent indirect block info */
+ hsize_t child_free_space; /* Total amount of free space in children */
+ haddr_t addr; /* Address of this indirect block on disk */
+ unsigned nrows; /* Total # of rows in indirect block */
+ unsigned max_rows; /* Max. # of rows in indirect block */
+ size_t size; /* Size of indirect block on disk */
+ unsigned next_col; /* "Column" of next managed block (in doubling table) */
+ unsigned next_row; /* "Row" of next managed block (in doubling table) */
+ hsize_t next_size; /* Size of next managed block */
+ H5HF_indirect_ent_t *ents; /* Pointer to block entry table */
+
+ /* Stored values */
+ haddr_t par_addr; /* Address of parent block on disk */
+ unsigned par_entry; /* Entry in parent's table */
+ unsigned par_nrows; /* Total # of rows in parent indirect block */
+ hsize_t block_off; /* Offset of the block within the heap's address space */
+ size_t next_entry; /* Entry of next managed block */
+} H5HF_indirect_t;
/* Direct block free list node */
typedef struct H5HF_direct_free_node_t {
@@ -245,60 +283,22 @@ typedef struct H5HF_direct_t {
H5AC_info_t cache_info;
/* Internal heap information */
- H5RC_t *shared; /* Ref-counted shared heap info */
- H5RC_t *parent; /* Ref-counted shared parent block info */
- size_t parent_entry; /* Entry in parent's table */
+ H5HF_t *shared; /* Shared heap header info */
+ H5HF_indirect_t *parent; /* Shared parent indirect block info */
size_t size; /* Size of direct block */
unsigned blk_off_size; /* Size of offsets in the block */
+ size_t blk_free_space; /* Total amount of free space in block */
H5HF_direct_free_head_t *free_list; /* Pointer to free list for block */
uint8_t *blk; /* Pointer to buffer containing block data */
/* Stored values */
+ haddr_t par_addr; /* Address of parent block on disk */
+ unsigned par_entry; /* Entry in parent's table */
+ unsigned par_nrows; /* Total # of rows in parent indirect block */
hsize_t block_off; /* Offset of the block within the heap's address space */
- size_t blk_free_space; /* Total amount of free space in block */
size_t free_list_head; /* Offset of head of free list in block */
} H5HF_direct_t;
-/* Indirect block entry */
-typedef struct H5HF_indirect_ent_t {
- haddr_t addr; /* Direct block's address */
- hsize_t free_space; /* Amount of free space in block pointed to */
-/* XXX: Will need space for block size, for blocks with I/O filters */
-} H5HF_indirect_ent_t;
-
-/* Fractal heap indirect block */
-typedef struct H5HF_indirect_t {
- /* Information for H5AC cache functions, _must_ be first field in structure */
- H5AC_info_t cache_info;
-
- /* Internal heap information */
- hbool_t dirty; /* Info is modified */
- H5RC_t *shared; /* Ref-counted shared info */
- H5RC_t *parent; /* Ref-counted shared parent block info */
- size_t parent_entry; /* Entry in parent's table */
- H5RC_t *self; /* Ref-counted shared 'self' block info */
- unsigned nrows; /* Total # of rows in indirect block */
- unsigned max_rows; /* Max. # of rows in indirect block */
- size_t size; /* Size of indirect block on disk */
- unsigned next_col; /* "Column" of next managed block (in doubling table) */
- unsigned next_row; /* "Row" of next managed block (in doubling table) */
- unsigned next_entry; /* Entry of next managed block */
- hsize_t next_size; /* Size of next managed block */
- H5HF_indirect_ent_t *ents; /* Pointer to block entry table */
-
- /* Stored values */
- hsize_t block_off; /* Offset of the block within the heap's address space */
- hsize_t child_free_space; /* Total amount of free space in children */
-} H5HF_indirect_t;
-
-/* Shared information for parent of a fractal heap block */
-typedef struct H5HF_parent_shared_t {
- H5RC_t *shared; /* Ref-counted shared heap info */
- H5RC_t *parent; /* Ref-counted shared parent block info */
- size_t parent_entry; /* Entry in parent's table */
- hsize_t parent_free_space; /* Free space in block, from parent */
-} H5HF_parent_shared_t;
-
/* Fractal heap metadata statistics info */
typedef struct H5HF_stat_t {
hsize_t total_size; /* Total size of heap allocated (man & std) */
@@ -348,22 +348,32 @@ H5FL_SEQ_EXTERN(H5HF_indirect_ent_t);
/* Package Private Prototypes */
/******************************/
-/* Routines for managing shared fractal heap info */
-H5_DLL H5HF_shared_t * H5HF_shared_alloc(H5F_t *f);
-H5_DLL herr_t H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t heap_addr, H5HF_create_t *cparam);
-H5_DLL herr_t H5HF_shared_own(H5HF_t *fh, H5HF_shared_t *shared);
+/* Routines for managing shared fractal heap header */
+H5_DLL H5HF_t * H5HF_alloc(H5F_t *f);
+H5_DLL herr_t H5HF_init(H5HF_t *fh, haddr_t heap_addr, H5HF_create_t *cparam);
+H5_DLL herr_t H5HF_finish_init(H5HF_t *fh);
+
+/* Doubling table routines */
+H5_DLL herr_t H5HF_dtable_dest(H5HF_dtable_t *dtable);
+
+/* Heap header routines */
+H5_DLL herr_t H5HF_cache_hdr_dest_real(H5HF_t *hdr);
+H5_DLL herr_t H5HF_hdr_incr(H5HF_t *hdr);
+H5_DLL herr_t H5HF_hdr_decr(H5HF_t *hdr);
/* Indirect block routines */
-H5_DLL herr_t H5HF_iblock_free(void *_iblock);
+H5_DLL herr_t H5HF_cache_iblock_dest_real(H5HF_indirect_t *iblock);
+H5_DLL herr_t H5HF_iblock_incr(H5HF_indirect_t *iblock);
+H5_DLL herr_t H5HF_iblock_decr(H5HF_indirect_t *iblock);
/* Routines for allocating space */
H5_DLL herr_t H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr);
-H5_DLL herr_t H5HF_man_find(H5RC_t *fh_shared, hid_t dxpl_id, size_t request,
+H5_DLL herr_t H5HF_man_find(H5HF_t *fh, hid_t dxpl_id, size_t request,
H5HF_section_free_node_t **sec_node/*out*/);
-H5_DLL herr_t H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id,
+H5_DLL herr_t H5HF_man_insert(H5HF_t *fh, hid_t dxpl_id,
H5HF_section_free_node_t *sec_node, size_t obj_size, const void *obj,
void *id);
-H5_DLL herr_t H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off,
+H5_DLL herr_t H5HF_man_read(H5HF_t *fh, hid_t dxpl_id, hsize_t obj_off,
void *obj);
/* Metadata cache callbacks */
diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h
index 4454ee7..6296e8c 100644
--- a/src/H5HFprivate.h
+++ b/src/H5HFprivate.h
@@ -65,8 +65,6 @@ typedef struct H5HF_create_t {
H5HF_addrmap_t addrmap; /* Type of address mapping for objects in heap */
uint32_t standalone_size; /* Size of object to store standalone */
/* (i.e. max. size of object to manage) */
- unsigned char ref_count_size; /* Size of ref. count field for objects, in bytes (0 means no ref. counts for objects) */
- /* (only for heaps w/ref. counted objects) */
} H5HF_create_t;
diff --git a/src/H5HFstat.c b/src/H5HFstat.c
index 6cdc61b..93e8036 100644
--- a/src/H5HFstat.c
+++ b/src/H5HFstat.c
@@ -85,8 +85,7 @@
herr_t
H5HF_stat_info(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_stat_t *stats)
{
- H5HF_t *fh = NULL; /* Pointer to the B-tree header */
- H5HF_shared_t *shared; /* Shared fractal heap information */
+ H5HF_t *hdr = NULL; /* Pointer to the fractal heap header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_stat_info)
@@ -97,24 +96,20 @@ H5HF_stat_info(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_stat_t *stats)
HDassert(stats);
/* Look up the fractal heap header */
- if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/* Report statistics for fractal heap */
- stats->total_size = shared->total_size;
- stats->man_size = shared->man_size;
- stats->std_size = shared->std_size;
- stats->man_free_space = shared->total_man_free;
- stats->nobjs = shared->nobjs;
+ stats->total_size = hdr->total_size;
+ stats->man_size = hdr->man_size;
+ stats->std_size = hdr->std_size;
+ stats->man_free_space = hdr->total_man_free;
+ stats->nobjs = hdr->nobjs;
/* XXX: Add more metadata statistics for the heap */
done:
/* Release fractal heap header node */
- if(fh && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, fh, H5AC__NO_FLAGS_SET) < 0)
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header info")
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5HFtest.c b/src/H5HFtest.c
index c96d516..02024b9 100644
--- a/src/H5HFtest.c
+++ b/src/H5HFtest.c
@@ -86,8 +86,7 @@
herr_t
H5HF_get_cparam_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_create_t *cparam)
{
- H5HF_t *fh = NULL; /* Pointer to the B-tree header */
- H5HF_shared_t *shared; /* Shared fractal heap information */
+ H5HF_t *hdr = NULL; /* Pointer to the fractal heap header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_get_cparam_test)
@@ -98,22 +97,17 @@ H5HF_get_cparam_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_create_t *cp
HDassert(cparam);
/* Look up the fractal heap header */
- if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap header")
- /* Get the pointer to the shared fractal heap info */
- shared = H5RC_GET_OBJ(fh->shared);
- HDassert(shared);
-
/* Get fractal heap creation parameters */
- cparam->addrmap = shared->addrmap;
- cparam->standalone_size = shared->standalone_size;
- cparam->ref_count_size = shared->ref_count_size;
- HDmemcpy(&(cparam->managed), &(shared->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t));
+ cparam->addrmap = hdr->addrmap;
+ cparam->standalone_size = hdr->standalone_size;
+ HDmemcpy(&(cparam->managed), &(hdr->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t));
done:
/* Release fractal heap header node */
- if(fh && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, fh, H5AC__NO_FLAGS_SET) < 0)
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header info")
FUNC_LEAVE_NOAPI(ret_value)