diff options
-rw-r--r-- | src/H5HF.c | 46 | ||||
-rw-r--r-- | src/H5HFcache.c | 482 | ||||
-rw-r--r-- | src/H5HFdbg.c | 121 | ||||
-rw-r--r-- | src/H5HFint.c | 922 | ||||
-rw-r--r-- | src/H5HFpkg.h | 198 | ||||
-rw-r--r-- | src/H5HFprivate.h | 2 | ||||
-rw-r--r-- | src/H5HFstat.c | 21 | ||||
-rw-r--r-- | src/H5HFtest.c | 18 | ||||
-rw-r--r-- | test/fheap.c | 4229 |
9 files changed, 5084 insertions, 955 deletions
@@ -99,7 +99,6 @@ herr_t H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p) { H5HF_t *fh = NULL; /* The new fractal heap header information */ - H5HF_shared_t *shared = NULL; /* Shared fractal heap information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_create, FAIL) @@ -111,26 +110,17 @@ H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p) HDassert(cparam); HDassert(addr_p); - /* - * Allocate file and memory data structures. - */ - if(NULL == (fh = H5FL_MALLOC(H5HF_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for fractal heap header") - - /* Reset the metadata cache info for the heap header */ - HDmemset(&fh->cache_info, 0, sizeof(H5AC_info_t)); - - /* Allocate & basic initialization for the shared info struct */ - if(NULL == (shared = H5HF_shared_alloc(f))) + /* Allocate & basic initialization for the shared header */ + if(NULL == (fh = H5HF_alloc(f))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for shared heap info") /* Allocate space for the header on disk */ - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(shared)))) + if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(fh)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap header") - /* Initialize shared fractal heap info */ - if(H5HF_shared_init(shared, fh, *addr_p, cparam) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared fractal heap info") + /* Initialize shared fractal heap header */ + if(H5HF_init(fh, *addr_p, cparam) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't initialize shared fractal heap header") /* Cache the new fractal heap header */ if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, *addr_p, fh, H5AC__NO_FLAGS_SET) < 0) @@ -165,7 +155,6 @@ H5HF_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size, const void *obj, void *id/*out*/) { H5HF_t *fh = NULL; /* The fractal heap header information */ - H5HF_shared_t *shared; /* Shared fractal heap information */ unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */ herr_t ret_value = SUCCEED; @@ -189,34 +178,30 @@ HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size); if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* Check if object is large enough to be standalone */ - if(size >= shared->standalone_size) { + if(size >= fh->standalone_size) { HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "standalone blocks not supported yet") } /* end if */ else { /* Check if we are in "append only" mode, or if there's enough room for the object */ - if(shared->write_once) { + if(fh->write_once) { HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'write once' managed blocks not supported yet") } /* end if */ else { H5HF_section_free_node_t *sec_node; /* Pointer to free space section */ /* Find free space in heap */ - if(H5HF_man_find(fh->shared, dxpl_id, size, &sec_node) < 0) + if(H5HF_man_find(fh, dxpl_id, size, &sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate space in fractal heap") /* Use free space for allocating object */ - if(H5HF_man_insert(fh->shared, dxpl_id, sec_node, size, obj, id) < 0) + if(H5HF_man_insert(fh, dxpl_id, sec_node, size, obj, id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate space for object in fractal heap") } /* end else */ } /* end else */ /* Check for making header dirty */ - if(shared->dirty) + if(fh->dirty) hdr_flags |= H5AC__DIRTIED_FLAG; done: @@ -245,7 +230,6 @@ H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_id, void *obj/*out*/) { H5HF_t *fh = NULL; /* The fractal heap header information */ - H5HF_shared_t *shared; /* Shared fractal heap information */ const uint8_t *id = (const uint8_t *)_id; /* Object ID */ hsize_t obj_off; /* Object's offset in heap */ herr_t ret_value = SUCCEED; @@ -266,12 +250,8 @@ H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_id, if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* Decode the offset within the heap */ - UINT64DECODE_VAR(id, obj_off, shared->heap_off_size); + UINT64DECODE_VAR(id, obj_off, fh->heap_off_size); #ifdef QAK HDfprintf(stderr, "%s: obj_off = %Hu\n", FUNC, obj_off); #endif /* QAK */ @@ -282,7 +262,7 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "standalone blocks not supported ye } /* end if */ else { /* Read object from managed heap blocks */ - if(H5HF_man_read(fh->shared, dxpl_id, obj_off, obj) < 0) + if(H5HF_man_read(fh, dxpl_id, obj_off, obj) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't read object from fractal heap") } /* end else */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 1fd3b51..ab6ea76 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -259,7 +259,6 @@ static H5HF_t * H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2) { H5HF_t *fh = NULL; /* Fractal heap info */ - H5HF_shared_t *shared = NULL; /* Shared fractal heap information */ size_t size; /* Header size */ uint8_t *buf = NULL; /* Temporary buffer */ const uint8_t *p; /* Pointer into raw data buffer */ @@ -267,23 +266,23 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud H5HF_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5HF_cache_hdr_load, NULL) +#ifdef QAK +HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); +#endif /* QAK */ /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); /* Allocate space for the fractal heap data structure */ - if(NULL == (fh = H5FL_MALLOC(H5HF_t))) + if(NULL == (fh = H5HF_alloc(f))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - HDmemset(&fh->cache_info, 0, sizeof(H5AC_info_t)); - /* Allocate & basic initialization for the shared info struct */ - if(NULL == (shared = H5HF_shared_alloc(f))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for shared heap info") - shared->heap_addr = addr; + /* Set the heap header's address */ + fh->heap_addr = addr; /* Compute the size of the fractal heap header on disk */ - size = H5HF_HEADER_SIZE(shared); + size = H5HF_HEADER_SIZE(fh); /* Allocate temporary buffer */ if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL) @@ -316,36 +315,33 @@ H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *ud HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap header") /* Heap address mapping */ - shared->addrmap = *p++; + fh->addrmap = *p++; HDassert(H5HF_ABSOLUTE == 0); - if(shared->addrmap > H5HF_MAPPED) + if(fh->addrmap > H5HF_MAPPED) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect fractal heap address mapping") /* Min. size of standalone objects */ - UINT32DECODE(p, shared->standalone_size); - - /* Size of ref. count for objects in heap */ - shared->ref_count_size = *p++; + UINT32DECODE(p, fh->standalone_size); /* Internal management information */ - H5F_DECODE_LENGTH(f, p, shared->total_man_free); - H5F_DECODE_LENGTH(f, p, shared->total_std_free); + H5F_DECODE_LENGTH(f, p, fh->total_man_free); + H5F_DECODE_LENGTH(f, p, fh->total_std_free); /* Statistics information */ - H5F_DECODE_LENGTH(f, p, shared->total_size); - H5F_DECODE_LENGTH(f, p, shared->man_size); - H5F_DECODE_LENGTH(f, p, shared->std_size); - H5F_DECODE_LENGTH(f, p, shared->nobjs); + H5F_DECODE_LENGTH(f, p, fh->total_size); + H5F_DECODE_LENGTH(f, p, fh->man_size); + H5F_DECODE_LENGTH(f, p, fh->std_size); + H5F_DECODE_LENGTH(f, p, fh->nobjs); /* Managed objects' doubling-table info */ - if(H5HF_dtable_decode(shared->f, &p, &(shared->man_dtable)) < 0) + if(H5HF_dtable_decode(fh->f, &p, &(fh->man_dtable)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, NULL, "unable to encode managed obj. doubling table info") HDassert((size_t)(p - buf) == size); /* Make shared heap info reference counted */ - if(H5HF_shared_own(fh, shared) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create ref-count wrapper for shared fractal heap info") + if(H5HF_finish_init(fh) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create ref-count wrapper for shared fractal heap header") /* Set return value */ ret_value = fh; @@ -376,30 +372,28 @@ done: static herr_t H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_t *fh) { - H5HF_shared_t *shared; /* Shared fractal heap information */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_cache_hdr_flush, FAIL) +#ifdef QAK +HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); +#endif /* QAK */ /* check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); HDassert(fh); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - if(fh->cache_info.is_dirty) { uint8_t *buf = NULL; /* Temporary raw data buffer */ uint8_t *p; /* Pointer into raw data buffer */ size_t size; /* Header size on disk */ /* Sanity check */ - HDassert(shared->dirty); + HDassert(fh->dirty); /* Compute the size of the heap header on disk */ - size = H5HF_HEADER_SIZE(shared); + size = H5HF_HEADER_SIZE(fh); /* Allocate temporary buffer */ if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL) @@ -424,26 +418,23 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H p += 4; /* Heap address mapping */ - *p++ = shared->addrmap; + *p++ = fh->addrmap; /* Min. size of standalone objects */ - UINT32ENCODE(p, shared->standalone_size); - - /* Size of ref. count for objects in heap */ - *p++ = shared->ref_count_size; + UINT32ENCODE(p, fh->standalone_size); /* Internal management information */ - H5F_ENCODE_LENGTH(f, p, shared->total_man_free); - H5F_ENCODE_LENGTH(f, p, shared->total_std_free); + H5F_ENCODE_LENGTH(f, p, fh->total_man_free); + H5F_ENCODE_LENGTH(f, p, fh->total_std_free); /* Statistics information */ - H5F_ENCODE_LENGTH(f, p, shared->total_size); - H5F_ENCODE_LENGTH(f, p, shared->man_size); - H5F_ENCODE_LENGTH(f, p, shared->std_size); - H5F_ENCODE_LENGTH(f, p, shared->nobjs); + H5F_ENCODE_LENGTH(f, p, fh->total_size); + H5F_ENCODE_LENGTH(f, p, fh->man_size); + H5F_ENCODE_LENGTH(f, p, fh->std_size); + H5F_ENCODE_LENGTH(f, p, fh->nobjs); /* Managed objects' doubling-table info */ - if(H5HF_dtable_encode(shared->f, &p, &(shared->man_dtable)) < 0) + if(H5HF_dtable_encode(fh->f, &p, &(fh->man_dtable)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "unable to encode managed obj. doubling table info") /* Write the heap header. */ @@ -453,7 +444,7 @@ H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5H H5FL_BLK_FREE(header_block, buf); - shared->dirty = FALSE; + fh->dirty = FALSE; fh->cache_info.is_dirty = FALSE; } /* end if */ @@ -467,6 +458,47 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_cache_hdr_dest_real + * + * Purpose: Destroys a fractal heap header in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_cache_hdr_dest_real(H5HF_t *fh) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_dest_real) + + /* + * Check arguments. + */ + HDassert(fh); +/* XXX: Take out this goofy routine, after metadata cache is supporting + * "un-evictable" flag + */ + if(fh->rc == 0 && fh->evicted == TRUE) { + /* Free the free list information for the heap */ + if(fh->flist) + H5HF_flist_free(fh->flist); + + /* Free the block size lookup table for the doubling table */ + H5HF_dtable_dest(&fh->man_dtable); + + /* Free the shared info itself */ + H5FL_FREE(H5HF_t, fh); + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_cache_hdr_dest_real() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_cache_hdr_dest * * Purpose: Destroys a fractal heap header in memory. @@ -489,13 +521,17 @@ H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_t *fh) * Check arguments. */ HDassert(fh); - - /* Decrement reference count on shared fractal heap info */ - if(fh->shared) - H5RC_DEC(fh->shared); - - /* Free fractal heap header info */ - H5FL_FREE(H5HF_t, fh); +/* XXX: Enable this after the metadata cache supports the "un-evictable" flag */ +/* HDassert(fh->rc == 0); */ +/* XXX: Take out this goofy 'if' statement, after metadata cache is supporting + * "un-evictable" flag + */ +/* XXX: Take out 'evicted' flag after "un-evictable" flag is working */ + fh->evicted = TRUE; +/* XXX: Take out this goofy routine, after metadata cache is supporting + * "un-evictable" flag + */ + H5HF_cache_hdr_dest_real(fh); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_cache_hdr_dest() */ @@ -556,8 +592,6 @@ done: static herr_t H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr) { - H5HF_shared_t *shared; /* Shared fractal heap information */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_size) /* check arguments */ @@ -565,12 +599,8 @@ H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr) HDassert(fh); HDassert(size_ptr); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* Set size value */ - *size_ptr = H5HF_HEADER_SIZE(shared); + *size_ptr = H5HF_HEADER_SIZE(fh); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_cache_hdr_size() */ @@ -592,11 +622,10 @@ H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *fh, size_t *size_ptr) *------------------------------------------------------------------------- */ static H5HF_direct_t * -H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_par_shared) +H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_hdr) { const size_t *size = (const size_t *)_size; /* Size of block */ - H5HF_parent_shared_t *par_shared = (H5HF_parent_shared_t *)_par_shared; /* Shared direct block information */ - H5HF_shared_t *shared = NULL; /* Shared fractal heap information */ + H5HF_t *hdr = (H5HF_t *)_hdr; /* Shared heap header information */ H5HF_direct_t *dblock = NULL; /* Direct block info */ const uint8_t *p; /* Pointer into raw data buffer */ haddr_t heap_addr; /* Address of heap header in the file */ @@ -608,7 +637,7 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(par_shared); + HDassert(hdr); /* Allocate space for the fractal heap direct block */ if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t))) @@ -616,19 +645,9 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - dblock->shared = par_shared->shared; - H5RC_INC(dblock->shared); - - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(dblock->shared); - HDassert(shared); - - /* Share common parent [indirect] block information */ - dblock->parent = par_shared->parent; - if(dblock->parent) - H5RC_INC(dblock->parent); - dblock->parent_entry = par_shared->parent_entry; - dblock->blk_free_space = (size_t)par_shared->parent_free_space; + dblock->shared = hdr; + if(H5HF_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") /* Set block's internal information */ dblock->size = *size; @@ -668,11 +687,48 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, /* Address of heap that owns this block (skip) */ H5F_addr_decode(f, &p, &heap_addr); - if(H5F_addr_ne(heap_addr, shared->heap_addr)) + if(H5F_addr_ne(heap_addr, hdr->heap_addr)) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") + /* Address of parent block */ + H5F_addr_decode(f, &p, &dblock->par_addr); + UINT16DECODE(p, dblock->par_entry); + UINT16DECODE(p, dblock->par_nrows); + if(H5F_addr_defined(dblock->par_addr)) { + H5HF_indirect_t *iblock; /* Pointer to parent indirect block */ + + /* Check for direct block as a child of the root indirect block + * and retrieve the # of rows in the root indirect block from + * the shared heap header, because the root indirect block can + * change size. + */ + if(H5F_addr_eq(iblock->par_addr, hdr->man_dtable.table_addr)) + dblock->par_nrows = hdr->man_dtable.curr_root_rows; + + /* Protect parent indirect block */ + if(NULL == (iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, dblock->par_addr, &dblock->par_nrows, hdr, hdr->mode))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") + + /* Share parent block */ + dblock->parent = iblock; + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block") + + /* Retrieve this block's free space from parent */ + dblock->blk_free_space = iblock->ents[dblock->par_entry].free_space; + + /* Release the indirect block */ + if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, dblock->par_addr, iblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") + } /* end if */ + else { + /* Direct block is linked directly from heap header */ + dblock->parent = NULL; + dblock->blk_free_space = hdr->total_man_free; + } /* end else */ + /* Offset of heap within the heap's address space */ - UINT64DECODE_VAR(p, dblock->block_off, shared->heap_off_size); + UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size); /* Offset of free list head */ /* (Defer deserializing the whole free list until we actually need to modify it) */ @@ -715,12 +771,11 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, HDassert(dblock); if(dblock->cache_info.is_dirty) { - H5HF_shared_t *shared; /* Shared fractal heap information */ - uint8_t *p; /* Pointer into raw data buffer */ + H5HF_t *hdr; /* Shared fractal heap information */ + uint8_t *p; /* Pointer into raw data buffer */ - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(dblock->shared); - HDassert(shared); + /* Get the pointer to the shared heap header */ + hdr = dblock->shared; p = dblock->blk; @@ -741,20 +796,25 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, p += 4; /* Address of heap header for heap which owns this block */ - H5F_addr_encode(f, &p, shared->heap_addr); + H5F_addr_encode(f, &p, hdr->heap_addr); + + /* Info for parent block of this block */ + H5F_addr_encode(f, &p, dblock->par_addr); + UINT16ENCODE(p, dblock->par_entry); + UINT16ENCODE(p, dblock->par_nrows); /* Offset of block in heap */ - UINT64ENCODE_VAR(p, dblock->block_off, shared->heap_off_size); + UINT64ENCODE_VAR(p, dblock->block_off, hdr->heap_off_size); /* Check for (currently) unsupported address mapping */ - if(shared->addrmap != H5HF_ABSOLUTE) + if(hdr->addrmap != H5HF_ABSOLUTE) HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "encoding mapped direct blocks not supported currently") /* Offset of free list head */ UINT64ENCODE_VAR(p, dblock->free_list_head, dblock->blk_off_size); /* Sanity check */ - HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(shared, dblock)); + HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock)); /* Check for dirty free list */ if(dblock->free_list && dblock->free_list->dirty) { @@ -824,7 +884,9 @@ done: herr_t H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_dblock_dest) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_dest) /* * Check arguments. @@ -832,10 +894,12 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock) HDassert(dblock); /* Decrement reference count on shared fractal heap info */ - if(dblock->shared) - H5RC_DEC(dblock->shared); + HDassert(dblock->shared); + if(H5HF_hdr_decr(dblock->shared) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") if(dblock->parent) - H5RC_DEC(dblock->parent); + if(H5HF_iblock_decr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") /* Check for free list & free it, if necessary */ if(dblock->free_list) { @@ -864,7 +928,8 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock) /* Free fractal heap direct block info */ H5FL_FREE(H5HF_direct_t, dblock); - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_cache_dblock_dest() */ @@ -955,11 +1020,10 @@ H5HF_cache_dblock_size(const H5F_t UNUSED *f, const H5HF_direct_t *dblock, size_ *------------------------------------------------------------------------- */ static H5HF_indirect_t * -H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_par_shared) +H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_hdr) { const unsigned *nrows = (const unsigned *)_nrows; /* # of rows in indirect block */ - H5HF_parent_shared_t *par_shared = (H5HF_parent_shared_t *)_par_shared; /* Shared direct block information */ - H5HF_shared_t *shared = NULL; /* Shared fractal heap information */ + H5HF_t *hdr = (H5HF_t *)_hdr; /* Shared header information */ H5HF_indirect_t *iblock = NULL; /* Indirect block info */ uint8_t *buf = NULL; /* Temporary buffer */ const uint8_t *p; /* Pointer into raw data buffer */ @@ -969,11 +1033,14 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows H5HF_indirect_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5HF_cache_iblock_load, NULL) +#ifdef QAK +HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); +#endif /* QAK */ /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(par_shared); + HDassert(hdr); /* Allocate space for the fractal heap indirect block */ if(NULL == (iblock = H5FL_MALLOC(H5HF_indirect_t))) @@ -981,33 +1048,19 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - iblock->shared = par_shared->shared; - H5RC_INC(iblock->shared); - - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(iblock->shared); - HDassert(shared); - - /* Share common parent [indirect] block information */ - iblock->parent = par_shared->parent; - if(iblock->parent) - H5RC_INC(iblock->parent); - iblock->parent_entry = par_shared->parent_entry; - iblock->child_free_space = par_shared->parent_free_space; - - /* Make a reference to this block */ - if(NULL == (iblock->self = H5RC_create(iblock, H5HF_iblock_free))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create ref-count wrapper for indirect fractal heap block") + iblock->shared = hdr; + if(H5HF_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") /* Set block's internal information */ + iblock->rc = 0; iblock->nrows = *nrows; - if(!iblock->parent) - iblock->max_rows = shared->man_dtable.max_root_rows; - else - iblock->max_rows = *nrows; + iblock->addr = addr; + iblock->dirty = FALSE; + iblock->evicted = FALSE; /* Compute size of indirect block */ - iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); /* Allocate buffer to decode block */ /* XXX: Use free list factories? */ @@ -1042,33 +1095,77 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows /* Address of heap that owns this block */ H5F_addr_decode(f, &p, &heap_addr); - if(H5F_addr_ne(heap_addr, shared->heap_addr)) + if(H5F_addr_ne(heap_addr, hdr->heap_addr)) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") + /* Address of parent block */ + H5F_addr_decode(f, &p, &iblock->par_addr); + UINT16DECODE(p, iblock->par_entry); + UINT16DECODE(p, iblock->par_nrows); + if(H5F_addr_defined(iblock->par_addr)) { + H5HF_indirect_t *tmp_iblock; /* Pointer to parent indirect block */ + + /* Check for indirect block as a child of the root indirect block + * and retrieve the # of rows in the root indirect block from + * the shared heap header, because the root indirect block can + * change size. + */ + if(H5F_addr_eq(iblock->par_addr, hdr->man_dtable.table_addr)) + iblock->par_nrows = hdr->man_dtable.curr_root_rows; + + /* Protect parent indirect block */ + if(NULL == (tmp_iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->par_addr, &iblock->par_nrows, hdr, hdr->mode))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") + + /* Share parent block */ + iblock->parent = tmp_iblock; + if(H5HF_iblock_incr(tmp_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block") + + /* Retrieve this block's free space from parent */ + iblock->child_free_space = tmp_iblock->ents[iblock->par_entry].free_space; + + /* Release the indirect block */ + if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->par_addr, tmp_iblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") + tmp_iblock = NULL; + + /* Set max. # of rows in this block */ + iblock->max_rows = iblock->nrows; + } /* end if */ + else { + /* Direct block is linked directly from heap header */ + iblock->parent = NULL; + iblock->child_free_space = hdr->total_man_free; + + /* Set max. # of rows in this block */ + iblock->max_rows = hdr->man_dtable.max_root_rows; + } /* end else */ + /* Offset of heap within the heap's address space */ - UINT64DECODE_VAR(p, iblock->block_off, shared->heap_off_size); + UINT64DECODE_VAR(p, iblock->block_off, hdr->heap_off_size); /* Offset of next entry to allocate within this block */ UINT32DECODE(p, iblock->next_entry); /* Compute next block column, row & size */ - iblock->next_col = iblock->next_entry % shared->man_dtable.cparam.width; - iblock->next_row = iblock->next_entry / shared->man_dtable.cparam.width; - iblock->next_size = shared->man_dtable.row_block_size[iblock->next_row]; + iblock->next_col = iblock->next_entry % hdr->man_dtable.cparam.width; + iblock->next_row = iblock->next_entry / hdr->man_dtable.cparam.width; + iblock->next_size = hdr->man_dtable.row_block_size[iblock->next_row]; /* Allocate & decode indirect block entry tables */ HDassert(iblock->nrows > 0); - if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * shared->man_dtable.cparam.width)))) + if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries") - for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) { + for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { /* Decode block address */ H5F_addr_decode(f, &p, &(iblock->ents[u].addr)); /* Decode direct & indirect blocks differently */ - if(u < (shared->man_dtable.max_direct_rows * shared->man_dtable.cparam.width)) - UINT32DECODE_VAR(p, iblock->ents[u].free_space, shared->man_dtable.max_dir_blk_off_size) + if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) + UINT32DECODE_VAR(p, iblock->ents[u].free_space, hdr->man_dtable.max_dir_blk_off_size) else - UINT64DECODE_VAR(p, iblock->ents[u].free_space, shared->heap_off_size) + UINT64DECODE_VAR(p, iblock->ents[u].free_space, hdr->heap_off_size) } /* end for */ /* Sanity check */ @@ -1108,6 +1205,9 @@ H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_cache_iblock_flush, FAIL) +#ifdef QAK +HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); +#endif /* QAK */ /* check arguments */ HDassert(f); @@ -1115,20 +1215,16 @@ H5HF_cache_iblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, HDassert(iblock); if(iblock->cache_info.is_dirty) { - H5HF_shared_t *shared; /* Shared fractal heap information */ - uint8_t *buf = NULL; /* Temporary buffer */ - uint8_t *p; /* Pointer into raw data buffer */ - size_t u; /* Local index variable */ + H5HF_t *hdr; /* Shared fractal heap information */ + uint8_t *buf = NULL; /* Temporary buffer */ + uint8_t *p; /* Pointer into raw data buffer */ + size_t u; /* Local index variable */ /* Sanity check */ HDassert(iblock->dirty); -#ifdef QAK -HDfprintf(stderr, "%s: Flushing indirect block\n", FUNC); -#endif /* QAK */ - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(iblock->shared); - HDassert(shared); + /* Get the pointer to the shared heap header */ + hdr = iblock->shared; /* Allocate buffer to encode block */ /* XXX: Use free list factories? */ @@ -1136,7 +1232,7 @@ HDfprintf(stderr, "%s: Flushing indirect block\n", FUNC); HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); HDfprintf(stderr, "%s: iblock->size = %Zu\n", FUNC, iblock->size); HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off); -HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->man_dtable.cparam.width); +HDfprintf(stderr, "%s: hdr->man_dtable.cparam.width = %u\n", FUNC, hdr->man_dtable.cparam.width); #endif /* QAK */ if((buf = H5FL_BLK_MALLOC(indirect_block, iblock->size)) == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") @@ -1160,24 +1256,32 @@ HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->ma p += 4; /* Address of heap header for heap which owns this block */ - H5F_addr_encode(f, &p, shared->heap_addr); + H5F_addr_encode(f, &p, hdr->heap_addr); + + /* Info for parent block of this block */ + H5F_addr_encode(f, &p, iblock->par_addr); + UINT16ENCODE(p, iblock->par_entry); + UINT16ENCODE(p, iblock->par_nrows); /* Offset of block in heap */ - UINT64ENCODE_VAR(p, iblock->block_off, shared->heap_off_size); + UINT64ENCODE_VAR(p, iblock->block_off, hdr->heap_off_size); /* Next block entry to allocate from */ UINT32ENCODE(p, iblock->next_entry); /* Encode indirect block-specific fields */ - for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) { + for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { +#ifdef QAK +HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a, %Hu}\n", FUNC, u, iblock->ents[u].addr, iblock->ents[u].free_space); +#endif /* QAK */ /* Encode block address */ H5F_addr_encode(f, &p, iblock->ents[u].addr); /* Encode direct & indirect blocks differently */ - if(u < (shared->man_dtable.max_direct_rows * shared->man_dtable.cparam.width)) - UINT32ENCODE_VAR(p, iblock->ents[u].free_space, shared->man_dtable.max_dir_blk_off_size) + if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) + UINT32ENCODE_VAR(p, iblock->ents[u].free_space, hdr->man_dtable.max_dir_blk_off_size) else - UINT64ENCODE_VAR(p, iblock->ents[u].free_space, shared->heap_off_size) + UINT64ENCODE_VAR(p, iblock->ents[u].free_space, hdr->heap_off_size) } /* end for */ /* Sanity check */ @@ -1190,6 +1294,8 @@ HDfprintf(stderr, "%s: shared->man_dtable.cparam.width = %u\n", FUNC, shared->ma /* Free buffer */ H5FL_BLK_FREE(indirect_block, buf); + /* Reset dirty flags */ + iblock->dirty = FALSE; iblock->cache_info.is_dirty = FALSE; } /* end if */ @@ -1203,6 +1309,58 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_cache_iblock_dest_real + * + * Purpose: Destroys a fractal heap indirect block in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 6 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_cache_iblock_dest_real(H5HF_indirect_t *iblock) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_dest_real) + + /* + * Check arguments. + */ + HDassert(iblock); +#ifdef QAK +HDfprintf(stderr, "%s: Destroying indirect block\n", "H5HF_cache_iblock_dest"); +#endif /* QAK */ +/* XXX: Take out this goofy routine, after metadata cache is supporting + * "un-evictable" flag + */ + if(iblock->rc == 0 && iblock->evicted) { + /* Decrement reference count on shared info */ + HDassert(iblock->shared); + if(H5HF_hdr_decr(iblock->shared) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") + if(iblock->parent) + if(H5HF_iblock_decr(iblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Release entry tables */ + if(iblock->ents) + H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); + + /* Free fractal heap indirect block info */ + H5FL_FREE(H5HF_indirect_t, iblock); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_cache_iblock_dest_real() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_cache_iblock_dest * * Purpose: Destroys a fractal heap indirect block in memory. @@ -1219,34 +1377,28 @@ done: herr_t H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_dest) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_dest) /* * Check arguments. */ HDassert(iblock); +/* XXX: Enable this after the metadata cache supports the "un-evictable" flag */ +/* HDassert(iblock->rc == 0); */ #ifdef QAK HDfprintf(stderr, "%s: Destroying indirect block\n", "H5HF_cache_iblock_dest"); #endif /* QAK */ - - /* Decrement reference count on self */ - /* (let ref-counting API's callback for the block perform all cleanup) */ -/* XXX: This should actually free all the indirect block info, since this - * routine should not get called until the block has no dependents (once - * the "un-evictable" flag is in the metadata cache) +/* XXX: Take out 'evicted' flag after "un-evictable" flag is working */ + iblock->evicted = TRUE; +/* XXX: Take out this goofy routine, after metadata cache is supporting + * "un-evictable" flag */ -/* XXX: Once the "un-evictable" flag is working in the metadata cache, can - * get rid of the "self" field and make a wrapper when creating the parent - * info for each "child" block, which will make the indirect block - * un-evictable as well as create the initial ref-counted object. - */ -/* XXX: Once the "un-evictable" flag is working in the metadata cache, the - * ref-counted 'free' callback should just make the indirect block - * evictable again. - */ - H5RC_DEC(iblock->self); + ret_value = H5HF_cache_iblock_dest_real(iblock); - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_cache_iblock_dest() */ @@ -1305,18 +1457,12 @@ done: static herr_t H5HF_cache_iblock_size(const H5F_t UNUSED *f, const H5HF_indirect_t *iblock, size_t *size_ptr) { - H5HF_shared_t *shared; /* Shared fractal heap information */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_iblock_size) /* check arguments */ HDassert(iblock); HDassert(size_ptr); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(iblock->shared); - HDassert(shared); - /* Set size value */ *size_ptr = iblock->size; diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c index 43a6064..8ad9949 100644 --- a/src/H5HFdbg.c +++ b/src/H5HFdbg.c @@ -165,7 +165,6 @@ herr_t H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth) { H5HF_t *fh = NULL; /* Fractal heap header info */ - H5HF_shared_t *shared; /* Shared fractal heap information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_hdr_debug, FAIL) @@ -185,10 +184,6 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* Print opening message */ HDfprintf(stream, "%*sFractal Heap Header...\n", indent, ""); @@ -197,37 +192,33 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, */ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Heap address mapping method:", - ((shared->addrmap) == H5HF_ABSOLUTE ? "Absolute" : - ((shared->addrmap) == H5HF_MAPPED ? "Mapped" : + ((fh->addrmap) == H5HF_ABSOLUTE ? "Absolute" : + ((fh->addrmap) == H5HF_MAPPED ? "Mapped" : "Unknown!"))); HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Min. size of standalone object:", - (unsigned long)shared->standalone_size); - HDfprintf(stream, "%*s%-*s %u%s\n", indent, "", fwidth, - "Ref. count size:", - (unsigned)shared->ref_count_size, - (shared->ref_count_size == 0 ? " (ref. count not stored)" : "")); + (unsigned long)fh->standalone_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total free space in managed blocks:", - shared->total_man_free); + fh->total_man_free); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total # of free entries for standalone blocks:", - shared->total_std_free); + fh->total_std_free); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total data block size:", - shared->total_size); + fh->total_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total managed space data block size:", - shared->man_size); + fh->man_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total standalone space data block size:", - shared->std_size); + fh->std_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Number of objects in heap:", - shared->nobjs); + fh->nobjs); HDfprintf(stream, "%*sManaged Objects Doubling-Table Info...\n", indent, ""); - H5HF_dtable_debug(&shared->man_dtable, stream, indent + 3, MAX(0, fwidth -3)); + H5HF_dtable_debug(&fh->man_dtable, stream, indent + 3, MAX(0, fwidth -3)); done: if(fh && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, addr, fh, H5AC__NO_FLAGS_SET) < 0) @@ -254,11 +245,9 @@ herr_t H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, haddr_t hdr_addr, size_t block_size) { - H5HF_t *fh = NULL; /* Fractal heap header info */ + H5HF_t *hdr = NULL; /* Fractal heap header info */ H5HF_direct_t *dblock = NULL; /* Fractal heap direct block info */ - H5HF_parent_shared_t par_shared; /* Parent shared information */ H5HF_direct_free_node_t *node; /* Pointer to free list node for block */ - H5HF_shared_t *shared; /* Shared fractal heap information */ size_t blk_prefix_size; /* Size of prefix for block */ unsigned node_count = 0; /* Number of free space nodes */ size_t amount_free = 0; /* Amount of free space in block */ @@ -283,21 +272,13 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, /* * Load the fractal heap header. */ - if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ))) + if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* * Load the heap direct block */ - par_shared.shared = fh->shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = 0; - if(NULL == (dblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, &block_size, &par_shared, H5AC_READ))) + if(NULL == (dblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, &block_size, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap direct block") /* Check for valid free list */ @@ -306,11 +287,6 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, FAIL, "can't decode free list for block") HDassert(dblock->free_list); - /* Release the heap header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, fh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header") - fh = NULL; - /* Print opening message */ HDfprintf(stream, "%*sFractal Heap Direct Block...\n", indent, ""); @@ -319,11 +295,20 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, */ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of fractal heap that owns this block:", - shared->heap_addr); + hdr->heap_addr); + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, + "Parent address:", + dblock->par_addr); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Parent entry:", + dblock->par_entry); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Parent # of rows:", + dblock->par_nrows); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Offset of direct block in heap:", dblock->block_off); - blk_prefix_size = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(shared, dblock); + blk_prefix_size = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of block header:", blk_prefix_size); @@ -388,6 +373,8 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, done: if(dblock && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, dblock, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap direct block") + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_dblock_debug() */ @@ -410,9 +397,7 @@ herr_t H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, haddr_t hdr_addr, unsigned nrows) { - H5HF_t *fh = NULL; /* Fractal heap header info */ - H5HF_shared_t *shared; /* Shared fractal heap information */ - H5HF_parent_shared_t par_shared; /* Parent shared information */ + H5HF_t *hdr = NULL; /* Fractal heap header info */ H5HF_indirect_t *iblock = NULL; /* Fractal heap direct block info */ size_t dblock_size; /* Current direct block size */ char temp_str[64]; /* Temporary string, for formatting */ @@ -435,28 +420,15 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, /* * Load the fractal heap header. */ - if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ))) + if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* * Load the heap direct block */ - par_shared.shared = fh->shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = 0; - if(NULL == (iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, &nrows, &par_shared, H5AC_READ))) + if(NULL == (iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, &nrows, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block") - /* Release the heap header */ - if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, fh, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header") - fh = NULL; - /* Print opening message */ HDfprintf(stream, "%*sFractal Heap Indirect Block...\n", indent, ""); @@ -465,7 +437,16 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, */ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of fractal heap that owns this block:", - shared->heap_addr); + hdr->heap_addr); + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, + "Parent address:", + iblock->par_addr); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Parent entry:", + iblock->par_entry); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Parent # of rows:", + iblock->par_nrows); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Offset of indirect block in heap:", iblock->block_off); @@ -483,7 +464,7 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, iblock->max_rows); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Max direct block rows:", - shared->man_dtable.max_direct_rows); + hdr->man_dtable.max_direct_rows); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Next block column:", iblock->next_col); @@ -496,15 +477,15 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, /* Print the entry tables */ HDfprintf(stream, "%*sDirect Block Entries (address, free space):\n", indent, ""); - for(u = 0; u < shared->man_dtable.max_direct_rows && u < iblock->nrows; u++) { - sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)shared->man_dtable.row_block_size[u]); + for(u = 0; u < hdr->man_dtable.max_direct_rows && u < iblock->nrows; u++) { + sprintf(temp_str, "Row #%u: (block size: %lu)", (unsigned)u, (unsigned long)hdr->man_dtable.row_block_size[u]); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); - for(v = 0; v < shared->man_dtable.cparam.width; v++) { - size_t off = (u * shared->man_dtable.cparam.width) + v; + for(v = 0; v < hdr->man_dtable.cparam.width; v++) { + size_t off = (u * hdr->man_dtable.cparam.width) + v; sprintf(temp_str, "Col #%u:", (unsigned)v); - HDfprintf(stream, "%*s%-*s %8a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6), + HDfprintf(stream, "%*s%-*s %9a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6), temp_str, iblock->ents[off].addr, iblock->ents[off].free_space); @@ -512,16 +493,16 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, dblock_size *= 2; } /* end for */ HDfprintf(stream, "%*sIndirect Block Entries:\n", indent, ""); - if(iblock->nrows > shared->man_dtable.max_direct_rows) { - for(u = shared->man_dtable.max_direct_rows; u < iblock->nrows; u++) { + if(iblock->nrows > hdr->man_dtable.max_direct_rows) { + for(u = hdr->man_dtable.max_direct_rows; u < iblock->nrows; u++) { sprintf(temp_str, "Row #%u:", (unsigned)u); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); - for(v = 0; v < shared->man_dtable.cparam.width; v++) { - size_t off = (u * shared->man_dtable.cparam.width) + v; + for(v = 0; v < hdr->man_dtable.cparam.width; v++) { + size_t off = (u * hdr->man_dtable.cparam.width) + v; sprintf(temp_str, "Col #%u:", (unsigned)v); - HDfprintf(stream, "%*s%-*s %8a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6), + HDfprintf(stream, "%*s%-*s %9a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6), temp_str, iblock->ents[off].addr, iblock->ents[off].free_space); @@ -536,6 +517,8 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, done: if(iblock && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, iblock, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap direct block") + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_iblock_debug() */ diff --git a/src/H5HFint.c b/src/H5HFint.c index e25ad64..3fee747 100644 --- a/src/H5HFint.c +++ b/src/H5HFint.c @@ -76,28 +76,30 @@ struct H5HF_section_free_node_t { /********************/ /* Doubling table routines */ -static herr_t H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable); +static herr_t H5HF_dtable_init(H5HF_dtable_t *dtable); static herr_t H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off, unsigned *row, unsigned *col); /* Shared heap header routines */ -static herr_t H5HF_shared_free(void *_shared); +static herr_t H5HF_hdr_dirty(hid_t dxpl_id, H5HF_t *hdr); /* Direct block routines */ static herr_t H5HF_dblock_section_node_free_cb(void *item, void UNUSED *key, void UNUSED *op_data); -static herr_t H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, - hid_t dxpl_id, size_t block_size, hsize_t block_off, haddr_t *addr_p); -static herr_t H5HF_man_dblock_new(H5RC_t *fh_shared, hid_t dxpl_id, +static herr_t H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr, + H5HF_indirect_t *par_iblock, unsigned par_entry, size_t block_size, + hsize_t block_off, haddr_t *addr_p); +static herr_t H5HF_man_dblock_new(H5HF_t *fh, hid_t dxpl_id, size_t request); -static herr_t H5HF_man_dblock_adj_free(H5HF_direct_t *dblock, ssize_t amt); +static herr_t H5HF_man_dblock_adj_free(hid_t dxpl_id, H5HF_direct_t *dblock, ssize_t amt); /* Indirect block routines */ static herr_t H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock); -static H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id, +static herr_t H5HF_iblock_dirty(hid_t dxpl_id, H5HF_indirect_t *iblock); +static H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5HF_t *fh, hid_t dxpl_id, size_t min_dblock_size, haddr_t *addr_p, size_t *entry_p, size_t *dblock_size); -static herr_t H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, +static herr_t H5HF_man_iblock_create(H5HF_t *fh, hid_t dxpl_id, hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p); /*********************/ @@ -132,9 +134,6 @@ H5FL_SEQ_DEFINE(H5HF_indirect_ent_t); /* Local Variables */ /*******************/ -/* Declare a free list to manage the H5HF_shared_t struct */ -H5FL_DEFINE_STATIC(H5HF_shared_t); - /*------------------------------------------------------------------------- @@ -151,7 +150,7 @@ H5FL_DEFINE_STATIC(H5HF_shared_t); *------------------------------------------------------------------------- */ static herr_t -H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable) +H5HF_dtable_init(H5HF_dtable_t *dtable) { hsize_t tmp_block_size; /* Temporary block size */ size_t u; /* Local index variable */ @@ -162,7 +161,6 @@ H5HF_dtable_init(const H5HF_shared_t *shared, H5HF_dtable_t *dtable) /* * Check arguments. */ - HDassert(shared); HDassert(dtable); /* Compute/cache some values */ @@ -232,25 +230,55 @@ H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off, unsigned *row, unsi /*------------------------------------------------------------------------- - * Function: H5HF_shared_alloc + * Function: H5HF_dtable_dest * - * Purpose: Allocate shared fractal heap info + * Purpose: Release information for doubling table * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu - * Feb 27 2006 + * Mar 27 2006 * *------------------------------------------------------------------------- */ -H5HF_shared_t * -H5HF_shared_alloc(H5F_t *f) +herr_t +H5HF_dtable_dest(H5HF_dtable_t *dtable) { - H5HF_shared_t *shared = NULL; /* Shared fractal heap information */ - H5HF_shared_t *ret_value = NULL; /* Return value */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_dtable_dest) - FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_alloc) + /* + * Check arguments. + */ + HDassert(dtable); + + /* Free the block size lookup table for the doubling table */ + H5MM_xfree(dtable->row_block_size); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_dtable_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_alloc + * + * Purpose: Allocate shared fractal heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 21 2006 + * + *------------------------------------------------------------------------- + */ +H5HF_t * +H5HF_alloc(H5F_t *f) +{ + H5HF_t *fh = NULL; /* Shared fractal heap header */ + H5HF_t *ret_value = NULL; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_alloc) /* * Check arguments. @@ -258,95 +286,88 @@ H5HF_shared_alloc(H5F_t *f) HDassert(f); /* Allocate space for the shared information */ - if(NULL == (shared = H5FL_CALLOC(H5HF_shared_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared information") + if(NULL == (fh = H5FL_CALLOC(H5HF_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header") /* Set the internal parameters for the heap */ - shared->f = f; - shared->sizeof_size = H5F_SIZEOF_SIZE(f); - shared->sizeof_addr = H5F_SIZEOF_ADDR(f); + fh->f = f; + fh->sizeof_size = H5F_SIZEOF_SIZE(f); + fh->sizeof_addr = H5F_SIZEOF_ADDR(f); /* Set the return value */ - ret_value = shared; + ret_value = fh; done: if(!ret_value) - if(shared) - H5HF_shared_free(shared); + if(fh) + (void)H5HF_cache_hdr_dest(f, fh); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_shared_alloc() */ +} /* end H5HF_alloc() */ /*------------------------------------------------------------------------- - * Function: H5HF_shared_own + * Function: H5HF_finish_init * - * Purpose: Have heap take ownership of the shared info + * Purpose: Finish initializing info in shared heap header * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu - * Feb 27 2006 + * Mar 21 2006 * *------------------------------------------------------------------------- */ herr_t -H5HF_shared_own(H5HF_t *fh, H5HF_shared_t *shared) +H5HF_finish_init(H5HF_t *fh) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_own) + FUNC_ENTER_NOAPI_NOINIT(H5HF_finish_init) /* * Check arguments. */ HDassert(fh); - HDassert(shared); /* Compute/cache some values */ - shared->ref_count_obj = (shared->ref_count_size > 0); - shared->heap_off_size = H5HF_SIZEOF_OFFSET_BITS(shared->man_dtable.cparam.max_index); - if(H5HF_dtable_init(shared, &shared->man_dtable) < 0) + fh->heap_off_size = H5HF_SIZEOF_OFFSET_BITS(fh->man_dtable.cparam.max_index); + if(H5HF_dtable_init(&fh->man_dtable) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize doubling table info") /* Create the free-list structure for the heap */ - if(NULL == (shared->flist = H5HF_flist_create(shared->man_dtable.cparam.max_direct_size, H5HF_dblock_section_node_free_cb))) + if(NULL == (fh->flist = H5HF_flist_create(fh->man_dtable.cparam.max_direct_size, H5HF_dblock_section_node_free_cb))) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free list info") - /* Make shared heap info reference counted */ - if(NULL == (fh->shared = H5RC_create(shared, H5HF_shared_free))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap info") - done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_shared_own() */ +} /* end H5HF_finish_init() */ /*------------------------------------------------------------------------- - * Function: H5HF_shared_create + * Function: H5HF_init * - * Purpose: Allocate & create shared fractal heap info for new heap + * Purpose: Initialize shared fractal heap header for new heap * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu - * Feb 24 2006 + * Mar 21 2006 * *------------------------------------------------------------------------- */ herr_t -H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) +H5HF_init(H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_shared_init) + FUNC_ENTER_NOAPI_NOINIT(H5HF_init) /* * Check arguments. */ - HDassert(shared); HDassert(fh); HDassert(cparam); @@ -361,71 +382,33 @@ H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t fh_addr, H5HF_create HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two") if(cparam->managed.max_direct_size < cparam->standalone_size) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not large enough to hold all managed blocks") - if(cparam->managed.max_index > (8 * shared->sizeof_size) || cparam->managed.max_index == 0) + if(cparam->managed.max_index > (8 * fh->sizeof_size) || cparam->managed.max_index == 0) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not power of two") #endif /* NDEBUG */ /* Set the creation parameters for the heap */ - shared->heap_addr = fh_addr; - shared->addrmap = cparam->addrmap; - shared->standalone_size = cparam->standalone_size; - shared->ref_count_size = cparam->ref_count_size; - HDmemcpy(&(shared->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); + fh->heap_addr = fh_addr; + fh->addrmap = cparam->addrmap; + fh->standalone_size = cparam->standalone_size; + HDmemcpy(&(fh->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); /* Set root table address */ - shared->man_dtable.table_addr = HADDR_UNDEF; + fh->man_dtable.table_addr = HADDR_UNDEF; /* Note that the shared info is dirty (it's not written to the file yet) */ - shared->dirty = TRUE; + fh->dirty = TRUE; /* Make shared heap info reference counted */ - if(H5HF_shared_own(fh, shared) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap info") + if(H5HF_finish_init(fh) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap header") done: if(ret_value < 0) - if(shared) - H5HF_shared_free(shared); + if(fh) + (void)H5HF_cache_hdr_dest(NULL, fh); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_shared_init() */ - - -/*------------------------------------------------------------------------- - * Function: H5HF_shared_free - * - * Purpose: Free shared fractal heap info - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Feb 24 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_shared_free(void *_shared) -{ - H5HF_shared_t *shared = (H5HF_shared_t *)_shared; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_shared_free) - - /* Sanity check */ - HDassert(shared); - - /* Free the free list information for the heap */ - if(shared->flist) - H5HF_flist_free(shared->flist); - - /* Free the block size lookup table for the doubling table */ - H5MM_xfree(shared->man_dtable.row_block_size); - - /* Free the shared info itself */ - H5FL_FREE(H5HF_shared_t, shared); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HF_shared_free() */ +} /* end H5HF_init() */ /*------------------------------------------------------------------------- @@ -444,7 +427,6 @@ H5HF_shared_free(void *_shared) static herr_t H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) { - H5HF_shared_t *shared; /* Pointer to shared heap info */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_inc_loc) @@ -454,10 +436,6 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) */ HDassert(iblock); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(iblock->shared); - HDassert(shared); - /* Increment block entry */ iblock->next_entry++; @@ -465,13 +443,14 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) iblock->next_col++; /* Check for walking off end of column */ - if(iblock->next_col == shared->man_dtable.cparam.width) { + if(iblock->next_col == iblock->shared->man_dtable.cparam.width) { /* Reset column */ iblock->next_col = 0; /* Increment row & block size */ iblock->next_row++; - iblock->next_size *= 2; + if(iblock->next_row > 1) + iblock->next_size *= 2; /* Check for filling up indirect block */ if(iblock->next_row == iblock->max_rows) { @@ -480,8 +459,7 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location") /* Increment location for parent indirect block */ - iblock = H5RC_GET_OBJ(iblock->parent); - if(H5HF_man_iblock_inc_loc(iblock) < 0) + if(H5HF_man_iblock_inc_loc(iblock->parent) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location") } /* end if */ } /* end if */ @@ -489,10 +467,9 @@ H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) #ifdef QAK HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row); HDfprintf(stderr, "%s: iblock->next_col = %u\n", FUNC, iblock->next_col); +HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry); HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size); #endif /* QAK */ - /* Mark heap header as modified */ - shared->dirty = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) @@ -513,12 +490,12 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, hid_t dxpl_id, +H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr, H5HF_indirect_t *par_iblock, + unsigned par_entry, size_t block_size, hsize_t block_off, haddr_t *addr_p) { H5HF_direct_free_node_t *node; /* Pointer to free list node for block */ H5HF_section_free_node_t *sec_node; /* Pointer to free list section for block */ - H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_direct_t *dblock = NULL; /* Pointer to direct block */ size_t free_space; /* Free space in new block */ herr_t ret_value = SUCCEED; /* Return value */ @@ -528,8 +505,7 @@ H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, hid_t dxpl_id, /* * Check arguments. */ - HDassert(par_shared); - HDassert(par_shared->shared); + HDassert(hdr); HDassert(block_size > 0); HDassert(addr_p); @@ -543,26 +519,31 @@ H5HF_man_dblock_create(H5HF_parent_shared_t *par_shared, hid_t dxpl_id, HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - dblock->shared = par_shared->shared; - H5RC_INC(dblock->shared); - - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(dblock->shared); - HDassert(shared); + dblock->shared = hdr; + if(H5HF_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header") /* Set info for direct block */ #ifdef QAK HDfprintf(stderr, "%s: size = %Zu, block_off = %Hu\n", FUNC, block_size, block_off); #endif /* QAK */ - dblock->parent = par_shared->parent; - if(dblock->parent) - H5RC_INC(dblock->parent); - dblock->parent_entry = par_shared->parent_entry; + dblock->parent = par_iblock; + if(dblock->parent) { + if(H5HF_iblock_incr(par_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + dblock->par_addr = par_iblock->addr; + dblock->par_nrows = par_iblock->nrows; + } /* end if */ + else { + dblock->par_addr = HADDR_UNDEF; + dblock->par_nrows = 0; + } /* end else */ + dblock->par_entry = par_entry; dblock->size = block_size; dblock->block_off = block_off; dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(block_size); - dblock->free_list_head = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(shared, dblock); - dblock->blk_free_space = par_shared->parent_free_space; + dblock->free_list_head = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock); + dblock->blk_free_space = 0; /* temporarily, this is modified later */ free_space = block_size - dblock->free_list_head; /* Allocate buffer for block */ @@ -593,7 +574,7 @@ HDmemset(dblock->blk, 0, dblock->size); dblock->free_list->first = node; /* Allocate space for the header on disk */ - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)block_size))) + if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_DBLOCK, dxpl_id, (hsize_t)block_size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap direct block") /* Create free list section node */ @@ -605,31 +586,32 @@ HDmemset(dblock->blk, 0, dblock->size); sec_node->block_size = block_size; sec_node->sect_addr = *addr_p + node->my_offset; /* (section size is "object size", without the metadata overhead) */ - sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock); + sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock); /* Add new free space to the global list of space */ - if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) + if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list") /* Adjust free space to include new block's space */ - if(H5HF_man_dblock_adj_free(dblock, (ssize_t)free_space) < 0) + if(H5HF_man_dblock_adj_free(dxpl_id, dblock, (ssize_t)free_space) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for direct block & parents") - /* Update shared heap info */ - shared->total_size += dblock->size; - shared->man_size += dblock->size; + /* Update shared heap header */ + hdr->total_size += dblock->size; + hdr->man_size += dblock->size; /* Mark heap header as modified */ - shared->dirty = TRUE; + if(H5HF_hdr_dirty(dxpl_id, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") /* Cache the new fractal heap direct block */ - if(H5AC_set(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, *addr_p, dblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, *addr_p, dblock, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap direct block to cache") done: if(ret_value < 0) if(dblock) - (void)H5HF_cache_dblock_dest(shared->f, dblock); + (void)H5HF_cache_dblock_dest(hdr->f, dblock); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_dblock_create() */ @@ -681,7 +663,6 @@ herr_t H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) { H5HF_direct_free_head_t *head = NULL; /* Pointer to free list head for block */ - H5HF_shared_t *shared; /* Pointer to shared heap info */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_build_freelist) @@ -700,6 +681,7 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) if(dblock->free_list_head == 0) head->first = NULL; else { + H5HF_t *hdr; /* Pointer to shared heap header */ H5HF_section_free_node_t *sec_node; /* Pointer to free list section for block */ H5HF_direct_free_node_t *node = NULL; /* Pointer to free list node for block */ H5HF_direct_free_node_t *prev_node; /* Pointer to previous free list node for block */ @@ -709,8 +691,7 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) uint8_t *p; /* Temporary pointer to free node info */ /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(dblock->shared); - HDassert(shared); + hdr = dblock->shared; /* Point to first node in free list */ p = dblock->blk + dblock->free_list_head; @@ -744,10 +725,10 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) sec_node->block_size = dblock->size; sec_node->sect_addr = dblock_addr + node->my_offset; /* (section size is "object size", without the metadata overhead) */ - sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock); + sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock); /* Add new free space to the global list of space */ - if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) + if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list") /* Set up trailing node pointer */ @@ -786,10 +767,10 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) sec_node->block_size = dblock->size; sec_node->sect_addr = dblock_addr + node->my_offset; /* (section size is "object size", without the metadata overhead) */ - sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock); + sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock); /* Add new free space to the global list of space */ - if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) + if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list") /* Update trailing info */ @@ -824,11 +805,12 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_man_dblock_adj_free(H5HF_direct_t *dblock, ssize_t amt) +H5HF_man_dblock_adj_free(hid_t dxpl_id, H5HF_direct_t *dblock, ssize_t amt) { - H5HF_shared_t *shared; /* Shared heap information */ + H5HF_t *hdr; /* Shared heap information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_dblock_adj_free) + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_adj_free) #ifdef QAK HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt); #endif /* QAK */ @@ -838,9 +820,8 @@ HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt); */ HDassert(dblock); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(dblock->shared); - HDassert(shared); + /* Get the pointer to the shared heap header */ + hdr = dblock->shared; /* Adjust space available in block */ dblock->blk_free_space += amt; @@ -850,44 +831,47 @@ HDfprintf(stderr, "%s: amt = %Zd\n", "H5HF_man_dblock_adj_free", amt); H5HF_indirect_t *iblock; /* Block's parent */ /* Get the pointer to the shared parent indirect block */ - iblock = H5RC_GET_OBJ(dblock->parent); - HDassert(iblock); + iblock = dblock->parent; /* Adjust this indirect block's child free space */ #ifdef QAK HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_free", iblock->child_free_space); #endif /* QAK */ - iblock->ents[dblock->parent_entry].free_space += amt; + iblock->ents[dblock->par_entry].free_space += amt; iblock->child_free_space += amt; /* Mark indirect block as dirty */ - iblock->dirty = TRUE; + if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") /* Modify the free space in parent block(s) */ while(iblock->parent) { - size_t parent_entry; /* Entry in parent */ + size_t par_entry; /* Entry in parent */ /* Get the pointer to the shared parent indirect block */ - parent_entry = iblock->parent_entry; - iblock = H5RC_GET_OBJ(iblock->parent); + par_entry = iblock->par_entry; + iblock = iblock->parent; HDassert(iblock); /* Adjust this indirect block's child free space */ - iblock->ents[parent_entry].free_space += amt; + iblock->ents[par_entry].free_space += amt; iblock->child_free_space += amt; /* Mark indirect block as dirty */ - iblock->dirty = TRUE; + if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") } /* end while */ } /* end if */ - /* Update shared heap free space info */ - shared->total_man_free += amt; + /* Update shared heap free space header */ + hdr->total_man_free += amt; /* Mark heap header as modified */ - shared->dirty = TRUE; + if(H5HF_hdr_dirty(dxpl_id, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_dblock_adj_free() */ @@ -906,10 +890,8 @@ HDfprintf(stderr, "%s: iblock->child_free_space = %Hu\n", "H5HF_man_dblock_adj_f *------------------------------------------------------------------------- */ static herr_t -H5HF_man_dblock_new(H5RC_t *fh_shared, hid_t dxpl_id, size_t request) +H5HF_man_dblock_new(H5HF_t *hdr, hid_t dxpl_id, size_t request) { - H5HF_parent_shared_t par_shared; /* Parent shared information */ - H5HF_shared_t *shared; /* Shared heap information */ haddr_t dblock_addr; /* Address of new direct block */ size_t dblock_size; /* Size of new direct block */ size_t min_dblock_size; /* Min. size of direct block to allocate */ @@ -923,52 +905,44 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); /* * Check arguments. */ - HDassert(fh_shared); + HDassert(hdr); HDassert(request > 0); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh_shared); - HDassert(shared); - /* Compute the min. size of the direct block needed to fulfill the request */ - if(request < shared->man_dtable.cparam.start_block_size) - min_dblock_size = shared->man_dtable.cparam.start_block_size; + if(request < hdr->man_dtable.cparam.start_block_size) + min_dblock_size = hdr->man_dtable.cparam.start_block_size; else { min_dblock_size = 2 * H5V_log2_gen((hsize_t)request); - HDassert(min_dblock_size <= shared->man_dtable.cparam.max_direct_size); + HDassert(min_dblock_size <= hdr->man_dtable.cparam.max_direct_size); } /* end else */ /* Adjust the size of block needed to fulfill request, with overhead */ #ifdef QAK -HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(shared, shared->man_dtable.cparam.start_block_size)); -HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(shared, shared->man_dtable.cparam.start_block_size)); +HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(hdr, hdr->man_dtable.cparam.start_block_size)); +HDfprintf(stderr, "%s: H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE = %u\n", FUNC, H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(hdr, hdr->man_dtable.cparam.start_block_size)); #endif /* QAK */ - if((min_dblock_size - request) < (H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(shared, min_dblock_size) - + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(shared, min_dblock_size))) + if((min_dblock_size - request) < (H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(hdr, min_dblock_size) + + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(hdr, min_dblock_size))) min_dblock_size *= 2; #ifdef QAK HDfprintf(stderr, "%s: min_dblock_size = %Zu\n", FUNC, min_dblock_size); #endif /* QAK */ /* Check if this is the first block in the heap */ - if(!H5F_addr_defined(shared->man_dtable.table_addr)) { + if(!H5F_addr_defined(hdr->man_dtable.table_addr)) { /* Create new direct block at corrent location*/ - dblock_size = shared->man_dtable.cparam.start_block_size; - par_shared.shared = fh_shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = 0; - if(H5HF_man_dblock_create(&par_shared, dxpl_id, dblock_size, shared->man_dtable.next_dir_block, &dblock_addr) < 0) + dblock_size = hdr->man_dtable.cparam.start_block_size; + if(H5HF_man_dblock_create(dxpl_id, hdr, NULL, 0, dblock_size, hdr->man_dtable.next_dir_block, &dblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block") #ifdef QAK HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); -HDfprintf(stderr, "%s: shared->man_dtable.next_dir_block = %Hu\n", FUNC, shared->man_dtable.next_dir_block); +HDfprintf(stderr, "%s: hdr->man_dtable.next_dir_block = %Hu\n", FUNC, hdr->man_dtable.next_dir_block); #endif /* QAK */ /* Point root at new direct block */ - shared->man_dtable.curr_root_rows = 0; - shared->man_dtable.table_addr = dblock_addr; + hdr->man_dtable.curr_root_rows = 0; + hdr->man_dtable.table_addr = dblock_addr; } /* end if */ /* Root entry already exists, go get indirect block for new direct block */ else { @@ -977,19 +951,16 @@ HDfprintf(stderr, "%s: shared->man_dtable.next_dir_block = %Hu\n", FUNC, shared- size_t dblock_entry; /* Direct entry for new direct block */ /* Find indirect block with room for block of correct size */ - if(NULL == (iblock = H5HF_man_iblock_place_dblock(fh_shared, dxpl_id, min_dblock_size, &iblock_addr, &dblock_entry, &dblock_size))) + if(NULL == (iblock = H5HF_man_iblock_place_dblock(hdr, dxpl_id, min_dblock_size, &iblock_addr, &dblock_entry, &dblock_size))) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to locate indirect block with space for direct block") #ifdef QAK +HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); HDfprintf(stderr, "%s: dblock_entry = %Zu\n", FUNC, dblock_entry); HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size); #endif /* QAK */ /* Create new direct block at corrent location*/ - par_shared.shared = fh_shared; - par_shared.parent = iblock->self; - par_shared.parent_entry = dblock_entry; - par_shared.parent_free_space = 0; - if(H5HF_man_dblock_create(&par_shared, dxpl_id, dblock_size, shared->man_dtable.next_dir_block, &dblock_addr) < 0) + if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, dblock_entry, dblock_size, hdr->man_dtable.next_dir_block, &dblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block") #ifdef QAK @@ -1000,16 +971,17 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); iblock->ents[dblock_entry].addr = dblock_addr; /* Mark indirect block as modified */ - iblock->dirty = TRUE; + if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") /* Release the indirect block (marked as dirty) */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") } /* end else */ - /* Update shared info */ + /* Update shared header */ /* XXX: This is going to cause problems when we support skipping blocks */ - shared->man_dtable.next_dir_block += dblock_size; + hdr->man_dtable.next_dir_block += dblock_size; done: FUNC_LEAVE_NOAPI(ret_value) @@ -1031,10 +1003,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_find(H5RC_t *fh_shared, hid_t dxpl_id, size_t request, +H5HF_man_find(H5HF_t *fh, hid_t dxpl_id, size_t request, H5HF_section_free_node_t **sec_node/*out*/) { - H5HF_shared_t *shared; /* Shared heap information */ htri_t node_found; /* Whether an existing free list node was found */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1046,16 +1017,12 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); /* * Check arguments. */ - HDassert(fh_shared); + HDassert(fh); HDassert(request > 0); HDassert(sec_node); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh_shared); - HDassert(shared); - /* Look for free space in global free list */ - if((node_found = H5HF_flist_find(shared->flist, request, (void **)sec_node)) < 0) + if((node_found = H5HF_flist_find(fh->flist, request, (void **)sec_node)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block") /* XXX: Make certain we've loaded all the direct blocks in the heap */ @@ -1063,12 +1030,12 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); /* If we didn't find a node, go make one big enough to hold the requested block */ if(!node_found) { /* Allocate direct block big enough to hold requested size */ - if(H5HF_man_dblock_new(fh_shared, dxpl_id, request) < 0) + if(H5HF_man_dblock_new(fh, dxpl_id, request) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create fractal heap direct block") /* Request space from the free list */ /* (Ought to be able to be filled, now) */ - if(H5HF_flist_find(shared->flist, request, (void **)sec_node) <= 0) + if(H5HF_flist_find(fh->flist, request, (void **)sec_node) <= 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block") } /* end if */ HDassert(*sec_node); @@ -1098,10 +1065,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_node, +H5HF_man_insert(H5HF_t *hdr, hid_t dxpl_id, H5HF_section_free_node_t *sec_node, size_t obj_size, const void *obj, void *id) { - H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_direct_t *dblock = NULL; /* Pointer to direct block to modify */ haddr_t dblock_addr; /* Direct block address */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1111,24 +1077,20 @@ H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_ /* * Check arguments. */ - HDassert(fh_shared); + HDassert(hdr); HDassert(obj_size > 0); HDassert(obj); HDassert(id); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh_shared); - HDassert(shared); - /* Lock direct block */ dblock_addr = sec_node->block_addr; - if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &sec_node->block_size, fh_shared, H5AC_WRITE))) + if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &sec_node->block_size, hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block") /* Insert object into block */ /* Check for address mapping type */ - if(shared->addrmap == H5HF_ABSOLUTE) { + if(hdr->addrmap == H5HF_ABSOLUTE) { H5HF_direct_free_node_t *node; /* Block's free list node */ uint8_t *p; /* Temporary pointer to obj info in block */ size_t obj_off; /* Offset of object within block */ @@ -1144,7 +1106,7 @@ H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_ node = node->next; /* Compute full object size, with metadata for object */ - full_obj_size = obj_size + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(shared, dblock); + full_obj_size = obj_size + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(hdr, dblock); /* Sanity checks */ HDassert(dblock->blk_free_space >= full_obj_size); @@ -1197,7 +1159,7 @@ H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, H5HF_section_free_node_t *sec_ sec_node->sect_size -= full_obj_size; /* Re-insert section node onto global list */ - if(H5HF_flist_add(shared->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) + if(H5HF_flist_add(hdr->flist, sec_node, &sec_node->sect_size, &sec_node->sect_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add direct block free space to global list") } /* end else */ @@ -1215,7 +1177,7 @@ HDfprintf(stderr, "%s: full_obj_size = %Zu\n", FUNC, full_obj_size); HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size); #endif /* QAK */ /* Reduce space available in parent block(s) */ - if(H5HF_man_dblock_adj_free(dblock, -(ssize_t)alloc_obj_size) < 0) + if(H5HF_man_dblock_adj_free(dxpl_id, dblock, -(ssize_t)alloc_obj_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't adjust free space for direct block & parents") /* Encode the object in the block */ @@ -1229,10 +1191,6 @@ HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size); /* Encode the free fragment size */ *p++ = free_frag_size; - /* Encode a ref. count (of 1), if required */ - if(shared->ref_count_obj) - UINT64ENCODE_VAR(p, 1, shared->ref_count_size); - /* Copy the object's data into the heap */ HDmemcpy(p, obj, obj_size); p += obj_size; @@ -1252,21 +1210,22 @@ HDfprintf(stderr, "%s: alloc_obj_size = %Zu\n", FUNC, alloc_obj_size); #ifdef QAK HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off); #endif /* QAK */ - UINT64ENCODE_VAR(id, (dblock->block_off + obj_off), shared->heap_off_size); + UINT64ENCODE_VAR(id, (dblock->block_off + obj_off), hdr->heap_off_size); } /* end if */ else { HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "inserting within mapped managed blocks not supported yet") } /* end else */ /* Update statistics about heap */ - shared->nobjs++; + hdr->nobjs++; /* Mark heap header as modified */ - shared->dirty = TRUE; + if(H5HF_hdr_dirty(dxpl_id, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") done: /* Release the direct block (marked as dirty) */ - if(dblock && H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG) < 0) + if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__DIRTIED_FLAG) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block") FUNC_LEAVE_NOAPI(ret_value) @@ -1287,10 +1246,8 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj) +H5HF_man_read(H5HF_t *hdr, hid_t dxpl_id, hsize_t obj_off, void *obj) { - H5HF_parent_shared_t par_shared; /* Parent shared information */ - H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_direct_t *dblock; /* Pointer to direct block to query */ size_t blk_off; /* Offset of object in block */ uint8_t *p; /* Temporary pointer to obj info in block */ @@ -1304,27 +1261,18 @@ H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj) /* * Check arguments. */ - HDassert(fh_shared); + HDassert(hdr); HDassert(obj_off > 0); HDassert(obj); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh_shared); - HDassert(shared); - /* Check for root direct block */ - if(shared->man_dtable.curr_root_rows == 0) { + if(hdr->man_dtable.curr_root_rows == 0) { /* Set direct block info */ - par_shared.shared = fh_shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = shared->total_man_free; - - dblock_addr = shared->man_dtable.table_addr; - dblock_size = shared->man_dtable.cparam.start_block_size; + dblock_addr = hdr->man_dtable.table_addr; + dblock_size = hdr->man_dtable.cparam.start_block_size; /* Lock direct block */ - if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ))) + if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") } /* end if */ else { @@ -1334,48 +1282,40 @@ H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, void *obj) size_t entry; /* Entry of block */ /* Look up row & column for object */ - if(H5HF_dtable_lookup(&shared->man_dtable, obj_off, &row, &col) < 0) + if(H5HF_dtable_lookup(&hdr->man_dtable, obj_off, &row, &col) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object") #ifdef QAK HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); #endif /* QAK */ /* Set initial indirect block info */ - iblock_addr = shared->man_dtable.table_addr; + iblock_addr = hdr->man_dtable.table_addr; /* Lock indirect block */ - par_shared.shared = fh_shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = shared->total_man_free; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_READ))) + if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Check for indirect block row */ - while(row >= shared->man_dtable.max_direct_rows) { + while(row >= hdr->man_dtable.max_direct_rows) { haddr_t new_iblock_addr; /* New indirect block's address */ H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */ unsigned nrows; /* Number of rows in new indirect block */ /* Compute # of rows in child indirect block */ - nrows = (H5V_log2_gen(shared->man_dtable.row_block_size[row]) - shared->man_dtable.first_row_bits) + 1; + nrows = (H5V_log2_gen(hdr->man_dtable.row_block_size[row]) - hdr->man_dtable.first_row_bits) + 1; /* Compute indirect block's entry */ - entry = (row * shared->man_dtable.cparam.width) + col; + entry = (row * hdr->man_dtable.cparam.width) + col; /* Locate child indirect block */ new_iblock_addr = iblock->ents[entry].addr; /* Lock new indirect block */ - par_shared.shared = fh_shared; - par_shared.parent = iblock->self; - par_shared.parent_entry = entry; - par_shared.parent_free_space = iblock->ents[entry].free_space; - if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_READ))) + if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Release the current indirect block (possibly marked as dirty) */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") /* Switch variables to use new indirect block */ @@ -1383,31 +1323,30 @@ HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); iblock_addr = new_iblock_addr; /* Look up row & column in new indirect block for object */ - if(H5HF_dtable_lookup(&shared->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0) + if(H5HF_dtable_lookup(&hdr->man_dtable, (obj_off - iblock->block_off), &row, &col) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object") + +#ifdef QAK +HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); +#endif /* QAK */ } /* end while */ /* Compute direct block's entry */ - entry = (row * shared->man_dtable.cparam.width) + col; + entry = (row * hdr->man_dtable.cparam.width) + col; #ifdef QAK -HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->dblock_ents[entry].addr); +HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr); #endif /* QAK */ /* Set direct block info */ - par_shared.shared = fh_shared; - par_shared.parent = iblock->self; - par_shared.parent_entry = entry; - par_shared.parent_free_space = iblock->ents[entry].free_space; - dblock_addr = iblock->ents[entry].addr; - dblock_size = shared->man_dtable.row_block_size[row]; + dblock_size = hdr->man_dtable.row_block_size[row]; /* Lock direct block */ - if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_shared, H5AC_READ))) + if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") /* Unlock indirect block */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") iblock = NULL; } /* end else */ @@ -1422,14 +1361,14 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->dblock_ents[entry].a /* Decode the length */ UINT64DECODE_VAR(p, obj_size, dblock->blk_off_size); - /* Skip over the free fragment size & ref count */ - p += 1 + (shared->ref_count_obj ? shared->ref_count_size : 0); + /* Skip over the free fragment size */ + p++; /* Copy the object's data into the heap */ HDmemcpy(obj, p, obj_size); /* Unlock direct block */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block") dblock = NULL; @@ -1439,46 +1378,248 @@ done: /*------------------------------------------------------------------------- - * Function: H5HF_iblock_free + * Function: H5HF_hdr_incr * - * Purpose: Free fractal heap indirect block + * Purpose: Increment reference count on shared heap header * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu - * Mar 13 2006 + * Mar 27 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_hdr_incr(H5HF_t *hdr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_incr) + + /* Sanity check */ + HDassert(hdr); + +/* XXX: When "un-evictable" feature is finished, mark the header as + * unevictable on the first block to share it. - QAK + */ + + /* Increment reference count on shared header */ + hdr->rc++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_hdr_incr() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_hdr_decr + * + * Purpose: Decrement reference count on shared heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 27 2006 * *------------------------------------------------------------------------- */ herr_t -H5HF_iblock_free(void *_iblock) +H5HF_hdr_decr(H5HF_t *hdr) { - H5HF_indirect_t *iblock = (H5HF_indirect_t *)_iblock; + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_decr) - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_free) + /* Sanity check */ + HDassert(hdr); + + /* Decrement reference count on shared header */ + hdr->rc--; + +/* XXX: When "un-evictable" feature is finished, mark the header as + * evictable when the ref. count drops to zero. - QAK + */ +/* XXX: Take this call out after "un-evictable" flag is working */ + H5HF_cache_hdr_dest_real(hdr); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_hdr_decr() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_hdr_dirty + * + * Purpose: Mark heap header as dirty + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 27 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_hdr_dirty(hid_t dxpl_id, H5HF_t *hdr) +{ + H5HF_t *tmp_hdr; /* Temporary pointer to heap header */ + hbool_t is_protected; /* Whether the indirect block is protected */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_dirty) +#ifdef QAK +HDfprintf(stderr, "%s: Marking heap header as dirty\n", FUNC); +#endif /* QAK */ + + /* Sanity check */ + HDassert(hdr); + +/* XXX: When "un-evictable" feature is finished, just mark the header as dirty + * in the cache, instead of this protect -> unprotect kludge - QAK + */ + /* Protect the header */ + is_protected = hdr->cache_info.is_protected; + if(!is_protected) { #ifdef QAK -HDfprintf(stderr, "%s: Freeing indirect block\n", "H5HF_iblock_free"); +HDfprintf(stderr, "%s: hdr->heap_addr = %a\n", FUNC, hdr->heap_addr); #endif /* QAK */ + if(NULL == (tmp_hdr = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, NULL, NULL, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + HDassert(hdr == tmp_hdr); + } /* end if */ + + /* Set the dirty flags for the heap header */ + hdr->dirty = TRUE; + + /* Release the heap header (marked as dirty) */ + if(!is_protected) { + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, tmp_hdr, H5AC__DIRTIED_FLAG) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_hdr_dirty() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_iblock_incr + * + * Purpose: Increment reference count on shared indirect block + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 27 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_iblock_incr(H5HF_indirect_t *iblock) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_incr) + + /* Sanity check */ + HDassert(iblock); + +/* XXX: When "un-evictable" feature is finished, mark the block as + * unevictable on the first block to share it. - QAK + */ + + /* Increment reference count on shared indirect block */ + iblock->rc++; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_iblock_incr() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_iblock_decr + * + * Purpose: Decrement reference count on shared indirect block + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 27 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_iblock_decr(H5HF_indirect_t *iblock) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_decr) /* Sanity check */ HDassert(iblock); - /* Decrement reference count on shared fractal heap info */ - if(iblock->shared) - H5RC_DEC(iblock->shared); - if(iblock->parent) - H5RC_DEC(iblock->parent); + /* Decrement reference count on shared indirect block */ + iblock->rc--; - /* Release entry tables */ - if(iblock->ents) - H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); +/* XXX: When "un-evictable" feature is finished, mark the block as + * evictable when the ref. count drops to zero. - QAK + */ +/* XXX: Take this call out after "un-evictable" flag is working */ + H5HF_cache_iblock_dest_real(iblock); - /* Free fractal heap indirect block info */ - H5FL_FREE(H5HF_indirect_t, iblock); FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HF_iblock_free() */ +} /* end H5HF_iblock_decr() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_iblock_dirty + * + * Purpose: Mark indirect block as dirty + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Mar 21 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_iblock_dirty(hid_t dxpl_id, H5HF_indirect_t *iblock) +{ + H5HF_indirect_t *tmp_iblock; /* Temporary pointer to indirect block */ + hbool_t is_protected; /* Whether the indirect block is protected */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_iblock_dirty) +#ifdef QAK +HDfprintf(stderr, "%s: Marking indirect block as dirty\n", FUNC); +#endif /* QAK */ + + /* Sanity check */ + HDassert(iblock); + +/* XXX: When "un-evictable" feature is finished, just mark the block as dirty + * in the cache, instead of this protect -> unprotect kludge - QAK + */ + /* Protect the indirect block */ + is_protected = iblock->cache_info.is_protected; + if(!is_protected) { +#ifdef QAK +HDfprintf(stderr, "%s: iblock->addr = %a\n", FUNC, iblock->addr); +#endif /* QAK */ + if(NULL == (tmp_iblock = H5AC_protect(iblock->shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, &iblock->nrows, iblock->shared, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + HDassert(iblock == tmp_iblock); + } /* end if */ + + /* Set the dirty flags for the indirect block */ + iblock->dirty = TRUE; + + /* Release the indirect block (marked as dirty) */ + if(!is_protected) { + if(H5AC_unprotect(iblock->shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, tmp_iblock, H5AC__DIRTIED_FLAG) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_iblock_dirty() */ /*------------------------------------------------------------------------- @@ -1497,12 +1638,9 @@ HDfprintf(stderr, "%s: Freeing indirect block\n", "H5HF_iblock_free"); *------------------------------------------------------------------------- */ static H5HF_indirect_t * -H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id, - size_t min_dblock_size, haddr_t *addr_p, size_t *entry_p, - size_t *dblock_size) +H5HF_man_iblock_place_dblock(H5HF_t *hdr, hid_t dxpl_id, size_t min_dblock_size, + haddr_t *addr_p, size_t *entry_p, size_t *dblock_size) { - H5HF_parent_shared_t par_shared; /* Parent shared information */ - H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_indirect_t *iblock; /* Pointer to indirect block */ haddr_t iblock_addr; /* Indirect block's address */ H5HF_indirect_t *ret_value; /* Return value */ @@ -1512,16 +1650,12 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id, /* * Check arguments. */ - HDassert(fh_shared); + HDassert(hdr); HDassert(min_dblock_size > 0); HDassert(addr_p); - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(fh_shared); - HDassert(shared); - /* Check for creating first indirect block */ - if(shared->man_dtable.curr_root_rows == 0) { + if(hdr->man_dtable.curr_root_rows == 0) { H5HF_direct_t *dblock; /* Pointer to direct block to query */ unsigned nrows; /* Number of rows for root indirect block */ @@ -1529,13 +1663,13 @@ H5HF_man_iblock_place_dblock(H5RC_t *fh_shared, hid_t dxpl_id, HDfprintf(stderr, "%s: creating first indirect block\n", FUNC); #endif /* QAK */ /* Check for allocating entire root indirect block initially */ - if(shared->man_dtable.cparam.start_root_rows == 0) - nrows = shared->man_dtable.max_root_rows; + if(hdr->man_dtable.cparam.start_root_rows == 0) + nrows = hdr->man_dtable.max_root_rows; else - nrows = shared->man_dtable.cparam.start_root_rows; + nrows = hdr->man_dtable.cparam.start_root_rows; /* Allocate root indirect block */ - if(H5HF_man_iblock_create(fh_shared, dxpl_id, (hsize_t)0, nrows, shared->man_dtable.max_root_rows, &iblock_addr) < 0) + if(H5HF_man_iblock_create(hdr, dxpl_id, (hsize_t)0, nrows, hdr->man_dtable.max_root_rows, &iblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block") #ifdef QAK HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); @@ -1544,30 +1678,28 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); /* Move current direct block (used as root) into new indirect block */ /* Lock new indirect block */ - par_shared.shared = fh_shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = 0; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, &par_shared, H5AC_WRITE))) + if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") /* Lock first (root) direct block */ - par_shared.parent_free_space = shared->total_man_free; - if(NULL == (dblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, &shared->man_dtable.cparam.start_block_size, &par_shared, H5AC_READ))) + if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, &hdr->man_dtable.cparam.start_block_size, hdr, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block") /* Point indirect block at direct block to add */ - iblock->ents[0].addr = shared->man_dtable.table_addr; + iblock->ents[0].addr = hdr->man_dtable.table_addr; iblock->ents[0].free_space = dblock->blk_free_space; iblock->child_free_space += dblock->blk_free_space; /* Make direct block share parent indirect block */ - dblock->parent = iblock->self; - dblock->parent_entry = 0; - H5RC_INC(dblock->parent); + dblock->parent = iblock; + dblock->par_entry = 0; + dblock->par_addr = iblock->addr; + dblock->par_nrows = iblock->nrows; + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block") /* Unlock first (root) direct block */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_DBLOCK, shared->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, hdr->man_dtable.table_addr, dblock, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap direct block") dblock = NULL; @@ -1577,14 +1709,15 @@ HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") /* Mark indirect block as modified */ - iblock->dirty = TRUE; + if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty") /* Point heap header at new indirect block */ - shared->man_dtable.curr_root_rows = nrows; - shared->man_dtable.table_addr = iblock_addr; + hdr->man_dtable.curr_root_rows = nrows; + hdr->man_dtable.table_addr = iblock_addr; /* Mark heap header as modified */ - shared->dirty = TRUE; + hdr->dirty = TRUE; } /* end if */ else { #ifdef QAK @@ -1592,12 +1725,8 @@ HDfprintf(stderr, "%s: searching root indirect block\n", FUNC); #endif /* QAK */ /* Lock root indirect block */ - par_shared.shared = fh_shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = shared->total_man_free; - iblock_addr = shared->man_dtable.table_addr; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE))) + iblock_addr = hdr->man_dtable.table_addr; + if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") #ifdef QAK @@ -1611,7 +1740,7 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); /* Check for special case of second row, which has blocks the same size as first row */ if(iblock->next_row == 1) - iblock->next_size = shared->man_dtable.cparam.start_block_size; + iblock->next_size = hdr->man_dtable.cparam.start_block_size; /* Compute new # of rows in indirect block */ new_nrows = MIN(2 * iblock->nrows, iblock->max_rows); @@ -1629,54 +1758,53 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows); * QAK - 3/14/2006 */ /* Free previous indirect block disk space */ - if(H5MF_xfree(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size)<0) + if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock_addr, (hsize_t)iblock->size)<0) HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, NULL, "unable to free fractal heap indirect block") /* Compute size of buffer needed for new indirect block */ iblock->nrows = new_nrows; - iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); /* Allocate space for the new indirect block on disk */ - if(HADDR_UNDEF == (new_addr = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) + if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for fractal heap indirect block") /* Re-allocate direct block entry table */ - if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * shared->man_dtable.cparam.width)))) + if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries") /* Initialize new direct block entries */ - for(u = (iblock->next_row * shared->man_dtable.cparam.width); - u < (iblock->nrows * shared->man_dtable.cparam.width); + for(u = (iblock->next_row * hdr->man_dtable.cparam.width); + u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { iblock->ents[u].addr = HADDR_UNDEF; iblock->ents[u].free_space = 0; } /* end for */ /* Mark indirect block as dirty */ - iblock->dirty = TRUE; + if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty") /* Release the indirect block (marked as dirty) */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, H5AC__DIRTIED_FLAG) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") + iblock = NULL; /* Move object in cache */ - if(H5AC_rename(shared->f, H5AC_FHEAP_IBLOCK, iblock_addr, new_addr) < 0) + if(H5AC_rename(hdr->f, H5AC_FHEAP_IBLOCK, iblock_addr, new_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, NULL, "unable to move fractal heap root indirect block") /* Update other shared header info */ - shared->man_dtable.curr_root_rows = new_nrows; - shared->man_dtable.table_addr = iblock_addr = new_addr; + hdr->man_dtable.curr_root_rows = new_nrows; + hdr->man_dtable.table_addr = iblock_addr = new_addr; /* Mark heap header as modified */ - shared->dirty = TRUE; + hdr->dirty = TRUE; /* Lock root indirect block (again) */ - par_shared.shared = fh_shared; - par_shared.parent = NULL; - par_shared.parent_entry = 0; - par_shared.parent_free_space = shared->total_man_free; - if(NULL == (iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &shared->man_dtable.curr_root_rows, &par_shared, H5AC_WRITE))) + if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") + iblock->addr = iblock_addr; } /* end if */ #ifdef QAK @@ -1686,14 +1814,14 @@ HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size); HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry); #endif /* QAK */ /* Check for full direct block entries in current indirect block */ - while(iblock->next_row >= shared->man_dtable.max_direct_rows) { + while(iblock->next_row >= hdr->man_dtable.max_direct_rows) { haddr_t new_iblock_addr; /* New indirect block's address */ H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */ unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */ unsigned nrows; /* Number of rows in new indirect block */ /* Compute # of rows in child indirect block */ - nrows = (H5V_log2_gen(iblock->next_size) - shared->man_dtable.first_row_bits) + 1; + nrows = (H5V_log2_gen(iblock->next_size) - hdr->man_dtable.first_row_bits) + 1; #ifdef QAK HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->next_size, nrows); #endif /* QAK */ @@ -1704,32 +1832,28 @@ HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->nex HDfprintf(stderr, "%s: Allocating new indirect block\n", FUNC); #endif /* QAK */ /* Allocate new indirect block */ - if(H5HF_man_iblock_create(fh_shared, dxpl_id, shared->man_dtable.next_dir_block, nrows, nrows, &new_iblock_addr) < 0) + if(H5HF_man_iblock_create(hdr, dxpl_id, hdr->man_dtable.next_dir_block, nrows, nrows, &new_iblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block") /* Lock new indirect block */ - par_shared.shared = fh_shared; - par_shared.parent = iblock->self; - par_shared.parent_entry = iblock->next_entry; - par_shared.parent_free_space = 0; - if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE))) + if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") -#ifdef QAK -HDfprintf(stderr, "%s: new_iblock->next_row = %u\n", FUNC, new_iblock->next_row); -HDfprintf(stderr, "%s: new_iblock->next_col = %u\n", FUNC, new_iblock->next_col); -HDfprintf(stderr, "%s: new_iblock->next_size = %Zu\n", FUNC, new_iblock->next_size); -HDfprintf(stderr, "%s: new_iblock->next_entry = %u\n", FUNC, new_iblock->next_entry); -#endif /* QAK */ + + /* Set parent information */ + HDassert(new_iblock->parent == NULL); + new_iblock->parent = iblock; + new_iblock->par_entry = iblock->next_entry; + new_iblock->par_nrows = iblock->nrows; + new_iblock->par_addr = iblock->addr; + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block") /* Point current indirect block at new indirect block */ iblock->ents[iblock->next_entry].addr = new_iblock_addr; - /* Increment location of next block from current indirect block */ - if(H5HF_man_iblock_inc_loc(iblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") - /* Mark current indirect block as modified */ - iblock->dirty = TRUE; + if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty") /* Release the current indirect block (marked as dirty) */ hdr_flags |= H5AC__DIRTIED_FLAG; @@ -1742,16 +1866,18 @@ HDfprintf(stderr, "%s: Descending existing indirect block\n", FUNC); new_iblock_addr = iblock->ents[iblock->next_entry].addr; /* Lock new indirect block */ - par_shared.shared = fh_shared; - par_shared.parent = iblock->self; - par_shared.parent_entry = iblock->next_entry; - par_shared.parent_free_space = iblock->ents[iblock->next_entry].free_space; - if(NULL == (new_iblock = H5AC_protect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, &par_shared, H5AC_WRITE))) + if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") } /* end else */ +#ifdef QAK +HDfprintf(stderr, "%s: new_iblock->next_row = %u\n", FUNC, new_iblock->next_row); +HDfprintf(stderr, "%s: new_iblock->next_col = %u\n", FUNC, new_iblock->next_col); +HDfprintf(stderr, "%s: new_iblock->next_size = %Zu\n", FUNC, new_iblock->next_size); +HDfprintf(stderr, "%s: new_iblock->next_entry = %u\n", FUNC, new_iblock->next_entry); +#endif /* QAK */ /* Release the current indirect block (possibly marked as dirty) */ - if(H5AC_unprotect(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, hdr_flags) < 0) + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, hdr_flags) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") /* Switch variables to use new indirect block */ @@ -1804,10 +1930,9 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, +H5HF_man_iblock_create(H5HF_t *hdr, hid_t dxpl_id, hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p) { - H5HF_shared_t *shared; /* Pointer to shared heap info */ H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */ size_t u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1817,7 +1942,7 @@ H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, /* * Check arguments. */ - HDassert(fh_shared); + HDassert(hdr); HDassert(nrows > 0); HDassert(addr_p); @@ -1831,23 +1956,19 @@ H5HF_man_iblock_create(H5RC_t *fh_shared, hid_t dxpl_id, HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - iblock->shared = fh_shared; - H5RC_INC(iblock->shared); - - /* Get the pointer to the shared heap info */ - shared = H5RC_GET_OBJ(iblock->shared); - HDassert(shared); - - /* Make a reference to this block */ - if(NULL == (iblock->self = H5RC_create(iblock, H5HF_iblock_free))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for indirect fractal heap block") + iblock->shared = hdr; + if(H5HF_hdr_incr(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header") #ifdef QAK HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows); #endif /* QAK */ /* Set info for direct block */ + iblock->rc = 0; iblock->parent = NULL; /* Temporary, except for root indirect block */ - iblock->parent_entry = 0; + iblock->par_entry = 0; + iblock->par_nrows = 0; + iblock->par_addr = HADDR_UNDEF; iblock->block_off = block_off; iblock->child_free_space = 0; iblock->nrows = nrows; @@ -1855,44 +1976,47 @@ HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows); iblock->next_col = 0; iblock->next_row = 0; iblock->next_entry = 0; - iblock->next_size = shared->man_dtable.cparam.start_block_size; + iblock->next_size = hdr->man_dtable.cparam.start_block_size; + iblock->dirty = TRUE; + iblock->evicted = FALSE; /* Compute size of buffer needed for indirect block */ - iblock->size = H5HF_MAN_INDIRECT_SIZE(shared, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); /* Allocate indirect block entry tables */ - if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * shared->man_dtable.cparam.width)))) + if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries") /* Initialize indirect block entry tables */ - for(u = 0; u < (iblock->nrows * shared->man_dtable.cparam.width); u++) { + for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { iblock->ents[u].addr = HADDR_UNDEF; iblock->ents[u].free_space = 0; } /* end for */ /* Allocate space for the indirect block on disk */ - if(HADDR_UNDEF == (*addr_p = H5MF_alloc(shared->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) + if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") + iblock->addr = *addr_p; /* XXX: Update indirect statistics when they are added */ #ifdef LATER /* Update shared heap info */ - shared->total_man_free += dblock->blk_free_space; - shared->total_size += dblock->size; - shared->man_size += dblock->size; + hdr->total_man_free += dblock->blk_free_space; + hdr->total_size += dblock->size; + hdr->man_size += dblock->size; /* Mark heap header as modified */ - shared->dirty = TRUE; + hdr->dirty = TRUE; #endif /* LATER */ /* Cache the new fractal heap header */ - if(H5AC_set(shared->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, iblock, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, *addr_p, iblock, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap indirect block to cache") done: if(ret_value < 0) if(iblock) - (void)H5HF_cache_iblock_dest(shared->f, iblock); + (void)H5HF_cache_iblock_dest(hdr->f, iblock); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_iblock_create() */ diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 175b521..cede8c9 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -57,82 +57,87 @@ ) /* Size of doubling-table information */ -#define H5HF_DTABLE_INFO_SIZE(s) ( \ +#define H5HF_DTABLE_INFO_SIZE(h) ( \ 2 /* Width of table (i.e. # of columns) */ \ - + (s)->sizeof_size /* Starting block size */ \ - + (s)->sizeof_size /* Maximum direct block size */ \ + + (h)->sizeof_size /* Starting block size */ \ + + (h)->sizeof_size /* Maximum direct block size */ \ + 2 /* Max. size of heap (log2 of actual value - i.e. the # of bits) */ \ + 2 /* Starting # of rows in root indirect block */ \ - + (s)->sizeof_addr /* File address of table managed */ \ + + (h)->sizeof_addr /* File address of table managed */ \ + 2 /* Current # of rows in root indirect block */ \ - + (s)->sizeof_size /* Next direct block's heap offset */ \ + + (h)->sizeof_size /* Next direct block's heap offset */ \ ) /* Size of the fractal heap header on disk */ -#define H5HF_HEADER_SIZE(s) ( \ +#define H5HF_HEADER_SIZE(h) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE \ \ /* Fractal heap header specific fields */ \ - + 1 /* Address mapping */ \ + + 1 /* Address mapping mode */ \ + 4 /* Min. size of standalone object */ \ - + 1 /* Size of ref. count for objects */ \ - + (s)->sizeof_size /* Total man. free space */ \ - + (s)->sizeof_size /* Total std. free entries */ \ - + (s)->sizeof_size /* Total size of heap */ \ - + (s)->sizeof_size /* Size of man. space in heap */ \ - + (s)->sizeof_size /* Size of std. space in heap */ \ - + (s)->sizeof_size /* Number of objects in heap */ \ - + H5HF_DTABLE_INFO_SIZE(s) /* Size of managed obj. doubling-table info */ \ + + (h)->sizeof_size /* Total man. free space */ \ + + (h)->sizeof_size /* Total std. free entries */ \ + + (h)->sizeof_size /* Total size of heap */ \ + + (h)->sizeof_size /* Size of man. space in heap */ \ + + (h)->sizeof_size /* Size of std. space in heap */ \ + + (h)->sizeof_size /* Number of objects in heap */ \ + + H5HF_DTABLE_INFO_SIZE(h) /* Size of managed obj. doubling-table info */ \ ) /* Size of free space description in an absolute managed direct block */ #define H5HF_MAN_ABS_DIRECT_FREE_NODE_SIZE(d) (2 * (d)->blk_off_size) /* Size of header for each object in an absolute managed direct block */ -#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(s, o) ( \ +#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_SIZE(h, o) ( \ H5HF_SIZEOF_OFFSET_LEN(o) /* Length of object in block */ \ + 1 /* Free space fragment length */ \ - + (s)->ref_count_size /* Ref. count of object in block */ \ ) -#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(s, d) ( \ +#define H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN_DBLOCK(h, d) ( \ (d)->blk_off_size /* Length of object in block */ \ + 1 /* Free space fragment length */ \ - + (s)->ref_count_size /* Ref. count of object in block */ \ ) /* Size of overhead for a direct block */ -#define H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(s, o) ( \ +#define H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(h, o) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE \ \ /* Fractal heap managed, absolutely mapped direct block specific fields */ \ - + (s)->sizeof_addr /* File address of heap owning the block */ \ - + (s)->heap_off_size /* Offset of the block in the heap */ \ - + H5HF_SIZEOF_OFFSET_LEN(o) /* Total free space in a block */ \ + + (h)->sizeof_addr /* File address of heap owning the block */ \ + + (h)->sizeof_addr /* File address of parent block */ \ + + 2 /* Entry within parent block */ \ + + 2 /* # of rows for parent block */ \ + + (h)->heap_off_size /* Offset of the block in the heap */ \ + H5HF_SIZEOF_OFFSET_LEN(o) /* Offset of first descriptor in free list */ \ ) -#define H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(s, d) ( \ +#define H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(h, d) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE \ \ /* Fractal heap managed, absolutely mapped direct block specific fields */ \ - + (s)->sizeof_addr /* File address of heap owning the block */ \ - + (s)->heap_off_size /* Offset of the block in the heap */ \ + + (h)->sizeof_addr /* File address of heap owning the block */ \ + + (h)->sizeof_addr /* File address of parent block */ \ + + 2 /* Entry within parent block */ \ + + 2 /* # of rows for parent block */ \ + + (h)->heap_off_size /* Offset of the block in the heap */ \ + (d)->blk_off_size /* Offset of first descriptor in free list */ \ ) /* Size of managed indirect block (absolute & mapped) */ -#define H5HF_MAN_INDIRECT_SIZE(s, i) ( \ +#define H5HF_MAN_INDIRECT_SIZE(h, i) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE \ \ /* Fractal heap managed, absolutely mapped indirect block specific fields */ \ - + (s)->sizeof_addr /* File address of heap owning the block */ \ - + (s)->heap_off_size /* Offset of the block in the heap */ \ + + (h)->sizeof_addr /* File address of heap owning the block */ \ + + (h)->sizeof_addr /* File address of parent block */ \ + + 2 /* Entry within parent block */ \ + + 2 /* # of rows for parent block */ \ + + (h)->heap_off_size /* Offset of the block in the heap */ \ + 4 /* Next block entry to allocate from */ \ - + (MIN((i)->nrows, (s)->man_dtable.max_direct_rows) * (s)->man_dtable.cparam.width * ((s)->sizeof_addr + (s)->man_dtable.max_dir_blk_off_size)) /* Size of entries for direct blocks */ \ - + ((((i)->nrows > (s)->man_dtable.max_direct_rows) ? ((i)->nrows - (s)->man_dtable.max_direct_rows) : 0) * (s)->man_dtable.cparam.width * ((s)->sizeof_addr + (s)->heap_off_size)) /* Size of entries for indirect blocks */ \ + + (MIN((i)->nrows, (h)->man_dtable.max_direct_rows) * (h)->man_dtable.cparam.width * ((h)->sizeof_addr + (h)->man_dtable.max_dir_blk_off_size)) /* Size of entries for direct blocks */ \ + + ((((i)->nrows > (h)->man_dtable.max_direct_rows) ? ((i)->nrows - (h)->man_dtable.max_direct_rows) : 0) * (h)->man_dtable.cparam.width * ((h)->sizeof_addr + (h)->heap_off_size)) /* Size of entries for indirect blocks */ \ ) @@ -175,10 +180,14 @@ typedef struct H5HF_freelist_t H5HF_freelist_t; /* Fractal heap free list section info (forward decl - defined in H5HFint.c) */ typedef struct H5HF_section_free_node_t H5HF_section_free_node_t; -/* Each fractal heap has certain information that can be shared across all - * the instances of blocks in that fractal heap. +/* The fractal heap header information */ +/* (Each fractal heap header has certain information that is shared across all + * the instances of blocks in that fractal heap) */ -typedef struct H5HF_shared_t { +typedef struct H5HF_t { + /* Information for H5AC cache functions, _must_ be first field in structure */ + H5AC_info_t cache_info; + /* Shared internal information (varies during lifetime of heap) */ hsize_t total_man_free; /* Total amount of free space in managed blocks */ hsize_t total_std_free; /* Total # of free standalone ID entries */ @@ -190,8 +199,11 @@ typedef struct H5HF_shared_t { hsize_t nobjs; /* Number of objects in heap */ /* Cached/computed values (not stored in header) */ + size_t rc; /* Reference count of child blocks */ hbool_t dirty; /* Shared info is modified */ + hbool_t evicted; /* Shared info is evicted from cache */ haddr_t heap_addr; /* Address of heap header in the file */ + H5AC_protect_t mode; /* Access mode for heap */ H5F_t *f; /* Pointer to file for heap */ size_t sizeof_size; /* Size of file sizes */ size_t sizeof_addr; /* Size of file addresses */ @@ -205,23 +217,49 @@ typedef struct H5HF_shared_t { /* Information set by user */ H5HF_addrmap_t addrmap; /* Type of address mapping */ uint32_t standalone_size; /* Size of object to store standalone */ - unsigned char ref_count_size; /* Size of ref. count for objects (only for heaps w/ref. counted objects) */ /* Information derived from user parameters (not stored in header) */ unsigned char heap_off_size; /* Size of heap offsets (in bytes) */ - hbool_t ref_count_obj; /* Are objects in the heap ref. counted? */ + hbool_t debug_objs; /* Is the heap storing objects in 'debug' format */ hbool_t have_io_filter; /* Does the heap have I/O filters for the direct blocks? */ hbool_t write_once; /* Is heap being written in "write once" mode? */ -} H5HF_shared_t; +} H5HF_t; -/* The fractal heap header information */ -typedef struct H5HF_t { +/* Indirect block entry */ +typedef struct H5HF_indirect_ent_t { + haddr_t addr; /* Direct block's address */ + hsize_t free_space; /* Amount of free space in block pointed to */ +/* XXX: Will need space for block size, for blocks with I/O filters */ +} H5HF_indirect_ent_t; + +/* Fractal heap indirect block */ +typedef struct H5HF_indirect_t { /* Information for H5AC cache functions, _must_ be first field in structure */ H5AC_info_t cache_info; - /* Internal fractal heap information */ - H5RC_t *shared; /* Ref-counted shared info */ -} H5HF_t; + /* Internal heap information */ + size_t rc; /* Reference count of child blocks */ + hbool_t dirty; /* Info is modified */ + hbool_t evicted; /* Info is evicted from cache */ + H5HF_t *shared; /* Shared heap header info */ + struct H5HF_indirect_t *parent; /* Shared parent indirect block info */ + hsize_t child_free_space; /* Total amount of free space in children */ + haddr_t addr; /* Address of this indirect block on disk */ + unsigned nrows; /* Total # of rows in indirect block */ + unsigned max_rows; /* Max. # of rows in indirect block */ + size_t size; /* Size of indirect block on disk */ + unsigned next_col; /* "Column" of next managed block (in doubling table) */ + unsigned next_row; /* "Row" of next managed block (in doubling table) */ + hsize_t next_size; /* Size of next managed block */ + H5HF_indirect_ent_t *ents; /* Pointer to block entry table */ + + /* Stored values */ + haddr_t par_addr; /* Address of parent block on disk */ + unsigned par_entry; /* Entry in parent's table */ + unsigned par_nrows; /* Total # of rows in parent indirect block */ + hsize_t block_off; /* Offset of the block within the heap's address space */ + size_t next_entry; /* Entry of next managed block */ +} H5HF_indirect_t; /* Direct block free list node */ typedef struct H5HF_direct_free_node_t { @@ -245,60 +283,22 @@ typedef struct H5HF_direct_t { H5AC_info_t cache_info; /* Internal heap information */ - H5RC_t *shared; /* Ref-counted shared heap info */ - H5RC_t *parent; /* Ref-counted shared parent block info */ - size_t parent_entry; /* Entry in parent's table */ + H5HF_t *shared; /* Shared heap header info */ + H5HF_indirect_t *parent; /* Shared parent indirect block info */ size_t size; /* Size of direct block */ unsigned blk_off_size; /* Size of offsets in the block */ + size_t blk_free_space; /* Total amount of free space in block */ H5HF_direct_free_head_t *free_list; /* Pointer to free list for block */ uint8_t *blk; /* Pointer to buffer containing block data */ /* Stored values */ + haddr_t par_addr; /* Address of parent block on disk */ + unsigned par_entry; /* Entry in parent's table */ + unsigned par_nrows; /* Total # of rows in parent indirect block */ hsize_t block_off; /* Offset of the block within the heap's address space */ - size_t blk_free_space; /* Total amount of free space in block */ size_t free_list_head; /* Offset of head of free list in block */ } H5HF_direct_t; -/* Indirect block entry */ -typedef struct H5HF_indirect_ent_t { - haddr_t addr; /* Direct block's address */ - hsize_t free_space; /* Amount of free space in block pointed to */ -/* XXX: Will need space for block size, for blocks with I/O filters */ -} H5HF_indirect_ent_t; - -/* Fractal heap indirect block */ -typedef struct H5HF_indirect_t { - /* Information for H5AC cache functions, _must_ be first field in structure */ - H5AC_info_t cache_info; - - /* Internal heap information */ - hbool_t dirty; /* Info is modified */ - H5RC_t *shared; /* Ref-counted shared info */ - H5RC_t *parent; /* Ref-counted shared parent block info */ - size_t parent_entry; /* Entry in parent's table */ - H5RC_t *self; /* Ref-counted shared 'self' block info */ - unsigned nrows; /* Total # of rows in indirect block */ - unsigned max_rows; /* Max. # of rows in indirect block */ - size_t size; /* Size of indirect block on disk */ - unsigned next_col; /* "Column" of next managed block (in doubling table) */ - unsigned next_row; /* "Row" of next managed block (in doubling table) */ - unsigned next_entry; /* Entry of next managed block */ - hsize_t next_size; /* Size of next managed block */ - H5HF_indirect_ent_t *ents; /* Pointer to block entry table */ - - /* Stored values */ - hsize_t block_off; /* Offset of the block within the heap's address space */ - hsize_t child_free_space; /* Total amount of free space in children */ -} H5HF_indirect_t; - -/* Shared information for parent of a fractal heap block */ -typedef struct H5HF_parent_shared_t { - H5RC_t *shared; /* Ref-counted shared heap info */ - H5RC_t *parent; /* Ref-counted shared parent block info */ - size_t parent_entry; /* Entry in parent's table */ - hsize_t parent_free_space; /* Free space in block, from parent */ -} H5HF_parent_shared_t; - /* Fractal heap metadata statistics info */ typedef struct H5HF_stat_t { hsize_t total_size; /* Total size of heap allocated (man & std) */ @@ -348,22 +348,32 @@ H5FL_SEQ_EXTERN(H5HF_indirect_ent_t); /* Package Private Prototypes */ /******************************/ -/* Routines for managing shared fractal heap info */ -H5_DLL H5HF_shared_t * H5HF_shared_alloc(H5F_t *f); -H5_DLL herr_t H5HF_shared_init(H5HF_shared_t *shared, H5HF_t *fh, haddr_t heap_addr, H5HF_create_t *cparam); -H5_DLL herr_t H5HF_shared_own(H5HF_t *fh, H5HF_shared_t *shared); +/* Routines for managing shared fractal heap header */ +H5_DLL H5HF_t * H5HF_alloc(H5F_t *f); +H5_DLL herr_t H5HF_init(H5HF_t *fh, haddr_t heap_addr, H5HF_create_t *cparam); +H5_DLL herr_t H5HF_finish_init(H5HF_t *fh); + +/* Doubling table routines */ +H5_DLL herr_t H5HF_dtable_dest(H5HF_dtable_t *dtable); + +/* Heap header routines */ +H5_DLL herr_t H5HF_cache_hdr_dest_real(H5HF_t *hdr); +H5_DLL herr_t H5HF_hdr_incr(H5HF_t *hdr); +H5_DLL herr_t H5HF_hdr_decr(H5HF_t *hdr); /* Indirect block routines */ -H5_DLL herr_t H5HF_iblock_free(void *_iblock); +H5_DLL herr_t H5HF_cache_iblock_dest_real(H5HF_indirect_t *iblock); +H5_DLL herr_t H5HF_iblock_incr(H5HF_indirect_t *iblock); +H5_DLL herr_t H5HF_iblock_decr(H5HF_indirect_t *iblock); /* Routines for allocating space */ H5_DLL herr_t H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr); -H5_DLL herr_t H5HF_man_find(H5RC_t *fh_shared, hid_t dxpl_id, size_t request, +H5_DLL herr_t H5HF_man_find(H5HF_t *fh, hid_t dxpl_id, size_t request, H5HF_section_free_node_t **sec_node/*out*/); -H5_DLL herr_t H5HF_man_insert(H5RC_t *fh_shared, hid_t dxpl_id, +H5_DLL herr_t H5HF_man_insert(H5HF_t *fh, hid_t dxpl_id, H5HF_section_free_node_t *sec_node, size_t obj_size, const void *obj, void *id); -H5_DLL herr_t H5HF_man_read(H5RC_t *fh_shared, hid_t dxpl_id, hsize_t obj_off, +H5_DLL herr_t H5HF_man_read(H5HF_t *fh, hid_t dxpl_id, hsize_t obj_off, void *obj); /* Metadata cache callbacks */ diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index 4454ee7..6296e8c 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -65,8 +65,6 @@ typedef struct H5HF_create_t { H5HF_addrmap_t addrmap; /* Type of address mapping for objects in heap */ uint32_t standalone_size; /* Size of object to store standalone */ /* (i.e. max. size of object to manage) */ - unsigned char ref_count_size; /* Size of ref. count field for objects, in bytes (0 means no ref. counts for objects) */ - /* (only for heaps w/ref. counted objects) */ } H5HF_create_t; diff --git a/src/H5HFstat.c b/src/H5HFstat.c index 6cdc61b..93e8036 100644 --- a/src/H5HFstat.c +++ b/src/H5HFstat.c @@ -85,8 +85,7 @@ herr_t H5HF_stat_info(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_stat_t *stats) { - H5HF_t *fh = NULL; /* Pointer to the B-tree header */ - H5HF_shared_t *shared; /* Shared fractal heap information */ + H5HF_t *hdr = NULL; /* Pointer to the fractal heap header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_stat_info) @@ -97,24 +96,20 @@ H5HF_stat_info(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_stat_t *stats) HDassert(stats); /* Look up the fractal heap header */ - if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ))) + if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* Report statistics for fractal heap */ - stats->total_size = shared->total_size; - stats->man_size = shared->man_size; - stats->std_size = shared->std_size; - stats->man_free_space = shared->total_man_free; - stats->nobjs = shared->nobjs; + stats->total_size = hdr->total_size; + stats->man_size = hdr->man_size; + stats->std_size = hdr->std_size; + stats->man_free_space = hdr->total_man_free; + stats->nobjs = hdr->nobjs; /* XXX: Add more metadata statistics for the heap */ done: /* Release fractal heap header node */ - if(fh && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, fh, H5AC__NO_FLAGS_SET) < 0) + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header info") FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HFtest.c b/src/H5HFtest.c index c96d516..02024b9 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -86,8 +86,7 @@ herr_t H5HF_get_cparam_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_create_t *cparam) { - H5HF_t *fh = NULL; /* Pointer to the B-tree header */ - H5HF_shared_t *shared; /* Shared fractal heap information */ + H5HF_t *hdr = NULL; /* Pointer to the fractal heap header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_get_cparam_test) @@ -98,22 +97,17 @@ H5HF_get_cparam_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_create_t *cp HDassert(cparam); /* Look up the fractal heap header */ - if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ))) + if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap header") - /* Get the pointer to the shared fractal heap info */ - shared = H5RC_GET_OBJ(fh->shared); - HDassert(shared); - /* Get fractal heap creation parameters */ - cparam->addrmap = shared->addrmap; - cparam->standalone_size = shared->standalone_size; - cparam->ref_count_size = shared->ref_count_size; - HDmemcpy(&(cparam->managed), &(shared->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t)); + cparam->addrmap = hdr->addrmap; + cparam->standalone_size = hdr->standalone_size; + HDmemcpy(&(cparam->managed), &(hdr->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t)); done: /* Release fractal heap header node */ - if(fh && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, fh, H5AC__NO_FLAGS_SET) < 0) + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header info") FUNC_LEAVE_NOAPI(ret_value) diff --git a/test/fheap.c b/test/fheap.c index 6ae7830..24ba033 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -28,17 +28,29 @@ /* Other private headers that this test requires */ #include "H5Iprivate.h" #include "H5MMprivate.h" /* Memory management */ - -/* "Standard" creation table parameters */ +#include "H5Vprivate.h" /* Vectors and arrays */ + +/* "Small" heap creation parameters */ +#define SMALL_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */ +#define SMALL_STAND_SIZE (8 * 1024) /* Standalone obj. min. size */ +#define SMALL_MAN_WIDTH 4 /* Managed obj. table width */ +#define SMALL_MAN_START_BLOCK_SIZE 512 /* Managed obj. starting block size */ +#define SMALL_MAN_MAX_DIRECT_SIZE (64 * 1024) /* Managed obj. max. direct block size */ +#define SMALL_MAN_MAX_INDEX 32 /* Managed obj. # of bits for total heap size */ +#define SMALL_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */ + +/* "Standard" heap creation parameters */ #define STD_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */ #define STD_STAND_SIZE (64 * 1024) /* Standalone obj. min. size */ -#define STD_REF_COUNT_SIZE 0 /* Size of ref. count for obj. */ #define STD_MAN_WIDTH 32 /* Managed obj. table width */ #define STD_MAN_START_BLOCK_SIZE 1024 /* Managed obj. starting block size */ #define STD_MAN_MAX_DIRECT_SIZE (1024 * 1024) /* Managed obj. max. direct block size */ #define STD_MAN_MAX_INDEX 64 /* Managed obj. # of bits for total heap size */ #define STD_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */ +/* Heap metadata */ +#define DBLOCK_OVERHEAD 32 /* # of bytes in direct block overhead */ + const char *FILENAME[] = { "fheap", NULL @@ -73,7 +85,6 @@ init_std_cparam(H5HF_create_t *cparam) /* General parameters */ cparam->addrmap = STD_ADDRMAP; cparam->standalone_size = STD_STAND_SIZE; - cparam->ref_count_size = STD_REF_COUNT_SIZE; /* Managed object doubling-table parameters */ cparam->managed.width = STD_MAN_WIDTH; @@ -87,6 +98,42 @@ init_std_cparam(H5HF_create_t *cparam) /*------------------------------------------------------------------------- + * Function: init_small_cparam + * + * Purpose: Initialize heap creation parameter structure with small + * settings + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static int +init_small_cparam(H5HF_create_t *cparam) +{ + /* Wipe out background */ + HDmemset(cparam, 0, sizeof(H5HF_create_t)); + + /* General parameters */ + cparam->addrmap = SMALL_ADDRMAP; + cparam->standalone_size = SMALL_STAND_SIZE; + + /* Managed object doubling-table parameters */ + cparam->managed.width = SMALL_MAN_WIDTH; + cparam->managed.start_block_size = SMALL_MAN_START_BLOCK_SIZE; + cparam->managed.max_direct_size = SMALL_MAN_MAX_DIRECT_SIZE; + cparam->managed.max_index = SMALL_MAN_MAX_INDEX; + cparam->managed.start_root_rows = SMALL_MAN_START_ROOT_ROWS; + + return(0); +} /* init_small_cparam() */ + + +/*------------------------------------------------------------------------- * Function: check_stats * * Purpose: Verify stats for a heap @@ -154,8 +201,9 @@ error: *------------------------------------------------------------------------- */ static int -fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size, - size_t block_size, unsigned start_nobjs, unsigned *nobjs_ptr) +fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, + hsize_t heap_size, size_t block_size, + unsigned start_nobjs, unsigned *nobjs_ptr) { H5HF_stat_t heap_stats; /* Statistics about the heap */ hsize_t heap_id; /* Heap ID for object inserted */ @@ -173,12 +221,12 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size, /* Initialize variables */ if(block_size <= (64 * 1024)) { - data_size = block_size - 28; /* '28' is the size of the direct block's overhead */ + data_size = block_size - (DBLOCK_OVERHEAD + cparam->managed.max_index / 8); /* '28' is the size of the direct block's overhead */ obj_overhead = 3; free_overhead = 4; } /* end if */ else { - data_size = block_size - 29; /* '29' is the size of the direct block's overhead */ + data_size = block_size - (DBLOCK_OVERHEAD + 1 + cparam->managed.max_index / 8); /* '29' is the size of the direct block's overhead */ obj_overhead = 4; /* Will handle blocks up to 2^24 */ free_overhead = 6; } /* end else */ @@ -233,7 +281,7 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t heap_size, ids[nobjs - 1] = heap_id; /* Check stats for heap */ - if((heap_stats.man_free_space - (sizeof(obj) + obj_overhead)) < free_overhead) + if((heap_stats.man_free_space - (sizeof(obj) + obj_overhead)) <= free_overhead) free_frag_size = heap_stats.man_free_space - (sizeof(obj) + obj_overhead); if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)(data_size - ((nobjs * (sizeof(obj) + obj_overhead)) + free_frag_size)), (hsize_t)(start_nobjs + nobjs))) FAIL_STACK_ERROR @@ -316,12 +364,12 @@ error: *------------------------------------------------------------------------- */ static int -test_create(hid_t fapl) +test_create(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam, test_cparam; /* Creation parameters for heap */ + H5HF_create_t test_cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ /* Set the filename to use for this test (dependent on fapl) */ @@ -338,9 +386,8 @@ test_create(hid_t fapl) /* * Test fractal heap creation (w/absolute address mapping) */ - TESTING("Fractal heap creation (w/absolute address mapping)"); - init_std_cparam(&cparam); - if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, &cparam, &fh_addr/*out*/) < 0) + TESTING("fractal heap creation (w/absolute address mapping)"); + if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -349,34 +396,11 @@ test_create(hid_t fapl) PASSED() /* Query the type of address mapping */ - TESTING("Query absolute address mapping setting"); + TESTING("query heap creation parameters"); HDmemset(&test_cparam, 0, sizeof(H5HF_create_t)); if(H5HF_get_cparam_test(f, H5P_DATASET_XFER_DEFAULT, fh_addr, &test_cparam) < 0) FAIL_STACK_ERROR - if(HDmemcmp(&cparam, &test_cparam, sizeof(H5HF_create_t))) - FAIL_STACK_ERROR - PASSED() - - /* - * Test fractal heap creation (w/mapped address mapping) - */ - TESTING("Fractal heap creation (w/mapped address mapping)"); - init_std_cparam(&cparam); - cparam.addrmap = H5HF_MAPPED; - if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, &cparam, &fh_addr/*out*/) < 0) - FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) - FAIL_STACK_ERROR - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0)) - FAIL_STACK_ERROR - PASSED() - - /* Query the type of address mapping */ - TESTING("Query mapped address mapping setting"); - HDmemset(&test_cparam, 0, sizeof(H5HF_create_t)); - if(H5HF_get_cparam_test(f, H5P_DATASET_XFER_DEFAULT, fh_addr, &test_cparam) < 0) - FAIL_STACK_ERROR - if(HDmemcmp(&cparam, &test_cparam, sizeof(H5HF_create_t))) + if(HDmemcmp(cparam, &test_cparam, sizeof(H5HF_create_t))) FAIL_STACK_ERROR PASSED() @@ -410,17 +434,17 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_first(hid_t fapl) +test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for object to insert */ unsigned char robj[10]; /* Buffer for object to read */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ @@ -435,8 +459,7 @@ test_abs_insert_first(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -450,11 +473,12 @@ test_abs_insert_first(hid_t fapl) /* * Test inserting first (small) object into absolute heap */ - TESTING("Inserting first (small) object into absolute heap"); + TESTING("inserting first (small) object into absolute heap"); heap_id = 0; if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) FAIL_STACK_ERROR - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)983, (hsize_t)1)) + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1)) FAIL_STACK_ERROR /* Check reading back in the object */ @@ -495,19 +519,19 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_second(hid_t fapl) +test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for first object to insert */ unsigned char robj[10]; /* Buffer for reading first object */ unsigned char obj2[20]; /* Buffer for second object to insert */ unsigned char robj2[20]; /* Buffer for reading second object */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ @@ -522,8 +546,7 @@ test_abs_insert_second(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -537,11 +560,12 @@ test_abs_insert_second(hid_t fapl) /* * Test inserting first (small) object into absolute heap */ - TESTING("Inserting two (small) objects into absolute heap"); + TESTING("inserting two (small) objects into absolute heap"); heap_id = 0; if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) FAIL_STACK_ERROR - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)983, (hsize_t)1)) + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)1)) FAIL_STACK_ERROR /* Check reading back in the first object */ @@ -553,7 +577,8 @@ test_abs_insert_second(hid_t fapl) heap_id = 0; if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj2), obj2, &heap_id) < 0) FAIL_STACK_ERROR - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)1024, (hsize_t)1024, (hsize_t)0, (hsize_t)960, (hsize_t)2)) + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + (sizeof(obj2) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)cparam->managed.start_block_size, (hsize_t)cparam->managed.start_block_size, (hsize_t)0, free_space, (hsize_t)2)) FAIL_STACK_ERROR /* Check reading back in the second object */ @@ -595,13 +620,12 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_root_mult(hid_t fapl) +test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ /* Set the filename to use for this test (dependent on fapl) */ @@ -616,8 +640,7 @@ test_abs_insert_root_mult(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -628,7 +651,7 @@ test_abs_insert_root_mult(hid_t fapl) TESTING("inserting objects to fill absolute heap's root direct block"); /* Fill the heap up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, 0, NULL)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, 0, NULL)) FAIL_STACK_ERROR PASSED() @@ -665,16 +688,16 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_force_indirect(hid_t fapl) +test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for first object to insert */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned u; /* Local index variable */ @@ -690,8 +713,7 @@ test_abs_insert_force_indirect(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -702,7 +724,7 @@ test_abs_insert_force_indirect(hid_t fapl) TESTING("inserting objects to create root indirect block"); /* Fill the heap up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, 0, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, 0, &nobjs)) FAIL_STACK_ERROR /* Insert one more object, to force root indirect block creation */ @@ -719,7 +741,8 @@ test_abs_insert_force_indirect(hid_t fapl) /* Increment object count */ nobjs++; - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)2048, (hsize_t)2048, (hsize_t)0, (hsize_t)983, (hsize_t)nobjs)) + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)(2 * cparam->managed.start_block_size), (hsize_t)(2 * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)nobjs)) FAIL_STACK_ERROR PASSED() @@ -756,13 +779,12 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_fill_second(hid_t fapl) +test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ @@ -779,8 +801,7 @@ test_abs_insert_fill_second(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -791,12 +812,12 @@ test_abs_insert_fill_second(hid_t fapl) TESTING("inserting objects to fill second direct block"); /* Fill the first direct block heap up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; /* Fill the second direct block heap up (also creates initial root indirect block) */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(2 * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR PASSED() @@ -834,17 +855,17 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_third_direct(hid_t fapl) +test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for first object to insert */ unsigned char robj[10]; /* Buffer for reading object */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ unsigned u; /* Local index variable */ @@ -861,8 +882,7 @@ test_abs_insert_third_direct(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -872,13 +892,13 @@ test_abs_insert_third_direct(hid_t fapl) */ TESTING("inserting objects to create third direct block"); - /* Fill the first direct block heap up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)1024, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + /* Fill the first direct block up */ + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; /* Fill the second direct block heap up (also creates initial root indirect block) */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)2048, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(2 * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; @@ -896,7 +916,8 @@ test_abs_insert_third_direct(hid_t fapl) /* Increment object count */ tot_nobjs++; - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)3072, (hsize_t)3072, (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs)) + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)(3 * cparam->managed.start_block_size), (hsize_t)(3 * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR /* Read in object */ @@ -939,13 +960,12 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_first_row(hid_t fapl) +test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ @@ -963,8 +983,7 @@ test_abs_fill_first_row(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -975,9 +994,9 @@ test_abs_fill_first_row(hid_t fapl) TESTING("inserting objects to fill first row of root indirect block"); /* Loop over filling direct blocks, until first root indirect row is full */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1016,17 +1035,17 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_second_row(hid_t fapl) +test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for object to insert */ unsigned char robj[10]; /* Buffer for reading object */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ unsigned u; /* Local index variable */ @@ -1043,8 +1062,7 @@ test_abs_start_second_row(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -1055,9 +1073,9 @@ test_abs_start_second_row(hid_t fapl) TESTING("inserting objects to start second row of root indirect block"); /* Loop over filling direct blocks, until first root indirect row is full */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1076,7 +1094,8 @@ test_abs_start_second_row(hid_t fapl) /* Increment object count */ tot_nobjs++; - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)((STD_MAN_WIDTH + 1) * STD_MAN_START_BLOCK_SIZE), (hsize_t)((STD_MAN_WIDTH + 1) * STD_MAN_START_BLOCK_SIZE), (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs)) + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, (hsize_t)((cparam->managed.width + 1) * cparam->managed.start_block_size), (hsize_t)((cparam->managed.width + 1) * cparam->managed.start_block_size), (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR /* Read in object */ @@ -1119,13 +1138,12 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_second_row(hid_t fapl) +test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ @@ -1143,8 +1161,7 @@ test_abs_fill_second_row(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -1155,17 +1172,17 @@ test_abs_fill_second_row(hid_t fapl) TESTING("inserting objects to fill second row of root indirect block"); /* Loop over filling direct blocks, until first root indirect row is full */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ /* Loop over filling direct blocks, until second root indirect row is full */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)((cparam->managed.width * cparam->managed.start_block_size) + (u + 1) * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1205,17 +1222,17 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_third_row(hid_t fapl) +test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for object to insert */ unsigned char robj[10]; /* Buffer for reading object */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ hsize_t heap_size; /* Total size of heap */ @@ -1233,8 +1250,7 @@ test_abs_start_third_row(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -1245,17 +1261,17 @@ test_abs_start_third_row(hid_t fapl) TESTING("inserting objects to start third row of root indirect block"); /* Loop over filling direct blocks, until first root indirect row is full */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)(u + 1) * STD_MAN_START_BLOCK_SIZE, STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)(u + 1) * cparam->managed.start_block_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ /* Loop over filling direct blocks, until second root indirect row is full */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, (hsize_t)((STD_MAN_WIDTH * STD_MAN_START_BLOCK_SIZE) + (u + 1) * STD_MAN_START_BLOCK_SIZE), STD_MAN_START_BLOCK_SIZE, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)((cparam->managed.width * cparam->managed.start_block_size) + (u + 1) * cparam->managed.start_block_size), cparam->managed.start_block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1274,9 +1290,10 @@ test_abs_start_third_row(hid_t fapl) /* Increment object count */ tot_nobjs++; - heap_size = (2 * STD_MAN_WIDTH) * STD_MAN_START_BLOCK_SIZE + - (2 * STD_MAN_START_BLOCK_SIZE); - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)2007, (hsize_t)tot_nobjs)) + heap_size = (2 * cparam->managed.width) * cparam->managed.start_block_size + + (2 * cparam->managed.start_block_size); + free_space = (2 * cparam->managed.start_block_size) - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR /* Read in object */ @@ -1319,13 +1336,12 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_fourth_row(hid_t fapl) +test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ @@ -1345,8 +1361,7 @@ test_abs_fill_fourth_row(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -1357,14 +1372,14 @@ test_abs_fill_fourth_row(hid_t fapl) TESTING("inserting objects to fill four rows of root indirect block"); /* Loop over rows */ - block_size = STD_MAN_START_BLOCK_SIZE; + block_size = cparam->managed.start_block_size; heap_size = 0; for(v = 0; v < 4; v++) { /* Loop over filling direct blocks for a row */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ heap_size += block_size; - if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1408,13 +1423,12 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_all_root_direct(hid_t fapl) +test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ @@ -1435,14 +1449,10 @@ test_abs_fill_all_root_direct(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ /* * Test inserting mult. (small) objects to fill all direct rows in root indirect block @@ -1450,10 +1460,1052 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); TESTING("inserting objects to fill all direct rows of root indirect block"); /* Loop over rows */ - block_size = STD_MAN_START_BLOCK_SIZE; + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_all_root_direct() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_first_recursive_indirec5 + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block and create first recursive indirect block. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 20, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned char obj[10]; /* Buffer for object to insert */ + unsigned char robj[10]; /* Buffer for reading object */ + hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u; /* Local index variable */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to force creation of first recursive indirect block + */ + TESTING("inserting objects to create first recursive indirect block"); + + /* Loop over rows */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Insert one more object, to force creation of first recursive indirect block */ + + /* Initialize object buffer */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u + tot_nobjs; + + /* Insert object */ + heap_id = 0; + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) + FAIL_STACK_ERROR + + /* Increment object count */ + tot_nobjs++; + + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) + FAIL_STACK_ERROR + + /* Read in object */ + if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_first_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_second_direct_recursive_indirec5 + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, create first recursive indirect block and start second + * direct block in that indirect block. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned char obj[10]; /* Buffer for object to insert */ + unsigned char robj[10]; /* Buffer for reading object */ + hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u; /* Local index variable */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to force creation of second direct + * block in first recursive indirect block + */ + TESTING("inserting objects to create second direct block in first recursive indirect block"); + + /* Loop over rows */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Fill the first direct block in the recursive indirect block up */ + heap_size += cparam->managed.start_block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + + /* Insert one more object, to force creation of second direct block in + * first recursive indirect block + */ + + /* Initialize object buffer */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u + tot_nobjs; + + /* Insert object */ + heap_id = 0; + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) + FAIL_STACK_ERROR + + /* Increment object count */ + tot_nobjs++; + + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) + FAIL_STACK_ERROR + + /* Read in object */ + if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_second_direct_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_first_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, create first recursive indirect block and filling all + * direct blocks in that indirect block. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u; /* Local index variable */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill all direct blocks in first recursive indirect block"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); + while(block_size <= max_block_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_first_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_second_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, create first recursive indirect block, filling all + * direct blocks in that indirect block and adding another + * object to force creation of second recursive indirect block. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned char obj[10]; /* Buffer for object to insert */ + unsigned char robj[10]; /* Buffer for reading object */ + hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u; /* Local index variable */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to start second recursive indirect block"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); + while(block_size <= max_block_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Insert one more object, to force creation of second + * recursive indirect block + */ + + /* Initialize object buffer */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u + tot_nobjs; + + /* Insert object */ + heap_id = 0; + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) + FAIL_STACK_ERROR + + /* Increment object count */ + tot_nobjs++; + + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) + FAIL_STACK_ERROR + + /* Read in object */ + if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_second_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_second_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, create first recursive indirect block, filling all + * direct blocks in that indirect block and then create second + * recursive indirect block and fill all direct blocks in that + * indirect block. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u; /* Local index variable */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill all direct blocks in second recursive indirect block"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); + while(block_size <= max_block_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over direct block rows in second recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); + while(block_size <= max_block_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_second_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_recursive_indirect_row + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, create first recursive indirect block, filling all + * direct blocks in that indirect block and then create second + * recursive indirect block and fill all direct blocks in that + * indirect block. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill all direct blocks in first row of recursive indirect block"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; heap_size = 0; nrows = 0; - while(block_size <= STD_MAN_MAX_DIRECT_SIZE) { + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); + while(block_size <= max_block_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_recursive_indirect_row() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_start_2nd_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the first row of indirect + * blocks and start on first block in second row of indirect blocks + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned char obj[10]; /* Buffer for object to insert */ + unsigned char robj[10]; /* Buffer for reading object */ + hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to start second row of recursive indirect blocks"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); + while(block_size <= max_block_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + + /* Insert one more object, to force creation of second + * recursive indirect block + */ + + /* Initialize object buffer */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u + tot_nobjs; + + /* Insert object */ + heap_id = 0; + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) + FAIL_STACK_ERROR + + /* Increment object count */ + tot_nobjs++; + + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) + FAIL_STACK_ERROR + + /* Read in object */ + if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_start_2nd_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_recursive_indirect_two_deep + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill recursive indirect blocks two levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { #ifdef QAK HDfprintf(stderr, "block_size = %Zu\n", block_size); #endif /* QAK */ @@ -1461,13 +2513,13 @@ HDfprintf(stderr, "block_size = %Zu\n", block_size); #ifdef QAK HDfprintf(stderr, "block number: "); #endif /* QAK */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { #ifdef QAK HDfprintf(stderr, "%u ", u); #endif /* QAK */ /* Fill a direct heap block up */ heap_size += block_size; - if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1483,6 +2535,56 @@ HDfprintf(stderr, "\n"); nrows++; } /* end for */ + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + PASSED() /* Close the file */ @@ -1497,43 +2599,46 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_all_root_direct() */ +} /* test_abs_recursive_indirect_two_deep() */ /*------------------------------------------------------------------------- - * Function: test_abs_first_recursive_indirec5 + * Function: test_abs_start_3rd_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block and create first recursive indirect block. + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep and start first direct block + * in 3rd level of indirect blocks * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 20, 2006 + * Monday, March 27, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_first_recursive_indirect(hid_t fapl) +test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_create_t cparam; /* Creation parameters for heap */ haddr_t fh_addr; /* Address of fractal heap created */ unsigned char obj[10]; /* Buffer for object to insert */ unsigned char robj[10]; /* Buffer for reading object */ hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ unsigned nobjs = 0; /* Number of objects inserted */ unsigned tot_nobjs = 0; /* Total number of objects inserted */ size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ hsize_t heap_size; /* Total size of heap */ unsigned nrows; /* Number of rows inserted */ - unsigned u; /* Local index variable */ + unsigned u, v, w; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -1547,8 +2652,7 @@ test_abs_first_recursive_indirect(hid_t fapl) STACK_ERROR /* Create absolute heap */ - init_std_cparam(&cparam); - if(H5HF_create(f, dxpl, &cparam, &fh_addr/*out*/) < 0) + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR @@ -1557,15 +2661,16 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); #endif /* QAK */ /* - * Test inserting mult. (small) objects to force creation of first recursive indirect block + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block */ - TESTING("inserting objects to create first recursive indirect block"); + TESTING("inserting objects to start recursive indirect blocks three levels deep"); - /* Loop over rows */ - block_size = STD_MAN_START_BLOCK_SIZE; + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; heap_size = 0; nrows = 0; - while(block_size <= STD_MAN_MAX_DIRECT_SIZE) { + while(block_size <= cparam->managed.max_direct_size) { #ifdef QAK HDfprintf(stderr, "block_size = %Zu\n", block_size); #endif /* QAK */ @@ -1573,13 +2678,13 @@ HDfprintf(stderr, "block_size = %Zu\n", block_size); #ifdef QAK HDfprintf(stderr, "block number: "); #endif /* QAK */ - for(u = 0; u < STD_MAN_WIDTH; u++) { + for(u = 0; u < cparam->managed.width; u++) { #ifdef QAK HDfprintf(stderr, "%u ", u); #endif /* QAK */ /* Fill a direct heap block up */ heap_size += block_size; - if(fill_heap(f, dxpl, fh_addr, heap_size, block_size, tot_nobjs, &nobjs)) + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) FAIL_STACK_ERROR tot_nobjs += nobjs; } /* end for */ @@ -1595,7 +2700,59 @@ HDfprintf(stderr, "\n"); nrows++; } /* end for */ - /* Insert one more object, to force creation of first recursive indirect block */ + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Insert one more object, to force creation of third level deep + * recursive indirect block + */ /* Initialize object buffer */ for(u = 0; u < sizeof(obj); u++) @@ -1609,8 +2766,9 @@ HDfprintf(stderr, "\n"); /* Increment object count */ tot_nobjs++; - heap_size += STD_MAN_START_BLOCK_SIZE; - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, (hsize_t)983, (hsize_t)tot_nobjs)) + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) FAIL_STACK_ERROR /* Read in object */ @@ -1633,7 +2791,2755 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_first_recursive_indirect() */ +} /* test_abs_start_3rd_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_first_3rd_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep and fill first indirect block + * in 3rd level of indirect blocks + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill first indirect block of recursive indirect blocks three levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_first_3rd_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_3rd_recursive_indirect_row + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep and fill all indirect blocks + * first row of 3rd level of indirect blocks + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(w = 0; w < cparam->managed.width; w++) { + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2((2 * cparam->managed.max_direct_size) / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_3rd_recursive_indirect_row() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_all_3rd_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep and fill all indirect blocks + * that are three levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w, x, y; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_all_3rd_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_start_4th_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep and start first direct block that + * is four levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned char obj[10]; /* Buffer for object to insert */ + unsigned char robj[10]; /* Buffer for reading object */ + hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w, x, y; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to start first direct block in recursive indirect blocks four levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + /* Insert one more object, to force creation of four level deep + * recursive indirect block + */ + + /* Initialize object buffer */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u + tot_nobjs; + + /* Insert object */ + heap_id = 0; + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) + FAIL_STACK_ERROR + + /* Increment object count */ + tot_nobjs++; + + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) + FAIL_STACK_ERROR + + /* Read in object */ + if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_start_4th_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_first_4th_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep and fill the first (3rd level) + * indirect block that is four levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w, x, y; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill first (3rd level) indirect block in recursive indirect block four levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over direct block rows in fourth level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < 1; w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_first_4th_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_4th_recursive_indirect_row + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep and fill the first row of + * indirect block that is four levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w, x, y, z; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block + */ + TESTING("inserting objects to fill first row of recursive indirect blocks four levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over row of 4th level indirect blocks */ + for(z = 0; z < cparam->managed.width; z++) { +#ifdef QAK +HDfprintf(stderr, "4th indirect block # = %u\n", z); +#endif /* QAK */ + + /* Loop over direct block rows in fourth level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < 1; y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_4th_recursive_indirect_row() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_all_4th_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep and fill all rows of + * indirect blocks that are four levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w, x, y, z, uu; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in recursive indirect blocks four levels deep + */ + TESTING("inserting objects to fill all rows of recursive indirect blocks four levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(uu = 0; uu < (H5V_log2_of2(cparam->managed.width) + 1); uu++) { +#ifdef QAK +HDfprintf(stderr, "4th indirect row # = %u\n", uu); +#endif /* QAK */ + + /* Loop over row of 4th level indirect blocks */ + for(z = 0; z < cparam->managed.width; z++) { +#ifdef QAK +HDfprintf(stderr, "4th indirect block # = %u\n", z); +#endif /* QAK */ + + /* Loop over direct block rows in fourth level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (uu + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_all_4th_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_start_5th_recursive_indirect + * + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep, fill all rows of indirect blocks + * that are four levels deep and start first direct block in + * indirect blocks five levels deep + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, March 27, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + haddr_t fh_addr; /* Address of fractal heap created */ + unsigned char obj[10]; /* Buffer for object to insert */ + unsigned char robj[10]; /* Buffer for reading object */ + hsize_t heap_id; /* Heap ID for object inserted */ + hsize_t free_space; /* Size of free space in heap */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned tot_nobjs = 0; /* Total number of objects inserted */ + size_t block_size; /* Size of block added */ + size_t max_block_size; /* Max. size of block to add */ + hsize_t heap_size; /* Total size of heap */ + unsigned nrows; /* Number of rows inserted */ + unsigned u, v, w, x, y, z, uu; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR +#ifdef QAK +HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); +#endif /* QAK */ + + /* + * Test inserting mult. (small) objects to fill all direct + * blocks in recursive indirect blocks four levels deep + */ + TESTING("inserting objects to create first direct block in recursive indirect blocks five levels deep"); + + /* Loop over direct block rows in root indirect block */ + block_size = cparam->managed.start_block_size; + heap_size = 0; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (H5V_log2_of2(cparam->managed.width) + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(uu = 0; uu < (H5V_log2_of2(cparam->managed.width) + 1); uu++) { +#ifdef QAK +HDfprintf(stderr, "4th indirect row # = %u\n", uu); +#endif /* QAK */ + + /* Loop over row of 4th level indirect blocks */ + for(z = 0; z < cparam->managed.width; z++) { +#ifdef QAK +HDfprintf(stderr, "4th indirect block # = %u\n", z); +#endif /* QAK */ + + /* Loop over direct block rows in fourth level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (H5V_log2_of2(cparam->managed.width) + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + + /* Loop over rows of 3rd level deep indirect blocks */ + for(y = 0; y < (uu + 1); y++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect row # = %u\n", y); +#endif /* QAK */ + + /* Loop over row of 3rd level deep indirect blocks */ + for(x = 0; x < cparam->managed.width; x++) { +#ifdef QAK +HDfprintf(stderr, "3rd indirect block # = %u\n", x); +#endif /* QAK */ + + /* Loop over direct block rows in third level indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + while(block_size <= cparam->managed.max_direct_size) { + /* Loop over filling direct blocks for a row */ + for(u = 0; u < cparam->managed.width; u++) { + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + + /* Loop over rows of 2nd level deep indirect blocks */ + for(w = 0; w < (y + 1); w++) { +#ifdef QAK +HDfprintf(stderr, "indirect row # = %u\n", w); +#endif /* QAK */ + + /* Loop over row of indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) { +#ifdef QAK +HDfprintf(stderr, "indirect block # = %u\n", v); +#endif /* QAK */ + /* Loop over direct block rows in first recursive indirect block */ + block_size = cparam->managed.start_block_size; + nrows = 0; + max_block_size = block_size * (1 << ((H5V_log2_of2(cparam->managed.max_direct_size / cparam->managed.width) - + (H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width))) + (w + 1) + 1)); +#ifdef QAK +HDfprintf(stderr, "max_block_size = %Zu\n", max_block_size); +#endif /* QAK */ + while(block_size <= max_block_size) { +#ifdef QAK +HDfprintf(stderr, "block_size = %Zu\n", block_size); +#endif /* QAK */ + /* Loop over filling direct blocks for a row */ +#ifdef QAK +HDfprintf(stderr, "block number: "); +#endif /* QAK */ + for(u = 0; u < cparam->managed.width; u++) { +#ifdef QAK +HDfprintf(stderr, "%u ", u); +#endif /* QAK */ + /* Fill a direct heap block up */ + heap_size += block_size; + if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, tot_nobjs, &nobjs)) + FAIL_STACK_ERROR + tot_nobjs += nobjs; + } /* end for */ +#ifdef QAK +HDfprintf(stderr, "\n"); +#endif /* QAK */ + + /* Adjust block size for row */ + if(nrows > 0) + block_size *= 2; + + /* Increment row count */ + nrows++; + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + } /* end for */ + + /* Insert one more object, to force creation of five level deep + * recursive indirect block + */ + + /* Initialize object buffer */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u + tot_nobjs; + + /* Insert object */ + heap_id = 0; + if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, &heap_id) < 0) + FAIL_STACK_ERROR + + /* Increment object count */ + tot_nobjs++; + + heap_size += cparam->managed.start_block_size; + free_space = cparam->managed.start_block_size - ((sizeof(obj) + 3) + DBLOCK_OVERHEAD + (cparam->managed.max_index / 8)); + if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)tot_nobjs)) + FAIL_STACK_ERROR + + /* Read in object */ + if(H5HF_read(f, dxpl, fh_addr, &heap_id, robj) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(obj, robj, sizeof(obj))) + FAIL_STACK_ERROR + + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_start_5th_recursive_indirect() */ + + +/*------------------------------------------------------------------------- + * Function: run_tests + * + * Purpose: Test the fractal heap code, with different file access property + * lists and heap creation parameters + * + * Return: Success: + * + * Failure: + * + * Programmer: Quincey Koziol + * Tuesday, March 21, 2006 + * + *------------------------------------------------------------------------- + */ +static unsigned +run_tests(hid_t fapl, H5HF_create_t *cparam) +{ + unsigned nerrors = 0; /* Cumulative error count */ + + /* Test fractal heap creation */ + nerrors += test_create(fapl, cparam); + + /* Test fractal heap object insertion */ +#ifdef QAK + nerrors += test_abs_insert_first(fapl, cparam); + nerrors += test_abs_insert_second(fapl, cparam); + nerrors += test_abs_insert_root_mult(fapl, cparam); + nerrors += test_abs_insert_force_indirect(fapl, cparam); + nerrors += test_abs_insert_fill_second(fapl, cparam); + nerrors += test_abs_insert_third_direct(fapl, cparam); + nerrors += test_abs_fill_first_row(fapl, cparam); + nerrors += test_abs_start_second_row(fapl, cparam); + nerrors += test_abs_fill_second_row(fapl, cparam); + nerrors += test_abs_start_third_row(fapl, cparam); + nerrors += test_abs_fill_fourth_row(fapl, cparam); + nerrors += test_abs_fill_all_root_direct(fapl, cparam); + nerrors += test_abs_first_recursive_indirect(fapl, cparam); + nerrors += test_abs_second_direct_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_first_recursive_indirect(fapl, cparam); + nerrors += test_abs_second_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_second_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_recursive_indirect_row(fapl, cparam); + nerrors += test_abs_start_2nd_recursive_indirect(fapl, cparam); + nerrors += test_abs_recursive_indirect_two_deep(fapl, cparam); + nerrors += test_abs_start_3rd_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_first_3rd_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_3rd_recursive_indirect_row(fapl, cparam); + nerrors += test_abs_fill_all_3rd_recursive_indirect(fapl, cparam); + nerrors += test_abs_start_4th_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_first_4th_recursive_indirect(fapl, cparam); + nerrors += test_abs_fill_4th_recursive_indirect_row(fapl, cparam); + nerrors += test_abs_fill_all_4th_recursive_indirect(fapl, cparam); +#endif /* QAK */ + /* If this test fails, uncomment the tests above, which build up to this + * level of complexity gradually. -QAK + */ + nerrors += test_abs_start_5th_recursive_indirect(fapl, cparam); +#ifndef QAK +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ + + return nerrors; +} /* end run_tests() */ /*------------------------------------------------------------------------- @@ -1653,6 +5559,7 @@ error: int main(void) { + H5HF_create_t cparam; /* Creation parameters for heap */ hid_t fapl = -1; /* File access property list for data files */ unsigned nerrors = 0; /* Cumulative error count */ @@ -1660,28 +5567,20 @@ main(void) h5_reset(); fapl = h5_fileaccess(); - /* Test fractal heap creation */ #ifndef QAK - nerrors += test_create(fapl); + /* Test fractal heap with small parameters */ + init_small_cparam(&cparam); + puts("Testing with small heap creation parameters:"); + nerrors += run_tests(fapl, &cparam); - /* Test fractal heap object insertion */ - nerrors += test_abs_insert_first(fapl); - nerrors += test_abs_insert_second(fapl); - nerrors += test_abs_insert_root_mult(fapl); - nerrors += test_abs_insert_force_indirect(fapl); - nerrors += test_abs_insert_fill_second(fapl); - nerrors += test_abs_insert_third_direct(fapl); - nerrors += test_abs_fill_first_row(fapl); - nerrors += test_abs_start_second_row(fapl); - nerrors += test_abs_fill_second_row(fapl); - nerrors += test_abs_start_third_row(fapl); - nerrors += test_abs_fill_fourth_row(fapl); - nerrors += test_abs_fill_all_root_direct(fapl); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ - nerrors += test_abs_first_recursive_indirect(fapl); #ifdef QAK + /* Test fractal heap with standard parameters */ + init_std_cparam(&cparam); + puts("Testing with standard heap creation parameters:"); + nerrors += run_tests(fapl, &cparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ @@ -1689,7 +5588,7 @@ HDfprintf(stderr, "Uncomment tests!\n"); if(nerrors) goto error; puts("All fractal heap tests passed."); -#ifdef QAK +#ifndef QAK h5_cleanup(FILENAME, fapl); #else /* QAK */ HDfprintf(stderr, "Uncomment cleanup!\n"); @@ -1702,5 +5601,5 @@ error: H5Pclose(fapl); } H5E_END_TRY; return 1; -} +} /* end main() */ |