From 87050be33e3a5931ef88b4faee557c3bfdb809b4 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 27 Mar 2006 16:57:50 -0500 Subject: [svn-r12161] Purpose: Code checkpoint Description: Checkpoint fractal heap code at a stable point in development. It appears that adding objects to heaps and reading them back out is now working properly (as long as there are no gaps in the heap and no standalone objects are created). Platforms tested: FreeBSD 4.11 (sleipnir) Linux 2.4 (chicago) Linux 2.4 (mir) w/64-bit & FORTRAN & C++ Solaris 9 (shanti) w/64-bit --- src/H5HF.c | 46 +- src/H5HFcache.c | 482 +++--- src/H5HFdbg.c | 121 +- src/H5HFint.c | 922 +++++++----- src/H5HFpkg.h | 198 +-- src/H5HFprivate.h | 2 - src/H5HFstat.c | 21 +- src/H5HFtest.c | 18 +- test/fheap.c | 4309 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 9 files changed, 5124 insertions(+), 995 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,32 +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) - 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 absolute 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))) - 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) + 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 @@ -372,11 +396,11 @@ test_create(hid_t fapl) PASSED() /* Query the type of address mapping */ - TESTING("Query mapped 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))) + 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,30 +1460,18 @@ 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 <= STD_MAN_MAX_DIRECT_SIZE) { -#ifdef QAK -HDfprintf(stderr, "block_size = %Zu\n", block_size); -#endif /* QAK */ + while(block_size <= cparam->managed.max_direct_size) { /* Loop over filling direct blocks for a row */ -#ifdef QAK -HDfprintf(stderr, "block number: "); -#endif /* QAK */ - for(u = 0; u < STD_MAN_WIDTH; u++) { -#ifdef QAK -HDfprintf(stderr, "%u ", u); -#endif /* QAK */ + 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 */ -#ifdef QAK -HDfprintf(stderr, "\n"); -#endif /* QAK */ /* Adjust block size for row */ if(nrows > 0) @@ -1517,17 +1515,17 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_first_recursive_indirect(hid_t fapl) +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 */ - 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 */ @@ -1547,14 +1545,10 @@ 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 -#ifdef QAK -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 @@ -1562,30 +1556,18 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); TESTING("inserting objects to create first recursive 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 <= STD_MAN_MAX_DIRECT_SIZE) { -#ifdef QAK -HDfprintf(stderr, "block_size = %Zu\n", block_size); -#endif /* QAK */ + while(block_size <= cparam->managed.max_direct_size) { /* Loop over filling direct blocks for a row */ -#ifdef QAK -HDfprintf(stderr, "block number: "); -#endif /* QAK */ - for(u = 0; u < STD_MAN_WIDTH; u++) { -#ifdef QAK -HDfprintf(stderr, "%u ", u); -#endif /* QAK */ + 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 */ -#ifdef QAK -HDfprintf(stderr, "\n"); -#endif /* QAK */ /* Adjust block size for row */ if(nrows > 0) @@ -1609,8 +1591,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 */ @@ -1637,59 +1620,3975 @@ error: /*------------------------------------------------------------------------- - * Function: main + * Function: test_abs_second_direct_recursive_indirec5 * - * Purpose: Test the fractal heap code + * 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: + * Return: Success: 0 * - * Failure: + * Failure: 1 * * Programmer: Quincey Koziol - * Friday, February 24, 2006 + * Tuesday, March 21, 2006 * *------------------------------------------------------------------------- */ -int -main(void) +static int +test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) { - hid_t fapl = -1; /* File access property list for data files */ - unsigned nerrors = 0; /* Cumulative error count */ + 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 */ - /* Reset library */ - h5_reset(); - fapl = h5_fileaccess(); + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - /* Test fractal heap creation */ -#ifndef QAK - nerrors += test_create(fapl); + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR - /* 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 -#else /* QAK */ -HDfprintf(stderr, "Uncomment tests!\n"); -#endif /* QAK */ + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - if(nerrors) - goto error; - puts("All fractal heap tests passed."); -#ifdef QAK + /* 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 <= 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 */ + /* 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 */ + + 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_recursive_indirect_two_deep() */ + + +/*------------------------------------------------------------------------- + * 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, 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 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +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 */ + 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; /* 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 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 */ + + /* Insert one more object, to force creation of third 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_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() */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Test the fractal heap code + * + * Return: Success: + * + * Failure: + * + * Programmer: Quincey Koziol + * Friday, February 24, 2006 + * + *------------------------------------------------------------------------- + */ +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 */ + + /* Reset library */ + h5_reset(); + fapl = h5_fileaccess(); + +#ifndef QAK + /* Test fractal heap with small parameters */ + init_small_cparam(&cparam); + puts("Testing with small heap creation parameters:"); + nerrors += run_tests(fapl, &cparam); + +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ +#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 */ + + if(nerrors) + goto error; + puts("All fractal heap tests passed."); +#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() */ -- cgit v0.12