summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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
-rw-r--r--test/fheap.c4229
9 files changed, 5084 insertions, 955 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)
diff --git a/test/fheap.c b/test/fheap.c
index 6ae7830..24ba033 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -28,17 +28,29 @@
/* Other private headers that this test requires */
#include "H5Iprivate.h"
#include "H5MMprivate.h" /* Memory management */
-
-/* "Standard" creation table parameters */
+#include "H5Vprivate.h" /* Vectors and arrays */
+
+/* "Small" heap creation parameters */
+#define SMALL_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */
+#define SMALL_STAND_SIZE (8 * 1024) /* Standalone obj. min. size */
+#define SMALL_MAN_WIDTH 4 /* Managed obj. table width */
+#define SMALL_MAN_START_BLOCK_SIZE 512 /* Managed obj. starting block size */
+#define SMALL_MAN_MAX_DIRECT_SIZE (64 * 1024) /* Managed obj. max. direct block size */
+#define SMALL_MAN_MAX_INDEX 32 /* Managed obj. # of bits for total heap size */
+#define SMALL_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */
+
+/* "Standard" heap creation parameters */
#define STD_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */
#define STD_STAND_SIZE (64 * 1024) /* Standalone obj. min. size */
-#define STD_REF_COUNT_SIZE 0 /* Size of ref. count for obj. */
#define STD_MAN_WIDTH 32 /* Managed obj. table width */
#define STD_MAN_START_BLOCK_SIZE 1024 /* Managed obj. starting block size */
#define STD_MAN_MAX_DIRECT_SIZE (1024 * 1024) /* Managed obj. max. direct block size */
#define STD_MAN_MAX_INDEX 64 /* Managed obj. # of bits for total heap size */
#define STD_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */
+/* Heap metadata */
+#define DBLOCK_OVERHEAD 32 /* # of bytes in direct block overhead */
+
const char *FILENAME[] = {
"fheap",
NULL
@@ -73,7 +85,6 @@ init_std_cparam(H5HF_create_t *cparam)
/* General parameters */
cparam->addrmap = STD_ADDRMAP;
cparam->standalone_size = STD_STAND_SIZE;
- cparam->ref_count_size = STD_REF_COUNT_SIZE;
/* Managed object doubling-table parameters */
cparam->managed.width = STD_MAN_WIDTH;
@@ -87,6 +98,42 @@ init_std_cparam(H5HF_create_t *cparam)
/*-------------------------------------------------------------------------
+ * Function: init_small_cparam
+ *
+ * Purpose: Initialize heap creation parameter structure with small
+ * settings
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+init_small_cparam(H5HF_create_t *cparam)
+{
+ /* Wipe out background */
+ HDmemset(cparam, 0, sizeof(H5HF_create_t));
+
+ /* General parameters */
+ cparam->addrmap = SMALL_ADDRMAP;
+ cparam->standalone_size = SMALL_STAND_SIZE;
+
+ /* Managed object doubling-table parameters */
+ cparam->managed.width = SMALL_MAN_WIDTH;
+ cparam->managed.start_block_size = SMALL_MAN_START_BLOCK_SIZE;
+ cparam->managed.max_direct_size = SMALL_MAN_MAX_DIRECT_SIZE;
+ cparam->managed.max_index = SMALL_MAN_MAX_INDEX;
+ cparam->managed.start_root_rows = SMALL_MAN_START_ROOT_ROWS;
+
+ return(0);
+} /* init_small_cparam() */
+
+
+/*-------------------------------------------------------------------------
* Function: check_stats
*
* Purpose: Verify stats for a heap
@@ -154,8 +201,9 @@ error:
*-------------------------------------------------------------------------
*/
static int
-fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size,
- size_t block_size, unsigned start_nobjs, unsigned *nobjs_ptr)
+fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam,
+ hsize_t heap_size, size_t block_size,
+ unsigned start_nobjs, unsigned *nobjs_ptr)
{
H5HF_stat_t heap_stats; /* Statistics about the heap */
hsize_t heap_id; /* Heap ID for object inserted */
@@ -173,12 +221,12 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size,
/* Initialize variables */
if(block_size <= (64 * 1024)) {
- data_size = block_size - 28; /* '28' is the size of the direct block's overhead */
+ data_size = block_size - (DBLOCK_OVERHEAD + cparam->managed.max_index / 8); /* '28' is the size of the direct block's overhead */
obj_overhead = 3;
free_overhead = 4;
} /* end if */
else {
- data_size = block_size - 29; /* '29' is the size of the direct block's overhead */
+ data_size = block_size - (DBLOCK_OVERHEAD + 1 + cparam->managed.max_index / 8); /* '29' is the size of the direct block's overhead */
obj_overhead = 4; /* Will handle blocks up to 2^24 */
free_overhead = 6;
} /* end else */
@@ -233,7 +281,7 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size,
ids[nobjs - 1] = heap_id;
/* Check stats for heap */
- if((heap_stats.man_free_space - (sizeof(obj) + obj_overhead)) < free_overhead)
+ if((heap_stats.man_free_space - (sizeof(obj) + obj_overhead)) <= free_overhead)
free_frag_size = heap_stats.man_free_space - (sizeof(obj) + obj_overhead);
if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)(data_size - ((nobjs * (sizeof(obj) + obj_overhead)) + free_frag_size)), (hsize_t)(start_nobjs + nobjs)))
FAIL_STACK_ERROR
@@ -316,12 +364,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_create(hid_t fapl)
+test_create(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam, test_cparam; /* Creation parameters for heap */
+ H5HF_create_t test_cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
/* Set the filename to use for this test (dependent on fapl) */
@@ -338,9 +386,8 @@ test_create(hid_t fapl)
/*
* Test fractal heap creation (w/absolute address mapping)
*/
- TESTING("Fractal heap creation (w/absolute address mapping)");
- init_std_cparam(&cparam);
- if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, &cparam, &fh_addr/*out*/) < 0)
+ TESTING("fractal heap creation (w/absolute address mapping)");
+ if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -349,34 +396,11 @@ test_create(hid_t fapl)
PASSED()
/* Query the type of address mapping */
- TESTING("Query absolute address mapping setting");
+ TESTING("query heap creation parameters");
HDmemset(&test_cparam, 0, sizeof(H5HF_create_t));
if(H5HF_get_cparam_test(f, H5P_DATASET_XFER_DEFAULT, fh_addr, &test_cparam) < 0)
FAIL_STACK_ERROR
- if(HDmemcmp(&cparam, &test_cparam, sizeof(H5HF_create_t)))
- FAIL_STACK_ERROR
- PASSED()
-
- /*
- * Test fractal heap creation (w/mapped address mapping)
- */
- TESTING("Fractal heap creation (w/mapped address mapping)");
- init_std_cparam(&cparam);
- cparam.addrmap = H5HF_MAPPED;
- if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, &cparam, &fh_addr/*out*/) < 0)
- FAIL_STACK_ERROR
- if(!H5F_addr_defined(fh_addr))
- FAIL_STACK_ERROR
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0))
- FAIL_STACK_ERROR
- PASSED()
-
- /* Query the type of address mapping */
- TESTING("Query mapped address mapping setting");
- HDmemset(&test_cparam, 0, sizeof(H5HF_create_t));
- if(H5HF_get_cparam_test(f, H5P_DATASET_XFER_DEFAULT, fh_addr, &test_cparam) < 0)
- FAIL_STACK_ERROR
- if(HDmemcmp(&cparam, &test_cparam, sizeof(H5HF_create_t)))
+ if(HDmemcmp(cparam, &test_cparam, sizeof(H5HF_create_t)))
FAIL_STACK_ERROR
PASSED()
@@ -410,17 +434,17 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_insert_first(hid_t fapl)
+test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for object to insert */
unsigned char robj[10]; /* Buffer for object to read */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
@@ -435,8 +459,7 @@ test_abs_insert_first(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -450,11 +473,12 @@ test_abs_insert_first(hid_t fapl)
/*
* Test inserting first (small) object into absolute heap
*/
- TESTING("Inserting first (small) object into absolute heap");
+ TESTING("inserting first (small) object into absolute heap");
heap_id = 0;
if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
FAIL_STACK_ERROR
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)983, (hsize_t)1))
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1))
FAIL_STACK_ERROR
/* Check reading back in the object */
@@ -495,19 +519,19 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_insert_second(hid_t fapl)
+test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for first object to insert */
unsigned char robj[10]; /* Buffer for reading first object */
unsigned char obj2[20]; /* Buffer for second object to insert */
unsigned char robj2[20]; /* Buffer for reading second object */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned u; /* Local index variable */
/* Set the filename to use for this test (dependent on fapl) */
@@ -522,8 +546,7 @@ test_abs_insert_second(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -537,11 +560,12 @@ test_abs_insert_second(hid_t fapl)
/*
* Test inserting first (small) object into absolute heap
*/
- TESTING("Inserting two (small) objects into absolute heap");
+ TESTING("inserting two (small) objects into absolute heap");
heap_id = 0;
if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
FAIL_STACK_ERROR
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)983, (hsize_t)1))
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1))
FAIL_STACK_ERROR
/* Check reading back in the first object */
@@ -553,7 +577,8 @@ test_abs_insert_second(hid_t fapl)
heap_id = 0;
if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj2), obj2, &heap_id) < 0)
FAIL_STACK_ERROR
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)960, (hsize_t)2))
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + (sizeof(obj2) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)2))
FAIL_STACK_ERROR
/* Check reading back in the second object */
@@ -595,13 +620,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_insert_root_mult(hid_t fapl)
+test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
/* Set the filename to use for this test (dependent on fapl) */
@@ -616,8 +640,7 @@ test_abs_insert_root_mult(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -628,7 +651,7 @@ test_abs_insert_root_mult(hid_t fapl)
TESTING("inserting objects to fill absolute heap's root direct block");
/* Fill the heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, 0, NULL))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, 0, NULL))
FAIL_STACK_ERROR
PASSED()
@@ -665,16 +688,16 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_insert_force_indirect(hid_t fapl)
+test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for first object to insert */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned u; /* Local index variable */
@@ -690,8 +713,7 @@ test_abs_insert_force_indirect(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -702,7 +724,7 @@ test_abs_insert_force_indirect(hid_t fapl)
TESTING("inserting objects to create root indirect block");
/* Fill the heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, 0, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, 0, &nobjs))
FAIL_STACK_ERROR
/* Insert one more object, to force root indirect block creation */
@@ -719,7 +741,8 @@ test_abs_insert_force_indirect(hid_t fapl)
/* Increment object count */
nobjs++;
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)2048, (hsize_t)2048, (hsize_t)0, (hsize_t)983, (hsize_t)nobjs))
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)(2 * cparam->managed.start_block_size), (hsize_t)(2 * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)nobjs))
FAIL_STACK_ERROR
PASSED()
@@ -756,13 +779,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_insert_fill_second(hid_t fapl)
+test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -779,8 +801,7 @@ test_abs_insert_fill_second(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -791,12 +812,12 @@ test_abs_insert_fill_second(hid_t fapl)
TESTING("inserting objects to fill second direct block");
/* Fill the first direct block heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
/* Fill the second direct block heap up (also creates initial root indirect block) */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(2 * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
PASSED()
@@ -834,17 +855,17 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_insert_third_direct(hid_t fapl)
+test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for first object to insert */
unsigned char robj[10]; /* Buffer for reading object */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
unsigned u; /* Local index variable */
@@ -861,8 +882,7 @@ test_abs_insert_third_direct(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -872,13 +892,13 @@ test_abs_insert_third_direct(hid_t fapl)
*/
TESTING("inserting objects to create third direct block");
- /* Fill the first direct block heap up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ /* Fill the first direct block up */
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
/* Fill the second direct block heap up (also creates initial root indirect block) */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(2 * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
@@ -896,7 +916,8 @@ test_abs_insert_third_direct(hid_t fapl)
/* Increment object count */
tot_nobjs++;
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)3072, (hsize_t)3072, (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs))
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)(3 * cparam->managed.start_block_size), (hsize_t)(3 * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)tot_nobjs))
FAIL_STACK_ERROR
/* Read in object */
@@ -939,13 +960,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_fill_first_row(hid_t fapl)
+test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -963,8 +983,7 @@ test_abs_fill_first_row(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -975,9 +994,9 @@ test_abs_fill_first_row(hid_t fapl)
TESTING("inserting objects to fill first row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1016,17 +1035,17 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_start_second_row(hid_t fapl)
+test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for object to insert */
unsigned char robj[10]; /* Buffer for reading object */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
unsigned u; /* Local index variable */
@@ -1043,8 +1062,7 @@ test_abs_start_second_row(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -1055,9 +1073,9 @@ test_abs_start_second_row(hid_t fapl)
TESTING("inserting objects to start second row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1076,7 +1094,8 @@ test_abs_start_second_row(hid_t fapl)
/* Increment object count */
tot_nobjs++;
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)((STD_MAN_WIDTH + 1) * STD_MAN_START_BLOCK_SIZE), (hsize_t)((STD_MAN_WIDTH + 1) * STD_MAN_START_BLOCK_SIZE), (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs))
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)((cparam->managed.width + 1) * cparam->managed.start_block_size), (hsize_t)((cparam->managed.width + 1) * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)tot_nobjs))
FAIL_STACK_ERROR
/* Read in object */
@@ -1119,13 +1138,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_fill_second_row(hid_t fapl)
+test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -1143,8 +1161,7 @@ test_abs_fill_second_row(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -1155,17 +1172,17 @@ test_abs_fill_second_row(hid_t fapl)
TESTING("inserting objects to fill second row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
/* Loop over filling direct blocks, until second root indirect row is full */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)((cparam->managed.width * cparam->managed.start_block_size) + (u + 1) * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1205,17 +1222,17 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_start_third_row(hid_t fapl)
+test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for object to insert */
unsigned char robj[10]; /* Buffer for reading object */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
hsize_t heap_size; /* Total size of heap */
@@ -1233,8 +1250,7 @@ test_abs_start_third_row(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -1245,17 +1261,17 @@ test_abs_start_third_row(hid_t fapl)
TESTING("inserting objects to start third row of root indirect block");
/* Loop over filling direct blocks, until first root indirect row is full */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
/* Loop over filling direct blocks, until second root indirect row is full */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
- if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)((cparam->managed.width * cparam->managed.start_block_size) + (u + 1) * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1274,9 +1290,10 @@ test_abs_start_third_row(hid_t fapl)
/* Increment object count */
tot_nobjs++;
- heap_size = (2 * STD_MAN_WIDTH) * STD_MAN_START_BLOCK_SIZE +
- (2 * STD_MAN_START_BLOCK_SIZE);
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)2007, (hsize_t)tot_nobjs))
+ heap_size = (2 * cparam->managed.width) * cparam->managed.start_block_size +
+ (2 * cparam->managed.start_block_size);
+ free_space = (2 * cparam->managed.start_block_size) - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
FAIL_STACK_ERROR
/* Read in object */
@@ -1319,13 +1336,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_fill_fourth_row(hid_t fapl)
+test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -1345,8 +1361,7 @@ test_abs_fill_fourth_row(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -1357,14 +1372,14 @@ test_abs_fill_fourth_row(hid_t fapl)
TESTING("inserting objects to fill four rows of root indirect block");
/* Loop over rows */
- block_size = STD_MAN_START_BLOCK_SIZE;
+ block_size = cparam->managed.start_block_size;
heap_size = 0;
for(v = 0; v < 4; v++) {
/* Loop over filling direct blocks for a row */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
/* Fill a direct heap block up */
heap_size += block_size;
- if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1408,13 +1423,12 @@ error:
*-------------------------------------------------------------------------
*/
static int
-test_abs_fill_all_root_direct(hid_t fapl)
+test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
@@ -1435,14 +1449,10 @@ test_abs_fill_all_root_direct(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
-#ifdef QAK
-HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
-#endif /* QAK */
/*
* Test inserting mult. (small) objects to fill all direct rows in root indirect block
@@ -1450,10 +1460,1052 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
TESTING("inserting objects to fill all direct rows of root indirect block");
/* Loop over rows */
- block_size = STD_MAN_START_BLOCK_SIZE;
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_all_root_direct() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_first_recursive_indirec5
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block and create first recursive indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 20, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to force creation of first recursive indirect block
+ */
+ TESTING("inserting objects to create first recursive indirect block");
+
+ /* Loop over rows */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Insert one more object, to force creation of first recursive indirect block */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_first_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_second_direct_recursive_indirec5
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, create first recursive indirect block and start second
+ * direct block in that indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to force creation of second direct
+ * block in first recursive indirect block
+ */
+ TESTING("inserting objects to create second direct block in first recursive indirect block");
+
+ /* Loop over rows */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Fill the first direct block in the recursive indirect block up */
+ heap_size += cparam->managed.start_block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+
+ /* Insert one more object, to force creation of second direct block in
+ * first recursive indirect block
+ */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_second_direct_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_first_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, create first recursive indirect block and filling all
+ * direct blocks in that indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill all direct blocks in first recursive indirect block");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+ while(block_size <= max_block_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_first_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_second_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, create first recursive indirect block, filling all
+ * direct blocks in that indirect block and adding another
+ * object to force creation of second recursive indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to start second recursive indirect block");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+ while(block_size <= max_block_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Insert one more object, to force creation of second
+ * recursive indirect block
+ */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_second_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_second_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, create first recursive indirect block, filling all
+ * direct blocks in that indirect block and then create second
+ * recursive indirect block and fill all direct blocks in that
+ * indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u; /* Local index variable */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill all direct blocks in second recursive indirect block");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+ while(block_size <= max_block_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over direct block rows in second recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+ while(block_size <= max_block_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_second_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_recursive_indirect_row
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, create first recursive indirect block, filling all
+ * direct blocks in that indirect block and then create second
+ * recursive indirect block and fill all direct blocks in that
+ * indirect block.
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill all direct blocks in first row of recursive indirect block");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
heap_size = 0;
nrows = 0;
- while(block_size <= STD_MAN_MAX_DIRECT_SIZE) {
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+ while(block_size <= max_block_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_recursive_indirect_row() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_start_2nd_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the first row of indirect
+ * blocks and start on first block in second row of indirect blocks
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to start second row of recursive indirect blocks");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+ while(block_size <= max_block_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+
+ /* Insert one more object, to force creation of second
+ * recursive indirect block
+ */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_start_2nd_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_recursive_indirect_two_deep
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill recursive indirect blocks two levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
#ifdef QAK
HDfprintf(stderr, "block_size = %Zu\n", block_size);
#endif /* QAK */
@@ -1461,13 +2513,13 @@ HDfprintf(stderr, "block_size = %Zu\n", block_size);
#ifdef QAK
HDfprintf(stderr, "block number: ");
#endif /* QAK */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
#ifdef QAK
HDfprintf(stderr, "%u ", u);
#endif /* QAK */
/* Fill a direct heap block up */
heap_size += block_size;
- if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1483,6 +2535,56 @@ HDfprintf(stderr, "\n");
nrows++;
} /* end for */
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
PASSED()
/* Close the file */
@@ -1497,43 +2599,46 @@ error:
H5Fclose(file);
} H5E_END_TRY;
return(1);
-} /* test_abs_fill_all_root_direct() */
+} /* test_abs_recursive_indirect_two_deep() */
/*-------------------------------------------------------------------------
- * Function: test_abs_first_recursive_indirec5
+ * Function: test_abs_start_3rd_recursive_indirect
*
* Purpose: Test inserting mult. objects into absolute heap, creating
* enough direct blocks to fill all direct rows of root indirect
- * block and create first recursive indirect block.
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep and start first direct block
+ * in 3rd level of indirect blocks
*
* Return: Success: 0
*
* Failure: 1
*
* Programmer: Quincey Koziol
- * Monday, March 20, 2006
+ * Monday, March 27, 2006
*
*-------------------------------------------------------------------------
*/
static int
-test_abs_first_recursive_indirect(hid_t fapl)
+test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
{
hid_t file = -1; /* File ID */
hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
char filename[1024]; /* Filename to use */
H5F_t *f = NULL; /* Internal file object pointer */
- H5HF_create_t cparam; /* Creation parameters for heap */
haddr_t fh_addr; /* Address of fractal heap created */
unsigned char obj[10]; /* Buffer for object to insert */
unsigned char robj[10]; /* Buffer for reading object */
hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
unsigned nobjs = 0; /* Number of objects inserted */
unsigned tot_nobjs = 0; /* Total number of objects inserted */
size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
hsize_t heap_size; /* Total size of heap */
unsigned nrows; /* Number of rows inserted */
- unsigned u; /* Local index variable */
+ unsigned u, v, w; /* Local index variables */
/* Set the filename to use for this test (dependent on fapl) */
h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
@@ -1547,8 +2652,7 @@ test_abs_first_recursive_indirect(hid_t fapl)
STACK_ERROR
/* Create absolute heap */
- init_std_cparam(&cparam);
- if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0)
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
FAIL_STACK_ERROR
if(!H5F_addr_defined(fh_addr))
FAIL_STACK_ERROR
@@ -1557,15 +2661,16 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
#endif /* QAK */
/*
- * Test inserting mult. (small) objects to force creation of first recursive indirect block
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
*/
- TESTING("inserting objects to create first recursive indirect block");
+ TESTING("inserting objects to start recursive indirect blocks three levels deep");
- /* Loop over rows */
- block_size = STD_MAN_START_BLOCK_SIZE;
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
heap_size = 0;
nrows = 0;
- while(block_size <= STD_MAN_MAX_DIRECT_SIZE) {
+ while(block_size <= cparam->managed.max_direct_size) {
#ifdef QAK
HDfprintf(stderr, "block_size = %Zu\n", block_size);
#endif /* QAK */
@@ -1573,13 +2678,13 @@ HDfprintf(stderr, "block_size = %Zu\n", block_size);
#ifdef QAK
HDfprintf(stderr, "block number: ");
#endif /* QAK */
- for(u = 0; u < STD_MAN_WIDTH; u++) {
+ for(u = 0; u < cparam->managed.width; u++) {
#ifdef QAK
HDfprintf(stderr, "%u ", u);
#endif /* QAK */
/* Fill a direct heap block up */
heap_size += block_size;
- if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs))
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
FAIL_STACK_ERROR
tot_nobjs += nobjs;
} /* end for */
@@ -1595,7 +2700,59 @@ HDfprintf(stderr, "\n");
nrows++;
} /* end for */
- /* Insert one more object, to force creation of first recursive indirect block */
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Insert one more object, to force creation of third level deep
+ * recursive indirect block
+ */
/* Initialize object buffer */
for(u = 0; u < sizeof(obj); u++)
@@ -1609,8 +2766,9 @@ HDfprintf(stderr, "\n");
/* Increment object count */
tot_nobjs++;
- heap_size += STD_MAN_START_BLOCK_SIZE;
- if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs))
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
FAIL_STACK_ERROR
/* Read in object */
@@ -1633,7 +2791,2755 @@ error:
H5Fclose(file);
} H5E_END_TRY;
return(1);
-} /* test_abs_first_recursive_indirect() */
+} /* test_abs_start_3rd_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_first_3rd_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep and fill first indirect block
+ * in 3rd level of indirect blocks
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill first indirect block of recursive indirect blocks three levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_first_3rd_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_3rd_recursive_indirect_row
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep and fill all indirect blocks
+ * first row of 3rd level of indirect blocks
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(w = 0; w < cparam->managed.width; w++) {
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_3rd_recursive_indirect_row() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_all_3rd_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep and fill all indirect blocks
+ * that are three levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w, x, y; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_all_3rd_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_start_4th_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep, fill all indirect blocks
+ * that are three levels deep and start first direct block that
+ * is four levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w, x, y; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to start first direct block in recursive indirect blocks four levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Insert one more object, to force creation of four level deep
+ * recursive indirect block
+ */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_start_4th_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_first_4th_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep, fill all indirect blocks
+ * that are three levels deep and fill the first (3rd level)
+ * indirect block that is four levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w, x, y; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill first (3rd level) indirect block in recursive indirect block four levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over direct block rows in fourth level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < 1; w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_first_4th_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_4th_recursive_indirect_row
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep, fill all indirect blocks
+ * that are three levels deep and fill the first row of
+ * indirect block that is four levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w, x, y, z; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in first recursive indirect block
+ */
+ TESTING("inserting objects to fill first row of recursive indirect blocks four levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over row of 4th level indirect blocks */
+ for(z = 0; z < cparam->managed.width; z++) {
+#ifdef QAK
+HDfprintf(stderr, "4th indirect block # = %u\n", z);
+#endif /* QAK */
+
+ /* Loop over direct block rows in fourth level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < 1; y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_4th_recursive_indirect_row() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_fill_all_4th_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep, fill all indirect blocks
+ * that are three levels deep and fill all rows of
+ * indirect blocks that are four levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w, x, y, z, uu; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in recursive indirect blocks four levels deep
+ */
+ TESTING("inserting objects to fill all rows of recursive indirect blocks four levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(uu = 0; uu < (H5V_log2_of2(cparam->managed.width) + 1); uu++) {
+#ifdef QAK
+HDfprintf(stderr, "4th indirect row # = %u\n", uu);
+#endif /* QAK */
+
+ /* Loop over row of 4th level indirect blocks */
+ for(z = 0; z < cparam->managed.width; z++) {
+#ifdef QAK
+HDfprintf(stderr, "4th indirect block # = %u\n", z);
+#endif /* QAK */
+
+ /* Loop over direct block rows in fourth level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (uu + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_fill_all_4th_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: test_abs_start_5th_recursive_indirect
+ *
+ * Purpose: Test inserting mult. objects into absolute heap, creating
+ * enough direct blocks to fill all direct rows of root indirect
+ * block, fill all direct blocks in the row of indirect
+ * blocks that are 2 levels deep, fill all indirect blocks
+ * that are three levels deep, fill all rows of indirect blocks
+ * that are four levels deep and start first direct block in
+ * indirect blocks five levels deep
+ *
+ * Return: Success: 0
+ *
+ * Failure: 1
+ *
+ * Programmer: Quincey Koziol
+ * Monday, March 27, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam)
+{
+ hid_t file = -1; /* File ID */
+ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */
+ char filename[1024]; /* Filename to use */
+ H5F_t *f = NULL; /* Internal file object pointer */
+ haddr_t fh_addr; /* Address of fractal heap created */
+ unsigned char obj[10]; /* Buffer for object to insert */
+ unsigned char robj[10]; /* Buffer for reading object */
+ hsize_t heap_id; /* Heap ID for object inserted */
+ hsize_t free_space; /* Size of free space in heap */
+ unsigned nobjs = 0; /* Number of objects inserted */
+ unsigned tot_nobjs = 0; /* Total number of objects inserted */
+ size_t block_size; /* Size of block added */
+ size_t max_block_size; /* Max. size of block to add */
+ hsize_t heap_size; /* Total size of heap */
+ unsigned nrows; /* Number of rows inserted */
+ unsigned u, v, w, x, y, z, uu; /* Local index variables */
+
+ /* Set the filename to use for this test (dependent on fapl) */
+ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename));
+
+ /* Create the file to work on */
+ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ TEST_ERROR
+
+ /* Get a pointer to the internal file object */
+ if(NULL == (f = H5I_object(file)))
+ STACK_ERROR
+
+ /* Create absolute heap */
+ if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0)
+ FAIL_STACK_ERROR
+ if(!H5F_addr_defined(fh_addr))
+ FAIL_STACK_ERROR
+#ifdef QAK
+HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr);
+#endif /* QAK */
+
+ /*
+ * Test inserting mult. (small) objects to fill all direct
+ * blocks in recursive indirect blocks four levels deep
+ */
+ TESTING("inserting objects to create first direct block in recursive indirect blocks five levels deep");
+
+ /* Loop over direct block rows in root indirect block */
+ block_size = cparam->managed.start_block_size;
+ heap_size = 0;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(uu = 0; uu < (H5V_log2_of2(cparam->managed.width) + 1); uu++) {
+#ifdef QAK
+HDfprintf(stderr, "4th indirect row # = %u\n", uu);
+#endif /* QAK */
+
+ /* Loop over row of 4th level indirect blocks */
+ for(z = 0; z < cparam->managed.width; z++) {
+#ifdef QAK
+HDfprintf(stderr, "4th indirect block # = %u\n", z);
+#endif /* QAK */
+
+ /* Loop over direct block rows in fourth level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Loop over rows of 3rd level deep indirect blocks */
+ for(y = 0; y < (uu + 1); y++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect row # = %u\n", y);
+#endif /* QAK */
+
+ /* Loop over row of 3rd level deep indirect blocks */
+ for(x = 0; x < cparam->managed.width; x++) {
+#ifdef QAK
+HDfprintf(stderr, "3rd indirect block # = %u\n", x);
+#endif /* QAK */
+
+ /* Loop over direct block rows in third level indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ while(block_size <= cparam->managed.max_direct_size) {
+ /* Loop over filling direct blocks for a row */
+ for(u = 0; u < cparam->managed.width; u++) {
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+
+ /* Loop over rows of 2nd level deep indirect blocks */
+ for(w = 0; w < (y + 1); w++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect row # = %u\n", w);
+#endif /* QAK */
+
+ /* Loop over row of indirect blocks */
+ for(v = 0; v < cparam->managed.width; v++) {
+#ifdef QAK
+HDfprintf(stderr, "indirect block # = %u\n", v);
+#endif /* QAK */
+ /* Loop over direct block rows in first recursive indirect block */
+ block_size = cparam->managed.start_block_size;
+ nrows = 0;
+ max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) -
+ (H5V_log2_of2(cparam->managed.start_block_size) +
+ H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1));
+#ifdef QAK
+HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size);
+#endif /* QAK */
+ while(block_size <= max_block_size) {
+#ifdef QAK
+HDfprintf(stderr, "block_size = %Zu\n", block_size);
+#endif /* QAK */
+ /* Loop over filling direct blocks for a row */
+#ifdef QAK
+HDfprintf(stderr, "block number: ");
+#endif /* QAK */
+ for(u = 0; u < cparam->managed.width; u++) {
+#ifdef QAK
+HDfprintf(stderr, "%u ", u);
+#endif /* QAK */
+ /* Fill a direct heap block up */
+ heap_size += block_size;
+ if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs))
+ FAIL_STACK_ERROR
+ tot_nobjs += nobjs;
+ } /* end for */
+#ifdef QAK
+HDfprintf(stderr, "\n");
+#endif /* QAK */
+
+ /* Adjust block size for row */
+ if(nrows > 0)
+ block_size *= 2;
+
+ /* Increment row count */
+ nrows++;
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+ } /* end for */
+
+ /* Insert one more object, to force creation of five level deep
+ * recursive indirect block
+ */
+
+ /* Initialize object buffer */
+ for(u = 0; u < sizeof(obj); u++)
+ obj[u] = u + tot_nobjs;
+
+ /* Insert object */
+ heap_id = 0;
+ if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0)
+ FAIL_STACK_ERROR
+
+ /* Increment object count */
+ tot_nobjs++;
+
+ heap_size += cparam->managed.start_block_size;
+ free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8));
+ if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs))
+ FAIL_STACK_ERROR
+
+ /* Read in object */
+ if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0)
+ FAIL_STACK_ERROR
+ if(HDmemcmp(obj, robj, sizeof(obj)))
+ FAIL_STACK_ERROR
+
+ PASSED()
+
+ /* Close the file */
+ if(H5Fclose(file) < 0)
+ TEST_ERROR
+
+ /* All tests passed */
+ return(0);
+
+error:
+ H5E_BEGIN_TRY {
+ H5Fclose(file);
+ } H5E_END_TRY;
+ return(1);
+} /* test_abs_start_5th_recursive_indirect() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: run_tests
+ *
+ * Purpose: Test the fractal heap code, with different file access property
+ * lists and heap creation parameters
+ *
+ * Return: Success:
+ *
+ * Failure:
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, March 21, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static unsigned
+run_tests(hid_t fapl, H5HF_create_t *cparam)
+{
+ unsigned nerrors = 0; /* Cumulative error count */
+
+ /* Test fractal heap creation */
+ nerrors += test_create(fapl, cparam);
+
+ /* Test fractal heap object insertion */
+#ifdef QAK
+ nerrors += test_abs_insert_first(fapl, cparam);
+ nerrors += test_abs_insert_second(fapl, cparam);
+ nerrors += test_abs_insert_root_mult(fapl, cparam);
+ nerrors += test_abs_insert_force_indirect(fapl, cparam);
+ nerrors += test_abs_insert_fill_second(fapl, cparam);
+ nerrors += test_abs_insert_third_direct(fapl, cparam);
+ nerrors += test_abs_fill_first_row(fapl, cparam);
+ nerrors += test_abs_start_second_row(fapl, cparam);
+ nerrors += test_abs_fill_second_row(fapl, cparam);
+ nerrors += test_abs_start_third_row(fapl, cparam);
+ nerrors += test_abs_fill_fourth_row(fapl, cparam);
+ nerrors += test_abs_fill_all_root_direct(fapl, cparam);
+ nerrors += test_abs_first_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_second_direct_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_first_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_second_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_second_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_recursive_indirect_row(fapl, cparam);
+ nerrors += test_abs_start_2nd_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_recursive_indirect_two_deep(fapl, cparam);
+ nerrors += test_abs_start_3rd_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_first_3rd_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_3rd_recursive_indirect_row(fapl, cparam);
+ nerrors += test_abs_fill_all_3rd_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_start_4th_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_first_4th_recursive_indirect(fapl, cparam);
+ nerrors += test_abs_fill_4th_recursive_indirect_row(fapl, cparam);
+ nerrors += test_abs_fill_all_4th_recursive_indirect(fapl, cparam);
+#endif /* QAK */
+ /* If this test fails, uncomment the tests above, which build up to this
+ * level of complexity gradually. -QAK
+ */
+ nerrors += test_abs_start_5th_recursive_indirect(fapl, cparam);
+#ifndef QAK
+#else /* QAK */
+HDfprintf(stderr, "Uncomment tests!\n");
+#endif /* QAK */
+
+ return nerrors;
+} /* end run_tests() */
/*-------------------------------------------------------------------------
@@ -1653,6 +5559,7 @@ error:
int
main(void)
{
+ H5HF_create_t cparam; /* Creation parameters for heap */
hid_t fapl = -1; /* File access property list for data files */
unsigned nerrors = 0; /* Cumulative error count */
@@ -1660,28 +5567,20 @@ main(void)
h5_reset();
fapl = h5_fileaccess();
- /* Test fractal heap creation */
#ifndef QAK
- nerrors += test_create(fapl);
+ /* Test fractal heap with small parameters */
+ init_small_cparam(&cparam);
+ puts("Testing with small heap creation parameters:");
+ nerrors += run_tests(fapl, &cparam);
- /* Test fractal heap object insertion */
- nerrors += test_abs_insert_first(fapl);
- nerrors += test_abs_insert_second(fapl);
- nerrors += test_abs_insert_root_mult(fapl);
- nerrors += test_abs_insert_force_indirect(fapl);
- nerrors += test_abs_insert_fill_second(fapl);
- nerrors += test_abs_insert_third_direct(fapl);
- nerrors += test_abs_fill_first_row(fapl);
- nerrors += test_abs_start_second_row(fapl);
- nerrors += test_abs_fill_second_row(fapl);
- nerrors += test_abs_start_third_row(fapl);
- nerrors += test_abs_fill_fourth_row(fapl);
- nerrors += test_abs_fill_all_root_direct(fapl);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
- nerrors += test_abs_first_recursive_indirect(fapl);
#ifdef QAK
+ /* Test fractal heap with standard parameters */
+ init_std_cparam(&cparam);
+ puts("Testing with standard heap creation parameters:");
+ nerrors += run_tests(fapl, &cparam);
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
@@ -1689,7 +5588,7 @@ HDfprintf(stderr, "Uncomment tests!\n");
if(nerrors)
goto error;
puts("All fractal heap tests passed.");
-#ifdef QAK
+#ifndef QAK
h5_cleanup(FILENAME, fapl);
#else /* QAK */
HDfprintf(stderr, "Uncomment cleanup!\n");
@@ -1702,5 +5601,5 @@ error:
H5Pclose(fapl);
} H5E_END_TRY;
return 1;
-}
+} /* end main() */