From 4965bf1839b4219c3063e27d37bc59a777cc1fb5 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sun, 30 Apr 2006 08:32:41 -0500 Subject: [svn-r12317] Purpose: Code checkpoint Description: More progress on fractal heap, can now re-open an existing heap, although the free space algorithm still needs work. Also, use the new "pinned entry" metadata cache code. Platforms tested: FreeBSD 4.11 (sleipnir) Linux 2.4 (heping) Solaris 9 (shanti) Linux 2.4/64 (mir) --- MANIFEST | 1 + src/H5HF.c | 325 +++- src/H5HFcache.c | 362 ++--- src/H5HFdbg.c | 80 +- src/H5HFdblock.c | 269 +++- src/H5HFdtable.c | 34 + src/H5HFflist.c | 113 +- src/H5HFhdr.c | 165 ++- src/H5HFiblock.c | 1172 +++++++++------ src/H5HFint.c | 227 ++- src/H5HFiter.c | 693 +++++++++ src/H5HFpkg.h | 263 ++-- src/H5HFprivate.h | 15 +- src/H5HFstat.c | 31 +- src/H5HFtest.c | 46 +- src/Makefile.am | 2 +- src/Makefile.in | 5 +- test/fheap.c | 4230 +++++++++++++++++++++++++++++++++++++++++++++-------- 18 files changed, 6324 insertions(+), 1709 deletions(-) create mode 100644 src/H5HFiter.c diff --git a/MANIFEST b/MANIFEST index c65e647..81fba07 100644 --- a/MANIFEST +++ b/MANIFEST @@ -497,6 +497,7 @@ ./src/H5HFhdr.c ./src/H5HFiblock.c ./src/H5HFint.c +./src/H5HFiter.c ./src/H5HFpkg.h ./src/H5HFprivate.h ./src/H5HFpublic.h diff --git a/src/H5HF.c b/src/H5HF.c index f6a8707..4e26927 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -39,6 +39,7 @@ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5FOprivate.h" /* File objects */ #include "H5HFpkg.h" /* Fractal heaps */ #include "H5MFprivate.h" /* File memory management */ @@ -66,8 +67,8 @@ /* Package Variables */ /*********************/ -/* Declare a free list to manage the H5HF_t struct */ -H5FL_DEFINE(H5HF_t); +/* Declare a free list to manage the H5HF_hdr_t struct */ +H5FL_DEFINE(H5HF_hdr_t); /*****************************/ @@ -79,6 +80,9 @@ H5FL_DEFINE(H5HF_t); /* Local Variables */ /*******************/ +/* Declare a free list to manage the H5HF_t struct */ +H5FL_DEFINE_STATIC(H5HF_t); + /*------------------------------------------------------------------------- @@ -86,8 +90,8 @@ H5FL_DEFINE(H5HF_t); * * Purpose: Creates a new empty fractal heap in the file. * - * Return: Non-negative on success (with address of new fractal heap - * filled in), negative on failure + * Return: Pointer to heap wrapper on success + * NULL on failure * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu @@ -95,48 +99,79 @@ H5FL_DEFINE(H5HF_t); * *------------------------------------------------------------------------- */ -herr_t -H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, haddr_t *addr_p, - size_t *id_len_p) +H5HF_t * +H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam) { - H5HF_t *hdr = NULL; /* The new fractal heap header information */ - herr_t ret_value = SUCCEED; /* Return value */ + H5HF_t *fh = NULL; /* Pointer to new fractal heap */ + H5HF_hdr_t *hdr = NULL; /* The new fractal heap header information */ + haddr_t hdr_addr; /* Heap header address */ + H5HF_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5HF_create, FAIL) + FUNC_ENTER_NOAPI(H5HF_create, NULL) /* * Check arguments. */ HDassert(f); HDassert(cparam); - HDassert(addr_p); - HDassert(id_len_p); /* Allocate & basic initialization for the shared header */ if(NULL == (hdr = H5HF_hdr_alloc(f))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate space for shared heap info") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "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(hdr)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap header") + if(HADDR_UNDEF == (hdr_addr = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)H5HF_HEADER_SIZE(hdr)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "file allocation failed for fractal heap header") /* Initialize shared fractal heap header */ - if(H5HF_hdr_init(hdr, *addr_p, cparam) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't initialize shared fractal heap header") + /* (This routine is only called for newly created heaps) */ + if(H5HF_hdr_init(hdr, hdr_addr, cparam) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't initialize shared fractal heap header") - /* Set the length of heap IDs */ - *id_len_p = hdr->id_len; #ifdef QAK HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); #endif /* QAK */ /* Cache the new fractal heap header */ - if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, *addr_p, hdr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add fractal heap header to cache") + if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't add fractal heap header to cache") + + /* Create fractal heap wrapper */ + if(NULL == (fh = H5FL_MALLOC(H5HF_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info") + + /* Lock the heap header into memory */ +#ifdef QAK +HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr); +#endif /* QAK */ + if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, NULL, NULL, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to load fractal heap header") + + /* Point fractal heap wrapper at header */ + fh->hdr = hdr; + if(H5HF_hdr_incr(fh->hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") + + /* Unlock heap header, now pinned */ + if(H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header") + hdr = NULL; + + /* Add heap to list of open objects in file */ + if(H5FO_insert(f, fh->hdr->heap_addr, fh) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert heap into list of open objects") + + /* Set open object count */ + fh->fo_count = 1; + + /* Set the return value */ + ret_value = fh; done: - if(ret_value < 0) { - if(hdr) + if(!ret_value) { + if(fh) + (void)H5HF_close(fh); + else if(hdr) (void)H5HF_cache_hdr_dest(f, hdr); } /* end if */ @@ -145,6 +180,149 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_open + * + * Purpose: Opens an existing fractal heap in the file. + * + * Return: Pointer to heap wrapper on success + * NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 18 2006 + * + *------------------------------------------------------------------------- + */ +H5HF_t * +H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr) +{ + H5HF_t *fh = NULL; /* Pointer to new fractal heap */ + H5HF_hdr_t *hdr = NULL; /* The new fractal heap header information */ + H5HF_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5HF_open, NULL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(H5F_addr_defined(fh_addr)); + + /* Check if group was already open */ + if((fh = H5FO_opened(f, fh_addr)) == NULL) { + + /* Clear any errors from H5FO_opened() */ + H5E_clear_stack(NULL); + + /* Load the heap header into memory */ +#ifdef QAK +HDfprintf(stderr, "%s: fh_addr = %a\n", FUNC, fh_addr); +#endif /* QAK */ + if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load fractal heap header") +#ifdef QAK +HDfprintf(stderr, "%s: hdr->rc = %u\n", FUNC, hdr->rc); +#endif /* QAK */ + + /* Create fractal heap info */ + if(NULL == (fh = H5FL_MALLOC(H5HF_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info") + + /* Point fractal heap wrapper at header */ + fh->hdr = hdr; + if(H5HF_hdr_incr(fh->hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") + + /* Add heap to list of open objects in file */ + if(H5FO_insert(f, fh->hdr->heap_addr, fh) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert heap into list of open objects") + + /* Set open object count */ + fh->fo_count = 1; + } /* end if */ + else { + /* Increment shared reference count */ + fh->fo_count++; + } /* end else */ + + /* Set the return value */ + ret_value = fh; + +done: + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_PROTECT, NULL, "unable to release fractal heap header") + if(!ret_value) { + if(fh) + (void)H5HF_close(fh); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_get_id_len + * + * Purpose: Get the size of IDs for entries in a fractal heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 17 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_get_id_len(H5HF_t *fh, size_t *id_len_p) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5HF_get_id_len) + + /* + * Check arguments. + */ + HDassert(fh); + HDassert(id_len_p); + + /* Retrieve the ID length for entries in this heap */ + *id_len_p = fh->hdr->id_len; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_get_id_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_get_heap_addr + * + * Purpose: Get the address of a fractal heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 18 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_get_heap_addr(H5HF_t *fh, haddr_t *heap_addr_p) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5HF_get_heap_addr) + + /* + * Check arguments. + */ + HDassert(fh); + HDassert(heap_addr_p); + + /* Retrieve the heap header address for this heap */ + *heap_addr_p = fh->hdr->heap_addr; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_get_heap_addr() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_insert * * Purpose: Insert a new object into a fractal heap. @@ -159,11 +337,10 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size, - const void *obj, void *id/*out*/) +H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size, const void *obj, + void *id/*out*/) { - H5HF_t *hdr = NULL; /* The fractal heap header information */ - unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for header */ + H5HF_hdr_t *hdr = NULL; /* The fractal heap header information */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5HF_insert, FAIL) @@ -174,17 +351,13 @@ HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size); /* * Check arguments. */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); + HDassert(fh); HDassert(size > 0); HDassert(obj); HDassert(id); - /* - * Load the fractal heap header. - */ - if(NULL == (hdr = 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 fractal heap header */ + hdr = fh->hdr; /* Check if object is large enough to be standalone */ if(size >= hdr->standalone_size) { @@ -208,14 +381,7 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'write once' managed blocks not su } /* end else */ } /* end else */ - /* Check for making header dirty */ - if(hdr->dirty) - hdr_flags |= H5AC__DIRTIED_FLAG; - done: - if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, addr, hdr, hdr_flags) < 0) - HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release fractal heap header") - FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_insert() */ @@ -234,10 +400,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_id, - void *obj/*out*/) +H5HF_read(H5HF_t *fh, hid_t dxpl_id, const void *_id, void *obj/*out*/) { - H5HF_t *hdr = NULL; /* The fractal heap header information */ + H5HF_hdr_t *hdr = NULL; /* The fractal heap header information */ const uint8_t *id = (const uint8_t *)_id; /* Object ID */ hsize_t obj_off; /* Object's offset in heap */ size_t obj_len; /* Object's length in heap */ @@ -248,16 +413,12 @@ H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_id, /* * Check arguments. */ - HDassert(f); - HDassert(H5F_addr_defined(addr)); + HDassert(fh); HDassert(id); HDassert(obj); - /* - * Load the fractal heap header. - */ - if(NULL == (hdr = 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 fractal heap header */ + hdr = fh->hdr; /* Decode the object offset within the heap & it's length */ UINT64DECODE_VAR(id, obj_off, hdr->heap_off_size); @@ -277,9 +438,65 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "standalone blocks not supported ye } /* end else */ done: - if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_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_read() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_close + * + * Purpose: Close a fractal heap wrapper + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 17 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_close(H5HF_t *fh) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5HF_close, FAIL) + + /* + * Check arguments. + */ + HDassert(fh); + + /* Decrement shared object count */ + --fh->fo_count; + + /* Check if this is the last reference to the shared heap wrapper */ + if(0 == fh->fo_count) { + /* Remove the heap from the list of opened objects in the file */ + if(H5FO_delete(fh->hdr->f, H5AC_dxpl_id, fh->hdr->heap_addr) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects") + + /* Reset the free list information */ + /* (Bump the "generation" counter in case this heap header is still + * in the cache when the heap is re-opened -QAK) + */ + H5HF_flist_reset(fh->hdr->flist); + fh->hdr->fl_gen++; + fh->hdr->freelist_sync = FALSE; + + /* Reset the block iterator */ + if(H5HF_man_iter_reset(&fh->hdr->next_block) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't reset block iterator") + + /* Decrement the reference count on the heap header */ + if(H5HF_hdr_decr(fh->hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") + + /* Release the fractal heap wrapper */ + H5FL_FREE(H5HF_t, fh); + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_close() */ + diff --git a/src/H5HFcache.c b/src/H5HFcache.c index 6305fb8..c9d4163 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -62,10 +62,10 @@ /********************/ /* Metadata cache callbacks */ -static H5HF_t *H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); -static herr_t H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_t *hdr); -static herr_t H5HF_cache_hdr_clear(H5F_t *f, H5HF_t *hdr, hbool_t destroy); -static herr_t H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *hdr, size_t *size_ptr); +static H5HF_hdr_t *H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); +static herr_t H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_hdr_t *hdr); +static herr_t H5HF_cache_hdr_clear(H5F_t *f, H5HF_hdr_t *hdr, hbool_t destroy); +static herr_t H5HF_cache_hdr_size(const H5F_t *f, const H5HF_hdr_t *hdr, size_t *size_ptr); static H5HF_direct_t *H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); static herr_t H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_direct_t *dblock); static herr_t H5HF_cache_dblock_clear(H5F_t *f, H5HF_direct_t *dblock, hbool_t destroy); @@ -249,17 +249,17 @@ H5HF_dtable_encode(H5F_t *f, uint8_t **pp, const H5HF_dtable_t *dtable) * *------------------------------------------------------------------------- */ -static H5HF_t * +static H5HF_hdr_t * H5HF_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2) { - H5HF_t *hdr = NULL; /* Fractal heap info */ + H5HF_hdr_t *hdr = NULL; /* Fractal heap info */ size_t size; /* Header size */ uint8_t *buf = NULL; /* Temporary buffer */ const uint8_t *p; /* Pointer into raw data buffer */ uint32_t metadata_chksum; /* Metadata checksum value */ - H5HF_t *ret_value; /* Return value */ + H5HF_hdr_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5HF_cache_hdr_load, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_load) #ifdef QAK HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); #endif /* QAK */ @@ -324,6 +324,7 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); /* Statistics information */ H5F_DECODE_LENGTH(f, p, hdr->total_size); H5F_DECODE_LENGTH(f, p, hdr->man_size); + H5F_DECODE_LENGTH(f, p, hdr->man_alloc_size); H5F_DECODE_LENGTH(f, p, hdr->std_size); H5F_DECODE_LENGTH(f, p, hdr->nobjs); @@ -333,9 +334,18 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); HDassert((size_t)(p - buf) == size); - /* Make shared heap info reference counted */ + /* If the heap has any blocks stored, the memory free list is out of sync */ + if(H5F_addr_defined(hdr->man_dtable.table_addr)) + hdr->freelist_sync = FALSE; + else + hdr->freelist_sync = TRUE; + + /* Finish initialization of heap header */ if(H5HF_hdr_finish_init(hdr) < 0) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't create ref-count wrapper for shared fractal heap header") + HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't finish initializing shared fractal heap header") +#ifdef QAK +HDfprintf(stderr, "%s: hdr->flist = %p\n", FUNC, hdr->flist); +#endif /* QAK */ /* Set return value */ ret_value = hdr; @@ -364,11 +374,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_t *hdr) +H5HF_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HF_hdr_t *hdr) { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5HF_cache_hdr_flush, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_hdr_flush) #ifdef QAK HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); #endif /* QAK */ @@ -424,6 +434,7 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a /* Statistics information */ H5F_ENCODE_LENGTH(f, p, hdr->total_size); H5F_ENCODE_LENGTH(f, p, hdr->man_size); + H5F_ENCODE_LENGTH(f, p, hdr->man_alloc_size); H5F_ENCODE_LENGTH(f, p, hdr->std_size); H5F_ENCODE_LENGTH(f, p, hdr->nobjs); @@ -452,47 +463,6 @@ 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 *hdr) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_dest_real) - - /* - * Check arguments. - */ - HDassert(hdr); -/* XXX: Take out this goofy routine, after metadata cache is supporting - * "un-evictable" flag - */ - if(hdr->rc == 0 && hdr->evicted == TRUE) { - /* Free the free list information for the heap */ - if(hdr->flist) - H5HF_flist_free(hdr->flist); - - /* Free the block size lookup table for the doubling table */ - H5HF_dtable_dest(&hdr->man_dtable); - - /* Free the shared info itself */ - H5FL_FREE(H5HF_t, hdr); - } /* 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. @@ -507,7 +477,7 @@ H5HF_cache_hdr_dest_real(H5HF_t *hdr) */ /* ARGSUSED */ herr_t -H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_t *hdr) +H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_hdr_t *hdr) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_dest) @@ -515,17 +485,16 @@ H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_t *hdr) * Check arguments. */ HDassert(hdr); -/* XXX: Enable this after the metadata cache supports the "un-evictable" flag */ -/* HDassert(hdr->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 */ - hdr->evicted = TRUE; -/* XXX: Take out this goofy routine, after metadata cache is supporting - * "un-evictable" flag - */ - H5HF_cache_hdr_dest_real(hdr); + HDassert(hdr->rc == 0); + + /* Free the free list section information */ + H5HF_flist_free(hdr->flist); + + /* Free the block size lookup table for the doubling table */ + H5HF_dtable_dest(&hdr->man_dtable); + + /* Free the shared info itself */ + H5FL_FREE(H5HF_hdr_t, hdr); FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_cache_hdr_dest() */ @@ -545,7 +514,7 @@ H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_t *hdr) *------------------------------------------------------------------------- */ static herr_t -H5HF_cache_hdr_clear(H5F_t *f, H5HF_t *hdr, hbool_t destroy) +H5HF_cache_hdr_clear(H5F_t *f, H5HF_hdr_t *hdr, hbool_t destroy) { herr_t ret_value = SUCCEED; /* Return value */ @@ -584,7 +553,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *hdr, size_t *size_ptr) +H5HF_cache_hdr_size(const H5F_t UNUSED *f, const H5HF_hdr_t *hdr, size_t *size_ptr) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cache_hdr_size) @@ -616,22 +585,22 @@ H5HF_cache_hdr_size(const H5F_t *f, const H5HF_t *hdr, 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 *_hdr) +H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, void *_par_info) { const size_t *size = (const size_t *)_size; /* Size of block */ - H5HF_t *hdr = (H5HF_t *)_hdr; /* Shared heap header information */ + H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Pointer to parent 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 */ uint32_t metadata_chksum; /* Metadata checksum value */ H5HF_direct_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5HF_cache_dblock_load, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_load) /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(hdr); + HDassert(par_info); /* Allocate space for the fractal heap direct block */ if(NULL == (dblock = H5FL_MALLOC(H5HF_direct_t))) @@ -639,14 +608,15 @@ 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 = hdr; - if(H5HF_hdr_incr(hdr) < 0) + dblock->hdr = par_info->hdr; + if(H5HF_hdr_incr(dblock->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; dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size); dblock->free_list = NULL; + dblock->fl_gen = 0; /* Allocate block buffer */ /* XXX: Change to using free-list factories */ @@ -681,48 +651,27 @@ 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, hdr->heap_addr)) + if(H5F_addr_ne(heap_addr, dblock->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") - + dblock->parent = par_info->iblock; + dblock->par_entry = par_info->entry; + if(dblock->parent) { /* Share parent block */ - dblock->parent = iblock; - if(H5HF_iblock_incr(iblock) < 0) + if(H5HF_iblock_incr(dblock->parent) < 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") + dblock->blk_free_space = dblock->parent->ents[dblock->par_entry].free_space; } /* end if */ else { /* Direct block is linked directly from heap header */ - dblock->parent = NULL; - dblock->blk_free_space = hdr->total_man_free; + dblock->blk_free_space = dblock->hdr->total_man_free; } /* end else */ /* Offset of heap within the heap's address space */ - UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size); + UINT64DECODE_VAR(p, dblock->block_off, dblock->hdr->heap_off_size); /* Offset of free list head */ /* (Defer deserializing the whole free list until we actually need to modify it) */ @@ -757,7 +706,7 @@ H5HF_cache_dblock_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_dblock_flush, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_dblock_flush) /* check arguments */ HDassert(f); @@ -765,11 +714,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_t *hdr; /* Shared fractal heap information */ + H5HF_hdr_t *hdr; /* Shared fractal heap information */ uint8_t *p; /* Pointer into raw data buffer */ /* Get the pointer to the shared heap header */ - hdr = dblock->shared; + hdr = dblock->hdr; p = dblock->blk; @@ -792,11 +741,6 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, /* Address of heap header for heap which owns this block */ 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, hdr->heap_off_size); @@ -888,33 +832,17 @@ H5HF_cache_dblock_dest(H5F_t UNUSED *f, H5HF_direct_t *dblock) HDassert(dblock); /* Decrement reference count on shared fractal heap info */ - HDassert(dblock->shared); - if(H5HF_hdr_decr(dblock->shared) < 0) + HDassert(dblock->hdr); + if(H5HF_hdr_decr(dblock->hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header") if(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) { - H5HF_direct_free_node_t *node; /* Pointer to free list node for block */ - - /* Walk through list, freeing the nodes */ - node = dblock->free_list->first; - while(node) { - H5HF_direct_free_node_t *last_node; /* Pointer to last free list node for block */ - - /* Advance to next node */ - last_node = node; - node = node->next; - - /* Release the last node */ - H5FL_FREE(H5HF_direct_free_node_t, last_node); - } /* end while */ - - /* Release the free list head */ - H5FL_FREE(H5HF_direct_free_head_t, dblock->free_list); - } /* end if */ + if(dblock->free_list) + if(H5HF_man_dblock_destroy_freelist(dblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't destroy free list for direct block") /* Free block's buffer */ H5FL_BLK_FREE(direct_block, dblock->blk); @@ -1014,10 +942,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 *_hdr) +H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_par_info) { const unsigned *nrows = (const unsigned *)_nrows; /* # of rows in indirect block */ - H5HF_t *hdr = (H5HF_t *)_hdr; /* Shared header information */ + H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Shared parent information */ H5HF_indirect_t *iblock = NULL; /* Indirect block info */ uint8_t *buf = NULL; /* Temporary buffer */ const uint8_t *p; /* Pointer into raw data buffer */ @@ -1029,7 +957,7 @@ H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows size_t u; /* Local index variable */ H5HF_indirect_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5HF_cache_iblock_load, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_load) #ifdef QAK HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); #endif /* QAK */ @@ -1037,7 +965,7 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); /* Check arguments */ HDassert(f); HDassert(H5F_addr_defined(addr)); - HDassert(hdr); + HDassert(par_info); /* Allocate space for the fractal heap indirect block */ if(NULL == (iblock = H5FL_MALLOC(H5HF_indirect_t))) @@ -1045,8 +973,8 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - iblock->shared = hdr; - if(H5HF_hdr_incr(hdr) < 0) + iblock->hdr = par_info->hdr; + if(H5HF_hdr_incr(iblock->hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") /* Set block's internal information */ @@ -1054,10 +982,10 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); iblock->nrows = *nrows; iblock->addr = addr; iblock->dirty = FALSE; - iblock->evicted = FALSE; + iblock->fl_gen = 0; /* Compute size of indirect block */ - iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(iblock->hdr, iblock); /* Allocate buffer to decode block */ /* XXX: Use free list factories? */ @@ -1092,89 +1020,60 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); /* Address of heap that owns this block */ H5F_addr_decode(f, &p, &heap_addr); - if(H5F_addr_ne(heap_addr, hdr->heap_addr)) + if(H5F_addr_ne(heap_addr, iblock->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") - + iblock->parent = par_info->iblock; + iblock->par_entry = par_info->entry; + if(iblock->parent) { /* Share parent block */ - iblock->parent = tmp_iblock; - if(H5HF_iblock_incr(tmp_iblock) < 0) + if(H5HF_iblock_incr(iblock->parent) < 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; + iblock->child_free_space = iblock->parent->ents[iblock->par_entry].free_space; /* 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; + iblock->child_free_space = iblock->hdr->total_man_free; /* Set max. # of rows in this block */ - iblock->max_rows = hdr->man_dtable.max_root_rows; + iblock->max_rows = iblock->hdr->man_dtable.max_root_rows; } /* end else */ /* Offset of heap within the heap's address space */ - 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 % 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]; + UINT64DECODE_VAR(p, iblock->block_off, iblock->hdr->heap_off_size); /* Allocate & decode indirect block entry tables */ HDassert(iblock->nrows > 0); - if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * hdr->man_dtable.cparam.width)))) + if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (iblock->nrows * iblock->hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries") #ifndef NDEBUG /* Reset child free space */ acc_child_free_space = 0; #endif /* NDEBUG */ - for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { + for(u = 0; u < (iblock->nrows * iblock->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 < (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) + if(u < (iblock->hdr->man_dtable.max_direct_rows * iblock->hdr->man_dtable.cparam.width)) + UINT32DECODE_VAR(p, iblock->ents[u].free_space, iblock->hdr->man_dtable.max_dir_blk_off_size) else - UINT64DECODE_VAR(p, iblock->ents[u].free_space, hdr->heap_off_size) + UINT64DECODE_VAR(p, iblock->ents[u].free_space, iblock->hdr->heap_off_size) +#ifdef QAK +HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a, %Hu}\n", FUNC, u, iblock->ents[u].addr, iblock->ents[u].free_space); +#endif /* QAK */ #ifndef NDEBUG acc_child_free_space += iblock->ents[u].free_space; #endif /* NDEBUG */ -/* XXX: Add code to indirect block cache load routine to create range sections for skipped blocks */ -/* XXX: ?? How to add code to indirect block cache load routine to create indirect sections for skipped blocks ?? */ } /* end for */ #ifndef NDEBUG - HDassert(acc_child_free_space == iblock->child_free_space); + HDassert(iblock->parent == NULL || acc_child_free_space == iblock->child_free_space); #endif /* NDEBUG */ /* Sanity check */ @@ -1213,7 +1112,7 @@ 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) + FUNC_ENTER_NOAPI_NOINIT(H5HF_cache_iblock_flush) #ifdef QAK HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy); #endif /* QAK */ @@ -1224,7 +1123,7 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC HDassert(iblock); if(iblock->cache_info.is_dirty) { - H5HF_t *hdr; /* Shared fractal heap information */ + H5HF_hdr_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 */ @@ -1233,7 +1132,7 @@ HDfprintf(stderr, "%s: Flushing indirect block, addr = %a, destroy = %u\n", FUNC HDassert(iblock->dirty); /* Get the pointer to the shared heap header */ - hdr = iblock->shared; + hdr = iblock->hdr; /* Allocate buffer to encode block */ /* XXX: Use free list factories? */ @@ -1267,17 +1166,9 @@ HDfprintf(stderr, "%s: hdr->man_dtable.cparam.width = %u\n", FUNC, hdr->man_dtab /* Address of heap header for heap which owns this block */ 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, 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 * hdr->man_dtable.cparam.width); u++) { #ifdef QAK @@ -1318,58 +1209,6 @@ 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. @@ -1394,17 +1233,26 @@ H5HF_cache_iblock_dest(H5F_t UNUSED *f, H5HF_indirect_t *iblock) * Check arguments. */ HDassert(iblock); -/* XXX: Enable this after the metadata cache supports the "un-evictable" flag */ -/* HDassert(iblock->rc == 0); */ + HDassert(iblock->rc == 0); + HDassert(!iblock->dirty); #ifdef QAK HDfprintf(stderr, "%s: Destroying indirect block\n", "H5HF_cache_iblock_dest"); #endif /* QAK */ -/* 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 - */ - ret_value = H5HF_cache_iblock_dest_real(iblock); + + /* Decrement reference count on shared info */ + HDassert(iblock->hdr); + if(H5HF_hdr_decr(iblock->hdr) < 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); done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c index 8ad9949..6173fd8 100644 --- a/src/H5HFdbg.c +++ b/src/H5HFdbg.c @@ -37,6 +37,7 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5HFpkg.h" /* Fractal heaps */ #include "H5MMprivate.h" /* Memory management */ +#include "H5Vprivate.h" /* Vectors and arrays */ /****************/ /* Local Macros */ @@ -164,7 +165,7 @@ H5HF_dtable_debug(H5HF_dtable_t *dtable, FILE *stream, int indent, int fwidth) 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_hdr_t *hdr = NULL; /* Fractal heap header info */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_hdr_debug, FAIL) @@ -181,7 +182,7 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* * Load the fractal heap header. */ - if(NULL == (fh = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, addr, NULL, NULL, H5AC_READ))) + if(NULL == (hdr = 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") /* Print opening message */ @@ -192,36 +193,36 @@ 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:", - ((fh->addrmap) == H5HF_ABSOLUTE ? "Absolute" : - ((fh->addrmap) == H5HF_MAPPED ? "Mapped" : + ((hdr->addrmap) == H5HF_ABSOLUTE ? "Absolute" : + ((hdr->addrmap) == H5HF_MAPPED ? "Mapped" : "Unknown!"))); HDfprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, "Min. size of standalone object:", - (unsigned long)fh->standalone_size); + (unsigned long)hdr->standalone_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total free space in managed blocks:", - fh->total_man_free); + hdr->total_man_free); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total # of free entries for standalone blocks:", - fh->total_std_free); + hdr->total_std_free); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total data block size:", - fh->total_size); + hdr->total_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total managed space data block size:", - fh->man_size); + hdr->man_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total standalone space data block size:", - fh->std_size); + hdr->std_size); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Number of objects in heap:", - fh->nobjs); + hdr->nobjs); HDfprintf(stream, "%*sManaged Objects Doubling-Table Info...\n", indent, ""); - H5HF_dtable_debug(&fh->man_dtable, stream, indent + 3, MAX(0, fwidth -3)); + H5HF_dtable_debug(&hdr->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) + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_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) @@ -245,7 +246,7 @@ 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 *hdr = NULL; /* Fractal heap header info */ + H5HF_hdr_t *hdr = NULL; /* Fractal heap header info */ H5HF_direct_t *dblock = NULL; /* Fractal heap direct block info */ H5HF_direct_free_node_t *node; /* Pointer to free list node for block */ size_t blk_prefix_size; /* Size of prefix for block */ @@ -278,7 +279,7 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, /* * Load the heap direct block */ - if(NULL == (dblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_DBLOCK, addr, &block_size, hdr, H5AC_READ))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, addr, block_size, NULL, 0, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap direct block") /* Check for valid free list */ @@ -296,15 +297,6 @@ 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:", 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); @@ -397,10 +389,11 @@ 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 *hdr = NULL; /* Fractal heap header info */ + H5HF_hdr_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 */ + hsize_t child_free_space; /* Block's children's free space */ size_t u, v; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -426,33 +419,29 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, /* * Load the heap direct block */ - if(NULL == (iblock = H5AC_protect(f, dxpl_id, H5AC_FHEAP_IBLOCK, addr, &nrows, hdr, H5AC_READ))) + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, addr, nrows, NULL, 0, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load fractal heap indirect block") /* Print opening message */ HDfprintf(stream, "%*sFractal Heap Indirect Block...\n", indent, ""); + /* Compute the child free space */ + child_free_space = 0; + for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) + child_free_space += iblock->ents[u].free_space; + /* * Print the values. */ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of fractal heap that owns this block:", 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); HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Total children free space:", - iblock->child_free_space); + child_free_space); HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Size of indirect block:", iblock->size); @@ -465,15 +454,6 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Max direct block rows:", hdr->man_dtable.max_direct_rows); - HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Next block column:", - iblock->next_col); - HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Next block row:", - iblock->next_row); - HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, - "Next block size:", - iblock->next_size); /* Print the entry tables */ HDfprintf(stream, "%*sDirect Block Entries (address, free space):\n", indent, ""); @@ -494,15 +474,21 @@ H5HF_iblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, } /* end for */ HDfprintf(stream, "%*sIndirect Block Entries:\n", indent, ""); if(iblock->nrows > hdr->man_dtable.max_direct_rows) { + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned num_indirect_rows; /* Number of rows of blocks in each indirect block */ + + first_row_bits = H5V_log2_of2(hdr->man_dtable.cparam.start_block_size) + + H5V_log2_of2(hdr->man_dtable.cparam.width); for(u = hdr->man_dtable.max_direct_rows; u < iblock->nrows; u++) { - sprintf(temp_str, "Row #%u:", (unsigned)u); + num_indirect_rows = (H5V_log2_gen(hdr->man_dtable.row_block_size[u]) - first_row_bits) + 1; + sprintf(temp_str, "Row #%u: (# of rows: %u)", (unsigned)u, num_indirect_rows); HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), temp_str); 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 %9a, %8Zu\n", indent + 6, "", MAX(0, fwidth - 6), + HDfprintf(stream, "%*s%-*s %9a, %8Hu\n", indent + 6, "", MAX(0, fwidth - 6), temp_str, iblock->ents[off].addr, iblock->ents[off].free_space); diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c index dcb704c..8ac411b 100644 --- a/src/H5HFdblock.c +++ b/src/H5HFdblock.c @@ -56,6 +56,8 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5HF_man_dblock_regen_freelist(H5HF_direct_t *dblock, + haddr_t dblock_addr); /*********************/ @@ -97,7 +99,7 @@ H5FL_DEFINE(H5HF_direct_free_node_t); *------------------------------------------------------------------------- */ herr_t -H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr, H5HF_indirect_t *par_iblock, +H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock, unsigned par_entry, size_t block_size, hsize_t block_off, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node) { @@ -126,7 +128,7 @@ H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr, H5HF_indirect_t *par_iblock, HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - dblock->shared = hdr; + dblock->hdr = hdr; if(H5HF_hdr_incr(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header") @@ -138,17 +140,12 @@ HDfprintf(stderr, "%s: size = %Zu, block_off = %Hu\n", FUNC, block_size, block_o 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->fl_gen = hdr->fl_gen; /* New blocks have their free list generation set up correctly */ dblock->free_list_head = H5HF_MAN_ABS_DIRECT_OVERHEAD_DBLOCK(hdr, dblock); dblock->blk_free_space = block_size - (H5HF_MAN_ABS_DIRECT_OVERHEAD_SIZE(hdr, block_size) + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr)); @@ -194,6 +191,12 @@ HDmemset(dblock->blk, 0, dblock->size); /* (section size is "object size", without the metadata overhead) */ sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr); sec_node->type = H5HF_SECT_SINGLE; + sec_node->u.single.parent = dblock->parent; + if(dblock->parent) { + if(H5HF_iblock_incr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + } /* end if */ + sec_node->u.single.par_entry = dblock->par_entry; sec_node->u.single.dblock_addr = *addr_p; sec_node->u.single.dblock_size = block_size; @@ -256,7 +259,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_hdr_t *hdr; /* Pointer to shared heap header */ H5HF_free_section_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 */ @@ -266,7 +269,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 */ - hdr = dblock->shared; + hdr = dblock->hdr; /* Point to first node in free list */ p = dblock->blk + dblock->free_list_head; @@ -300,6 +303,12 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) /* (section size is "object size", without the metadata overhead) */ sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr); sec_node->type = H5HF_SECT_SINGLE; + sec_node->u.single.parent = dblock->parent; + if(dblock->parent) { + if(H5HF_iblock_incr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + } /* end if */ + sec_node->u.single.par_entry = dblock->par_entry; sec_node->u.single.dblock_addr = dblock_addr; sec_node->u.single.dblock_size = dblock->size; @@ -343,6 +352,12 @@ H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) /* (section size is "object size", without the metadata overhead) */ sec_node->sect_size = node->size - H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr); sec_node->type = H5HF_SECT_SINGLE; + sec_node->u.single.parent = dblock->parent; + if(dblock->parent) { + if(H5HF_iblock_incr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + } /* end if */ + sec_node->u.single.par_entry = dblock->par_entry; sec_node->u.single.dblock_addr = dblock_addr; sec_node->u.single.dblock_size = dblock->size; @@ -369,6 +384,123 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_man_dblock_regen_freelist + * + * Purpose: Regenerate the free section information for the free space + * in a direct block's free list. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_man_dblock_regen_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr) +{ + H5HF_hdr_t *hdr; /* Pointer to shared heap header */ + H5HF_free_section_t *sec_node; /* Pointer to free list section for block */ + H5HF_direct_free_node_t *node; /* First node in free list */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_regen_freelist) + + /* + * Check arguments. + */ + HDassert(dblock); + HDassert(dblock->free_list); + + /* Get the pointer to the shared heap info */ + hdr = dblock->hdr; + + /* Iterate through nodes on block's free list */ + node = dblock->free_list->first; + while(node) { + /* Create free list section node */ + if(NULL == (sec_node = H5FL_MALLOC(H5HF_free_section_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + + /* Set section's information */ + sec_node->sect_addr = dblock->block_off + 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(hdr); + sec_node->type = H5HF_SECT_SINGLE; + sec_node->u.single.parent = dblock->parent; + if(dblock->parent) { + if(H5HF_iblock_incr(dblock->parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + } /* end if */ + sec_node->u.single.par_entry = dblock->par_entry; + sec_node->u.single.dblock_addr = dblock_addr; + sec_node->u.single.dblock_size = dblock->size; + + /* Add new free space to the global list of space */ + 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") + + /* Advance to next node */ + node = node->next; + } /* end while */ + +done: +/* XXX: cleanup on failure? */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_dblock_regen_freelist() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_dblock_destroy_freelist + * + * Purpose: Destroy the free list information for a direct block + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 22 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_dblock_destroy_freelist(H5HF_direct_t *dblock) +{ + H5HF_direct_free_node_t *node; /* Pointer to free list node for block */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_dblock_destroy_freelist) + + /* + * Check arguments. + */ + HDassert(dblock); + HDassert(dblock->free_list); + + /* Walk through list, freeing the nodes */ + node = dblock->free_list->first; + while(node) { + H5HF_direct_free_node_t *last_node; /* Pointer to last free list node for block */ + + /* Advance to next node */ + last_node = node; + node = node->next; + + /* Release the last node */ + H5FL_FREE(H5HF_direct_free_node_t, last_node); + } /* end while */ + + /* Release the free list head */ + H5FL_FREE(H5HF_direct_free_head_t, dblock->free_list); + + /* Reset the free list head */ + dblock->free_list = NULL; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_man_dblock_destroy_freelist() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_man_dblock_adj_free * * Purpose: Adjust the free space for a direct block, and it's parents @@ -382,9 +514,9 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_dblock_adj_free(hid_t dxpl_id, H5HF_direct_t *dblock, ssize_t amt) +H5HF_man_dblock_adj_free(H5HF_direct_t *dblock, ssize_t amt) { - H5HF_t *hdr; /* Shared heap information */ + H5HF_hdr_t *hdr; /* Shared heap information */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_adj_free) @@ -398,7 +530,7 @@ HDfprintf(stderr, "%s: amt = %Zd\n", FUNC, amt); HDassert(dblock); /* Get the pointer to the shared heap header */ - hdr = dblock->shared; + hdr = dblock->hdr; /* Adjust space available in block */ HDassert(amt > 0 || dblock->blk_free_space >= (size_t)-amt); @@ -424,7 +556,7 @@ HDfprintf(stderr, "%s: iblock->ents[dblock->par_entry].free_space = %Hu\n", FUNC iblock->child_free_space += amt; /* Mark indirect block as dirty */ - if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + if(H5HF_iblock_dirty(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") /* Modify the free space in parent block(s) */ @@ -443,7 +575,7 @@ HDfprintf(stderr, "%s: iblock->ents[dblock->par_entry].free_space = %Hu\n", FUNC iblock->child_free_space += amt; /* Mark indirect block as dirty */ - if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + if(H5HF_iblock_dirty(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") } /* end while */ } /* end if */ @@ -456,7 +588,7 @@ HDfprintf(stderr, "%s: hdr->total_man_free = %Hu\n", FUNC, hdr->total_man_free); #endif /* QAK */ /* Mark heap header as modified */ - if(H5HF_hdr_dirty(dxpl_id, hdr) < 0) + if(H5HF_hdr_dirty(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") done: @@ -479,12 +611,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_dblock_new(H5HF_t *hdr, hid_t dxpl_id, size_t request) +H5HF_man_dblock_new(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t request) { - 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 */ - herr_t ret_value = SUCCEED; /* Return value */ + haddr_t dblock_addr; /* Address of new direct block */ + hsize_t dblock_off; /* Direct block offset in heap address space */ + size_t dblock_size; /* Size of new direct block */ + size_t min_dblock_size; /* Min. size of direct block to allocate */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_new) #ifdef QAK @@ -523,7 +656,8 @@ HDfprintf(stderr, "%s: Check 2 - min_dblock_size = %Zu\n", FUNC, min_dblock_size min_dblock_size == hdr->man_dtable.cparam.start_block_size) { /* Create new direct block at starting offset */ dblock_size = hdr->man_dtable.cparam.start_block_size; - if(H5HF_man_dblock_create(dxpl_id, hdr, NULL, 0, dblock_size, (hsize_t)0, &dblock_addr, NULL) < 0) + dblock_off = 0; + if(H5HF_man_dblock_create(dxpl_id, hdr, NULL, 0, dblock_size, dblock_off, &dblock_addr, NULL) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block") #ifdef QAK @@ -541,15 +675,14 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); /* Root entry already exists, go get indirect block for new direct block */ else { H5HF_indirect_t *iblock; /* Pointer to indirect block to create */ - haddr_t iblock_addr; /* Indirect block's address */ size_t dblock_entry; /* Direct entry for new direct block */ - hsize_t dblock_off; /* Direct block offset in heap address space */ /* Find indirect block with room for block of correct size */ - if(NULL == (iblock = H5HF_man_iblock_place_dblock(hdr, 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, &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: iblock = %p\n", FUNC, iblock); +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 */ @@ -571,15 +704,89 @@ HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); iblock->ents[dblock_entry].addr = dblock_addr; /* Mark indirect block as modified */ - if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + if(H5HF_iblock_dirty(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(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 */ + /* Advance the allocated heap size/new block iterator */ + if(H5HF_hdr_inc_alloc(hdr, dblock_off + dblock_size, 1) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_dblock_new() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_man_dblock_protect + * + * Purpose: Convenience wrapper around H5AC_protect on a direct block + * (Use H5AC_unprotect to unprotect it for now) + * + * Return: Pointer to direct block on success, NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 17 2006 + * + *------------------------------------------------------------------------- + */ +H5HF_direct_t * +H5HF_man_dblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t dblock_addr, + size_t dblock_size, H5HF_indirect_t *par_iblock, unsigned par_entry, + H5AC_protect_t rw) +{ + H5HF_parent_t par_info; /* Parent info for loading block */ + H5HF_direct_t *dblock; /* Direct block from cache */ + H5HF_direct_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_dblock_protect) +#ifdef QAK +HDfprintf(stderr, "%s: dblock_addr = %a, dblock_size = %Zu\n", FUNC, dblock_addr, dblock_size); +#endif /* QAK */ + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(H5F_addr_defined(dblock_addr)); + HDassert(dblock_size > 0); + + /* Set up parent info */ + par_info.hdr = hdr; + par_info.iblock = par_iblock; + par_info.entry = par_entry; + + /* Protect the direct block */ + if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, &par_info, rw))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block") + + /* Regenerate the free list information for this block, if necessary */ + /* (Only create free list information if write access is requested) */ + if(rw == H5AC_WRITE && hdr->fl_gen != dblock->fl_gen) { +#ifdef QAK +HDfprintf(stderr, "%s: building free list for direct block\n", FUNC); +#endif /* QAK */ + /* If the block has a free list from a previous generation, get rid of it */ + if(dblock->free_list) { + if(H5HF_man_dblock_regen_freelist(dblock, dblock_addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "can't regenerate free list for direct block") + } /* end if */ + else { + /* Build the free list for the block */ + if(H5HF_man_dblock_build_freelist(dblock, dblock_addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode free list for block") + } /* end else */ + HDassert(dblock->free_list); + + /* Mark the block's free list generation as up to date now */ + dblock->fl_gen = hdr->fl_gen; + } /* end if */ + + /* Set the return value */ + ret_value = dblock; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_dblock_protect() */ + diff --git a/src/H5HFdtable.c b/src/H5HFdtable.c index e571b85..e51b45b 100644 --- a/src/H5HFdtable.c +++ b/src/H5HFdtable.c @@ -211,3 +211,37 @@ H5HF_dtable_dest(H5HF_dtable_t *dtable) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_dtable_dest() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_dtable_size_to_row + * + * Purpose: Compute row that can hold block of a certain size + * + * Return: Non-negative on success (can't fail) + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +unsigned +H5HF_dtable_size_to_row(H5HF_dtable_t *dtable, size_t block_size) +{ + unsigned row; /* Row where block will fit */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_dtable_size_to_row) + + /* + * Check arguments. + */ + HDassert(dtable); + + if(block_size == dtable->cparam.start_block_size) + row = 0; + else + row = (H5V_log2_of2((uint32_t)block_size) - H5V_log2_of2(dtable->cparam.start_block_size)) + 1; + + FUNC_LEAVE_NOAPI(row) +} /* end H5HF_dtable_size_to_row() */ + diff --git a/src/H5HFflist.c b/src/H5HFflist.c index 988024d..962f3ad 100644 --- a/src/H5HFflist.c +++ b/src/H5HFflist.c @@ -78,6 +78,7 @@ struct H5HF_freelist_t { /* Local Prototypes */ /********************/ static herr_t H5HF_flist_node_free_cb(void *item, void *key, void *op_data); +static herr_t H5HF_flist_init(H5HF_freelist_t *flist); /*********************/ @@ -107,6 +108,41 @@ H5FL_SEQ_DEFINE_STATIC(H5SL_ptr_t); /*------------------------------------------------------------------------- + * Function: H5HF_flist_init + * + * Purpose: Initialize free list for heap + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_flist_init(H5HF_freelist_t *flist) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_flist_init) + + /* Check arguments. */ + HDassert(flist); + + /* Set free list parameters */ + flist->tot_space = 0; + flist->sec_count = 0; + flist->single.node = NULL; + flist->single.size_key = NULL; + flist->single.addr_key = NULL; + flist->bins = NULL; + flist->using_bins = FALSE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_flist_init() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_flist_create * * Purpose: Allocate & initialize free list for heap @@ -121,7 +157,7 @@ H5FL_SEQ_DEFINE_STATIC(H5SL_ptr_t); *------------------------------------------------------------------------- */ H5HF_freelist_t * -H5HF_flist_create(size_t max_block_size, H5SL_operator_t node_free_op) +H5HF_flist_create(unsigned max_index_bits, H5SL_operator_t node_free_op) { H5HF_freelist_t *flist; /* New free list structure */ H5HF_freelist_t *ret_value; /* Return value */ @@ -136,16 +172,12 @@ H5HF_flist_create(size_t max_block_size, H5SL_operator_t node_free_op) if(NULL == (flist = H5FL_MALLOC(H5HF_freelist_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap free list") - /* Set free list parameters */ - flist->tot_space = 0; - flist->sec_count = 0; - flist->single.node = NULL; - flist->single.size_key = NULL; - flist->single.addr_key = NULL; - flist->nbins = H5V_log2_of2(max_block_size); + /* Set immutable free list parameters */ + flist->nbins = max_index_bits; flist->node_free_op = node_free_op; - flist->bins = NULL; - flist->using_bins = FALSE; + + /* Set modifiable free list parameters */ + H5HF_flist_init(flist); /* Set return value */ ret_value = flist; @@ -190,6 +222,7 @@ HDfprintf(stderr, "%s: *size_key = %Zu, *addr_key = %a\n", FUNC, *size_key, *add /* Determine correct bin which holds items of the section's size */ bin = H5V_log2_gen((hsize_t)*size_key); + HDassert(bin < flist->nbins); if(flist->bins[bin] == NULL) { if(NULL == (flist->bins[bin] = H5SL_create(H5SL_TYPE_SIZE, 0.5, H5HF_FLIST_DEFAULT_SKIPLIST_HEIGHT))) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create skip list for free list nodes") @@ -256,6 +289,9 @@ HDfprintf(stderr, "%s: *size_key = %Zu, *addr_key = %a\n", FUNC, *size_key, *add HDassert(addr_key); /* Check for special cases of # of sections on free list */ +#ifdef QAK +HDfprintf(stderr, "%s: flist->sec_count = %Zu\n", FUNC, flist->sec_count); +#endif /* QAK */ if(flist->sec_count == 0) { HDassert(flist->single.node == NULL); @@ -330,6 +366,7 @@ H5HF_flist_find_bin_node(H5HF_freelist_t *flist, size_t request, void **node) /* Determine correct bin which holds items of at least the section's size */ bin = H5V_log2_gen((hsize_t)request); + HDassert(bin < flist->nbins); while(bin < flist->nbins && flist->bins[bin] == NULL) bin++; @@ -412,6 +449,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); HDassert(node); /* Check for any sections on free list */ +#ifdef QAK +HDfprintf(stderr, "%s: flist->sec_count = %Zu\n", FUNC, flist->sec_count); +#endif /* QAK */ if(flist->sec_count > 0) { /* Check for single section */ /* XXX: Take out the "&& !flist->using_bins" when bins converted back into single section */ @@ -435,8 +475,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "can't remove section from bins") } /* end else */ - /* Decrement # of sections on free list */ - flist->sec_count--; + /* Decrement # of sections on free list, if we found an object */ + if(ret_value > 0) { + flist->sec_count--; /* XXX: Should check for only one section in bins & convert to single section * This is somewhat hard because we "lose" the the size & address keys * (The address key is actually available, but the size key is gone, unless @@ -444,8 +485,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); * * Drop back to using a "single" node when the bins are empty. */ - if(flist->sec_count == 0) - flist->using_bins = FALSE; + if(flist->sec_count == 0) + flist->using_bins = FALSE; + } /* end if */ } /* end if */ done: @@ -487,25 +529,26 @@ H5HF_flist_node_free_cb(void *item, void UNUSED *key, void *op_data) /*------------------------------------------------------------------------- - * Function: H5HF_flist_free + * Function: H5HF_flist_reset * - * Purpose: Destroy & deallocate free list structure + * Purpose: Reset free list structure by freeing all existing sections + * and restoring free list info to initial conditions. * * Return: Success: non-negative * * Failure: negative * * Programmer: Quincey Koziol - * Tuesday, March 7, 2006 + * Tuesday, April 18, 2006 * *------------------------------------------------------------------------- */ herr_t -H5HF_flist_free(H5HF_freelist_t *flist) +H5HF_flist_reset(H5HF_freelist_t *flist) { unsigned u; /* Local index variable */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_flist_free) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_flist_reset) /* Check arguments. */ HDassert(flist); @@ -531,6 +574,38 @@ H5HF_flist_free(H5HF_freelist_t *flist) H5FL_SEQ_FREE(H5SL_ptr_t, flist->bins); } /* end if */ + /* Reset free list info back to initial state */ + H5HF_flist_init(flist); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_flist_reset() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_flist_free + * + * Purpose: Destroy & deallocate free list structure + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, March 7, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_flist_free(H5HF_freelist_t *flist) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_flist_free) + + /* Check arguments. */ + HDassert(flist); + + /* Reset free list information */ + H5HF_flist_reset(flist); + /* Free fractal heap free list info */ H5FL_FREE(H5HF_freelist_t, flist); diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index 04d3959..b598191 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -92,11 +92,11 @@ * *------------------------------------------------------------------------- */ -H5HF_t * +H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f) { - H5HF_t *fh = NULL; /* Shared fractal heap header */ - H5HF_t *ret_value = NULL; /* Return value */ + H5HF_hdr_t *hdr = NULL; /* Shared fractal heap header */ + H5HF_hdr_t *ret_value = NULL; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_alloc) @@ -106,21 +106,21 @@ H5HF_hdr_alloc(H5F_t *f) HDassert(f); /* Allocate space for the shared information */ - if(NULL == (fh = H5FL_CALLOC(H5HF_t))) + if(NULL == (hdr = H5FL_CALLOC(H5HF_hdr_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header") /* Set the internal parameters for the heap */ - fh->f = f; - fh->sizeof_size = H5F_SIZEOF_SIZE(f); - fh->sizeof_addr = H5F_SIZEOF_ADDR(f); + hdr->f = f; + hdr->sizeof_size = H5F_SIZEOF_SIZE(f); + hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); /* Set the return value */ - ret_value = fh; + ret_value = hdr; done: if(!ret_value) - if(fh) - (void)H5HF_cache_hdr_dest(f, fh); + if(hdr) + (void)H5HF_cache_hdr_dest(f, hdr); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_alloc() */ @@ -141,7 +141,7 @@ done: *------------------------------------------------------------------------- */ static hsize_t -H5HF_hdr_compute_free_space(H5HF_t *hdr, hsize_t iblock_size) +H5HF_hdr_compute_free_space(H5HF_hdr_t *hdr, hsize_t iblock_size) { hsize_t acc_heap_size; /* Accumumated heap space */ hsize_t acc_dblock_free; /* Accumumated direct block free space */ @@ -189,7 +189,7 @@ H5HF_hdr_compute_free_space(H5HF_t *hdr, hsize_t iblock_size) *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_finish_init(H5HF_t *hdr) +H5HF_hdr_finish_init(H5HF_hdr_t *hdr) { size_t u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -207,9 +207,16 @@ H5HF_hdr_finish_init(H5HF_t *hdr) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize doubling table info") /* Create the free-list structure for the heap */ - if(NULL == (hdr->flist = H5HF_flist_create(hdr->man_dtable.cparam.max_direct_size, H5HF_free_section_free_cb))) + if(NULL == (hdr->flist = H5HF_flist_create(hdr->man_dtable.cparam.max_index, H5HF_free_section_free_cb))) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize free list info") + /* Start the free list "generation" count */ + /* (Must be "out of sync" with starting value for indirect & direct block + * cache loading routines, in order to trigger re-building the free list + * information for each block when a heap is opened->closed->reopened -QAK) + */ + hdr->fl_gen = 1; + /* Set the size of heap IDs */ hdr->id_len = hdr->heap_off_size + MIN(hdr->man_dtable.max_dir_blk_off_size, ((H5V_log2_gen((hsize_t)hdr->standalone_size) + 7) / 8)); @@ -229,6 +236,10 @@ HDfprintf(stderr, "%s: row_dblock_free[%Zu] = %Hu\n", FUNC, u, hdr->man_dtable.r #endif /* QAK */ } /* end for */ + /* Initialize the block iterator for searching for free space */ + if(H5HF_man_iter_init(&hdr->next_block) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize space search block iterator") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_finish_init() */ @@ -248,7 +259,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_init(H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) +H5HF_hdr_init(H5HF_hdr_t *hdr, haddr_t fh_addr, H5HF_create_t *cparam) { herr_t ret_value = SUCCEED; /* Return value */ @@ -257,7 +268,7 @@ H5HF_hdr_init(H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) /* * Check arguments. */ - HDassert(fh); + HDassert(hdr); HDassert(cparam); #ifndef NDEBUG @@ -271,30 +282,33 @@ H5HF_hdr_init(H5HF_t *fh, haddr_t fh_addr, H5HF_create_t *cparam) 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 * fh->sizeof_size) || cparam->managed.max_index == 0) + if(cparam->managed.max_index > (8 * hdr->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 */ - 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)); + hdr->heap_addr = fh_addr; + hdr->addrmap = cparam->addrmap; + hdr->standalone_size = cparam->standalone_size; + HDmemcpy(&(hdr->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); /* Set root table address */ - fh->man_dtable.table_addr = HADDR_UNDEF; + hdr->man_dtable.table_addr = HADDR_UNDEF; + + /* Newly created heap's free list is always in sync in memory */ + hdr->freelist_sync = TRUE; /* Note that the shared info is dirty (it's not written to the file yet) */ - fh->dirty = TRUE; + hdr->dirty = TRUE; /* Make shared heap info reference counted */ - if(H5HF_hdr_finish_init(fh) < 0) + if(H5HF_hdr_finish_init(hdr) < 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(fh) - (void)H5HF_cache_hdr_dest(NULL, fh); + if(hdr) + (void)H5HF_cache_hdr_dest(NULL, hdr); FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_init() */ @@ -314,9 +328,11 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_incr(H5HF_t *hdr) +H5HF_hdr_incr(H5HF_hdr_t *hdr) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_incr) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_incr) /* Sanity check */ HDassert(hdr); @@ -324,11 +340,16 @@ H5HF_hdr_incr(H5HF_t *hdr) /* XXX: When "un-evictable" feature is finished, mark the header as * unevictable on the first block to share it. - QAK */ + /* Mark header as un-evictable when a block is depending on it */ + if(hdr->rc == 0) + if(H5AC_pin_protected_entry(hdr->f, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPIN, FAIL, "unable to pin fractal heap header") /* Increment reference count on shared header */ hdr->rc++; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_incr() */ @@ -346,9 +367,11 @@ H5HF_hdr_incr(H5HF_t *hdr) *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_decr(H5HF_t *hdr) +H5HF_hdr_decr(H5HF_hdr_t *hdr) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_decr) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_decr) /* Sanity check */ HDassert(hdr); @@ -356,13 +379,13 @@ H5HF_hdr_decr(H5HF_t *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); + /* Mark header as evictable again when no child blocks depend on it */ + if(hdr->rc == 0) + if(H5AC_unpin_entry(hdr->f, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap header") - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_decr() */ @@ -380,10 +403,8 @@ H5HF_hdr_decr(H5HF_t *hdr) *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_dirty(hid_t dxpl_id, H5HF_t *hdr) +H5HF_hdr_dirty(H5HF_hdr_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) @@ -394,29 +415,13 @@ HDfprintf(stderr, "%s: Marking heap header as dirty\n", FUNC); /* 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: 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 */ + /* Mark header as dirty in cache */ + if(H5AC_mark_pinned_entry_dirty(hdr->f, hdr, FALSE, 0) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark fractal heap header as dirty") /* 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() */ @@ -436,7 +441,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_hdr_extend_heap(H5HF_t *hdr, hsize_t new_size, hsize_t extra_free) +H5HF_hdr_extend_heap(H5HF_hdr_t *hdr, hsize_t new_size, hsize_t extra_free) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_extend_heap) @@ -456,3 +461,45 @@ H5HF_hdr_extend_heap(H5HF_t *hdr, hsize_t new_size, hsize_t extra_free) FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5HF_hdr_extend_heap() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_hdr_inc_alloc + * + * Purpose: Increase allocated size of heap + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_hdr_inc_alloc(H5HF_hdr_t *hdr, hsize_t new_alloc_size, unsigned nentries) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_inc_alloc) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(new_alloc_size >= hdr->man_alloc_size); + + /* Advance the iterator for the current location with in the indirect block */ + if(hdr->next_block.curr) + if(H5HF_man_iter_next(hdr, &hdr->next_block, nentries) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTNEXT, FAIL, "unable to advance current block iterator location") + + /* Update the "allocated" size within the heap */ + hdr->man_alloc_size = new_alloc_size; +#ifdef QAK +HDfprintf(stderr, "%s: hdr->man_alloc_size = %Hu\n", FUNC, hdr->man_alloc_size); +#endif /* QAK */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_hdr_inc_alloc() */ + diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 1ecaa9a..fd7b520 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -58,15 +58,17 @@ /********************/ /* Indirect block routines */ -static herr_t H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock); -static herr_t H5HF_man_iblock_skip_blocks(H5HF_t *hdr, +static herr_t H5HF_man_iblock_skip_blocks(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock, haddr_t iblock_addr, unsigned start_entry, unsigned nentries); -static herr_t H5HF_man_iblock_skip_ranges(H5HF_t *hdr, +static herr_t H5HF_man_iblock_skip_ranges(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock, haddr_t iblock_addr, unsigned start_entry, unsigned nentries); -static herr_t H5HF_man_iblock_create(H5HF_t *fh, hid_t dxpl_id, +static herr_t H5HF_man_iblock_double_root(H5HF_hdr_t *hdr, hid_t dxpl_id, + size_t min_dblock_size); +static herr_t H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p); +static herr_t H5HF_man_iblock_build_sections(H5HF_indirect_t *iblock); /*********************/ /* Package Variables */ @@ -91,71 +93,6 @@ H5FL_SEQ_DEFINE(H5HF_indirect_ent_t); /*------------------------------------------------------------------------- - * Function: H5HF_man_iblock_inc_loc - * - * Purpose: Increment location of next direct block in indirect block - * - * Return: SUCCEED/FAIL - * - * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * Mar 14 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5HF_man_iblock_inc_loc(H5HF_indirect_t *iblock) -{ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_inc_loc) - - /* - * Check arguments. - */ - HDassert(iblock); - - /* Increment block entry */ - iblock->next_entry++; - - /* Increment column */ - iblock->next_col++; - - /* Check for walking off end of column */ - if(iblock->next_col == iblock->shared->man_dtable.cparam.width) { - /* Reset column */ - iblock->next_col = 0; - - /* Increment row & block size */ - iblock->next_row++; - if(iblock->next_row > 1) - iblock->next_size *= 2; - - /* Check for filling up indirect block */ - if(iblock->next_row == iblock->max_rows) { - /* Check for "full" heap */ - if(iblock->parent == NULL) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't advance fractal heap block location") - - /* Increment location for parent indirect block */ - 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 */ - -#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 */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_man_iblock_inc_loc() */ - - -/*------------------------------------------------------------------------- * Function: H5HF_iblock_incr * * Purpose: Increment reference count on shared indirect block @@ -171,19 +108,23 @@ done: herr_t H5HF_iblock_incr(H5HF_indirect_t *iblock) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_incr) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(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 - */ + /* Mark block as un-evictable when a child block is depending on it */ + if(iblock->rc == 0) + if(H5AC_pin_protected_entry(iblock->hdr->f, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPIN, FAIL, "unable to pin fractal heap indirect block") /* Increment reference count on shared indirect block */ iblock->rc++; - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_iblock_incr() */ @@ -203,7 +144,9 @@ H5HF_iblock_incr(H5HF_indirect_t *iblock) herr_t H5HF_iblock_decr(H5HF_indirect_t *iblock) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_iblock_decr) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_iblock_decr) /* Sanity check */ HDassert(iblock); @@ -211,14 +154,13 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock) /* Decrement reference count on shared indirect block */ iblock->rc--; -/* 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); - + /* Mark block as evictable again when no child blocks depend on it */ + if(iblock->rc == 0) + if(H5AC_unpin_entry(iblock->hdr->f, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block") - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_iblock_decr() */ @@ -236,10 +178,8 @@ H5HF_iblock_decr(H5HF_indirect_t *iblock) *------------------------------------------------------------------------- */ herr_t -H5HF_iblock_dirty(hid_t dxpl_id, H5HF_indirect_t *iblock) +H5HF_iblock_dirty(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) @@ -250,28 +190,23 @@ HDfprintf(stderr, "%s: Marking indirect block as dirty\n", FUNC); /* 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 */ +/* XXX: Need to mark a protected block as dirty eventually also... */ +{ + unsigned entry_status; /* Indirect block entry status */ - /* Set the dirty flags for the indirect block */ - iblock->dirty = TRUE; + if(H5AC_get_entry_status(iblock->hdr->f, iblock->addr, &entry_status) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to query fractal heap indirect block status") + HDassert(entry_status & H5AC_ES__IN_CACHE); - /* 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") + if(!(entry_status & H5AC_ES__IS_PROTECTED)) { + /* Mark indirect block as dirty in cache */ + if(H5AC_mark_pinned_entry_dirty(iblock->hdr->f, iblock, FALSE, 0) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark fractal heap indirect block as dirty") } /* end if */ +} + + /* Set the dirty flag for the indirect block */ + iblock->dirty = TRUE; done: FUNC_LEAVE_NOAPI(ret_value) @@ -292,7 +227,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_man_iblock_skip_blocks(H5HF_t *hdr, H5HF_indirect_t *iblock, +H5HF_man_iblock_skip_blocks(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock, haddr_t iblock_addr, unsigned start_entry, unsigned nentries) { H5HF_free_section_t *sec_node; /* Pointer to free list section for range */ @@ -322,8 +257,7 @@ HDfprintf(stderr, "%s: start_entry = %u, nentries = %u\n", FUNC, start_entry, ne sect_off = iblock->block_off; for(u = 0; u < curr_row; u++) sect_off += hdr->man_dtable.row_block_size[u] * hdr->man_dtable.cparam.width; - for(u = 0; u < curr_col; u++) - sect_off += hdr->man_dtable.row_block_size[curr_row]; + sect_off += hdr->man_dtable.row_block_size[curr_row] * curr_col; #ifdef QAK HDfprintf(stderr, "%s: sect_off = %Zu\n", FUNC, sect_off); #endif /* QAK */ @@ -350,8 +284,9 @@ HDfprintf(stderr, "%s: row_entries = %u, hdr->man_dtable.row_dblock_free[%u] = % sec_node->sect_addr = sect_off; sec_node->sect_size = hdr->man_dtable.row_dblock_free[curr_row]; sec_node->type = H5HF_SECT_RANGE; - sec_node->u.range.iblock_addr = iblock_addr; - sec_node->u.range.iblock_nrows = iblock->nrows; + sec_node->u.range.iblock = iblock; + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") sec_node->u.range.row = curr_row; sec_node->u.range.col = curr_col; sec_node->u.range.num_entries = row_entries; @@ -364,23 +299,17 @@ HDfprintf(stderr, "%s: row_entries = %u, hdr->man_dtable.row_dblock_free[%u] = % sect_off += row_entries * hdr->man_dtable.row_block_size[curr_row]; curr_row++; curr_col = 0; /* (first partial row aligns this) */ + + /* Increment index variable */ u += row_entries; } /* end for */ - - /* Re-compute row information for next empty block */ -#ifdef QAK -HDfprintf(stderr, "%s: u = %u\n", FUNC, u); -#endif /* QAK */ - curr_row = u / hdr->man_dtable.cparam.width; #ifdef QAK -HDfprintf(stderr, "%s: curr_row = %u\n", FUNC, curr_row); +HDfprintf(stderr, "%s: sect_off = %Zu\n", FUNC, sect_off); #endif /* QAK */ - /* Set indirect block's "next entry" information */ - iblock->next_col = 0; - iblock->next_row = curr_row; - iblock->next_size = hdr->man_dtable.row_block_size[curr_row]; - iblock->next_entry = u; + /* Advance the allocated heap size/new block iterator */ + if(H5HF_hdr_inc_alloc(hdr, sect_off, nentries) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size") done: FUNC_LEAVE_NOAPI(ret_value) @@ -401,7 +330,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_man_iblock_skip_ranges(H5HF_t *hdr, H5HF_indirect_t *iblock, +H5HF_man_iblock_skip_ranges(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock, haddr_t iblock_addr, unsigned start_entry, unsigned nentries) { H5HF_free_section_t *sec_node; /* Pointer to free list section for range */ @@ -428,19 +357,21 @@ HDfprintf(stderr, "%s: start_entry = %u, nentries = %u\n", FUNC, start_entry, ne /* Compute starting column & row */ curr_row = start_entry / hdr->man_dtable.cparam.width; curr_col = start_entry % hdr->man_dtable.cparam.width; +#ifdef QAK +HDfprintf(stderr, "%s: curr_col = %u, curr_row = %u\n", FUNC, curr_col, curr_row); +#endif /* QAK */ /* Initialize information for rows skipped over */ sect_off = iblock->block_off; for(u = 0; u < curr_row; u++) sect_off += hdr->man_dtable.row_block_size[u] * hdr->man_dtable.cparam.width; - for(u = 0; u < curr_col; u++) - sect_off += hdr->man_dtable.row_block_size[curr_row]; + sect_off += hdr->man_dtable.row_block_size[curr_row] * curr_col; #ifdef QAK HDfprintf(stderr, "%s: sect_off = %Zu\n", FUNC, sect_off); #endif /* QAK */ /* Loop over the blocks to skip */ - for(u = start_entry; u < (start_entry + nentries); /* u is advanced in inner loop */) { + for(u = start_entry; u < (start_entry + nentries); /* u is advanced in loop */) { unsigned row_entries; /* Number of entries in a particular row */ unsigned num_rows; /* Number of rows in indirect blocks referenced */ @@ -481,8 +412,9 @@ HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); #endif /* QAK */ sec_node->sect_size = hdr->man_dtable.row_dblock_free[w]; sec_node->type = H5HF_SECT_INDIRECT; - sec_node->u.indirect.iblock_addr = iblock_addr; - sec_node->u.indirect.iblock_nrows = iblock->nrows; + sec_node->u.indirect.iblock = iblock; + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") sec_node->u.indirect.row = curr_row; sec_node->u.indirect.col = curr_col; sec_node->u.indirect.num_entries = row_entries; @@ -501,27 +433,179 @@ HDfprintf(stderr, "%s: acc_row_dblock_free_space = %Zu\n", FUNC, acc_row_dblock_ sect_off += row_entries * hdr->man_dtable.row_block_size[curr_row]; curr_row++; curr_col = 0; /* (first partial row aligns this) */ + + /* Advance outer loop index */ u += row_entries; } /* end for */ - /* Re-compute row information for next empty block */ + /* Advance the allocated heap size/new block iterator */ + if(H5HF_hdr_inc_alloc(hdr, sect_off, nentries) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iblock_skip_ranges() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iblock_double_root + * + * Purpose: Double size of root indirect block + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 17 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_man_iblock_double_root(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_size) +{ + H5HF_indirect_t *iblock; /* Pointer to root indirect block */ + haddr_t new_addr; /* New address of indirect block */ + hsize_t acc_dblock_free; /* Accumulated free space in direct blocks */ + hsize_t next_size; /* The previous value of the "next size" for the new block iterator */ + unsigned next_row; /* The next row to allocate block in */ + unsigned next_entry; /* The previous value of the "next entry" for the new block iterator */ + unsigned new_next_entry; /* The new value of the "next entry" for the new block iterator */ + unsigned min_nrows = 0; /* Min. # of direct rows */ + unsigned old_nrows; /* Old # of rows */ + unsigned new_nrows; /* New # of rows */ + hbool_t skip_direct_rows = FALSE; /* Whether we are skipping direct rows */ + size_t u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_double_root) + #ifdef QAK -HDfprintf(stderr, "%s: u = %u\n", FUNC, u); +HDfprintf(stderr, "%s: Extending root indirect block\n", FUNC); #endif /* QAK */ - curr_row = u / hdr->man_dtable.cparam.width; + + /* Get "new block" iterator information */ + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, &next_entry, &iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "unable to retrieve current block iterator location") + next_size = hdr->man_dtable.row_block_size[next_row]; + + /* Make certain the iterator is at the root indirect block */ + HDassert(iblock->parent == NULL); + + /* Keep this for later */ + old_nrows = iblock->nrows; + + /* Check for skipping over direct block rows */ + if(iblock->nrows < hdr->man_dtable.max_direct_rows && min_dblock_size > next_size) { + /* Sanity check */ + HDassert(min_dblock_size > hdr->man_dtable.cparam.start_block_size); + + /* Set flag */ + skip_direct_rows = TRUE; + + /* Make certain we allocate at least the required row for the block requested */ + min_nrows = 1 + H5HF_dtable_size_to_row(&hdr->man_dtable, min_dblock_size); + + /* Set the information for the next block, of the appropriate size */ + new_next_entry = (min_nrows - 1) * hdr->man_dtable.cparam.width; + } /* end if */ + + /* Compute new # of rows in indirect block */ + new_nrows = MAX(min_nrows, MIN(2 * iblock->nrows, iblock->max_rows)); #ifdef QAK -HDfprintf(stderr, "%s: curr_row = %u\n", FUNC, curr_row); +HDfprintf(stderr, "%s: min_nrows = %u, new_nrows = %u\n", FUNC, min_nrows, new_nrows); +HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); +HDfprintf(stderr, "%s: old_next_entry = %u, iblock->next_entry = %u\n", FUNC, old_next_entry, iblock->next_entry); #endif /* QAK */ - /* Set indirect block's "next entry" information */ - iblock->next_col = 0; - iblock->next_row = curr_row; - iblock->next_size = hdr->man_dtable.row_block_size[curr_row]; - iblock->next_entry = u; +/* Currently, the old block data is "thrown away" after the space is reallocated, +* so avoid data copy in H5MF_realloc() call by just free'ing the space and +* allocating new space. +* +* This also keeps the file smaller, by freeing the space and then +* allocating new space, instead of vice versa (in H5MF_realloc). +* +* QAK - 3/14/2006 +*/ + /* Free previous indirect block disk space */ + if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size)<0) + HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, FAIL, "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(hdr, iblock); + + /* Allocate space for the new indirect block on disk */ + 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, FAIL, "file allocation failed for fractal heap indirect block") +#ifdef QAK +HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr); +#endif /* QAK */ + + /* Re-allocate direct block entry table */ + 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, FAIL, "memory allocation failed for direct entries") + + /* Check for skipping over rows and add free section for skipped rows */ + if(skip_direct_rows) { + /* Add skipped blocks to heap's free space */ + if(H5HF_man_iblock_skip_blocks(hdr, iblock, new_addr, + next_entry, (new_next_entry - next_entry)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't add skipped blocks to heap's free space") + } /* end if */ + + /* Initialize new direct block entries in rows added */ + acc_dblock_free = 0; + for(u = (old_nrows * hdr->man_dtable.cparam.width); u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { + unsigned row = u / hdr->man_dtable.cparam.width; /* Row for current entry */ + + iblock->ents[u].addr = HADDR_UNDEF; + iblock->ents[u].free_space = hdr->man_dtable.row_dblock_free[row]; + iblock->child_free_space += iblock->ents[u].free_space; + acc_dblock_free += iblock->ents[u].free_space; + } /* end for */ + + /* Mark indirect block as dirty */ + if(H5HF_iblock_dirty(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") + + /* Move object in cache */ + if(H5AC_rename(hdr->f, H5AC_FHEAP_IBLOCK, iblock->addr, new_addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, FAIL, "unable to move fractal heap root indirect block") + + /* Update other shared header info */ + hdr->man_dtable.curr_root_rows = new_nrows; + hdr->man_dtable.table_addr = new_addr; + + /* Extend heap to cover new root indirect block */ +#ifdef QAK +HDfprintf(stderr, "%s: hdr->man_dtable.row_block_off[new_nrows - 1] = %Hu\n", FUNC, hdr->man_dtable.row_block_off[new_nrows - 1]); +HDfprintf(stderr, "%s: hdr->man_dtable.row_block_off[new_nrows] = %Hu\n", FUNC, hdr->man_dtable.row_block_off[new_nrows]); +HDfprintf(stderr, "%s: acc_dblock_free = %Hu\n", FUNC, acc_dblock_free); +#endif /* QAK */ + if(H5HF_hdr_extend_heap(hdr, 2 * hdr->man_dtable.row_block_off[new_nrows - 1], acc_dblock_free) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, FAIL, "can't increase space to cover root direct block") + + /* Mark heap header as modified */ + if(H5HF_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark header as dirty") + + /* Lock root indirect block (again) */ + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_addr, hdr->man_dtable.curr_root_rows, NULL, 0, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + iblock->addr = new_addr; + + /* Update the indirect block pointer in iterator */ + /* (pins the indirect block after it's in the new location) */ + if(H5HF_man_iter_update_iblock(&hdr->next_block, iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMODIFY, FAIL, "unable to update indirect block for block iterator") + + /* Release the indirect block (marked as dirty) */ + 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") done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5HF_man_iblock_skip_ranges() */ +} /* end H5HF_man_iblock_double_root() */ /*------------------------------------------------------------------------- @@ -540,8 +624,8 @@ done: *------------------------------------------------------------------------- */ H5HF_indirect_t * -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_man_iblock_place_dblock(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t min_dblock_size, + size_t *entry_p, size_t *dblock_size) { H5HF_indirect_t *iblock; /* Pointer to indirect block */ haddr_t iblock_addr; /* Indirect block's address */ @@ -557,7 +641,6 @@ HDfprintf(stderr, "%s: min_dblock_size = %Zu\n", FUNC, min_dblock_size); */ HDassert(hdr); HDassert(min_dblock_size > 0); - HDassert(addr_p); /* Check for creating first indirect block */ if(hdr->man_dtable.curr_root_rows == 0) { @@ -600,7 +683,7 @@ 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 */ - if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &nrows, hdr, H5AC_WRITE))) + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, nrows, NULL, 0, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") /* Check if there's already a direct block as root) */ @@ -610,7 +693,7 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl #endif /* QAK */ if(have_direct_block) { /* Lock first (root) direct block */ - 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))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, hdr->man_dtable.table_addr, hdr->man_dtable.cparam.start_block_size, iblock, 0, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap direct block") /* Point indirect block at direct block to add */ @@ -621,8 +704,6 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl /* Make direct block share parent indirect block */ 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") @@ -630,26 +711,29 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl 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; - - /* Increment size of next block from this indirect block */ - /* (account for the already existing direct block */ - if(H5HF_man_iblock_inc_loc(iblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") } /* end if */ + /* Set up iterator at correct location */ + if(H5HF_man_iter_start_entry(hdr, &hdr->next_block, iblock, have_direct_block) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't initialize block iterator") + /* Check for skipping over direct blocks, in order to get to large enough block */ - if(min_dblock_size > iblock->next_size) { + if(min_dblock_size > hdr->man_dtable.cparam.start_block_size) { /* Add skipped blocks to heap's free space */ if(H5HF_man_iblock_skip_blocks(hdr, iblock, iblock_addr, have_direct_block, ((nrows - 1) * hdr->man_dtable.cparam.width) - have_direct_block) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't add skipped blocks to heap's free space") - HDassert(iblock->next_size == min_dblock_size); } /* end if */ /* Mark indirect block as modified */ - if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + if(H5HF_iblock_dirty(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty") + /* Unprotect root indirect block (it's pinned by the iterator though) */ + 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; + /* Point heap header at new indirect block */ hdr->man_dtable.curr_root_rows = nrows; hdr->man_dtable.table_addr = iblock_addr; @@ -668,341 +752,289 @@ HDfprintf(stderr, "%s: have_direct_block = %u\n", FUNC, (unsigned)have_direct_bl HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, NULL, "can't increase space to cover root direct block") /* Mark heap header as modified */ - hdr->dirty = TRUE; + if(H5HF_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark header as dirty") } /* end if */ else { + hbool_t walked_up, walked_down; /* Condition variables for finding direct block location */ + unsigned next_row; /* Iterator's next block row */ + unsigned next_entry; /* Iterator's next block entry */ + unsigned min_dblock_row; /* Minimum row for direct block size request */ + #ifdef QAK HDfprintf(stderr, "%s: searching root indirect block\n", FUNC); #endif /* QAK */ - - /* Lock root indirect block */ - 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") - + /* Compute min. row for direct block requested */ + min_dblock_row = H5HF_dtable_size_to_row(&hdr->man_dtable, min_dblock_size); #ifdef QAK -HDfprintf(stderr, "%s: iblock->next_row = %u, iblock->nrows = %u\n", FUNC, iblock->next_row, iblock->nrows); -HDfprintf(stderr, "%s: iblock->next_size = %Zu\n", FUNC, iblock->next_size); +HDfprintf(stderr, "%s: min_dblock_size = %Zu, min_dblock_row = %u\n", FUNC, min_dblock_size, min_dblock_row); #endif /* QAK */ - /* Check if we need a block past current allocation */ - /* (i.e. extend the root indirect block) */ - if(iblock->next_row == iblock->nrows || - /* Don't try to extend the root indirect block if the requested - * direct block is too large, but the - * next direct block is in a child indirect block. - */ - (iblock->nrows < hdr->man_dtable.max_direct_rows && - min_dblock_size > iblock->next_size)) { - haddr_t new_addr; /* New address of indirect block */ - hsize_t acc_dblock_free; /* Accumulated free space in direct blocks */ - unsigned old_next_entry; /* The previous value of the "next entry" for the indirect block */ - unsigned min_nrows = 0; /* Min. # of direct rows */ - unsigned old_nrows; /* Old # of rows */ - unsigned new_nrows; /* New # of rows */ - size_t u; /* Local index variable */ + /* Initialize block iterator, if necessary */ + if(!H5HF_man_iter_ready(&hdr->next_block)) { #ifdef QAK -HDfprintf(stderr, "%s: Extending root indirect block\n", FUNC); +HDfprintf(stderr, "%s: hdr->man_alloc_size = %Hu\n", FUNC, hdr->man_alloc_size); #endif /* QAK */ + /* Start iterator with offset of allocated space */ + if(H5HF_man_iter_start_offset(hdr, dxpl_id, &hdr->next_block, hdr->man_alloc_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "unable to set block iterator location") + } /* end if */ - /* Keep this for later */ - old_next_entry = iblock->next_entry; - old_nrows = iblock->nrows; - - /* Check for skipping over rows */ - if(iblock->nrows < hdr->man_dtable.max_direct_rows && min_dblock_size > iblock->next_size) { - /* Sanity check */ - HDassert(min_dblock_size > hdr->man_dtable.cparam.start_block_size); - - /* Make certain we allocate at least the required row for the block requested */ - min_nrows = 2 + (H5V_log2_of2(min_dblock_size) - H5V_log2_of2(hdr->man_dtable.cparam.start_block_size)); - - /* Set the information for the next block, of the appropriate size */ - iblock->next_entry = (min_nrows - 1) * hdr->man_dtable.cparam.width; - } /* end if */ - /* Check for special case of second row, which has blocks the same size as first row */ - else if(iblock->next_row == 1) - iblock->next_size = hdr->man_dtable.cparam.start_block_size; + /* Get information about current iterator location */ + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, + &next_entry, &iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location") - /* Compute new # of rows in indirect block */ - new_nrows = MAX(min_nrows, MIN(2 * iblock->nrows, iblock->max_rows)); #ifdef QAK -HDfprintf(stderr, "%s: min_nrows = %u, new_nrows = %u\n", FUNC, min_nrows, new_nrows); +HDfprintf(stderr, "%s: Check 1.0\n", FUNC); +HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock); HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); -HDfprintf(stderr, "%s: old_next_entry = %u, iblock->next_entry = %u\n", FUNC, old_next_entry, iblock->next_entry); +HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row); +HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry); #endif /* QAK */ - -/* Currently, the old block data is "thrown away" after the space is reallocated, -* so avoid data copy in H5MF_realloc() call by just free'ing the space and -* allocating new space. -* -* This also keeps the file smaller, by freeing the space and then -* allocating new space, instead of vice versa (in H5MF_realloc). -* -* QAK - 3/14/2006 -*/ - /* Free previous indirect block disk space */ - 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(hdr, iblock); - - /* Allocate space for the new indirect block on disk */ - 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") + /* Check for skipping over blocks in the current block */ + if(min_dblock_row > next_row) { + unsigned min_entry; /* Min entry for direct block requested */ + unsigned skip_entries; /* Number of entries to skip in the current block */ + + /* Compute the number of entries to skip in the current block */ + min_entry = min_dblock_row * hdr->man_dtable.cparam.width; + if(min_dblock_row >= iblock->nrows) + skip_entries = (iblock->nrows * hdr->man_dtable.cparam.width) - next_entry; + else + skip_entries = min_entry - next_entry; #ifdef QAK -HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr); +HDfprintf(stderr, "%s: min_entry = %u, skip_entries = %u\n", FUNC, min_entry, skip_entries); #endif /* QAK */ - /* Re-allocate direct block entry table */ - 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") - - /* Check for skipping over rows and add free section for skipped rows */ - if(iblock->nrows < hdr->man_dtable.max_direct_rows && min_dblock_size > iblock->next_size) { - /* Add skipped blocks to heap's free space */ - if(H5HF_man_iblock_skip_blocks(hdr, iblock, new_addr, - old_next_entry, (iblock->next_entry - old_next_entry)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't add skipped blocks to heap's free space") - HDassert(iblock->next_size == min_dblock_size); - } /* end if */ - - /* Initialize new direct block entries in rows added */ - acc_dblock_free = 0; - for(u = (old_nrows * hdr->man_dtable.cparam.width); u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { - unsigned row = u / hdr->man_dtable.cparam.width; /* Row for current entry */ - - iblock->ents[u].addr = HADDR_UNDEF; - iblock->ents[u].free_space = hdr->man_dtable.row_dblock_free[row]; - iblock->child_free_space += iblock->ents[u].free_space; - acc_dblock_free += iblock->ents[u].free_space; - } /* end for */ - - /* Mark indirect block as dirty */ - 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(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(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 */ - hdr->man_dtable.curr_root_rows = new_nrows; - hdr->man_dtable.table_addr = iblock_addr = new_addr; + /* Add skipped direct blocks to heap's free space */ + if(H5HF_man_iblock_skip_blocks(hdr, iblock, iblock->addr, next_entry, skip_entries) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't add skipped blocks to heap's free space") - /* Extend heap to cover new root indirect block */ + /* Get information about new iterator location */ + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, + &next_entry, &iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location") + } /* end if */ #ifdef QAK -HDfprintf(stderr, "%s: hdr->man_dtable.row_block_off[new_nrows - 1] = %Hu\n", FUNC, hdr->man_dtable.row_block_off[new_nrows - 1]); -HDfprintf(stderr, "%s: hdr->man_dtable.row_block_off[new_nrows] = %Hu\n", FUNC, hdr->man_dtable.row_block_off[new_nrows]); -HDfprintf(stderr, "%s: acc_dblock_free = %Hu\n", FUNC, acc_dblock_free); +HDfprintf(stderr, "%s: Check 2.0\n", FUNC); +HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock); +HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); +HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row); +HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry); #endif /* QAK */ - if(H5HF_hdr_extend_heap(hdr, 2 * hdr->man_dtable.row_block_off[new_nrows - 1], acc_dblock_free) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, NULL, "can't increase space to cover root direct block") - - /* Mark heap header as modified */ - hdr->dirty = TRUE; - /* Lock root indirect block (again) */ - 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 */ + do { + /* Reset conditions for leaving loop */ + walked_up = walked_down = FALSE; + /* Check for walking off end of indirect block */ + /* (walk up iterator) */ + while(next_row >= iblock->nrows) { #ifdef QAK -HDfprintf(stderr, "%s: Check 1.0\n", FUNC); -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_size = %Zu\n", FUNC, iblock->next_size); -HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry); +HDfprintf(stderr, "%s: Off the end of a block\n", FUNC); #endif /* QAK */ - /* Check for full direct block entries in current indirect block */ - 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 indirect block */ - unsigned nrows; /* Number of rows in new indirect block */ - - /* Compute # of rows in child indirect block */ - nrows = (H5V_log2_of2((uint32_t)iblock->next_size) - hdr->man_dtable.first_row_bits) + 1; + /* Check for needing to expand root indirect block */ + if(iblock->parent == NULL) { #ifdef QAK -HDfprintf(stderr, "%s: Check 2.0\n", FUNC); -HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->next_size, nrows); -HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry); -HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row); -HDfprintf(stderr, "%s: iblock->max_rows = %u\n", FUNC, iblock->max_rows); +HDfprintf(stderr, "%s: Doubling root block\n", FUNC); +#endif /* QAK */ + if(H5HF_man_iblock_double_root(hdr, dxpl_id, min_dblock_size) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTEXTEND, NULL, "unable to double root indirect block") + } /* end if */ + else { +#ifdef QAK +HDfprintf(stderr, "%s: Walking up a level\n", FUNC); #endif /* QAK */ + /* Move iterator up one level */ + if(H5HF_man_iter_up(&hdr->next_block) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTNEXT, NULL, "unable to advance current block iterator location") - /* Check for skipping over indirect block rows */ - if(hdr->man_dtable.row_block_size[nrows - 1] < min_dblock_size) { - unsigned child_rows_needed; /* Number of rows needed to hold direct block */ + /* Increment location of next block at this level */ + if(H5HF_man_iter_next(hdr, &hdr->next_block, 1) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") + } /* end else */ + + /* Get information about new iterator location */ + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, + &next_entry, &iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location") - /* Compute # of rows needed in child indirect block */ - child_rows_needed = (H5V_log2_of2(min_dblock_size) - H5V_log2_of2(hdr->man_dtable.cparam.start_block_size)) + 2; - HDassert(child_rows_needed > nrows); + /* Indicate that we walked up */ + walked_up = TRUE; + } /* end if */ #ifdef QAK -HDfprintf(stderr, "%s: child_rows_needed = %u\n", FUNC, child_rows_needed); +HDfprintf(stderr, "%s: Check 3.0\n", FUNC); +HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock); +HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); +HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row); +HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry); #endif /* QAK */ - /* Add skipped indirect ranges to heap's free space */ - if(H5HF_man_iblock_skip_ranges(hdr, iblock, iblock->addr, iblock->next_entry, (child_rows_needed - nrows) * hdr->man_dtable.cparam.width) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't add skipped blocks to heap's free space") + /* Check for walking into child indirect block */ + /* (walk down iterator) */ + if(next_row >= hdr->man_dtable.max_direct_rows) { + hsize_t next_size; /* Size of next direct block to create */ + unsigned child_nrows; /* Number of rows in new indirect block */ - /* Update the number of rows in requested child indirect block */ - nrows = child_rows_needed; #ifdef QAK -HDfprintf(stderr, "%s: (new) nrows = %u\n", FUNC, nrows); +HDfprintf(stderr, "%s: Walking down into child indirect block\n", FUNC); #endif /* QAK */ - } /* end if */ #ifdef QAK -HDfprintf(stderr, "%s: iblock->next_size = %Hu, nrows = %u\n", FUNC, iblock->next_size, nrows); -HDfprintf(stderr, "%s: iblock->next_entry = %u\n", FUNC, iblock->next_entry); -HDfprintf(stderr, "%s: iblock->next_row = %u\n", FUNC, iblock->next_row); -HDfprintf(stderr, "%s: iblock->max_rows = %u\n", FUNC, iblock->max_rows); +HDfprintf(stderr, "%s: Check 3.1\n", FUNC); +HDfprintf(stderr, "%s: iblock = %p\n", FUNC, iblock); +HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows); +HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row); +HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry); #endif /* QAK */ + HDassert(!H5F_addr_defined(iblock->ents[next_entry].addr)); - /* Check for walking off indirect block rows */ - if(iblock->next_row >= iblock->max_rows) { + /* Compute # of rows in next child indirect block to use */ + next_size = hdr->man_dtable.row_block_size[next_row]; + child_nrows = (H5V_log2_gen(next_size) - hdr->man_dtable.first_row_bits) + 1; #ifdef QAK -HDfprintf(stderr, "%s: iblock->parent->nrows = %u\n", FUNC, iblock->parent->nrows); -HDfprintf(stderr, "%s: iblock->parent->next_entry = %u\n", FUNC, iblock->parent->next_entry); -HDfprintf(stderr, "%s: iblock->parent->next_size = %Hu\n", FUNC, iblock->parent->next_size); -HDfprintf(stderr, "%s: iblock->parent->next_row = %u\n", FUNC, iblock->parent->next_row); -HDfprintf(stderr, "%s: iblock->parent->next_col = %u\n", FUNC, iblock->parent->next_col); +HDfprintf(stderr, "%s: child_nrows = %u\n", FUNC, child_nrows); #endif /* QAK */ - /* Locate parent indirect block */ - new_iblock_addr = iblock->parent->addr; - nrows = iblock->parent->nrows; - /* Lock parent indirect block */ - 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") + /* Check for skipping over indirect blocks */ + /* (that don't have direct blocks large enough to hold direct block size requested) */ + if(hdr->man_dtable.row_block_size[child_nrows - 1] < min_dblock_size) { + unsigned child_rows_needed; /* Number of rows needed to hold direct block */ + unsigned child_entry; /* Entry of child indirect block */ - /* Advance location in parent lock */ - if(H5HF_man_iblock_inc_loc(new_iblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") - } /* end if */ - else { - /* Check for allocating new indirect block */ - if(!H5F_addr_defined(iblock->ents[iblock->next_entry].addr)) { +#ifdef QAK +HDfprintf(stderr, "%s: Skipping indirect block row that is too small\n", FUNC); +#endif /* QAK */ + /* Compute # of rows needed in child indirect block */ + child_rows_needed = (H5V_log2_of2(min_dblock_size) - H5V_log2_of2(hdr->man_dtable.cparam.start_block_size)) + 2; + HDassert(child_rows_needed > child_nrows); + child_entry = (next_row + (child_rows_needed - child_nrows)) * hdr->man_dtable.cparam.width; +#ifdef QAK +HDfprintf(stderr, "%s: child_rows_needed = %u\n", FUNC, child_rows_needed); +HDfprintf(stderr, "%s: child_entry = %u\n", FUNC, child_entry); +#endif /* QAK */ + + /* Add skipped indirect ranges to heap's free space */ + if(H5HF_man_iblock_skip_ranges(hdr, iblock, iblock->addr, next_entry, (child_entry - next_entry)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't add skipped blocks to heap's free space") + } /* end if */ + else { + H5HF_indirect_t *new_iblock; /* Pointer to new indirect block */ hsize_t new_iblock_off; /* Direct block offset in heap address space */ + haddr_t new_iblock_addr; /* New indirect block's address */ + #ifdef QAK - HDfprintf(stderr, "%s: Allocating new indirect block\n", FUNC); +HDfprintf(stderr, "%s: Allocating new child indirect block\n", FUNC); #endif /* QAK */ /* Compute the direct block's offset in the heap's address space */ new_iblock_off = iblock->block_off; - new_iblock_off += hdr->man_dtable.row_block_off[iblock->next_entry / hdr->man_dtable.cparam.width]; - new_iblock_off += hdr->man_dtable.row_block_size[iblock->next_entry / hdr->man_dtable.cparam.width] * (iblock->next_entry % hdr->man_dtable.cparam.width); + new_iblock_off += hdr->man_dtable.row_block_off[next_entry / hdr->man_dtable.cparam.width]; + new_iblock_off += hdr->man_dtable.row_block_size[next_entry / hdr->man_dtable.cparam.width] * (next_entry % hdr->man_dtable.cparam.width); /* Allocate new indirect block */ - if(H5HF_man_iblock_create(hdr, dxpl_id, new_iblock_off, nrows, nrows, &new_iblock_addr) < 0) + if(H5HF_man_iblock_create(hdr, dxpl_id, new_iblock_off, child_nrows, child_nrows, &new_iblock_addr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate fractal heap indirect block") /* Lock new indirect block */ - if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_WRITE))) + if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, child_nrows, iblock, next_entry, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") /* 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; + new_iblock->par_entry = next_entry; 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; + iblock->ents[next_entry].addr = new_iblock_addr; + + /* Move iterator down one level */ + if(H5HF_man_iter_down(&hdr->next_block, new_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTNEXT, NULL, "unable to advance current block iterator location") + + /* Get information about new iterator location */ + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, + &next_entry, NULL) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location") + next_size = hdr->man_dtable.row_block_size[next_row]; #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); +HDfprintf(stderr, "%s: next_row = %u\n", FUNC, next_row); +HDfprintf(stderr, "%s: next_entry = %u\n", FUNC, next_entry); #endif /* QAK */ /* Check for skipping over rows and add free section for skipped rows */ - if(min_dblock_size > new_iblock->next_size) { + if(min_dblock_size > next_size) { unsigned new_entry; /* Entry of direct block which is large enough */ /* Compute entry for direct block size requested */ - new_entry = hdr->man_dtable.cparam.width * - (1 + (H5V_log2_of2(min_dblock_size) - H5V_log2_of2(hdr->man_dtable.cparam.start_block_size))); + new_entry = hdr->man_dtable.cparam.width * min_dblock_row; #ifdef QAK - HDfprintf(stderr, "%s: new_entry = %u\n", FUNC, new_entry); +HDfprintf(stderr, "%s: Skipping rows in new child indirect block - new_entry = %u\n", FUNC, new_entry); #endif /* QAK */ /* Add skipped blocks to heap's free space */ if(H5HF_man_iblock_skip_blocks(hdr, new_iblock, new_iblock->addr, 0, new_entry) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, NULL, "can't add skipped blocks to heap's free space") - HDassert(new_iblock->next_size == min_dblock_size); } /* end if */ - /* Mark current indirect block as modified */ - if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + /* Mark new indirect block as modified */ + if(H5HF_iblock_dirty(new_iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty") - /* Set dirty flag for the current indirect block */ - hdr_flags |= H5AC__DIRTIED_FLAG; - } /* end if */ - else { -#ifdef QAK - HDfprintf(stderr, "%s: Descending existing indirect block\n", FUNC); -#endif /* QAK */ - /* Locate child indirect block */ - new_iblock_addr = iblock->ents[iblock->next_entry].addr; + /* Mark current indirect block as modified */ + if(H5HF_iblock_dirty(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, NULL, "can't mark indirect block as dirty") - /* Lock new indirect block */ - 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 */ - } /* 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 */ + /* Unprotect child indirect block */ + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock->addr, new_iblock, H5AC__DIRTIED_FLAG) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap indirect block") + } /* end else */ - /* Release the current indirect block (possibly marked as dirty) */ - 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") + /* Get information about new iterator location */ + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, + &next_entry, &iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location") - /* Switch variables to use new indirect block */ - iblock = new_iblock; - iblock_addr = new_iblock_addr; -#ifdef QAK -HDfprintf(stderr, "%s: new_iblock_addr = %a\n", FUNC, new_iblock_addr); -#endif /* QAK */ - } /* end while */ + /* Indicate that we walked down */ + walked_down = TRUE; + } /* end while */ + } while(walked_down || walked_up); } /* end else */ + /* Get information about iterator location */ +{ + unsigned next_row; /* Iterator's next block row */ + unsigned next_entry; /* Iterator's next block entry */ + size_t next_size; /* Size of next direct block to create */ + + if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, + &next_entry, &iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, NULL, "unable to retrieve current block iterator location") + HDassert(next_row < iblock->nrows); + next_size = hdr->man_dtable.row_block_size[next_row]; + /* Check for skipping over blocks */ - if(min_dblock_size > iblock->next_size) { -HDfprintf(stderr, "%s: Skipping direct block sizes not supported, iblock->next_size = %Zu\n", FUNC, iblock->next_size); + if(min_dblock_size > next_size) { +HDfprintf(stderr, "%s: Skipping direct block sizes not supported, min_dblock_size = %Zu, next_size = %Zu\n", FUNC, min_dblock_size, next_size); HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "skipping direct block sizes not supported yet") } /* end if */ - /* Set address of indirect block that's the immediate parent of new direct block */ - *addr_p = iblock_addr; - /* Set entry for new direct block to use */ - *entry_p = iblock->next_entry; + *entry_p = next_entry; /* Set size of direct block to create */ - *dblock_size = iblock->next_size; + *dblock_size = next_size; +#ifdef OLD_WAY /* Increment location of next block from this indirect block */ - if(H5HF_man_iblock_inc_loc(iblock) < 0) + if(H5HF_man_iter_next(hdr, &hdr->next_block, 1) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't advance fractal heap block location") +#endif /* OLD_WAY */ /* Set return value */ ret_value = iblock; +} done: FUNC_LEAVE_NOAPI(ret_value) @@ -1026,16 +1058,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_iblock_alloc_range(H5HF_t *hdr, hid_t dxpl_id, - H5HF_free_section_t **sec_node, size_t obj_size) +H5HF_man_iblock_alloc_range(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t **sec_node) { H5HF_indirect_t *iblock; /* Pointer to indirect block */ - haddr_t iblock_addr; /* Indirect block's address */ haddr_t dblock_addr; /* Direct block's address */ - unsigned iblock_nrows; /* Indirect block's number of rows */ H5HF_free_section_t *dblock_sec_node = NULL; /* Pointer to direct block's section node */ H5HF_free_section_t *old_sec_node = *sec_node; /* Pointer to old section node */ - size_t full_obj_size; /* Size of object including metadata */ unsigned cur_entry; /* Current entry in indirect block */ herr_t ret_value = SUCCEED; /* Return value */ @@ -1046,7 +1075,6 @@ H5HF_man_iblock_alloc_range(H5HF_t *hdr, hid_t dxpl_id, */ HDassert(hdr); HDassert(sec_node && *sec_node); - HDassert(obj_size > 0); /* Compute info about range */ cur_entry = (old_sec_node->u.range.row * hdr->man_dtable.cparam.width) + old_sec_node->u.range.col; @@ -1057,20 +1085,9 @@ HDfprintf(stderr, "%s: Can't handle range sections over indirect blocks yet\n", HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'range' free space sections over indirect blocks not supported yet") } /* end if */ - /* Get information about indirect block covering section */ - /* (Allow for root indirect block being resized) */ - iblock_addr = old_sec_node->u.range.iblock_addr; - if(H5F_addr_eq(iblock_addr, hdr->man_dtable.table_addr)) - iblock_nrows = hdr->man_dtable.curr_root_rows; - else - iblock_nrows = old_sec_node->u.range.iblock_nrows; - /* Get a pointer to the indirect block covering the range */ - if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, hdr, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") - - /* Compute size of object, with metadata overhead */ - full_obj_size = obj_size + H5HF_MAN_ABS_DIRECT_OBJ_PREFIX_LEN(hdr); + iblock = old_sec_node->u.range.iblock; + HDassert(iblock); #ifdef QAK HDfprintf(stderr, "%s: cur_entry = %u\n", FUNC, cur_entry); @@ -1087,9 +1104,19 @@ HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect /* Hook direct block up to indirect block */ iblock->ents[cur_entry].addr = dblock_addr; + /* Mark indirect block as dirty */ + if(H5HF_iblock_dirty(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") + /* Check for only single block covered in range section */ - if(old_sec_node->u.range.num_entries == 1) + if(old_sec_node->u.range.num_entries == 1) { + /* Drop reference count on indirect block that free section is in */ + if(H5HF_iblock_decr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Free section structure */ H5FL_FREE(H5HF_free_section_t, old_sec_node); + } /* end if */ else { /* Adjust section information */ old_sec_node->sect_addr += hdr->man_dtable.row_block_size[old_sec_node->u.range.row]; @@ -1103,10 +1130,6 @@ HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add indirect block free space to global list") } /* end else */ - /* Release the indirect block (marked as dirty) */ - 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") - /* Point 'sec_node' at new direct block section node */ *sec_node = dblock_sec_node; @@ -1133,16 +1156,13 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_iblock_alloc_indirect(H5HF_t *hdr, hid_t dxpl_id, - H5HF_free_section_t **sec_node, size_t obj_size) +H5HF_man_iblock_alloc_indirect(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t **sec_node) { H5HF_indirect_t *iblock; /* Pointer to indirect block */ H5HF_indirect_t *child_iblock; /* Pointer to child indirect block */ - unsigned iblock_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for parent indirect block */ - haddr_t iblock_addr; /* Indirect block's address */ haddr_t child_iblock_addr; /* Address of child indirect block */ haddr_t dblock_addr; /* New direct block's address */ - unsigned iblock_nrows; /* Indirect block's number of rows */ H5HF_free_section_t *dblock_sec_node = NULL; /* Pointer to direct block's section node */ H5HF_free_section_t *range_sec_node = NULL; /* Pointer to new range section node */ H5HF_free_section_t *old_sec_node = *sec_node; /* Pointer to old indirect section node */ @@ -1157,22 +1177,12 @@ H5HF_man_iblock_alloc_indirect(H5HF_t *hdr, hid_t dxpl_id, */ HDassert(hdr); HDassert(sec_node && *sec_node); - HDassert(obj_size > 0); /* Compute info about range */ curr_entry = (old_sec_node->u.indirect.row * hdr->man_dtable.cparam.width) + old_sec_node->u.indirect.col; - /* Get information about indirect block covering section */ - /* (Allow for root indirect block being resized) */ - iblock_addr = old_sec_node->u.indirect.iblock_addr; - if(H5F_addr_eq(iblock_addr, hdr->man_dtable.table_addr)) - iblock_nrows = hdr->man_dtable.curr_root_rows; - else - iblock_nrows = old_sec_node->u.indirect.iblock_nrows; - - /* Get a pointer to the indirect block covering the range */ - if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, hdr, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + /* Get a pointer to the indirect block covering the section */ + iblock = old_sec_node->u.indirect.iblock; #ifdef QAK HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry); @@ -1186,7 +1196,7 @@ HDfprintf(stderr, "%s: old_sec_node->u.indirect.num_entries = %u\n", FUNC, old_s if(H5F_addr_defined(iblock->ents[curr_entry].addr)) { /* Look up existing child indirect block */ child_iblock_addr = iblock->ents[curr_entry].addr; - if(NULL == (child_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock_addr, &old_sec_node->u.indirect.indir_nrows, hdr, H5AC_WRITE))) + if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_iblock_addr, old_sec_node->u.indirect.indir_nrows, iblock, curr_entry, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") } /* end if */ else { @@ -1207,15 +1217,13 @@ HDfprintf(stderr, "%s: new_iblock_off = %Hu\n", FUNC, new_iblock_off); HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap indirect block") /* Lock new child indirect block */ - if(NULL == (child_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock_addr, &old_sec_node->u.indirect.indir_nrows, hdr, H5AC_WRITE))) + if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_iblock_addr, old_sec_node->u.indirect.indir_nrows, iblock, curr_entry, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Set parent information */ HDassert(child_iblock->parent == NULL); child_iblock->parent = iblock; child_iblock->par_entry = curr_entry; - child_iblock->par_nrows = iblock->nrows; - child_iblock->par_addr = iblock->addr; if(H5HF_iblock_incr(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") #ifdef QAK @@ -1227,11 +1235,8 @@ HDfprintf(stderr, "%s: child_iblock->child_free_space = %Hu\n", FUNC, child_iblo HDassert(iblock->ents[curr_entry].free_space == child_iblock->child_free_space); /* Mark parent indirect block as modified */ - if(H5HF_iblock_dirty(dxpl_id, iblock) < 0) + if(H5HF_iblock_dirty(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") - - /* Set dirty flag for the parent indirect block */ - iblock_flags |= H5AC__DIRTIED_FLAG; } /* end else */ /* Compute entry for new direct block in child indirect block */ @@ -1249,6 +1254,10 @@ HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect /* Hook direct block up to child indirect block */ child_iblock->ents[dblock_entry].addr = dblock_addr; + /* Mark child indirect block as modified */ + if(H5HF_iblock_dirty(child_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") + /* Create "range" section for other direct blocks in row of child indirect block */ @@ -1261,8 +1270,9 @@ HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect + hdr->man_dtable.row_block_size[old_sec_node->u.indirect.indir_row]; range_sec_node->sect_size = old_sec_node->sect_size; range_sec_node->type = H5HF_SECT_RANGE; - range_sec_node->u.range.iblock_addr = child_iblock_addr; - range_sec_node->u.range.iblock_nrows = child_iblock->nrows; + range_sec_node->u.range.iblock = child_iblock; + if(H5HF_iblock_incr(child_iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") range_sec_node->u.range.row = old_sec_node->u.indirect.indir_row; range_sec_node->u.range.col = 1; range_sec_node->u.range.num_entries = hdr->man_dtable.cparam.width - 1; @@ -1275,8 +1285,14 @@ HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect /* Reduce "indirect" section */ /* Check for only single block covered in range section */ - if(old_sec_node->u.indirect.num_entries == 1) + if(old_sec_node->u.indirect.num_entries == 1) { + /* Drop reference count on indirect block that free section is in */ + if(H5HF_iblock_decr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Free section structure */ H5FL_FREE(H5HF_free_section_t, old_sec_node); + } /* end if */ else { /* Adjust section information */ old_sec_node->sect_addr += hdr->man_dtable.row_block_size[old_sec_node->u.indirect.row]; @@ -1294,10 +1310,6 @@ HDfprintf(stderr, "%s: old_sec_node->sect_addr = %a\n", FUNC, old_sec_node->sect if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock_addr, child_iblock, H5AC__DIRTIED_FLAG) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") - /* Release the parent indirect block (possibly dirty) */ - if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, iblock, iblock_flags) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") - /* Point 'sec_node' at new direct block section node */ *sec_node = dblock_sec_node; @@ -1307,6 +1319,117 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_man_iblock_alloc_opaque + * + * Purpose: Break up an opaque section into component sections + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iblock_alloc_opaque(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t **sec_node) +{ + H5HF_indirect_t *iblock; /* Pointer to indirect block */ + H5HF_free_section_t *old_sec_node = *sec_node; /* Pointer to old section node */ + haddr_t child_addr; /* Child block's address */ + unsigned entry; /* Entry of child block for section */ + unsigned row; /* Row of child block for section */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_alloc_opaque) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(sec_node && *sec_node); + + /* Get a pointer to the indirect block covering the section */ + iblock = old_sec_node->u.opaque.iblock; + HDassert(iblock); + + /* Compute info about child block */ + entry = old_sec_node->u.opaque.entry; + row = entry / hdr->man_dtable.cparam.width; + child_addr = iblock->ents[entry].addr; + + /* Check if this section's child block is direct or indirect */ + if(row < hdr->man_dtable.max_direct_rows) { + H5HF_direct_t *child_dblock; /* Direct child block */ + size_t dblock_size; /* Direct block's size */ + + /* Compute direct block info */ + dblock_size = hdr->man_dtable.row_block_size[row]; + + /* Check whether direct block exists yet */ + if(H5F_addr_defined(child_addr)) { + /* Lock child direct block */ + /* (also parses it's free space sections) */ + if(NULL == (child_dblock = H5HF_man_dblock_protect(hdr, dxpl_id, child_addr, dblock_size, iblock, entry, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") + + /* Unlock child direct block */ + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, child_addr, child_dblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block") + } /* end if */ + else { + haddr_t dblock_addr; /* Address of direct block created */ + + /* Create direct block of appropriate size */ + if(H5HF_man_dblock_create(dxpl_id, hdr, iblock, entry, dblock_size, (hsize_t)old_sec_node->sect_addr, &dblock_addr, NULL) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate fractal heap direct block") + + /* Hook direct block up to indirect block */ + iblock->ents[entry].addr = dblock_addr; + + /* Mark indirect block as dirty */ + if(H5HF_iblock_dirty(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") + } /* end else */ + } /* end if */ + else { + H5HF_indirect_t *child_iblock; /* Indirect child block */ + size_t iblock_nrows; /* Indirect block's size */ + + /* Compute indirect block info */ + iblock_nrows = (H5V_log2_gen(hdr->man_dtable.row_block_size[row]) - hdr->man_dtable.first_row_bits) + 1; + + /* Check whether direct block exists yet */ + if(H5F_addr_defined(child_addr)) { + /* Lock child indirect block */ + /* (also parses it's free space sections) */ + if(NULL == (child_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, child_addr, iblock_nrows, iblock, entry, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + + /* Release the child indirect block */ + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_addr, child_iblock, H5AC__NO_FLAGS_SET) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") + } /* end if */ + else { +HDfprintf(stderr, "%s: Creating indirect block from opaque section not supported\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "Creating indirect block from opaque section not supported yet") + } /* end else */ + } /* end else */ + + /* Drop reference count on indirect block that free section is in */ + if(H5HF_iblock_decr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Free section structure */ + H5FL_FREE(H5HF_free_section_t, old_sec_node); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iblock_alloc_opaque() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_man_iblock_create * * Purpose: Allocate & initialize a managed indirect block @@ -1320,7 +1443,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_man_iblock_create(H5HF_t *hdr, hid_t dxpl_id, +H5HF_man_iblock_create(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t block_off, unsigned nrows, unsigned max_rows, haddr_t *addr_p) { H5HF_indirect_t *iblock = NULL; /* Pointer to indirect block */ @@ -1347,7 +1470,7 @@ H5HF_man_iblock_create(H5HF_t *hdr, hid_t dxpl_id, HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t)); /* Share common heap information */ - iblock->shared = hdr; + iblock->hdr = hdr; if(H5HF_hdr_incr(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header") @@ -1358,17 +1481,11 @@ HDfprintf(stderr, "%s: nrows = %u, max_nrows = %u\n", FUNC, nrows, max_nrows); iblock->rc = 0; iblock->parent = NULL; /* Temporary, except for root indirect block */ iblock->par_entry = 0; - iblock->par_nrows = 0; - iblock->par_addr = HADDR_UNDEF; iblock->block_off = block_off; iblock->nrows = nrows; iblock->max_rows = max_rows; - iblock->next_col = 0; - iblock->next_row = 0; - iblock->next_entry = 0; - iblock->next_size = hdr->man_dtable.cparam.start_block_size; iblock->dirty = TRUE; - iblock->evicted = FALSE; + iblock->fl_gen = hdr->fl_gen; /* New blocks have their free list generation set up correctly */ /* Compute size of buffer needed for indirect block */ iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); @@ -1408,3 +1525,146 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_man_iblock_create() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iblock_build_sections + * + * Purpose: Build free space sections for child blocks of an indirect block + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_man_iblock_build_sections(H5HF_indirect_t *iblock) +{ + H5HF_free_section_t *sec_node; /* Pointer to free list section for block */ + H5HF_hdr_t *hdr; /* Heap header info */ + haddr_t curr_off; /* Offset of child block in heap */ + unsigned row, col; /* Current row & column being operated on */ + unsigned entry; /* Currenty entry being worked on */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_build_sections) + + /* + * Check arguments. + */ + HDassert(iblock); + + /* Get the heap header pointer (for convenience) */ + hdr = iblock->hdr; + + /* Set starting offset in heap */ + curr_off = iblock->block_off; + + /* Create a free space section for each child block of indirect block */ + entry = 0; +#ifdef QAK +HDfprintf(stderr, "%s: hdr->man_alloc_size = %Hu\n", FUNC, hdr->man_alloc_size); +#endif /* QAK */ + for(row = 0; row < iblock->nrows; row++) { + for(col = 0; col < hdr->man_dtable.cparam.width; col++) { +#ifdef QAK +HDfprintf(stderr, "%s: curr_off = %a\n", FUNC, curr_off); +#endif /* QAK */ + /* Only create free space sections for blocks within the allocated size of the heap */ + if(curr_off >= hdr->man_alloc_size) + break; + + /* Allocate section node */ + if(NULL == (sec_node = H5FL_MALLOC(H5HF_free_section_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + + /* Set section's information */ + sec_node->sect_addr = curr_off; + sec_node->sect_size = iblock->ents[entry].free_space; + sec_node->type = H5HF_SECT_OPAQUE; + sec_node->u.opaque.iblock = iblock; + sec_node->u.opaque.entry = entry; + + /* Increment reference count on indirect block */ + if(H5HF_iblock_incr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + + /* Add section to free list */ + 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 free space section to global list") + + /* Advance state */ + curr_off += hdr->man_dtable.row_block_size[row]; + entry++; + } /* end for */ + } /* end for */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iblock_build_sections() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iblock_protect + * + * Purpose: Convenience wrapper around H5AC_protect on a indirect block + * (Use H5AC_unprotect to unprotect it for now) + * + * Return: Pointer to indirect block on success, NULL on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 17 2006 + * + *------------------------------------------------------------------------- + */ +H5HF_indirect_t * +H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t iblock_addr, + unsigned iblock_nrows, H5HF_indirect_t *par_iblock, unsigned par_entry, + H5AC_protect_t rw) +{ + H5HF_parent_t par_info; /* Parent info for loading block */ + H5HF_indirect_t *iblock; /* Indirect block from cache */ + H5HF_indirect_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iblock_protect) +#ifdef QAK +HDfprintf(stderr, "%s: iblock_addr = %a, iblock_nrows = %u\n", FUNC, iblock_addr, iblock_nrows); +#endif /* QAK */ + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(H5F_addr_defined(iblock_addr)); + HDassert(iblock_nrows > 0); + + /* Set up parent info */ + par_info.hdr = hdr; + par_info.iblock = par_iblock; + par_info.entry = par_entry; + + /* Protect the indirect block */ + if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &iblock_nrows, &par_info, rw))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, NULL, "unable to protect fractal heap indirect block") + + /* Regenerate the free list information for this block, if necessary */ + /* (Only create free list information if write access is requested) */ + if(rw == H5AC_WRITE && hdr->fl_gen != iblock->fl_gen) { + /* Build the free list sections for the block */ + if(H5HF_man_iblock_build_sections(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't build free space sections for block") + + /* Mark the block's free list generation as up to date now */ + iblock->fl_gen = hdr->fl_gen; + } /* end if */ + + /* Set the return value */ + ret_value = iblock; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iblock_protect() */ + diff --git a/src/H5HFint.c b/src/H5HFint.c index 64de9c4..e8b380d 100644 --- a/src/H5HFint.c +++ b/src/H5HFint.c @@ -57,6 +57,7 @@ /********************/ /* Local Prototypes */ /********************/ +static herr_t H5HF_man_start_freelist(H5HF_hdr_t *hdr, hid_t dxpl_id); /*********************/ @@ -93,20 +94,135 @@ H5FL_DEFINE(H5HF_free_section_t); *------------------------------------------------------------------------- */ herr_t -H5HF_free_section_free_cb(void *item, void UNUSED *key, void UNUSED *op_data) +H5HF_free_section_free_cb(void *_sect, void UNUSED *key, void UNUSED *op_data) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_free_section_free_cb) + H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; + H5HF_indirect_t *iblock = NULL; /* Indirect block referenced */ + herr_t ret_value = 0; /* Return value */ - HDassert(item); + FUNC_ENTER_NOAPI_NOINIT(H5HF_free_section_free_cb) + + HDassert(sect); + + /* Find indirect block that free section references */ + switch(sect->type) { + case H5HF_SECT_SINGLE: + iblock = sect->u.single.parent; + break; + + case H5HF_SECT_OPAQUE: + iblock = sect->u.opaque.iblock; + break; + + case H5HF_SECT_RANGE: + iblock = sect->u.range.iblock; + break; + + case H5HF_SECT_INDIRECT: + iblock = sect->u.indirect.iblock; + break; + } /* end switch */ + + /* Release indirect block, if there was one */ + if(iblock) + if(H5HF_iblock_decr(iblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") /* Release the sections */ - H5FL_FREE(H5HF_free_section_t, item); + H5FL_FREE(H5HF_free_section_t, sect); - FUNC_LEAVE_NOAPI(0) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5HF_free_section_free_cb() */ /*------------------------------------------------------------------------- + * Function: H5HF_man_start_freelist + * + * Purpose: Start free list for existing heap, by bringing in root direct + * or indirect block and it's free space sections. + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_man_start_freelist(H5HF_hdr_t *hdr, hid_t dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_start_freelist) + + /* + * Check arguments. + */ + HDassert(hdr); + + /* Check for empty heap */ + if(!H5F_addr_defined(hdr->man_dtable.table_addr)) { +#ifdef QAK +HDfprintf(stderr, "%s: Empty heap to [not] start\n", FUNC); +#endif /* QAK */ + /* Nothing to do */ + ; + } /* end if */ + /* Check for root direct block */ + else if(hdr->man_dtable.curr_root_rows == 0) { + H5HF_direct_t *dblock; /* Pointer to direct block to query */ + haddr_t dblock_addr; /* Direct block address */ + size_t dblock_size; /* Direct block size */ + +#ifdef QAK +HDfprintf(stderr, "%s: Root direct block to start\n", FUNC); +#endif /* QAK */ + /* Bring root direct block into memory */ + /* (which will parse it's free list) */ + /* (Could create an "opaque" section for it, but it doesn't seem worthwhile) */ + dblock_addr = hdr->man_dtable.table_addr; + dblock_size = hdr->man_dtable.cparam.start_block_size; + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, NULL, 0, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") + + /* Unlock direct block */ + 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; + } /* end if */ + /* Must be a root indirect block */ + else { + H5HF_indirect_t *iblock; /* Pointer to root indirect block to query */ + haddr_t iblock_addr; /* Indirect block's address */ + +#ifdef QAK +HDfprintf(stderr, "%s: Root indirect block to start\n", FUNC); +#endif /* QAK */ + /* Get indirect block info */ + iblock_addr = hdr->man_dtable.table_addr; + + /* Lock root indirect block */ + /* (which will parse it's free space) */ + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + + /* Release the root indirect block */ + 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 */ + + /* Mark heap as being in sync now */ + hdr->freelist_sync = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_start_freelist() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_man_find * * Purpose: Find space for an object in a managed obj. heap @@ -121,10 +237,11 @@ H5HF_free_section_free_cb(void *item, void UNUSED *key, void UNUSED *op_data) *------------------------------------------------------------------------- */ herr_t -H5HF_man_find(H5HF_t *hdr, hid_t dxpl_id, size_t request, +H5HF_man_find(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t request, H5HF_free_section_t **sec_node/*out*/) { htri_t node_found; /* Whether an existing free list node was found */ + hbool_t search_again; /* Whether to search again for another free section */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_find) @@ -139,14 +256,51 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); HDassert(request > 0); HDassert(sec_node); - /* Look for free space in global free list */ - if((node_found = H5HF_flist_find(hdr->flist, request, (void **)sec_node)) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block") + /* Search for free space in the globel free list, until a non-opaque node is found */ + do { + /* Done searching, unless opaque node found */ + search_again = FALSE; + + /* Look for free space in global free list */ + if((node_found = H5HF_flist_find(hdr->flist, request, (void **)sec_node)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap direct block") + + /* Check for opaque section */ + if(node_found) { + if((*sec_node)->type == H5HF_SECT_OPAQUE) { + /* Break opaque section down into component sections */ + if(H5HF_man_iblock_alloc_opaque(hdr, dxpl_id, sec_node) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up opaque free section") + + /* Search again */ + search_again = TRUE; + } /* end if */ + } /* end if */ + /* If we didn't find a node, check if we've looked in all the direct blocks in the heap for space */ + else { +#ifdef QAK +HDfprintf(stderr, "%s: hdr->freelist_sync = %u\n", FUNC, (unsigned)hdr->freelist_sync); +#endif /* QAK */ + if(!hdr->freelist_sync) { +#ifdef QAK +HDfprintf(stderr, "%s: Start free list for existing blocks in heap\n", FUNC); +#endif /* QAK */ + /* Start freelist for existing heap */ + if(H5HF_man_start_freelist(hdr, dxpl_id) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't start fractal heap free list") + + /* Search again */ + search_again = TRUE; + } /* end if */ + } /* end else */ + } while(search_again); -/* XXX: Make certain we've loaded all the direct blocks in the heap */ /* If we didn't find a node, go make one big enough to hold the requested block */ if(!node_found) { +#ifdef QAK +HDfprintf(stderr, "%s: Allocate new direct block\n", FUNC); +#endif /* QAK */ /* Allocate direct block big enough to hold requested size */ if(H5HF_man_dblock_new(hdr, dxpl_id, request) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create fractal heap direct block") @@ -158,10 +312,9 @@ HDfprintf(stderr, "%s: request = %Zu\n", FUNC, request); } /* end if */ HDassert(*sec_node); #ifdef QAK -HDfprintf(stderr, "%s: (*sec_node)->block_addr = %a\n", FUNC, (*sec_node)->block_addr); -HDfprintf(stderr, "%s: (*sec_node)->block_size = %Zu\n", FUNC, (*sec_node)->block_size); HDfprintf(stderr, "%s: (*sec_node)->sect_addr = %a\n", FUNC, (*sec_node)->sect_addr); HDfprintf(stderr, "%s: (*sec_node)->sect_size = %Zu\n", FUNC, (*sec_node)->sect_size); +HDfprintf(stderr, "%s: (*sec_node)->type = %u\n", FUNC, (unsigned)(*sec_node)->type); #endif /* QAK */ done: @@ -183,7 +336,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_insert(H5HF_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, +H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, size_t obj_size, const void *obj, void *id) { H5HF_direct_t *dblock = NULL; /* Pointer to direct block to modify */ @@ -205,8 +358,9 @@ H5HF_man_insert(H5HF_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, #ifdef QAK HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); HDfprintf(stderr, "%s: sec_node->sect_size = %Zu\n", FUNC, sec_node->sect_size); -HDfprintf(stderr, "%s: sec_node->u.indirect.iblock_addr = %a\n", FUNC, sec_node->u.indirect.iblock_addr); -HDfprintf(stderr, "%s: sec_node->u.indirect.iblock_nrows = %u\n", FUNC, sec_node->u.indirect.iblock_nrows); +HDfprintf(stderr, "%s: sec_node->u.indirect.iblock = %p\n", FUNC, sec_node->u.indirect.iblock); +if(sec_node->u.indirect.iblock) + HDfprintf(stderr, "%s: sec_node->u.indirect.iblock->addr = %a\n", FUNC, sec_node->u.indirect.iblock->addr); HDfprintf(stderr, "%s: sec_node->u.indirect.row = %u\n", FUNC, sec_node->u.indirect.row); HDfprintf(stderr, "%s: sec_node->u.indirect.col = %u\n", FUNC, sec_node->u.indirect.col); HDfprintf(stderr, "%s: sec_node->u.indirect.num_entries = %u\n", FUNC, sec_node->u.indirect.num_entries); @@ -215,7 +369,7 @@ HDfprintf(stderr, "%s: sec_node->u.indirect.indir_nrows = %u\n", FUNC, sec_node- #endif /* QAK */ /* Allocate 'single' selection out of 'indirect' selection */ - if(H5HF_man_iblock_alloc_indirect(hdr, dxpl_id, &sec_node, obj_size) < 0) + if(H5HF_man_iblock_alloc_indirect(hdr, dxpl_id, &sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up indirect free section") } /* end if */ /* Check for range section */ @@ -223,14 +377,15 @@ HDfprintf(stderr, "%s: sec_node->u.indirect.indir_nrows = %u\n", FUNC, sec_node- #ifdef QAK HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); HDfprintf(stderr, "%s: sec_node->sect_size = %Zu\n", FUNC, sec_node->sect_size); -HDfprintf(stderr, "%s: sec_node->u.range.iblock_addr = %a\n", FUNC, sec_node->u.range.iblock_addr); -HDfprintf(stderr, "%s: sec_node->u.range.iblock_nrows = %u\n", FUNC, sec_node->u.range.iblock_nrows); +HDfprintf(stderr, "%s: sec_node->u.range.iblock = %p\n", FUNC, sec_node->u.range.iblock); +if(sec_node->u.range.iblock) + HDfprintf(stderr, "%s: sec_node->u.range.iblock->addr = %a\n", FUNC, sec_node->u.range.iblock->addr); HDfprintf(stderr, "%s: sec_node->u.range.row = %u\n", FUNC, sec_node->u.range.row); HDfprintf(stderr, "%s: sec_node->u.range.col = %u\n", FUNC, sec_node->u.range.col); HDfprintf(stderr, "%s: sec_node->u.range.num_entries = %u\n", FUNC, sec_node->u.range.num_entries); #endif /* QAK */ /* Allocate 'single' selection out of 'range' selection */ - if(H5HF_man_iblock_alloc_range(hdr, dxpl_id, &sec_node, obj_size) < 0) + if(H5HF_man_iblock_alloc_range(hdr, dxpl_id, &sec_node) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't break up range free section") } /* end if */ @@ -238,11 +393,15 @@ HDfprintf(stderr, "%s: sec_node->u.range.num_entries = %u\n", FUNC, sec_node->u. #ifdef QAK HDfprintf(stderr, "%s: sec_node->sect_addr = %a\n", FUNC, sec_node->sect_addr); HDfprintf(stderr, "%s: sec_node->sect_size = %Zu\n", FUNC, sec_node->sect_size); +HDfprintf(stderr, "%s: sec_node->u.single.parent = %p\n", FUNC, sec_node->u.single.parent); +if(sec_node->u.single.parent) + HDfprintf(stderr, "%s: sec_node->u.single.parent->addr = %a\n", FUNC, sec_node->u.single.parent->addr); +HDfprintf(stderr, "%s: sec_node->u.single.par_entry = %u\n", FUNC, sec_node->u.single.par_entry); HDfprintf(stderr, "%s: sec_node->u.single.dblock_addr = %a\n", FUNC, sec_node->u.single.dblock_addr); HDfprintf(stderr, "%s: sec_node->u.single.dblock_size = %Zu\n", FUNC, sec_node->u.single.dblock_size); #endif /* QAK */ dblock_addr = sec_node->u.single.dblock_addr; - if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &sec_node->u.single.dblock_size, hdr, H5AC_WRITE))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, sec_node->u.single.dblock_size, sec_node->u.single.parent, sec_node->u.single.par_entry, H5AC_WRITE))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block") /* Insert object into block */ @@ -314,6 +473,14 @@ HDfprintf(stderr, "%s: node->size = %Zu\n", FUNC, node->size); free_frag_size = (unsigned char )(node->size - full_obj_size); whole_node = TRUE; + /* Drop reference count on parent indirect block of direct block that free section is in */ + HDassert(dblock->parent == NULL || + sec_node->u.single.parent == NULL || + dblock->parent == sec_node->u.single.parent); + if(sec_node->u.single.parent) + if(H5HF_iblock_decr(sec_node->u.single.parent) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + /* Release the memory for the free list node & section */ H5FL_FREE(H5HF_direct_free_node_t, node); H5FL_FREE(H5HF_free_section_t, sec_node); @@ -350,7 +517,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(dxpl_id, dblock, -(ssize_t)free_obj_size) < 0) + if(H5HF_man_dblock_adj_free(dblock, -(ssize_t)free_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 */ @@ -391,7 +558,7 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "inserting within mapped managed bl hdr->nobjs++; /* Mark heap header as modified */ - if(H5HF_hdr_dirty(dxpl_id, hdr) < 0) + if(H5HF_hdr_dirty(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") done: @@ -417,7 +584,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5HF_man_read(H5HF_t *hdr, hid_t dxpl_id, hsize_t obj_off, size_t obj_len, void *obj) +H5HF_man_read(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t obj_off, size_t obj_len, void *obj) { H5HF_direct_t *dblock; /* Pointer to direct block to query */ size_t blk_off; /* Offset of object in block */ @@ -441,11 +608,11 @@ HDfprintf(stderr, "%s: obj_off = %Hu, obj_len = %Zu\n", FUNC, obj_off, obj_len); /* Check for root direct block */ if(hdr->man_dtable.curr_root_rows == 0) { /* Set direct block info */ - dblock_addr = hdr->man_dtable.table_addr; - dblock_size = hdr->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(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, NULL, 0, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") } /* end if */ else { @@ -467,8 +634,8 @@ HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); HDfprintf(stderr, "%s: iblock_addr = %a\n", FUNC, iblock_addr); #endif /* QAK */ - /* Lock indirect block */ - if(NULL == (iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, iblock_addr, &hdr->man_dtable.curr_root_rows, hdr, H5AC_READ))) + /* Lock root indirect block */ + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, hdr->man_dtable.curr_root_rows, NULL, 0, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Check for indirect block row */ @@ -490,7 +657,7 @@ HDfprintf(stderr, "%s: entry = %Zu\n", FUNC, entry); new_iblock_addr = iblock->ents[entry].addr; /* Lock new indirect block */ - if(NULL == (new_iblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, new_iblock_addr, &nrows, hdr, H5AC_READ))) + if(NULL == (new_iblock = H5HF_man_iblock_protect(hdr, dxpl_id, new_iblock_addr, nrows, iblock, entry, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") /* Release the current indirect block */ @@ -525,7 +692,7 @@ HDfprintf(stderr, "%s: entry address = %a\n", FUNC, iblock->ents[entry].addr); dblock_size = hdr->man_dtable.row_block_size[row]; /* Lock direct block */ - if(NULL == (dblock = H5AC_protect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, &dblock_size, hdr, H5AC_READ))) + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, iblock, entry, H5AC_READ))) HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap direct block") /* Unlock indirect block */ diff --git a/src/H5HFiter.c b/src/H5HFiter.c new file mode 100644 index 0000000..90f2f14 --- /dev/null +++ b/src/H5HFiter.c @@ -0,0 +1,693 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5HFiter.c + * Apr 24 2006 + * Quincey Koziol + * + * Purpose: Block iteration routines for fractal heaps. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5HF_PACKAGE /*suppress error about including H5HFpkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5HFpkg.h" /* Fractal heaps */ +#include "H5Vprivate.h" /* Vectors and arrays */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5HF_block_loc_t struct */ +H5FL_DEFINE(H5HF_block_loc_t); + + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_init + * + * Purpose: Initialize a block iterator for walking over all the blocks + * in a fractal heap. (initialization finishes when iterator is + * actually used) + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_init(H5HF_block_iter_t *biter) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iter_init) + + /* + * Check arguments. + */ + HDassert(biter); + + /* Reset block iterator information */ + HDmemset(biter, 0, sizeof(H5HF_block_iter_t)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_man_iter_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_start_offset + * + * Purpose: Initialize a block iterator to a particular location, given + * an offset in the heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_start_offset(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_block_iter_t *biter, hsize_t offset) +{ + H5HF_indirect_t *iblock; /* Indirect block for location context */ + haddr_t iblock_addr; /* Address of indirect block */ + unsigned iblock_nrows; /* # of rows in indirect block */ + H5HF_indirect_t *iblock_parent; /* Parent indirect block of location context */ + unsigned iblock_par_entry; /* Entry within parent indirect block */ + hsize_t curr_offset; /* Current offset, as adjusted */ + unsigned row; /* Current row we are on */ + unsigned col; /* Column in row */ + hbool_t root_block = TRUE; /* Flag to indicate the current block is the root indirect block */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_start_offset) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(!biter->ready); + + /* Check for empty heap */ + HDassert(offset >= hdr->man_dtable.cparam.start_block_size); + + /* Allocate level structure */ + if(NULL == (biter->curr = H5FL_MALLOC(H5HF_block_loc_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + +/* +1: = offset> + + + + max_direct_rows> + + + + + + +*/ + do { + /* Walk down the rows in the doubling table until we've found the correct row for the next block */ + for(row = 0; row < hdr->man_dtable.max_root_rows; row++) + if((offset >= hdr->man_dtable.row_block_off[row]) && + (offset < hdr->man_dtable.row_block_off[row] + + (hdr->man_dtable.cparam.width * hdr->man_dtable.row_block_size[row]))) + break; + + /* Adjust offset by row offset */ + curr_offset = offset - hdr->man_dtable.row_block_off[row]; + + /* Compute column */ + col = curr_offset / hdr->man_dtable.row_block_size[row]; +#ifdef QAK +HDfprintf(stderr, "%s: row = %u, col = %u\n", FUNC, row, col); +HDfprintf(stderr, "%s: offset = %Hu\n", FUNC, offset); +HDfprintf(stderr, "%s: curr_offset = %Hu\n", FUNC, curr_offset); +#endif /* QAK */ + + /* Set the current level's context */ + biter->curr->row = row; + biter->curr->col = col; + biter->curr->entry = (row * hdr->man_dtable.cparam.width) + col; +#ifdef QAK +HDfprintf(stderr, "%s: biter->curr->entry = %u\n", FUNC, biter->curr->entry); +#endif /* QAK */ + + /* Get the context indirect block's information */ + if(root_block) { + iblock_addr = hdr->man_dtable.table_addr; + iblock_nrows = hdr->man_dtable.curr_root_rows; + iblock_parent = NULL; + iblock_par_entry = 0; + + /* The root block can't go up further... */ + biter->curr->up = NULL; + + /* Next time through the loop will not be with the root indirect block */ + root_block = FALSE; + } /* end if */ + else { + hsize_t child_size; /* Size of new indirect block to create */ + + /* Retrieve the parent information from the previous context location */ + iblock_parent = biter->curr->up->context; + iblock_par_entry = biter->curr->up->entry; + + /* Look up the address of context indirect block */ + iblock_addr = iblock_parent->ents[iblock_par_entry].addr; + + /* Compute # of rows in context indirect block */ + child_size = hdr->man_dtable.row_block_size[biter->curr->up->row]; + iblock_nrows = (H5V_log2_gen(child_size) - hdr->man_dtable.first_row_bits) + 1; + } /* end else */ + + /* Load indirect block for this context location */ + if(NULL == (iblock = H5HF_man_iblock_protect(hdr, dxpl_id, iblock_addr, iblock_nrows, iblock_parent, iblock_par_entry, H5AC_WRITE))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") + + /* Make indirect block the context for the current location */ + biter->curr->context = iblock; + + /* Hold the indirect block with the location */ + if(H5HF_iblock_incr(biter->curr->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + + /* Release the current indirect block */ + 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; + + /* See if the location falls in a direct block row */ + /* Or, if the offset has just filled up a direct or indirect block */ + if(curr_offset == (col * hdr->man_dtable.row_block_size[row]) || row < hdr->man_dtable.max_direct_rows) { + HDassert(curr_offset - (col * hdr->man_dtable.row_block_size[row]) == 0); + break; /* Done now */ + } /* end if */ + /* Indirect block row */ + else { + H5HF_block_loc_t *new_loc; /* Pointer to new block location */ + + /* Allocate level structure */ + if(NULL == (new_loc = H5FL_MALLOC(H5HF_block_loc_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + + /* Link new level into iterator */ + new_loc->up = biter->curr; + + /* Adjust offset for new level */ + offset = curr_offset - (col * hdr->man_dtable.row_block_size[row]); + + /* Make new block the current context */ + biter->curr = new_loc; + } /* end else */ + } while(1); /* Breaks out in middle */ + + /* Set flag to indicate block iterator finished initializing */ + biter->ready = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iter_start_offset() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_start + * + * Purpose: Initialize a block iterator to a particular location within + * an indirect block + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_start_entry(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, + H5HF_indirect_t *iblock, unsigned start_entry) +{ + H5HF_block_loc_t *new_loc; /* Pointer to new block location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_start_entry) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(biter); + HDassert(!biter->ready); + HDassert(iblock); + + /* Create new location for iterator */ + if(NULL == (new_loc = H5FL_MALLOC(H5HF_block_loc_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + + /* Set up location context */ + new_loc->entry = start_entry; + new_loc->row = start_entry / hdr->man_dtable.cparam.width; + new_loc->col = start_entry % hdr->man_dtable.cparam.width; + new_loc->context = iblock; + new_loc->up = NULL; + + /* Increment reference count on indirect block */ + if(H5HF_iblock_incr(new_loc->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + + /* Make new location the current location */ + biter->curr = new_loc; + + /* Set flag to indicate block iterator finished initializing */ + biter->ready = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iter_start_entry() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_reset + * + * Purpose: Reset a block iterator to it's initial state, freeing any + * location context it currently has + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_reset(H5HF_block_iter_t *biter) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_reset) + + /* + * Check arguments. + */ + HDassert(biter); + + /* Free any location contexts that exist */ + if(biter->curr) { + H5HF_block_loc_t *curr_loc; /* Pointer to current block location */ + H5HF_block_loc_t *next_loc; /* Pointer to next block location */ + + /* Free location contexts */ + curr_loc = biter->curr; + while(curr_loc) { + /* Get pointer to next node */ + next_loc = curr_loc->up; + + /* If this node is holding an indirect block, release the block */ + if(curr_loc->context) + if(H5HF_iblock_decr(curr_loc->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Free the current location context */ + H5FL_FREE(H5HF_block_loc_t, curr_loc); + + /* Advance to next location */ + curr_loc = next_loc; + } /* end while */ + + /* Reset top location context */ + biter->curr = NULL; + } /* end if */ + + /* Reset block iterator flags */ + biter->ready = FALSE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iter_reset() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_next + * + * Purpose: Advance to the next block within the current block of the heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_next(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, unsigned nentries) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iter_next) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(biter->curr); + HDassert(biter->curr->context); + + /* Advance to next entry in current block */ + HDassert(biter->curr->row < biter->curr->context->nrows); + if(nentries == 1) { + /* Increment block entry */ + biter->curr->entry++; + + /* Increment column */ + biter->curr->col++; + + /* Check for walking off end of column */ + if(biter->curr->col == hdr->man_dtable.cparam.width) { + /* Reset column */ + biter->curr->col = 0; + + /* Increment row & block size */ + biter->curr->row++; + } /* end if */ + } /* end if */ + /* Advance multiple entries */ + else { + biter->curr->entry += nentries; + biter->curr->row = biter->curr->entry / hdr->man_dtable.cparam.width; + biter->curr->col = biter->curr->entry % hdr->man_dtable.cparam.width; + } /* end else */ + HDassert(biter->curr->row <= biter->curr->context->nrows); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_man_iter_next() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_up + * + * Purpose: Move iterator up one level + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_up(H5HF_block_iter_t *biter) +{ + H5HF_block_loc_t *up_loc; /* Pointer to 'up' block location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_up) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(biter->ready); + HDassert(biter->curr); + HDassert(biter->curr->up); + HDassert(biter->curr->context); + + /* Release hold on current location's indirect block */ + if(H5HF_iblock_decr(biter->curr->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Get pointer to location context above this one */ + up_loc = biter->curr->up; + + /* Release this location */ + H5FL_FREE(H5HF_block_loc_t, biter->curr); + + /* Point location to next location up */ + biter->curr = up_loc; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iter_up() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_down + * + * Purpose: Move iterator down one level + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_down(H5HF_block_iter_t *biter, H5HF_indirect_t *iblock) +{ + H5HF_block_loc_t *down_loc; /* Pointer to new 'down' block location */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_down) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(biter->ready); + HDassert(biter->curr); + HDassert(biter->curr->context); + + /* Create new location to move down to */ + if(NULL == (down_loc = H5FL_MALLOC(H5HF_block_loc_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct block free list section") + + /* Initialize down location */ + down_loc->row = 0; + down_loc->col = 0; + down_loc->entry = 0; + down_loc->context = iblock; + down_loc->up = biter->curr; + + /* Increment reference count on indirect block */ + if(H5HF_iblock_incr(down_loc->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + + /* Make down location the current location */ + biter->curr = down_loc; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iter_down() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_update_iblock + * + * Purpose: Update indirect block for current iterator location + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_update_iblock(H5HF_block_iter_t *biter, H5HF_indirect_t *iblock) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_man_iter_update_iblock) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(biter->ready); + HDassert(biter->curr); + HDassert(biter->curr->context); + + /* Release hold on current location's indirect block */ + if(H5HF_iblock_decr(biter->curr->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block") + + /* Update current location's indirect block */ + biter->curr->context = iblock; + + /* Add hold to current location's indirect block */ + if(H5HF_iblock_incr(biter->curr->context) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared indirect block") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_man_iter_update_iblock() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_curr + * + * Purpose: Retrieve information about the current block iterator location + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 24 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_curr(H5HF_block_iter_t *biter, unsigned *row, unsigned *col, + unsigned *entry, H5HF_indirect_t **block) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iter_curr) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(biter->ready); + + /* Retrieve the information asked for */ + if(row) + *row = biter->curr->row; + if(col) + *col = biter->curr->col; + if(entry) + *entry = biter->curr->entry; + if(block) + *block = biter->curr->context; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_man_iter_curr() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_offset + * + * Purpose: Retrieve offset of iterator in heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_man_iter_offset(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, hsize_t *offset) +{ + hsize_t curr_offset; /* For computing offset in heap */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iter_offset) + + /* + * Check arguments. + */ + HDassert(biter); + HDassert(biter->ready); + HDassert(biter->curr->context); + HDassert(offset); + + /* Compute the offset in the heap */ + curr_offset = biter->curr->context->block_off; + curr_offset += hdr->man_dtable.row_block_off[biter->curr->row]; + curr_offset += biter->curr->col * hdr->man_dtable.row_block_size[biter->curr->row]; + + /* Assign the return value */ + *offset = curr_offset; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_man_iter_offset() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_man_iter_ready + * + * Purpose: Query if iterator is ready to use + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Apr 25 2006 + * + *------------------------------------------------------------------------- + */ +hbool_t +H5HF_man_iter_ready(H5HF_block_iter_t *biter) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_man_iter_ready) + + /* + * Check arguments. + */ + HDassert(biter); + + FUNC_LEAVE_NOAPI(biter->ready) +} /* end H5HF_man_iter_ready() */ + diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 1f1518b..af06770 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -79,6 +79,7 @@ + (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 alloacted 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 */ \ @@ -99,9 +100,6 @@ \ /* Fractal heap managed, absolutely mapped direct block specific fields */ \ + (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(s) /* Offset of first descriptor in free list */ \ ) @@ -111,9 +109,6 @@ \ /* Fractal heap managed, absolutely mapped direct block specific fields */ \ + (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 */ \ ) @@ -125,11 +120,7 @@ \ /* Fractal heap managed, absolutely mapped indirect block specific fields */ \ + (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, (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 */ \ ) @@ -148,7 +139,7 @@ typedef struct H5HF_dtable_t { /* Immutable, pre-set information for table */ H5HF_dtable_cparam_t cparam; /* Creation parameters for table */ - /* Derived information (stored, vary during lifetime of table) */ + /* Derived information (stored, varies during lifetime of table) */ haddr_t table_addr; /* Address of first block for table */ /* Undefined if no space allocated for table */ unsigned curr_root_rows; /* Current number of rows in the root indirect block */ @@ -175,46 +166,34 @@ typedef struct H5HF_dtable_t { /* Fractal heap free list info (forward decl - defined in H5HFflist.c) */ typedef struct H5HF_freelist_t H5HF_freelist_t; -/* Fractal heap free list section info */ -typedef struct H5HF_free_section_t { - haddr_t sect_addr; /* Address of free list section in the file */ - /* (Not actually used as address, used as unique ID for free list node) */ - size_t sect_size; /* Size of free space section */ - /* (section size is "object size", without the metadata overhead, since metadata overhead varies from block to block) */ - /* (for range sections, this is the largest single section within the range) */ - enum {H5HF_SECT_SINGLE, H5HF_SECT_RANGE, H5HF_SECT_INDIRECT} type; /* Type of free space section */ - union { - struct { - haddr_t dblock_addr; /* Address of direct block for free section */ - size_t dblock_size; /* Size of direct block */ - /* (Needed to retrieve direct block) */ - } single; - struct { - haddr_t iblock_addr; /* Address of indirect block for free section */ - unsigned iblock_nrows; /* Number of rows in indirect block */ - /* (Needed to retrieve indirect block) */ - unsigned row; /* Row for range of blocks */ - unsigned col; /* Column for range of blocks */ - unsigned num_entries; /* Number of entries covered */ - } range; - struct { - haddr_t iblock_addr; /* Address of indirect block for free section */ - unsigned iblock_nrows; /* Number of rows in indirect block */ - /* (Needed to retrieve indirect block) */ - unsigned row; /* Row for range of blocks */ - unsigned col; /* Column for range of blocks */ - unsigned num_entries; /* Number of entries covered */ - unsigned indir_row; /* Row for indirect range of blocks */ - unsigned indir_nrows; /* Number of rows in indirect blocks */ - } indirect; - } u; -} H5HF_free_section_t; +/* Forward decl indirect block info */ +typedef struct H5HF_indirect_t H5HF_indirect_t; + +/* Fractal heap block location */ +typedef struct H5HF_block_loc_t { + /* Necessary table fields */ + unsigned row; /* Row of block in doubling table */ + unsigned col; /* Column of block in doubling table */ + + /* Derived/computed/cached table fields */ + unsigned entry; /* Entry of block in doubling table */ + + /* Infrastructure */ + H5HF_indirect_t *context; /* Pointer to the indirect block containing the block */ + struct H5HF_block_loc_t *up; /* Pointer to next level up in the stack of levels */ +} H5HF_block_loc_t; + +/* Fractal heap block iterator info */ +typedef struct H5HF_block_iter_t { + hbool_t ready; /* Set if iterator is finished initializing */ + H5HF_block_loc_t *curr; /* Pointer to the current level information for iterator */ +} H5HF_block_iter_t; /* 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_t { +typedef struct H5HF_hdr_t { /* Information for H5AC cache functions, _must_ be first field in structure */ H5AC_info_t cache_info; @@ -225,20 +204,28 @@ typedef struct H5HF_t { /* Statistics for heap */ hsize_t total_size; /* Total amount of space used by heap (managed & standalone) */ hsize_t man_size; /* Total amount of managed space in heap */ + hsize_t man_alloc_size; /* Total amount of allocated managed space in heap */ hsize_t std_size; /* Total amount of standalone space in heap */ 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 */ - H5HF_freelist_t *flist; /* Free list for objects in heap */ size_t id_len; /* Size of heap IDs */ + H5HF_freelist_t *flist; /* Free list for objects in heap */ + unsigned fl_gen; /* Free list "generation" */ + H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */ + hbool_t freelist_sync; /* If the heap's free list in memory is in sync with the free list on disk */ + /* (ie. all existing blocks have been scanned + * for free space (or heap is new and there are + * no blocks with unknown free space) and new + * free space is added by adding new blocks) + */ /* Doubling table information */ /* (Partially set by user, partially derived/updated internally) */ @@ -254,7 +241,7 @@ typedef struct H5HF_t { 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_t; +} H5HF_hdr_t; /* Indirect block entry */ typedef struct H5HF_indirect_ent_t { @@ -264,33 +251,27 @@ typedef struct H5HF_indirect_ent_t { } H5HF_indirect_ent_t; /* Fractal heap indirect block */ -typedef struct H5HF_indirect_t { +struct H5HF_indirect_t { /* Information for H5AC cache functions, _must_ be first field in structure */ H5AC_info_t cache_info; - /* Internal heap information */ + /* Internal heap information (not stored) */ 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 */ + H5HF_hdr_t *hdr; /* Shared heap header info */ + unsigned fl_gen; /* Free list "generation" */ struct H5HF_indirect_t *parent; /* Shared parent indirect block info */ + unsigned par_entry; /* Entry in parent's table */ 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; + H5HF_indirect_ent_t *ents; /* Pointer to block entry table */ +}; /* Direct block free list node */ typedef struct H5HF_direct_free_node_t { @@ -314,8 +295,10 @@ typedef struct H5HF_direct_t { H5AC_info_t cache_info; /* Internal heap information */ - H5HF_t *shared; /* Shared heap header info */ + H5HF_hdr_t *hdr; /* Shared heap header info */ + unsigned fl_gen; /* Free list "generation" */ H5HF_indirect_t *parent; /* Shared parent indirect block info */ + unsigned par_entry; /* Entry in parent's table */ 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 */ @@ -323,13 +306,16 @@ typedef struct H5HF_direct_t { 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 free_list_head; /* Offset of head of free list in block */ } H5HF_direct_t; +/* Fractal heap */ +struct H5HF_t { + H5HF_hdr_t *hdr; /* Pointer to internal fractal heap header info */ + unsigned fo_count; /* Open object count for file */ +}; + /* Fractal heap metadata statistics info */ typedef struct H5HF_stat_t { hsize_t total_size; /* Total size of heap allocated (man & std) */ @@ -339,6 +325,56 @@ typedef struct H5HF_stat_t { hsize_t nobjs; /* Number of objects in heap */ } H5HF_stat_t; +/* Fractal heap free list section info */ +typedef struct H5HF_free_section_t { + haddr_t sect_addr; /* Address of free list section in the file */ + /* (Not actually used as address, used as unique ID for free list node) */ + size_t sect_size; /* Size of free space section */ + /* (section size is "object size", without the metadata overhead, since metadata overhead varies from block to block) */ + /* (for range sections, this is the largest single section within the range) */ + enum { + H5HF_SECT_SINGLE, /* Section is actual bytes in a direct block */ + H5HF_SECT_OPAQUE, /* Section is an opaque # of bytes in child of an indirect block */ + H5HF_SECT_RANGE, /* Section is a range of direct blocks in an indirect block row */ + H5HF_SECT_INDIRECT} /* Section is a range of _indirect_ blocks in an indirect block row */ + type; /* Type of free space section */ + union { + struct { + H5HF_indirect_t *parent; /* Indirect block parent for free section's direct block */ + unsigned par_entry; /* Entry of free section's direct block in parent indirect block */ + /* (Needed to retrieve direct block) */ + + haddr_t dblock_addr; /* Address of direct block for free section */ + size_t dblock_size; /* Size of direct block */ + /* (Needed to retrieve direct block) */ + } single; + struct { + H5HF_indirect_t *iblock; /* Indirect block parent for free section's child block */ + unsigned entry; /* Entry of free section's child block in parent indirect block */ + } opaque; + struct { + H5HF_indirect_t *iblock; /* Indirect block for free section */ + unsigned row; /* Row for range of blocks */ + unsigned col; /* Column for range of blocks */ + unsigned num_entries; /* Number of entries covered */ + } range; + struct { + H5HF_indirect_t *iblock; /* Indirect block for free section */ + unsigned row; /* Row for range of blocks */ + unsigned col; /* Column for range of blocks */ + unsigned num_entries; /* Number of entries covered */ + unsigned indir_row; /* Row for indirect range of blocks */ + unsigned indir_nrows; /* Number of rows in indirect blocks */ + } indirect; + } u; +} H5HF_free_section_t; + +/* Fractal heap "parent info" (for loading a block) */ +typedef struct H5HF_parent_t { + H5HF_hdr_t *hdr; /* Pointer to heap header info */ + H5HF_indirect_t *iblock; /* Pointer to parent indirect block */ + unsigned entry; /* Location of block in parent's entry table */ +} H5HF_parent_t; /*****************************/ /* Package Private Variables */ @@ -353,8 +389,8 @@ H5_DLLVAR const H5AC_class_t H5AC_FHEAP_DBLOCK[1]; /* H5HF indirect block inherits cache-like properties from H5AC */ H5_DLLVAR const H5AC_class_t H5AC_FHEAP_IBLOCK[1]; -/* Declare a free list to manage the H5HF_t struct */ -H5FL_EXTERN(H5HF_t); +/* Declare a free list to manage the H5HF_hdr_t struct */ +H5FL_EXTERN(H5HF_hdr_t); /* Declare a free list to manage the H5HF_direct_t struct */ H5FL_EXTERN(H5HF_direct_t); @@ -383,57 +419,68 @@ H5FL_EXTERN(H5HF_free_section_t); /******************************/ /* Routines for managing shared fractal heap header */ -H5_DLL H5HF_t * H5HF_hdr_alloc(H5F_t *f); -H5_DLL herr_t H5HF_hdr_init(H5HF_t *hdr, haddr_t heap_addr, H5HF_create_t *cparam); -H5_DLL herr_t H5HF_hdr_finish_init(H5HF_t *hdr); +H5_DLL H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f); +H5_DLL herr_t H5HF_hdr_init(H5HF_hdr_t *hdr, haddr_t fh_addr, H5HF_create_t *cparam); +H5_DLL herr_t H5HF_hdr_finish_init(H5HF_hdr_t *hdr); /* Doubling table routines */ H5_DLL herr_t H5HF_dtable_init(H5HF_dtable_t *dtable); H5_DLL herr_t H5HF_dtable_dest(H5HF_dtable_t *dtable); H5_DLL herr_t H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off, unsigned *row, unsigned *col); +H5_DLL unsigned H5HF_dtable_size_to_row(H5HF_dtable_t *dtable, size_t block_size); /* 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); -H5_DLL herr_t H5HF_hdr_dirty(hid_t dxpl_id, H5HF_t *hdr); -H5_DLL herr_t H5HF_hdr_extend_heap(H5HF_t *hdr, hsize_t new_size, hsize_t extra_free); +H5_DLL herr_t H5HF_hdr_incr(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_decr(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_dirty(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_hdr_extend_heap(H5HF_hdr_t *hdr, hsize_t new_size, hsize_t extra_free); +H5_DLL herr_t H5HF_hdr_inc_alloc(H5HF_hdr_t *hdr, hsize_t new_alloc_size, + unsigned nentries); /* Indirect block routines */ -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); -H5_DLL herr_t H5HF_iblock_dirty(hid_t dxpl_id, H5HF_indirect_t *iblock); -H5_DLL 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); -H5_DLL herr_t H5HF_man_iblock_alloc_range(H5HF_t *hdr, hid_t dxpl_id, - H5HF_free_section_t **sec_node, size_t obj_size); -H5_DLL herr_t H5HF_man_iblock_alloc_indirect(H5HF_t *hdr, hid_t dxpl_id, - H5HF_free_section_t **sec_node, size_t obj_size); +H5_DLL herr_t H5HF_iblock_dirty(H5HF_indirect_t *iblock); +H5_DLL H5HF_indirect_t * H5HF_man_iblock_place_dblock(H5HF_hdr_t *fh, hid_t dxpl_id, + size_t min_dblock_size, size_t *entry_p, size_t *dblock_size); +H5_DLL herr_t H5HF_man_iblock_alloc_range(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t **sec_node); +H5_DLL herr_t H5HF_man_iblock_alloc_indirect(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t **sec_node); +H5_DLL herr_t H5HF_man_iblock_alloc_opaque(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t **sec_node); +H5_DLL H5HF_indirect_t *H5HF_man_iblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, + haddr_t iblock_addr, unsigned iblock_nrows, + H5HF_indirect_t *par_iblock, unsigned par_entry, + H5AC_protect_t rw); /* Direct block routines */ -H5_DLL herr_t H5HF_man_dblock_new(H5HF_t *fh, hid_t dxpl_id, size_t request); -H5_DLL herr_t H5HF_man_dblock_create(hid_t dxpl_id, H5HF_t *hdr, +H5_DLL herr_t H5HF_man_dblock_new(H5HF_hdr_t *fh, hid_t dxpl_id, size_t request); +H5_DLL herr_t H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr); +H5_DLL herr_t H5HF_man_dblock_destroy_freelist(H5HF_direct_t *dblock); +H5_DLL herr_t H5HF_man_dblock_adj_free(H5HF_direct_t *dblock, ssize_t amt); +H5_DLL herr_t H5HF_man_dblock_create(hid_t dxpl_id, H5HF_hdr_t *hdr, H5HF_indirect_t *par_iblock, unsigned par_entry, size_t block_size, hsize_t block_off, haddr_t *addr_p, H5HF_free_section_t **ret_sec_node); -H5_DLL herr_t H5HF_man_dblock_adj_free(hid_t dxpl_id, H5HF_direct_t *dblock, ssize_t amt); -H5_DLL herr_t H5HF_man_dblock_build_freelist(H5HF_direct_t *dblock, haddr_t dblock_addr); +H5_DLL H5HF_direct_t *H5HF_man_dblock_protect(H5HF_hdr_t *hdr, hid_t dxpl_id, + haddr_t dblock_addr, size_t dblock_size, + H5HF_indirect_t *par_iblock, unsigned par_entry, + H5AC_protect_t rw); /* Routines for internal operations */ H5_DLL herr_t H5HF_free_section_free_cb(void *item, void UNUSED *key, void UNUSED *op_data); -H5_DLL herr_t H5HF_man_find(H5HF_t *fh, hid_t dxpl_id, size_t request, +H5_DLL herr_t H5HF_man_find(H5HF_hdr_t *fh, hid_t dxpl_id, size_t request, H5HF_free_section_t **sec_node/*out*/); -H5_DLL herr_t H5HF_man_insert(H5HF_t *fh, hid_t dxpl_id, +H5_DLL herr_t H5HF_man_insert(H5HF_hdr_t *fh, hid_t dxpl_id, H5HF_free_section_t *sec_node, size_t obj_size, const void *obj, void *id); -H5_DLL herr_t H5HF_man_read(H5HF_t *fh, hid_t dxpl_id, hsize_t obj_off, +H5_DLL herr_t H5HF_man_read(H5HF_hdr_t *fh, hid_t dxpl_id, hsize_t obj_off, size_t obj_len, void *obj); /* Metadata cache callbacks */ -H5_DLL herr_t H5HF_cache_hdr_dest(H5F_t *f, H5HF_t *fh); +H5_DLL herr_t H5HF_cache_hdr_dest(H5F_t *f, H5HF_hdr_t *fh); H5_DLL herr_t H5HF_cache_dblock_dest(H5F_t *f, H5HF_direct_t *dblock); H5_DLL herr_t H5HF_cache_iblock_dest(H5F_t *f, H5HF_indirect_t *iblock); @@ -446,24 +493,40 @@ H5_DLL 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); /* Statistics routines */ -H5_DLL herr_t H5HF_stat_info(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, - H5HF_stat_t *stats); +H5_DLL herr_t H5HF_stat_info(H5HF_t *fh, H5HF_stat_t *stats); /* Free list routines */ -H5_DLL H5HF_freelist_t * H5HF_flist_create(size_t max_block_size, +H5_DLL H5HF_freelist_t * H5HF_flist_create(unsigned max_index_bits, H5SL_operator_t node_free_op); H5_DLL herr_t H5HF_flist_add(H5HF_freelist_t *flist, void *node, size_t *size_key, haddr_t *addr_key); H5_DLL htri_t H5HF_flist_find(H5HF_freelist_t *flist, size_t request, void **node); +H5_DLL herr_t H5HF_flist_reset(H5HF_freelist_t *flist); H5_DLL herr_t H5HF_flist_free(H5HF_freelist_t *flist); +/* Block iteration routines */ +H5_DLL herr_t H5HF_man_iter_init(H5HF_block_iter_t *biter); +H5_DLL herr_t H5HF_man_iter_start_offset(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_block_iter_t *biter, hsize_t offset); +H5_DLL herr_t H5HF_man_iter_start_entry(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, + H5HF_indirect_t *iblock, unsigned start_entry); +H5_DLL herr_t H5HF_man_iter_next(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, + unsigned nentries); +H5_DLL herr_t H5HF_man_iter_up(H5HF_block_iter_t *biter); +H5_DLL herr_t H5HF_man_iter_down(H5HF_block_iter_t *biter, H5HF_indirect_t *iblock); +H5_DLL herr_t H5HF_man_iter_reset(H5HF_block_iter_t *biter); +H5_DLL herr_t H5HF_man_iter_update_iblock(H5HF_block_iter_t *biter, H5HF_indirect_t *iblock); +H5_DLL herr_t H5HF_man_iter_curr(H5HF_block_iter_t *biter, unsigned *row, unsigned *col, + unsigned *entry, H5HF_indirect_t **block); +H5_DLL herr_t H5HF_man_iter_offset(H5HF_hdr_t *hdr, H5HF_block_iter_t *biter, + hsize_t *offset); +H5_DLL hbool_t H5HF_man_iter_ready(H5HF_block_iter_t *biter); + /* Testing routines */ #ifdef H5HF_TESTING -H5_DLL herr_t H5HF_get_cparam_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, - H5HF_create_t *cparam); -H5_DLL hsize_t H5HF_get_dblock_free_test(H5F_t *f, hid_t dxpl_id, - haddr_t fh_addr, unsigned row); +H5_DLL herr_t H5HF_get_cparam_test(H5HF_t *fh, H5HF_create_t *cparam); +H5_DLL hsize_t H5HF_get_dblock_free_test(H5HF_t *fh, unsigned row); #endif /* H5HF_TESTING */ #endif /* _H5HFpkg_H */ diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index f97008c..455f426 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -67,6 +67,9 @@ typedef struct H5HF_create_t { /* (i.e. max. size of object to manage) */ } H5HF_create_t; +/* Fractal heap info (forward decl - defined in H5HFpkg.h) */ +typedef struct H5HF_t H5HF_t; + /*****************************/ /* Library-private Variables */ @@ -75,13 +78,15 @@ typedef struct H5HF_create_t { /***************************************/ /* Library-private Function Prototypes */ /***************************************/ -H5_DLL herr_t H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam, - haddr_t *addr_p, size_t *id_len_p); -H5_DLL herr_t H5HF_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size, +H5_DLL H5HF_t *H5HF_create(H5F_t *f, hid_t dxpl_id, H5HF_create_t *cparam); +H5_DLL H5HF_t *H5HF_open(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr); +H5_DLL herr_t H5HF_get_id_len(H5HF_t *fh, size_t *id_len_p); +H5_DLL herr_t H5HF_get_heap_addr(H5HF_t *fh, haddr_t *heap_addr); +H5_DLL herr_t H5HF_insert(H5HF_t *fh, hid_t dxpl_id, size_t size, const void *obj, void *id/*out*/); -H5_DLL herr_t H5HF_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *id, +H5_DLL herr_t H5HF_read(H5HF_t *fh, hid_t dxpl_id, const void *id, void *obj/*out*/); +H5_DLL herr_t H5HF_close(H5HF_t *fh); #endif /* _H5HFprivate_H */ - diff --git a/src/H5HFstat.c b/src/H5HFstat.c index 93e8036..693a6fa 100644 --- a/src/H5HFstat.c +++ b/src/H5HFstat.c @@ -83,35 +83,22 @@ *------------------------------------------------------------------------- */ herr_t -H5HF_stat_info(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_stat_t *stats) +H5HF_stat_info(H5HF_t *fh, H5HF_stat_t *stats) { - H5HF_t *hdr = NULL; /* Pointer to the fractal heap header */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5HF_stat_info) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_stat_info) /* Check arguments. */ - HDassert(f); - HDassert(H5F_addr_defined(fh_addr)); + HDassert(fh); HDassert(stats); - /* Look up the fractal heap header */ - 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") - /* Report statistics for fractal heap */ - 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; + stats->total_size = fh->hdr->total_size; + stats->man_size = fh->hdr->man_size; + stats->std_size = fh->hdr->std_size; + stats->man_free_space = fh->hdr->total_man_free; + stats->nobjs = fh->hdr->nobjs; /* XXX: Add more metadata statistics for the heap */ -done: - /* Release fractal heap header node */ - 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) + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_stat_info() */ diff --git a/src/H5HFtest.c b/src/H5HFtest.c index c01475c..4b627fd 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -84,33 +84,20 @@ *------------------------------------------------------------------------- */ herr_t -H5HF_get_cparam_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, H5HF_create_t *cparam) +H5HF_get_cparam_test(H5HF_t *fh, H5HF_create_t *cparam) { - 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) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_get_cparam_test) /* Check arguments. */ - HDassert(f); - HDassert(H5F_addr_defined(fh_addr)); + HDassert(fh); HDassert(cparam); - /* Look up the fractal heap header */ - 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 fractal heap creation parameters */ - 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(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") + cparam->addrmap = fh->hdr->addrmap; + cparam->standalone_size = fh->hdr->standalone_size; + HDmemcpy(&(cparam->managed), &(fh->hdr->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t)); - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_get_cparam_test() */ @@ -130,28 +117,17 @@ done: *------------------------------------------------------------------------- */ hsize_t -H5HF_get_dblock_free_test(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr, unsigned row) +H5HF_get_dblock_free_test(H5HF_t *fh, unsigned row) { - H5HF_t *hdr = NULL; /* Pointer to the fractal heap header */ hsize_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_get_dblock_free_test) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_get_dblock_free_test) /* Check arguments. */ - HDassert(f); - HDassert(H5F_addr_defined(fh_addr)); - - /* Look up the fractal heap header */ - if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, 0, "unable to load fractal heap header") + HDassert(fh); /* Return direct block free space */ - ret_value = hdr->man_dtable.row_dblock_free[row]; - -done: - /* Release fractal heap header node */ - if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, 0, "unable to release fractal heap header info") + ret_value = fh->hdr->man_dtable.row_dblock_free[row]; FUNC_LEAVE_NOAPI(ret_value) } /* H5HF_get_dblock_free_test() */ diff --git a/src/Makefile.am b/src/Makefile.am index 662a97c..bcba38a 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -56,7 +56,7 @@ libhdf5_la_SOURCES= H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5Gtest.c \ H5Gtraverse.c \ H5HF.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c H5HFflist.c \ - H5HFhdr.c H5HFiblock.c H5HFint.c H5HFstat.c H5HFtest.c \ + H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFstat.c H5HFtest.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ H5MP.c H5MPtest.c \ H5O.c \ diff --git a/src/Makefile.in b/src/Makefile.in index af7cec2..96c3f56 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -94,7 +94,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5dbg.lo H5A.lo H5AC.lo H5B.lo \ H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo \ H5Gstab.lo H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFcache.lo \ H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFflist.lo H5HFhdr.lo \ - H5HFiblock.lo H5HFint.lo H5HFstat.lo H5HFtest.lo H5HG.lo \ + H5HFiblock.lo H5HFint.lo H5HFiter.lo H5HFstat.lo H5HFtest.lo H5HG.lo \ H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5MF.lo H5MM.lo \ H5MP.lo H5MPtest.lo H5O.lo H5Oattr.lo H5Obogus.lo H5Ocache.lo \ H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ @@ -411,7 +411,7 @@ libhdf5_la_SOURCES = H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5Gtest.c \ H5Gtraverse.c \ H5HF.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c H5HFflist.c \ - H5HFhdr.c H5HFiblock.c H5HFint.c H5HFstat.c H5HFtest.c \ + H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFstat.c H5HFtest.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ H5MP.c H5MPtest.c \ H5O.c \ @@ -626,6 +626,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFhdr.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFiblock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFint.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFiter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFstat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HG.Plo@am__quote@ diff --git a/test/fheap.c b/test/fheap.c index 76b9021..3092d5a 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -47,19 +47,35 @@ /* #define ALL_INSERT_TESTS */ /* Heap metadata macros */ -#define DBLOCK_OVERHEAD 32 /* # of bytes in direct block overhead */ +#define DBLOCK_OVERHEAD 20 /* # of bytes in direct block overhead */ #define OBJ_PREFIX_LEN 1 /* # of bytes in object prefix overhead */ #define HEAP_ID_LEN 12 /* # of bytes to use for heap ID */ -#define DBLOCK_FREE(f, dxpl, a, r) H5HF_get_dblock_free_test(f, dxpl, a, r) +#define DBLOCK_FREE(fh, r) H5HF_get_dblock_free_test(fh, r) const char *FILENAME[] = { "fheap", NULL }; -static int check_stats(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t total_size, +/* Testing parameters */ +typedef struct fheap_test_param_t { + hbool_t reopen_heap; /* Whether to re-open the heap during the test */ +} fheap_test_param_t; + +/* Types of tests to perform */ +typedef enum { + FHEAP_TEST_NORMAL, /* "Normal" test, with no testing parameters set */ + FHEAP_TEST_REOPEN, /* Set the reopen_heap flag */ + FHEAP_TEST_NTESTS /* The number of test types, must be last */ +} fheap_test_type_t; + + +/* Local routines */ +static int init_small_cparam(H5HF_create_t *cparam); +static int check_stats(H5HF_t *fh, hsize_t total_size, hsize_t man_size, hsize_t std_size, hsize_t man_free_space, hsize_t nobjs); + /*------------------------------------------------------------------------- * Function: init_small_cparam @@ -112,13 +128,13 @@ init_small_cparam(H5HF_create_t *cparam) *------------------------------------------------------------------------- */ static int -check_stats(H5F_t *f, hid_t dxpl, haddr_t fh_addr, hsize_t total_size, +check_stats(H5HF_t *fh, hsize_t total_size, hsize_t man_size, hsize_t std_size, hsize_t man_free_space, hsize_t nobjs) { H5HF_stat_t heap_stats; /* Statistics about the heap */ /* Get statistics for heap and verify they are correct */ - if(H5HF_stat_info(f, dxpl, fh_addr, &heap_stats) < 0) + if(H5HF_stat_info(fh, &heap_stats) < 0) FAIL_STACK_ERROR if(heap_stats.total_size != total_size) { HDfprintf(stdout, "heap_stats.total_size = %Hu, total_size = %Hu\n", heap_stats.total_size, total_size); @@ -164,7 +180,7 @@ error: *------------------------------------------------------------------------- */ static int -add_obj(H5F_t *f, hid_t dxpl, haddr_t fh_addr, +add_obj(H5HF_t *fh, hid_t dxpl, hsize_t heap_size, hsize_t *free_space, unsigned *nobjs_ptr, unsigned obj_init, size_t obj_size, hbool_t will_fill_heap) { @@ -184,7 +200,7 @@ add_obj(H5F_t *f, hid_t dxpl, haddr_t fh_addr, /* Insert object */ HDmemset(heap_id, 0, sizeof(heap_id)); - if(H5HF_insert(f, dxpl, fh_addr, obj_size, obj, heap_id) < 0) + if(H5HF_insert(fh, dxpl, obj_size, obj, heap_id) < 0) FAIL_STACK_ERROR /* Increment the number of objects */ @@ -192,12 +208,12 @@ add_obj(H5F_t *f, hid_t dxpl, haddr_t fh_addr, /* Check free space left in heap */ *free_space -= obj_size + (will_fill_heap ? 0 : OBJ_PREFIX_LEN); - if(check_stats(f, H5P_DATASET_XFER_DEFAULT, fh_addr, heap_size, heap_size, (hsize_t)0, *free_space, (hsize_t)*nobjs_ptr)) + if(check_stats(fh, heap_size, heap_size, (hsize_t)0, *free_space, (hsize_t)*nobjs_ptr)) FAIL_STACK_ERROR /* Read in object */ robj = H5MM_malloc(obj_size); - if(H5HF_read(f, dxpl, fh_addr, heap_id, robj) < 0) + if(H5HF_read(fh, dxpl, heap_id, robj) < 0) FAIL_STACK_ERROR if(HDmemcmp(obj, robj, obj_size)) FAIL_STACK_ERROR @@ -230,7 +246,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_heap(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t heap_size, size_t block_size, hsize_t extra_free, unsigned *nobjs_ptr) { @@ -261,7 +277,7 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, /* Insert first object */ HDmemset(heap_id, 0, sizeof(heap_id)); - if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, heap_id) < 0) + if(H5HF_insert(fh, dxpl, sizeof(obj), obj, heap_id) < 0) FAIL_STACK_ERROR /* Increment object count */ @@ -280,11 +296,11 @@ fill_heap(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, HDfprintf(stderr, "extra_free = %Hu\n", extra_free); HDfprintf(stderr, "free_space = %Hu\n", free_space); #endif /* QAK */ - if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)(*nobjs_ptr + num_ids))) + if(check_stats(fh, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)(*nobjs_ptr + num_ids))) FAIL_STACK_ERROR /* Get statistics for heap */ - if(H5HF_stat_info(f, dxpl, fh_addr, &heap_stats) < 0) + if(H5HF_stat_info(fh, &heap_stats) < 0) FAIL_STACK_ERROR /* Loop over inserting objects into the root direct block, until there's no more space */ @@ -295,7 +311,7 @@ HDfprintf(stderr, "free_space = %Hu\n", free_space); obj[u] = u + num_ids; HDmemset(heap_id, 0, sizeof(heap_id)); - if(H5HF_insert(f, dxpl, fh_addr, sizeof(obj), obj, heap_id) < 0) + if(H5HF_insert(fh, dxpl, sizeof(obj), obj, heap_id) < 0) FAIL_STACK_ERROR /* Increment object count */ @@ -319,11 +335,11 @@ HDfprintf(stderr, "free_frag_size = %u\n", free_frag_size); #ifdef QAK HDfprintf(stderr, "free_space = %Hu\n", free_space); #endif /* QAK */ - if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)(num_ids + *nobjs_ptr))) + if(check_stats(fh, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)(num_ids + *nobjs_ptr))) FAIL_STACK_ERROR /* Get statistics for heap */ - if(H5HF_stat_info(f, dxpl, fh_addr, &heap_stats) < 0) + if(H5HF_stat_info(fh, &heap_stats) < 0) FAIL_STACK_ERROR } /* end while */ @@ -337,7 +353,7 @@ HDfprintf(stderr, "free_space = %Hu\n", free_space); /* Insert last object into the heap, using the remaining free space */ HDmemset(heap_id, 0, sizeof(heap_id)); - if(H5HF_insert(f, dxpl, fh_addr, last_obj_len, obj, heap_id) < 0) + if(H5HF_insert(fh, dxpl, last_obj_len, obj, heap_id) < 0) FAIL_STACK_ERROR /* Increment object count */ @@ -352,7 +368,7 @@ HDfprintf(stderr, "free_space = %Hu\n", free_space); HDmemcpy(&ids[(num_ids - 1) * HEAP_ID_LEN], heap_id, HEAP_ID_LEN); /* Verify that the heap is full */ - if(check_stats(f, dxpl, fh_addr, heap_size, heap_size, (hsize_t)0, extra_free, (hsize_t)(num_ids + *nobjs_ptr))) + if(check_stats(fh, heap_size, heap_size, (hsize_t)0, extra_free, (hsize_t)(num_ids + *nobjs_ptr))) FAIL_STACK_ERROR } /* end if */ else @@ -365,7 +381,7 @@ HDfprintf(stderr, "free_space = %Hu\n", free_space); obj[u] = u + v; /* Read in object */ - if(H5HF_read(f, dxpl, fh_addr, &ids[v * HEAP_ID_LEN], robj) < 0) + if(H5HF_read(fh, dxpl, &ids[v * HEAP_ID_LEN], robj) < 0) FAIL_STACK_ERROR if(HDmemcmp(obj, robj, (v == (num_ids - 1) ? last_obj_len : sizeof(obj)))) FAIL_STACK_ERROR @@ -399,7 +415,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_root_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_root_row(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *base_heap_size, hsize_t *base_free_space, unsigned row, unsigned *nobjs_ptr) { @@ -435,16 +451,16 @@ fill_root_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam /* Compute first block & all blocks heap size & free space */ if(*base_heap_size == 0) { first_heap_size = block_size; - first_free_space = DBLOCK_FREE(f, dxpl, fh_addr, row); + first_free_space = DBLOCK_FREE(fh, row); all_heap_size = cparam->managed.width * block_size; - all_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(f, dxpl, fh_addr, row); + all_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, row); } /* end if */ else if(expand_rows ==0) { all_heap_size = *base_heap_size; all_free_space = *base_free_space; first_heap_size = all_heap_size; first_free_space = all_free_space; - all_free_space -= DBLOCK_FREE(f, dxpl, fh_addr, row); /* Account for shift from first free space */ + all_free_space -= DBLOCK_FREE(fh, row); /* Account for shift from first free space */ } /* end if */ else { hsize_t block_mult; /* Base block size multiplier */ @@ -454,12 +470,12 @@ fill_root_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam block_mult = 1; for(u = 0; u < expand_rows; u++) { all_heap_size += cparam->managed.width * block_size * block_mult; - all_free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, row + u); + all_free_space += cparam->managed.width * DBLOCK_FREE(fh, row + u); block_mult *= 2; } /* end for */ first_heap_size = all_heap_size; first_free_space = all_free_space; - all_free_space -= DBLOCK_FREE(f, dxpl, fh_addr, row); /* Account for shift from first free space */ + all_free_space -= DBLOCK_FREE(fh, row); /* Account for shift from first free space */ } /* end else */ /* Loop over filling direct blocks, until first root indirect row is full */ @@ -471,10 +487,10 @@ fill_root_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam heap_size = all_heap_size; free_space = all_free_space; } /* end if */ - free_space -= DBLOCK_FREE(f, dxpl, fh_addr, row); + free_space -= DBLOCK_FREE(fh, row); /* Fill a direct heap block up */ - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, block_size, free_space, nobjs_ptr)) + if(fill_heap(fh, dxpl, cparam, heap_size, block_size, free_space, nobjs_ptr)) FAIL_STACK_ERROR } /* end for */ @@ -505,7 +521,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_row(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned row, unsigned *nobjs_ptr) { @@ -526,8 +542,8 @@ fill_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, /* Loop over filling direct blocks, until indirect row is full */ for(u = 0; u < cparam->managed.width; u++) { /* Fill a direct heap block up */ - *free_space -= DBLOCK_FREE(f, dxpl, fh_addr, row); - if(fill_heap(f, dxpl, fh_addr, cparam, *heap_size, block_size, *free_space, nobjs_ptr)) + *free_space -= DBLOCK_FREE(fh, row); + if(fill_heap(fh, dxpl, cparam, *heap_size, block_size, *free_space, nobjs_ptr)) FAIL_STACK_ERROR } /* end for */ @@ -557,7 +573,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_root_direct(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_root_direct(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs) { size_t block_size; /* Size of block added */ @@ -567,7 +583,7 @@ fill_root_direct(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cpa block_size = cparam->managed.start_block_size; nrows = 0; while(block_size <= cparam->managed.max_direct_size) { - if(fill_root_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nrows, nobjs)) + if(fill_root_row(fh, dxpl, cparam, heap_size, free_space, nrows, nobjs)) FAIL_STACK_ERROR /* Adjust block size for row */ @@ -603,10 +619,11 @@ error: *------------------------------------------------------------------------- */ static int -fill_2nd_indirect(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_2nd_indirect(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs, - size_t iblock_size) + unsigned pos) { + size_t iblock_size; /* Indirect block's size */ size_t max_dblock_size; /* Max. size of direct block to add */ size_t dblock_size; /* Size of direct block added */ unsigned nrows; /* Number of rows inserted */ @@ -614,11 +631,12 @@ fill_2nd_indirect(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cp /* Loop over rows */ nrows = 0; dblock_size = cparam->managed.start_block_size; + iblock_size = cparam->managed.max_direct_size * (1 << pos); max_dblock_size = dblock_size * (1 << ((H5V_log2_of2(iblock_size / cparam->managed.width) - (H5V_log2_of2(cparam->managed.start_block_size) + H5V_log2_of2(cparam->managed.width))) + 1)); while(dblock_size <= max_dblock_size) { - if(fill_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nrows, nobjs)) + if(fill_row(fh, dxpl, cparam, heap_size, free_space, nrows, nobjs)) FAIL_STACK_ERROR /* Adjust block size for row */ @@ -653,7 +671,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_all_direct(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_all_direct(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs) { size_t dblock_size; /* Size of direct block added */ @@ -663,7 +681,7 @@ fill_all_direct(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cpar nrows = 0; dblock_size = cparam->managed.start_block_size; while(dblock_size <= cparam->managed.max_direct_size) { - if(fill_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nrows, nobjs)) + if(fill_row(fh, dxpl, cparam, heap_size, free_space, nrows, nobjs)) FAIL_STACK_ERROR /* Adjust block size for row */ @@ -699,15 +717,15 @@ error: *------------------------------------------------------------------------- */ static int -fill_2nd_indirect_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_2nd_indirect_row(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs, - size_t iblock_size) + unsigned pos) { unsigned u; /* Local index variable */ /* Loop over row of indirect blocks */ for(u = 0; u < cparam->managed.width; u++) - if(fill_2nd_indirect(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs, iblock_size)) + if(fill_2nd_indirect(fh, dxpl, cparam, heap_size, free_space, nobjs, pos)) FAIL_STACK_ERROR /* Operations succeeded */ @@ -735,19 +753,15 @@ error: *------------------------------------------------------------------------- */ static int -fill_all_2nd_indirect_rows(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_all_2nd_indirect_rows(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs) { - size_t iblock_size; /* Size of indirect block for row */ unsigned u; /* Local index variable */ /* Loop over rows of 2nd level deep indirect blocks */ - iblock_size = 2 * cparam->managed.max_direct_size; - for(u = 0; u < (H5V_log2_of2(cparam->managed.width) + 1); u++) { - if(fill_2nd_indirect_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs, iblock_size)) + for(u = 0; u < (H5V_log2_of2(cparam->managed.width) + 1); u++) + if(fill_2nd_indirect_row(fh, dxpl, cparam, heap_size, free_space, nobjs, (u + 1))) FAIL_STACK_ERROR - iblock_size *= 2; - } /* end for */ /* Operations succeeded */ return(0); @@ -758,6 +772,46 @@ error: /*------------------------------------------------------------------------- + * Function: fill_3rd_indirect + * + * Purpose: Insert (small) objects to fill up the free space in all direct + * heap blocks in a third-level indirect block (which + * has one more level of indirect blocks) + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +fill_3rd_indirect(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, + hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs, + unsigned pos) +{ + unsigned u; /* Local index variable */ + + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, heap_size, free_space, nobjs)) + FAIL_STACK_ERROR + + /* Fill rows of recursive indirect blocks in third level indirect block */ + for(u = 0; u < pos; u++) + if(fill_2nd_indirect_row(fh, dxpl, cparam, heap_size, free_space, nobjs, (u + 1))) + FAIL_STACK_ERROR + + /* Operations succeeded */ + return(0); + +error: + return(1); +} /* fill_3rd_indirect() */ + + +/*------------------------------------------------------------------------- * Function: fill_3rd_indirect_row * * Purpose: Insert (small) objects to fill up the free space in all direct @@ -774,28 +828,18 @@ error: *------------------------------------------------------------------------- */ static int -fill_3rd_indirect_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_3rd_indirect_row(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs, unsigned pos) { - size_t iblock_size; /* Indirect block's size */ - unsigned u, v; /* Local index variable */ + unsigned u; /* Local index variable */ /* Loop over row of 3rd level indirect blocks */ - for(u = 0; u < cparam->managed.width; u++) { - /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs)) + for(u = 0; u < cparam->managed.width; u++) + /* Fill third level indirect block */ + if(fill_3rd_indirect(fh, dxpl, cparam, heap_size, free_space, nobjs, pos)) FAIL_STACK_ERROR - /* Fill rows of recursive indirect blocks in third level indirect block */ - iblock_size = 2 * cparam->managed.max_direct_size; - for(v = 0; v < pos; v++) { - if(fill_2nd_indirect_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs, iblock_size)) - FAIL_STACK_ERROR - iblock_size *= 2; - } /* end for */ - } /* end for */ - /* Operations succeeded */ return(0); @@ -821,17 +865,16 @@ error: *------------------------------------------------------------------------- */ static int -fill_all_3rd_indirect_rows(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_all_3rd_indirect_rows(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs) { unsigned u; /* Local index variable */ /* Loop over rows of 3rd level deep indirect blocks */ - for(u = 0; u < (H5V_log2_of2(cparam->managed.width) + 1); u++) { + for(u = 0; u < (H5V_log2_of2(cparam->managed.width) + 1); u++) /* Fill row of 3rd level indirect blocks */ - if(fill_3rd_indirect_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs, u + 1)) + if(fill_3rd_indirect_row(fh, dxpl, cparam, heap_size, free_space, nobjs, u + 1)) FAIL_STACK_ERROR - } /* end for */ /* Operations succeeded */ return(0); @@ -858,7 +901,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_4th_indirect_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_4th_indirect_row(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs, unsigned pos) { @@ -867,16 +910,16 @@ fill_4th_indirect_row(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t /* Loop over row of 4th level indirect blocks */ for(u = 0; u < cparam->managed.width; u++) { /* Fill all direct block rows in fourth level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs)) + if(fill_all_direct(fh, dxpl, cparam, heap_size, free_space, nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level deep indirect blocks in fourth level indirect block */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, heap_size, free_space, nobjs)) FAIL_STACK_ERROR /* Fill rows of third level indirect blocks in fourth level indirect block */ for(v = 0; v < pos; v++) - if(fill_3rd_indirect_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs, (v + 1))) + if(fill_3rd_indirect_row(fh, dxpl, cparam, heap_size, free_space, nobjs, (v + 1))) FAIL_STACK_ERROR } /* end for */ @@ -905,7 +948,7 @@ error: *------------------------------------------------------------------------- */ static int -fill_all_4th_indirect_rows(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_create_t *cparam, +fill_all_4th_indirect_rows(H5HF_t *fh, hid_t dxpl, const H5HF_create_t *cparam, hsize_t *heap_size, hsize_t *free_space, unsigned *nobjs) { unsigned u; /* Local index variable */ @@ -913,7 +956,7 @@ fill_all_4th_indirect_rows(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_cre /* Loop over rows of 4th level deep indirect blocks */ for(u = 0; u < (H5V_log2_of2(cparam->managed.width) + 1); u++) { /* Fill row of 4th level indirect blocks */ - if(fill_4th_indirect_row(f, dxpl, fh_addr, cparam, heap_size, free_space, nobjs, (u + 1))) + if(fill_4th_indirect_row(fh, dxpl, cparam, heap_size, free_space, nobjs, (u + 1))) FAIL_STACK_ERROR /* Account for root indirect block doubling # of rows again */ @@ -932,7 +975,7 @@ fill_all_4th_indirect_rows(H5F_t *f, hid_t dxpl, haddr_t fh_addr, const H5HF_cre row = 16; while(block_size <= max_block_size) { *heap_size += cparam->managed.width * block_size; - *free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, row); + *free_space += cparam->managed.width * DBLOCK_FREE(fh, row); /* Advance to next row */ block_size *= 2; @@ -964,13 +1007,13 @@ error: *------------------------------------------------------------------------- */ static int -test_create(hid_t fapl, H5HF_create_t *cparam) +test_create(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t UNUSED *tparam) { hid_t file = -1; /* File ID */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ H5HF_create_t test_cparam; /* Creation parameters for heap */ - haddr_t fh_addr; /* Address of fractal heap created */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ size_t id_len; /* Size of fractal heap IDs */ /* Set the filename to use for this test (dependent on fapl) */ @@ -988,25 +1031,29 @@ test_create(hid_t fapl, H5HF_create_t *cparam) * Test fractal heap creation (w/absolute address mapping) */ TESTING("fractal heap creation (w/absolute address mapping)"); - if(H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) 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)) + if(check_stats(fh, (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 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) + if(H5HF_get_cparam_test(fh, &test_cparam) < 0) FAIL_STACK_ERROR if(HDmemcmp(cparam, &test_cparam, sizeof(H5HF_create_t))) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1016,11 +1063,106 @@ test_create(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); } /* test_create() */ + +/*------------------------------------------------------------------------- + * Function: test_reopen + * + * Purpose: Create & reopen a fractal heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_reopen(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t UNUSED *tparam) +{ + hid_t file = -1; /* File ID */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5HF_create_t test_cparam; /* Creation parameters for heap */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + + /* 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 + + /* + * Test fractal heap creation (w/absolute address mapping) + */ + + TESTING("reopening existing fractal heap (w/absolute address mapping)"); + + /* Create heap */ + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + if(check_stats(fh, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0)) + FAIL_STACK_ERROR + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open the heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + + /* Query the type of address mapping */ + HDmemset(&test_cparam, 0, sizeof(H5HF_create_t)); + if(H5HF_get_cparam_test(fh, &test_cparam) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(cparam, &test_cparam, sizeof(H5HF_create_t))) + FAIL_STACK_ERROR + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + PASSED() + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_reopen() */ + #ifdef ALL_INSERT_TESTS /*------------------------------------------------------------------------- @@ -1038,15 +1180,17 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam) +test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of the heap */ unsigned nobjs = 0; /* Total number of objects inserted */ /* Set the filename to use for this test (dependent on fapl) */ @@ -1061,25 +1205,60 @@ test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) 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)) + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + if(check_stats(fh, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* * Test inserting first (small) object into absolute heap */ TESTING("inserting first (small) object into absolute heap"); - free_space = DBLOCK_FREE(f, dxpl, fh_addr, 0); - if(add_obj(f, dxpl, fh_addr, (hsize_t)cparam->managed.start_block_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + free_space = DBLOCK_FREE(fh, 0); + heap_size = cparam->managed.start_block_size; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check for correctly sized heap */ + if(check_stats(fh, heap_size, heap_size, (hsize_t)0, free_space, (hsize_t)1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1089,6 +1268,8 @@ test_abs_insert_first(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1110,13 +1291,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam) +test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ unsigned nobjs = 0; /* Total number of objects inserted */ @@ -1133,27 +1315,46 @@ test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting first (small) object into absolute heap */ TESTING("inserting two (small) objects into absolute heap"); - free_space = DBLOCK_FREE(f, dxpl, fh_addr, 0); - if(add_obj(f, dxpl, fh_addr, (hsize_t)cparam->managed.start_block_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + free_space = DBLOCK_FREE(fh, 0); + if(add_obj(fh, dxpl, (hsize_t)cparam->managed.start_block_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert second object */ - if(add_obj(f, dxpl, fh_addr, (hsize_t)cparam->managed.start_block_size, &free_space, &nobjs, 20, SMALL_OBJ_SIZE2, FALSE)) + if(add_obj(fh, dxpl, (hsize_t)cparam->managed.start_block_size, &free_space, &nobjs, 20, SMALL_OBJ_SIZE2, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1163,6 +1364,8 @@ test_abs_insert_second(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1185,13 +1388,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam) +test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ @@ -1207,12 +1411,16 @@ test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) object into absolute heap @@ -1220,11 +1428,26 @@ test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam) TESTING("inserting objects to fill absolute heap's root direct block"); /* Fill the heap up */ - if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) + if(fill_heap(fh, dxpl, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1234,6 +1457,8 @@ test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1257,13 +1482,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of the heap */ @@ -1281,12 +1507,16 @@ test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test forcing creation of indirect root block & second direct block @@ -1294,17 +1524,32 @@ test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam) TESTING("inserting objects to create root indirect block"); /* Fill the heap up */ - if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) + if(fill_heap(fh, dxpl, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force root indirect block creation */ - free_space = (cparam->managed.width - 1) * DBLOCK_FREE(f, dxpl, fh_addr, 0); + free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); heap_size = cparam->managed.width * cparam->managed.start_block_size; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1314,6 +1559,8 @@ test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1337,13 +1584,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam) +test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of the heap */ @@ -1361,12 +1609,16 @@ test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill second direct block @@ -1374,17 +1626,32 @@ test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam) TESTING("inserting objects to fill second direct block"); /* Fill the first direct block heap up */ - if(fill_heap(f, dxpl, fh_addr, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) + if(fill_heap(fh, dxpl, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill the second direct block heap up (also creates initial root indirect block) */ - free_space = (cparam->managed.width - 2) * DBLOCK_FREE(f, dxpl, fh_addr, 0); + free_space = (cparam->managed.width - 2) * DBLOCK_FREE(fh, 0); heap_size = cparam->managed.width * cparam->managed.start_block_size; - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) + if(fill_heap(fh, dxpl, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1394,6 +1661,8 @@ test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1418,13 +1687,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam) +test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of the heap */ @@ -1442,12 +1712,16 @@ test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to create third direct block @@ -1455,21 +1729,36 @@ test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam) TESTING("inserting objects to create third direct block"); /* 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, (hsize_t)0, &nobjs)) + if(fill_heap(fh, dxpl, cparam, (hsize_t)cparam->managed.start_block_size, cparam->managed.start_block_size, (hsize_t)0, &nobjs)) FAIL_STACK_ERROR /* Fill the second direct block heap up (also creates initial root indirect block) */ - free_space = (cparam->managed.width - 2) * DBLOCK_FREE(f, dxpl, fh_addr, 0); + free_space = (cparam->managed.width - 2) * DBLOCK_FREE(fh, 0); heap_size = cparam->managed.width * cparam->managed.start_block_size; - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) + if(fill_heap(fh, dxpl, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of third direct block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1479,6 +1768,8 @@ test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1502,13 +1793,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of heap */ @@ -1526,12 +1818,16 @@ test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill first row in root indirect block @@ -1541,11 +1837,26 @@ test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam) /* Fill first row of [root] indirect block */ heap_size = 0; free_space = 0; - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1555,6 +1866,8 @@ test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1578,13 +1891,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of the heap */ @@ -1602,12 +1916,16 @@ test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to start second row in root indirect block @@ -1617,17 +1935,32 @@ test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam) /* Fill first root indirect row */ heap_size = 0; free_space = 0; - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force expanding root indirect block to two rows */ heap_size += cparam->managed.width * cparam->managed.start_block_size; - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 1); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1637,6 +1970,8 @@ test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1660,13 +1995,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of the heap */ @@ -1684,12 +2020,16 @@ test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to start second row in root indirect block @@ -1699,15 +2039,30 @@ test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam) /* Fill first root indirect row */ heap_size = 0; free_space = 0; - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill second root indirect row */ - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1717,6 +2072,8 @@ test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1741,13 +2098,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ hsize_t free_space; /* Size of free space in heap */ hsize_t heap_size; /* Total size of heap */ @@ -1765,12 +2123,16 @@ test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to start third row in root indirect block @@ -1780,24 +2142,39 @@ test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam) /* Fill first root indirect row */ heap_size = 0; free_space = 0; - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR /* Fill second root indirect row */ - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force expanding root indirect block to four rows */ /* (Goes to four rows because it's doubling) */ heap_size += cparam->managed.width * cparam->managed.start_block_size * 2; heap_size += cparam->managed.width * cparam->managed.start_block_size * 4; - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 3); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1807,6 +2184,8 @@ test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1830,13 +2209,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -1855,12 +2235,16 @@ test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill four rows in root indirect block @@ -1871,11 +2255,26 @@ test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam) heap_size = 0; free_space = 0; for(u = 0; u < 4; u++) - if(fill_root_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_root_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) FAIL_STACK_ERROR + } /* end if */ PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1885,6 +2284,8 @@ test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1908,13 +2309,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -1932,12 +2334,16 @@ test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct rows in root indirect block @@ -1947,11 +2353,26 @@ test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam) /* Fill all direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -1961,6 +2382,8 @@ test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -1968,7 +2391,7 @@ error: /*------------------------------------------------------------------------- - * Function: test_abs_first_recursive_indirec5 + * Function: test_abs_first_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect @@ -1984,13 +2407,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2008,12 +2432,16 @@ test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 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 @@ -2023,15 +2451,30 @@ test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR - /* Insert one more object, to force creation of first recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert one more object, to force creation of first recursive indirect block */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2041,6 +2484,8 @@ test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2048,7 +2493,7 @@ error: /*------------------------------------------------------------------------- - * Function: test_abs_second_direct_recursive_indirec5 + * Function: test_abs_second_direct_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect @@ -2065,13 +2510,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2089,12 +2535,16 @@ test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to force creation of second direct @@ -2105,22 +2555,37 @@ test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill the first direct block in the recursive indirect block up */ - free_space -= DBLOCK_FREE(f, dxpl, fh_addr, 0); - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) + free_space -= DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of second direct block in * first recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2130,6 +2595,8 @@ test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2154,13 +2621,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2178,12 +2646,16 @@ test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2194,15 +2666,30 @@ test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill first recursive indirect block */ - if(fill_2nd_indirect(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2212,6 +2699,8 @@ test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2237,13 +2726,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2261,12 +2751,16 @@ test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2277,21 +2771,36 @@ test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill first recursive indirect block */ - if(fill_2nd_indirect(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of second * recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2301,6 +2810,8 @@ test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2327,13 +2838,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2351,12 +2863,16 @@ test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2367,19 +2883,34 @@ test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill first recursive indirect block */ - if(fill_2nd_indirect(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill 2nd recursive indirect block */ - if(fill_2nd_indirect(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2389,6 +2920,8 @@ test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2415,13 +2948,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2439,12 +2973,16 @@ test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2455,15 +2993,30 @@ test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks in root indirect block up */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill row of recursive indirect blocks */ - if(fill_2nd_indirect_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2473,6 +3026,8 @@ test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2497,13 +3052,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2521,12 +3077,16 @@ test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2537,21 +3097,36 @@ test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks in root indirect block up */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill row of recursive indirect blocks */ - if(fill_2nd_indirect_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of second * recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2561,6 +3136,8 @@ test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2585,13 +3162,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam) +test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2609,12 +3187,16 @@ test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2625,15 +3207,30 @@ test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2643,6 +3240,8 @@ test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2668,13 +3267,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2692,12 +3292,16 @@ test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2708,21 +3312,36 @@ test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of third level deep * recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2732,6 +3351,8 @@ test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2757,13 +3378,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2781,12 +3403,16 @@ test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2797,23 +3423,38 @@ test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill row of recursive indirect blocks in third level indirect block */ - if(fill_2nd_indirect_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 2 * cparam->managed.max_direct_size)) + if(fill_2nd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2823,6 +3464,8 @@ test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2848,13 +3491,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2872,12 +3516,16 @@ test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2888,19 +3536,34 @@ test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill 1st row of 3rd level indirect blocks */ - if(fill_3rd_indirect_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 1)) + if(fill_3rd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2910,6 +3573,8 @@ test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -2935,13 +3600,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -2959,12 +3625,16 @@ test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -2975,19 +3645,34 @@ test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -2997,6 +3682,8 @@ test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3023,13 +3710,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -3047,12 +3735,16 @@ test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -3063,25 +3755,40 @@ test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of four level deep * recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3091,6 +3798,8 @@ test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3117,13 +3826,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -3141,12 +3851,16 @@ test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -3157,31 +3871,46 @@ test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill direct block rows in fourth level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level deep indirect blocks in fourth level indirect block */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill first row of 3rd level deep indirect blocks in fourth level indirect block */ - if(fill_3rd_indirect_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 1)) + if(fill_3rd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3191,6 +3920,8 @@ test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3217,13 +3948,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -3241,12 +3973,16 @@ test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -3257,23 +3993,38 @@ test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill 1st row of 4th level indirect blocks */ - if(fill_4th_indirect_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs, 1)) + if(fill_4th_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3283,6 +4034,8 @@ test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3309,13 +4062,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -3333,12 +4087,16 @@ test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -3349,23 +4107,38 @@ test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Fill all rows of 4th level indirect blocks */ - if(fill_all_4th_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_4th_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3375,12 +4148,15 @@ test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); } /* test_abs_fill_all_4th_recursive_indirect() */ #endif /* ALL_INSERT_TESTS */ +#ifndef QAK /*------------------------------------------------------------------------- * Function: test_abs_start_5th_recursive_indirect @@ -3403,13 +4179,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) +test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ hsize_t free_space; /* Size of free space in heap */ @@ -3427,15 +4204,16 @@ test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting mult. (small) objects to fill all direct @@ -3447,29 +4225,44 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); /* Fill direct blocks up in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 4th level indirect blocks */ - if(fill_all_4th_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_4th_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to force creation of five level deep * recursive indirect block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, SMALL_OBJ_SIZE1, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3479,10 +4272,13 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); } /* test_abs_start_5th_recursive_indirect() */ +#endif /* QAK */ #ifndef QAK @@ -3503,13 +4299,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam) +test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -3528,13 +4325,17 @@ test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) 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)) + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + if(check_stats(fh, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0)) FAIL_STACK_ERROR /* @@ -3544,15 +4345,30 @@ test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam) TESTING("inserting object that is too large for starting block"); obj_size = cparam->managed.start_block_size + 1; - free_space = 2 * cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 0); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); + free_space = 2 * cparam->managed.width * DBLOCK_FREE(fh, 0); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); heap_size = 2 * cparam->managed.width * cparam->managed.start_block_size; heap_size += cparam->managed.width * (cparam->managed.start_block_size * 2); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3562,6 +4378,8 @@ test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3585,13 +4403,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam) +test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -3610,13 +4429,17 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) 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)) + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + if(check_stats(fh, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0)) FAIL_STACK_ERROR /* @@ -3627,24 +4450,39 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam) /* Insert object too large for starting block size */ obj_size = cparam->managed.start_block_size + 1; - free_space = 2 * cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 0); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); + free_space = 2 * cparam->managed.width * DBLOCK_FREE(fh, 0); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); heap_size = 2 * cparam->managed.width * cparam->managed.start_block_size; heap_size += cparam->managed.width * (cparam->managed.start_block_size * 2); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert an object to fill up the heap block just created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 2) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 2) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert second "real" object, which should go in earlier direct block */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, SMALL_OBJ_SIZE2, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, SMALL_OBJ_SIZE2, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3654,6 +4492,8 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3678,13 +4518,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -3703,13 +4544,17 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) 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)) + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + if(check_stats(fh, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0, (hsize_t)0)) FAIL_STACK_ERROR /* @@ -3720,30 +4565,45 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) /* Insert object too large for starting block size */ obj_size = cparam->managed.start_block_size + 1; - free_space = 2 * cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 0); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); + free_space = 2 * cparam->managed.width * DBLOCK_FREE(fh, 0); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); heap_size = 2 * cparam->managed.width * cparam->managed.start_block_size; heap_size += cparam->managed.width * (cparam->managed.start_block_size * 2); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert an object to fill up the heap block just created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 2) - (cparam->managed.start_block_size + 1 + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 2) - (cparam->managed.start_block_size + 1 + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) FAIL_STACK_ERROR /* Add rows of blocks to "backfill" direct blocks that were skipped */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert another object, which should go extend direct blocks, instead of backfill */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, SMALL_OBJ_SIZE2, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, SMALL_OBJ_SIZE2, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3753,6 +4613,8 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3777,13 +4639,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam) +test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -3802,12 +4665,16 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting first (small) object into absolute heap @@ -3816,26 +4683,41 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam) /* Insert small object, to create root direct block */ obj_size = SMALL_OBJ_SIZE1; - free_space = DBLOCK_FREE(f, dxpl, fh_addr, 0); + free_space = DBLOCK_FREE(fh, 0); heap_size = cparam->managed.start_block_size; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and * range of skipped blocks that are too small to hold the second object */ obj_size = cparam->managed.start_block_size + 1; - free_space += (cparam->managed.width - 1 )* DBLOCK_FREE(f, dxpl, fh_addr, 0); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 1); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); + free_space += (cparam->managed.width - 1 )* DBLOCK_FREE(fh, 0); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); heap_size += (cparam->managed.width - 1) * cparam->managed.start_block_size; heap_size += cparam->managed.width * cparam->managed.start_block_size; heap_size += cparam->managed.width * cparam->managed.start_block_size * 2; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3845,6 +4727,8 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3872,13 +4756,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -3898,12 +4783,16 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test inserting first (small) object into absolute heap @@ -3912,51 +4801,66 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) /* Insert small object, to create root direct block */ obj_size = SMALL_OBJ_SIZE1; - free_space = DBLOCK_FREE(f, dxpl, fh_addr, 0); + free_space = DBLOCK_FREE(fh, 0); heap_size = cparam->managed.start_block_size; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and * range of skipped blocks that are too small to hold the second object */ obj_size = cparam->managed.start_block_size + 1; - free_space += (cparam->managed.width - 1 )* DBLOCK_FREE(f, dxpl, fh_addr, 0); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 1); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); + free_space += (cparam->managed.width - 1 )* DBLOCK_FREE(fh, 0); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); heap_size += (cparam->managed.width - 1) * cparam->managed.start_block_size; heap_size += cparam->managed.width * cparam->managed.start_block_size; heap_size += cparam->managed.width * cparam->managed.start_block_size * 2; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert an object to fill up the (smaller) heap block just created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 0) - (SMALL_OBJ_SIZE1 + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 0) - (SMALL_OBJ_SIZE1 + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill remainder of 2 * start size block */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 2) - ((cparam->managed.start_block_size + 1) + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 2) - ((cparam->managed.start_block_size + 1) + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Insert objects to fill remaining rows of the starting block size */ for(u = 0; u < 2; u++) { /* Fill a row of direct heap blocks up */ for(v = 0; v < (cparam->managed.width - 1); v++) { - free_space -= DBLOCK_FREE(f, dxpl, fh_addr, u); - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) + free_space -= DBLOCK_FREE(fh, u); + if(fill_heap(fh, dxpl, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) FAIL_STACK_ERROR } /* end for */ } /* end for */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to create new 2 * start size direct block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -3966,6 +4870,8 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -3995,13 +4901,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -4021,12 +4928,16 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test absolute heap @@ -4036,14 +4947,14 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * /* Fill initial direct block */ heap_size = cparam->managed.start_block_size; free_space = 0; - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) + if(fill_heap(fh, dxpl, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) FAIL_STACK_ERROR /* Insert small object, to create root indirect block */ obj_size = SMALL_OBJ_SIZE1; heap_size += (cparam->managed.width - 1) * cparam->managed.start_block_size; - free_space += (cparam->managed.width - 1) * DBLOCK_FREE(f, dxpl, fh_addr, 0); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -4053,45 +4964,60 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * heap_size += cparam->managed.width * cparam->managed.start_block_size; heap_size += cparam->managed.width * cparam->managed.start_block_size * 2; heap_size += cparam->managed.width * cparam->managed.start_block_size * 4; - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 1); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 2); - free_space += cparam->managed.width * DBLOCK_FREE(f, dxpl, fh_addr, 3); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); + free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert an object to fill up the (smaller) heap block just created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 0) - (SMALL_OBJ_SIZE1 + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 0) - (SMALL_OBJ_SIZE1 + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) FAIL_STACK_ERROR /* Insert object to fill remainder of 4 * start size block */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 3) - (((2 * cparam->managed.start_block_size) + 1) + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 3) - (((2 * cparam->managed.start_block_size) + 1) + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Insert objects to fill remaining heaps in first row */ for(u = 0; u < (cparam->managed.width - 2); u++) { /* Fill a direct heap block up */ - free_space -= DBLOCK_FREE(f, dxpl, fh_addr, 0); - if(fill_heap(f, dxpl, fh_addr, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) + free_space -= DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, cparam, heap_size, cparam->managed.start_block_size, free_space, &nobjs)) FAIL_STACK_ERROR } /* end for */ /* Insert objects to fill remaining heaps in second row */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR /* Insert objects to fill remaining heaps in third row */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 2, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 2, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to create new 4 * start size direct block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4101,6 +5027,8 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4125,13 +5053,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -4150,12 +5079,16 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test absolute heap @@ -4165,38 +5098,53 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and * range of skipped blocks that are too small to hold the large object */ obj_size = (2 * cparam->managed.start_block_size) + 1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Add rows of blocks to "backfill" direct blocks that were skipped */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR /* Insert an object to fill up the (biggest) heap block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 3) - (((2 * cparam->managed.start_block_size) + 1) + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 3) - (((2 * cparam->managed.start_block_size) + 1) + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill direct block heaps with 2 * initial block size in nested indirect block */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 2, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 2, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Insert one more object, to create new 4 * start size direct block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4206,6 +5154,8 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4231,13 +5181,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned first_row_bits; /* Number of bits used bit addresses in first row */ unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ @@ -4263,15 +5214,16 @@ test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_ STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* Compute # of bits used in first row */ first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + @@ -4294,7 +5246,7 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -4305,12 +5257,12 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill all rows of direct blocks that are smaller than large object's block size */ @@ -4319,11 +5271,11 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); while(block_size < obj_block_size) { /* Fill rows of direct blocks in skipped indirect blocks */ for(u = 0; u < cparam->managed.width; u++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, row, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, row, &nobjs)) FAIL_STACK_ERROR /* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, row, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, row, &nobjs)) FAIL_STACK_ERROR /* Advance position in blocks */ @@ -4332,13 +5284,28 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); row++; } /* end while */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4348,6 +5315,8 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4355,10 +5324,168 @@ error: /*------------------------------------------------------------------------- - * Function: test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped + * Function: test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped * - * Purpose: Test filling all direct blocks in root indirect block, then - * add object too large for all direct blocks in first row of + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, except the last + * one, then insert object insert object that is too large to + * hold in row of 2nd level indirect blocks (forcing the use of + * the next row of 2nd level blocks), then backfill all skipped + * direct blocks & extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + unsigned u; /* 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, except last one, and insert object too large for 2nd level indirect blocks, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row (except one) of 2nd level indirect blocks */ + for(u = 0; u < cparam->managed.width - 1; u++) { + /* Fill all rows of 2nd level indirect blocks in root block */ + if(fill_2nd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + } /* end for */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in 2nd level indirect block's direct blocks + * (and rows of next 2nd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in skipped 2nd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in current 2nd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block, then + * add object too large for all direct blocks in first row of * indirect blocks, to force skipping a row of indirect blocks * (and range of skipped blocks), then add object that is too * large for initial block size in skipped indirect blocks, then @@ -4377,13 +5504,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned first_row_bits; /* Number of bits used bit addresses in first row */ unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ @@ -4409,15 +5537,16 @@ test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5 STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* Compute # of bits used in first row */ first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + @@ -4440,7 +5569,7 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -4451,12 +5580,12 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Insert object too large for initial block size in skipped indirect blocks */ @@ -4464,24 +5593,24 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (medium) block just created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 4) - (obj_size + OBJ_PREFIX_LEN); + obj_size = DBLOCK_FREE(fh, 4) - (obj_size + OBJ_PREFIX_LEN); #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Finish off blocks in row of medium block size (just to make row filling easier below) */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 4); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 4); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill all rows of direct blocks that are smaller than large object's block size */ @@ -4490,13 +5619,13 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); while(block_size < obj_block_size) { /* Fill rows of direct blocks in skipped indirect blocks */ for(u = 0; u < cparam->managed.width; u++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, row, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, row, &nobjs)) FAIL_STACK_ERROR /* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */ /* (Skip the row of blocks filled above) */ if(row != 4) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, row, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, row, &nobjs)) FAIL_STACK_ERROR /* Advance position in blocks */ @@ -4505,13 +5634,28 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); row++; } /* end while */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4521,6 +5665,8 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4545,13 +5691,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned first_row_bits; /* Number of bits used bit addresses in first row */ unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ @@ -4574,12 +5721,16 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* Compute # of bits used in first row */ first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + @@ -4595,19 +5746,19 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and * range of skipped blocks that are too small to hold the large object */ obj_size = (cparam->managed.max_direct_size / 2) + 1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert an object to fill up the (biggest) heap block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, num_first_indirect_rows + 1) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows + 1) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill rows skipped over in indirect block's direct blocks @@ -4615,16 +5766,16 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ for(u = 0; u < num_first_indirect_rows; u++) { /* Direct block rows in first row of skipped 2nd level indirect blocks */ for(v = 0; v < cparam->managed.width; v++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR /* Direct block rows in second row of skipped 2nd level indirect blocks */ for(v = 0; v < cparam->managed.width; v++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR /* Direct block row in used 2nd level indirect block */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR } /* end for */ @@ -4632,20 +5783,35 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ /* Direct block rows in skipped 2nd level indirect blocks */ for(v = 0; v < cparam->managed.width; v++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, num_first_indirect_rows, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, num_first_indirect_rows, &nobjs)) FAIL_STACK_ERROR /* Direct block row in used 2nd level indirect block */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, num_first_indirect_rows, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, num_first_indirect_rows, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4655,6 +5821,8 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4680,13 +5848,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -4705,15 +5874,16 @@ test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test absolute heap @@ -4723,11 +5893,11 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -4735,29 +5905,44 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); * object */ obj_size = (cparam->managed.start_block_size * 2) + 1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 3) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 3) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill rows skipped over in 3rd level indirect block's direct blocks */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 2, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 2, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4767,6 +5952,8 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4794,13 +5981,14 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ @@ -4819,15 +6007,16 @@ test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* * Test absolute heap @@ -4837,15 +6026,15 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -4853,31 +6042,46 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); * object */ obj_size = (cparam->managed.start_block_size * 2) + 1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, 3) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, 3) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill rows skipped over in (3rd level indirect block's) 2nd level * indirect block's direct blocks */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 0, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 0, &nobjs)) FAIL_STACK_ERROR - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 1, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 1, &nobjs)) FAIL_STACK_ERROR - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, 2, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, 2, &nobjs)) FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -4887,6 +6091,8 @@ HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); @@ -4899,9 +6105,9 @@ error: * Purpose: Test filling all direct blocks in root indirect block and all * direct blocks in 2nd level indirect blocks, fill all direct * blocks in 3rd level indirect block, then insert object - * that is too large to hold in row of indirect blocks of - * 3rd level indirect block, then backfill & extend all skipped - * direct blocks. + * that is too large to hold in first row of 2nd level indirect + * blocks of 3rd level indirect block, then backfill & extend all + * skipped direct blocks. * * Return: Success: 0 * @@ -4913,18 +6119,18 @@ error: *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned first_row_bits; /* Number of bits used bit addresses in first row */ unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - size_t obj_block_size; /* Size of block to hold large object added */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ hsize_t free_space; /* Size of free space in heap */ @@ -4943,27 +6149,26 @@ test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(h STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* Compute # of bits used in first row */ first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + H5V_log2_of2(cparam->managed.width); first_indirect_block_size = 2 * cparam->managed.max_direct_size; num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; - obj_block_size = 1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 1); #ifdef QAK HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); -HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); #endif /* QAK */ /* @@ -4974,15 +6179,15 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -4993,12 +6198,12 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR /* Fill rows skipped over in (first 3rd level indirect block's) 2nd level @@ -5008,21 +6213,36 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); for(u = 0; u < num_first_indirect_rows; u++) { /* Direct block rows in 2nd level indirect blocks */ for(v = 0; v < cparam->managed.width; v++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR /* Direct block row in 3rd level indirect block */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR } /* end for */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -5032,46 +6252,48 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); } /* test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ -#endif /* QAK */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped + * Function: test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped * * Purpose: Test filling all direct blocks in root indirect block and all - * direct blocks in 2nd level indirect blocks, fill all direct - * blocks and indirect blocks in 3rd level indirect block, then - * fill all direct blocks in 4th level indirect block, then - * insert object that is too large to hold in first row of 2nd - * level indirect blocks of 4th level indirect block, then - * backfill all skipped direct blocks & extend. + * direct blocks in 2nd level indirect blocks, all 3rd level + * indirect blocks in first row except the last one, fill direct + * blocks in lasts 3rd level indirect block, then insert object + * insert object that is too large to hold in last 3rd level + * indirect block's row of 2nd level indirect blocks (forcing the + * use of the next row of 3rd level blocks), then backfill all + * skipped direct blocks & extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, April 15, 2006 + * Tues, April 18, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam) +test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { 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 */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ unsigned first_row_bits; /* Number of bits used bit addresses in first row */ unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - size_t obj_block_size; /* Size of block to hold large object added */ unsigned nobjs = 0; /* Number of objects inserted */ size_t obj_size; /* Size of object */ hsize_t free_space; /* Size of free space in heap */ @@ -5090,50 +6312,51 @@ test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5 STACK_ERROR /* Create absolute heap */ - if(H5HF_create(f, dxpl, cparam, &fh_addr/*out*/, &id_len/*out*/) < 0) + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len > HEAP_ID_LEN) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address = %a\n", fh_addr); -#endif /* QAK */ + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR /* Compute # of bits used in first row */ first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + H5V_log2_of2(cparam->managed.width); first_indirect_block_size = 2 * cparam->managed.max_direct_size; num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; - obj_block_size = 1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 1); #ifdef QAK HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); -HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); #endif /* QAK */ /* * Test absolute heap */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill 4th level indirect block's direct blocks, and skip first row of 2nd indirect blocks of 4th level indirect block, then backfill and extend"); + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling first row of 3rd level indirect blocks, except last one, fill all direct blocks in last 3rd level indirect block, and insert object too large for it's 2nd level indirect blocks, then backfill and extend"); /* Fill direct blocks in root indirect block */ heap_size = 0; free_space = 0; - if(fill_root_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) - FAIL_STACK_ERROR + /* Fill first row (except one) of 3rd level indirect blocks */ + for(u = 0; u < cparam->managed.width - 1; u++) + /* Fill 3rd level indirect block */ + if(fill_3rd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR - /* Fill all direct block rows in fourth level indirect block */ - if(fill_all_direct(f, dxpl, fh_addr, cparam, &heap_size, &free_space, &nobjs)) + /* Fill all direct block rows in last third level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) FAIL_STACK_ERROR /* Insert large object, to force creation of indirect block and @@ -5144,36 +6367,50 @@ HDfprintf(stderr, "obj_block_size = %Zu\n", obj_block_size); #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) FAIL_STACK_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(f, dxpl, fh_addr, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) FAIL_STACK_ERROR - /* Fill rows skipped over in (first 4th level indirect block's) 2nd level - * indirect block's direct blocks - * (and second row of 2nd level indirect block's direct blocks) + /* Fill rows skipped over in 2nd level indirect block's direct blocks + * (and rows of next 3rd level indirect block's direct blocks) */ for(u = 0; u < num_first_indirect_rows; u++) { /* Direct block rows in 2nd level indirect blocks */ for(v = 0; v < cparam->managed.width; v++) - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR - /* Direct block row in 2nd level indirect block */ - if(fill_row(f, dxpl, fh_addr, cparam, &heap_size, &free_space, u, &nobjs)) + /* Direct block row in current 2nd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) FAIL_STACK_ERROR } /* end for */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - if(add_obj(f, dxpl, fh_addr, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) FAIL_STACK_ERROR PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + /* Close the file */ if(H5Fclose(file) < 0) TEST_ERROR @@ -5183,100 +6420,1911 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */ +} /* test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped() */ + /*------------------------------------------------------------------------- - * Function: main + * Function: test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped * - * Purpose: Test the fractal heap code + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, all 3rd level + * indirect blocks in first row, fill direct blocks in 2nd row 3rd + * level indirect block, fill all direct blocks in 1st row of + * 2nd level indirect blocks except the last one, then insert + * object that is too large to hold in 3rd level indirect block's + * first row of 2nd level indirect blocks (forcing the use of the + * next row of 2nd level blocks), then backfill all skipped direct + * blocks & extend. * - * Return: Success: + * Return: Success: 0 * - * Failure: + * Failure: 1 * * Programmer: Quincey Koziol - * Friday, February 24, 2006 + * Tues, April 18, 2006 * *------------------------------------------------------------------------- */ -int -main(void) +static int +test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { - H5HF_create_t cparam; /* Creation parameters for heap */ - hid_t fapl = -1; /* File access property list for data files */ - unsigned nerrors = 0; /* Cumulative error count */ - - /* Reset library */ - h5_reset(); - fapl = h5_fileaccess(); + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + unsigned u; /* Local index variables */ - /* Test fractal heap with small parameters */ - init_small_cparam(&cparam); + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - /* Test fractal heap creation */ - nerrors += test_create(fapl, &cparam); + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR - /* Test fractal heap object insertion */ -#ifdef ALL_INSERT_TESTS - 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 /* ALL_INSERT_TESTS */ - /* If this test fails, uncomment the tests above, which build up to this - * level of complexity gradually. -QAK + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling first row of 3rd level indirect blocks, fill all direct blocks in next 3rd level indirect block, fill all 1st row of 2nd level indirect blocks, except last one, and insert object too large for 2nd level indirect block, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row of 3rd level indirect blocks */ + if(fill_3rd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + + /* Fill all direct block rows in 2nd row third level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row (except one) of 2nd level indirect blocks */ + for(u = 0; u < cparam->managed.width - 1; u++) { + if(fill_2nd_indirect(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + } /* end for */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in 2nd level indirect block's direct blocks + * (and rows of next 2nd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in skipped 2nd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in current 2nd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, then + * fill all direct blocks in 4th level indirect block, then + * insert object that is too large to hold in first row of 2nd + * level indirect blocks of 4th level indirect block, then + * backfill all skipped direct blocks & extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Saturday, April 15, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill 4th level indirect block's direct blocks, and skip first row of 2nd indirect blocks of 4th level indirect block, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all direct block rows in fourth level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in (first 4th level indirect block's) 2nd level + * indirect block's direct blocks + * (and second row of 2nd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in 2nd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, then + * fill all direct blocks in 4th level indirect block, then + * insert object that is too large to hold in first row of 2nd + * level indirect blocks of 4th level indirect block, then + * backfill all skipped direct blocks & extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, April 17, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill 4th level indirect block's direct, 2nd level indirect blocks and 3rd level direct block, and skip first row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all direct block rows in fourth level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in fourth level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all direct block rows in fourth level indirect block's 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in (first 4th level indirect block's first 3rd + * level block's) 2nd level indirect block's direct blocks + * (and rows of 2nd 3rd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, fill all + * direct & indirect blocks in first row of 4th level indirect + * blocks, then fill all direct blocks in first row of 3rd level + * indirect blocks in 4th level indirect block, fill direct blocks + * in first block of 2nd row of 3rd level indirect blocks in 4th + * level indirect block, then insert object insert object that is + * too large to hold in first row of 2nd level indirect blocks of + * 3rd level indirect block (in 4th level indirect block), then + * backfill all skipped direct blocks & extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, April 17, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill first row of 4th level indirect blocks, fill 2nd row 4th level indirect block's direct, 2nd level indirect blocks, first row of 3rd level indirect blocks, 3rd level direct block in 2nd row, and skip first row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row of 4th level indirect blocks */ + if(fill_4th_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + + /* Account for root indirect block doubling # of rows again */ + /* (From 16 rows to the max. # of rows: 22) */ + { + hsize_t block_size; /* Current block size */ + hsize_t max_block_size; /* Maximum size of blocks in heap */ + unsigned row; /* Row in heap */ + + /* Compute current & maximum block size in heap */ + block_size = cparam->managed.start_block_size * ((hsize_t)1 << 15); + max_block_size = (((hsize_t)1 << cparam->managed.max_index) / 2) / + cparam->managed.width; + + /* Increase heap size & free space */ + row = 16; + while(block_size <= max_block_size) { + heap_size += cparam->managed.width * block_size; + free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + + /* Advance to next row */ + block_size *= 2; + row++; + } /* end while */ + } /* end if */ + + /* Fill all direct block rows in 2nd row 4th level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in 2nd row 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row of 3rd level indirect blocks in 2nd row 4th level indirect block */ + if(fill_3rd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + + /* Fill all direct block rows in 4th level indirect block's 2nd row of 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in (first block in 2nd row 4th level indirect + * block's first 3rd level block's) 2nd level indirect block's direct + * blocks (and rows of 2nd 3rd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, fill all + * direct & indirect blocks in 4th level indirect + * block, then fill all direct blocks in first row of 3rd + * level indirect blocks in 4th level indirect block except + * the last (3rd level indirect block) in 4th level indirect block, + * fill direct blocks in last 3rd level indirect block, then + * insert object insert object that is too large to hold in first + * row of 2nd level indirect blocks of 3rd level indirect block + * (in 4th level indirect block) (forcing the use of the next + * 4th level block), then backfill all skipped direct blocks & + * extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, April 17, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill first row of 3rd level indirect blocks in 4th level indirect block except last 3rd level block, fill direct blocks in 3rd level block, and skip row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all direct block rows in 4th level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row (except one) of 3rd level indirect blocks in 4th level indirect block */ + for(u = 0; u < cparam->managed.width - 1; u++) { + /* Fill all direct block rows in 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ + if(fill_2nd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + } /* end for */ + + /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in (4th level indirect block's first 3rd level + * block's) 2nd level indirect block's direct blocks (and rows of next 4th + * level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in 4th level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, fill all + * direct & indirect blocks in first row of 4th level indirect + * blocks, except last one, then fill all direct blocks in first + * row of 3rd level indirect blocks in 4th level indirect block + * except the last (3rd level indirect block) in 4th level + * indirect block, fill direct blocks in last 3rd level indirect + * block, then insert object insert object that is too large to + * hold in row of 2nd level indirect blocks in 3rd level indirect + * block (in 4th level indirect block) (forcing the use of the + * next row of 4th level blocks), then backfill all skipped direct + * blocks & extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, April 17, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill first row of 4th level indirect blocks, except last one, fill first row of 3rd level indirect blocks in last 4th level indirect block except last 3rd level block, fill direct blocks in 3rd level block, and skip row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill first row (except one) of 4th level indirect blocks */ + for(u = 0; u < cparam->managed.width - 1; u++) { + /* Fill all direct block rows in 4th level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill row of 3rd level indirect blocks in 4th level indirect block */ + if(fill_3rd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + } /* end for */ + + /* Fill all direct block rows in 4th level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill row (except one) of 3rd level indirect blocks in 4th level indirect block */ + for(u = 0; u < cparam->managed.width - 1; u++) { + /* Fill all direct block rows in 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ + if(fill_2nd_indirect_row(fh, dxpl, cparam, &heap_size, &free_space, &nobjs, 1)) + FAIL_STACK_ERROR + } /* end for */ + + /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Account for root indirect block doubling # of rows again */ + /* (From 16 rows to the max. # of rows: 22) */ + { + hsize_t block_size; /* Current block size */ + hsize_t max_block_size; /* Maximum size of blocks in heap */ + unsigned row; /* Row in heap */ + + /* Compute current & maximum block size in heap */ + block_size = cparam->managed.start_block_size * ((hsize_t)1 << 15); + max_block_size = (((hsize_t)1 << cparam->managed.max_index) / 2) / + cparam->managed.width; + + /* Increase heap size & free space */ + row = 16; + while(block_size <= max_block_size) { + heap_size += cparam->managed.width * block_size; + free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + + /* Advance to next row */ + block_size *= 2; + row++; + } /* end while */ + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = (1 << ((num_first_indirect_rows + H5V_log2_of2(cparam->managed.start_block_size)) - 2)) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - (obj_size + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Fill rows skipped over in (4th level indirect block's first 3rd level + * block's) 2nd level indirect block's direct blocks (and rows of next 4th + * level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + + /* Direct block row in 4th level indirect block */ + if(fill_row(fh, dxpl, cparam, &heap_size, &free_space, u, &nobjs)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +#endif /* QAK */ + +#ifndef QAK + +/*------------------------------------------------------------------------- + * Function: test_abs_frag_simple + * + * Purpose: Test inserting small object to create root direct block, then + * insert objects small enough to fit into first row of direct + * blocks, but not to share a block with another object, until + * initial-block-size * 2 blocks are reached. Then, go back and + * fill in the space in the blocks skipped. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + unsigned u; /* 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* + * Test absolute heap + */ + TESTING("fragmenting small blocks, then backfill and extend"); + + /* Insert objects small enough to fit into initial blocks, but not to + * share them with other objects of the same size, until the next larger + * block size is reached. + */ + obj_size = cparam->managed.start_block_size / 2; + heap_size = cparam->managed.start_block_size; + free_space = DBLOCK_FREE(fh, 0); + for(u = 0; u < cparam->managed.width; u++) { + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + if(u == 0) { + heap_size = cparam->managed.start_block_size * cparam->managed.width; + free_space += DBLOCK_FREE(fh, 0) * (cparam->managed.width - 1); + } /* end if */ + } /* end for */ + heap_size += cparam->managed.start_block_size * cparam->managed.width; + free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width; + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Add one more object, to create a 2 * start_block_size block */ + /* (Account for doubling root indirect block in calc. below) */ + heap_size += (cparam->managed.start_block_size * 2) * cparam->managed.width; + heap_size += (cparam->managed.start_block_size * 4) * cparam->managed.width; + free_space += DBLOCK_FREE(fh, 2) * cparam->managed.width; + free_space += DBLOCK_FREE(fh, 3) * cparam->managed.width; + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Go back and fill in direct blocks of initial block size (which have large free space in them) */ + obj_size = DBLOCK_FREE(fh, 0) - (obj_size + OBJ_PREFIX_LEN); + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill in 2 * start_block_size block */ + obj_size = DBLOCK_FREE(fh, 2) - ((cparam->managed.start_block_size / 2) + OBJ_PREFIX_LEN); + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 20, obj_size, TRUE)) + FAIL_STACK_ERROR + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_frag_simple() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_frag_direct + * + * Purpose: Test inserting small object to fit into each direct block + * in root block, but not to share a block with another object, + * Then, go back and fill in the space in the blocks skipped. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + hsize_t block_mult; /* Base block size multiplier */ + unsigned base_row; /* Base row for adding new rows */ + unsigned nobjs = 0; /* Number of objects inserted */ + unsigned root_direct_rows; /* Number of rows in root indirect block */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of direct rows in root indirect block */ + root_direct_rows = (H5V_log2_of2(cparam->managed.max_direct_size) - H5V_log2_of2(cparam->managed.start_block_size)) + 2; + + /* + * Test absolute heap + */ + TESTING("fragmenting direct blocks, then backfill and extend"); + + /* Insert objects small enough to fit into each direct block, but not to + * share them with other objects of the same size. + */ + obj_size = cparam->managed.start_block_size / 2; + heap_size = cparam->managed.start_block_size; + free_space = DBLOCK_FREE(fh, 0); + /* First row */ + for(u = 0; u < cparam->managed.width; u++) { + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + if(u == 0) { + heap_size = cparam->managed.start_block_size * cparam->managed.width; + free_space += DBLOCK_FREE(fh, 0) * (cparam->managed.width - 1); + } /* end if */ + } /* end for */ + heap_size += cparam->managed.start_block_size * cparam->managed.width; + free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width; + /* Second row */ + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* (Account for doubling root indirect block for rows 3-4 */ + base_row = 2; + block_mult = 2; + for(u = 0; u < 2; u++) { + heap_size += (cparam->managed.start_block_size * block_mult) * cparam->managed.width; + free_space += DBLOCK_FREE(fh, base_row + u) * cparam->managed.width; + block_mult *= 2; + } /* end for */ + + /* Rows 3-4 */ + block_mult = 2; + for(u = 0; u < 2; u++) { + obj_size = (cparam->managed.start_block_size * block_mult) / 2; + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + block_mult *= 2; + } /* end for */ + + /* (Account for doubling root indirect block for rows 5-8 */ + base_row = 4; + block_mult = 8; + for(u = 0; u < 4; u++) { + heap_size += (cparam->managed.start_block_size * block_mult) * cparam->managed.width; + free_space += DBLOCK_FREE(fh, base_row + u) * cparam->managed.width; + block_mult *= 2; + } /* end for */ + + /* Rows 5-8 */ + block_mult = 8; + for(u = 0; u < 4; u++) { + obj_size = (cparam->managed.start_block_size * block_mult) / 2; + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + block_mult *= 2; + } /* end for */ + + /* (Account for doubling root indirect block for rows 9-16 */ + base_row = 8; + block_mult = 128; + for(u = 0; u < 8; u++) { + heap_size += (cparam->managed.start_block_size * block_mult) * cparam->managed.width; + free_space += DBLOCK_FREE(fh, base_row + u) * cparam->managed.width; + block_mult *= 2; + } /* end for */ + + /* Row 9 (last direct block row) */ + block_mult = 128; + obj_size = (cparam->managed.start_block_size * block_mult) / 2; + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Go back and backfill all root block's direct blocks */ + block_mult = 1; + for(u = 0; u < root_direct_rows; u++) { + obj_size = DBLOCK_FREE(fh, u) - (((cparam->managed.start_block_size * block_mult) / 2) + OBJ_PREFIX_LEN); + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + FAIL_STACK_ERROR + if(u != 0) + block_mult *= 2; + } /* end for */ + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_frag_direct() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_frag_2nd_direct + * + * Purpose: Test filling all direct blocks in root indirect block, then + * inserting small object to fit into each direct block + * in 2nd level indirect block, but not to share a block with + * another object. + * Then, go back and fill in the space in the blocks skipped. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + hsize_t block_mult; /* Base block size multiplier */ + unsigned first_row_bits; /* Number of bits used bit addresses in first row */ + unsigned first_indirect_block_size; /* Range of addresses covered by each of the first indirect blocks */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of bits used in first row */ + first_row_bits = H5V_log2_of2(cparam->managed.start_block_size) + + H5V_log2_of2(cparam->managed.width); + first_indirect_block_size = 2 * cparam->managed.max_direct_size; + num_first_indirect_rows = (H5V_log2_of2(first_indirect_block_size) - first_row_bits) + 1; +#ifdef QAK +HDfprintf(stderr, "first_row_bits = %u\n", first_row_bits); +HDfprintf(stderr, "first_indirect_block_size = %u\n", first_indirect_block_size); +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + + /* + * Test absolute heap + */ + TESTING("fill root direct blocks, then fragment 2nd level indirect block's direct blocks, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Insert objects small enough to fit into each direct block, but not to + * share them with other objects of the same size. + */ + block_mult = 1; + for(u = 0; u < num_first_indirect_rows; u++) { + obj_size = (cparam->managed.start_block_size * block_mult) / 2; + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + if(u != 0) + block_mult *= 2; + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Go back and backfill all 2nd level indirect block's direct blocks */ + block_mult = 1; + for(u = 0; u < num_first_indirect_rows; u++) { + obj_size = DBLOCK_FREE(fh, u) - (((cparam->managed.start_block_size * block_mult) / 2) + OBJ_PREFIX_LEN); + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + FAIL_STACK_ERROR + if(u != 0) + block_mult *= 2; + } /* end for */ + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_frag_2nd_direct() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_frag_3rd_direct + * + * Purpose: Test filling all direct blocks in root indirect block and + * all 2nd level indirect blocks, then + * inserting small object to fit into each direct block + * in 3rd level indirect block, but not to share a block with + * another object. + * Then, go back and fill in the space in the blocks skipped. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + 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_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + size_t id_len; /* Size of fractal heap IDs */ + hsize_t block_mult; /* Base block size multiplier */ + unsigned root_direct_rows; /* Number of rows in root indirect block */ + unsigned nobjs = 0; /* Number of objects inserted */ + size_t obj_size; /* Size of object */ + hsize_t free_space; /* Size of free space in heap */ + hsize_t heap_size; /* Total size of heap */ + 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(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + + /* Compute # of direct rows in root indirect block */ + root_direct_rows = (H5V_log2_of2(cparam->managed.max_direct_size) - H5V_log2_of2(cparam->managed.start_block_size)) + 2; + + /* + * Test absolute heap + */ + TESTING("fill root direct blocks and 2nd level indirect blocks, then fragment 3rd level indirect block's direct blocks, then backfill and extend"); + + /* Fill direct blocks in root indirect block */ + heap_size = 0; + free_space = 0; + if(fill_root_direct(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Fill all rows of 2nd level indirect blocks in root indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, cparam, &heap_size, &free_space, &nobjs)) + FAIL_STACK_ERROR + + /* Insert objects small enough to fit into each direct block, but not to + * share them with other objects of the same size. */ + block_mult = 1; + for(u = 0; u < root_direct_rows; u++) { + obj_size = (cparam->managed.start_block_size * block_mult) / 2; + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, FALSE)) + FAIL_STACK_ERROR + if(u != 0) + block_mult *= 2; + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Go back and backfill all 3rd level indirect block's direct blocks */ + block_mult = 1; + for(u = 0; u < root_direct_rows; u++) { + obj_size = DBLOCK_FREE(fh, u) - (((cparam->managed.start_block_size * block_mult) / 2) + OBJ_PREFIX_LEN); + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, heap_size, &free_space, &nobjs, 10, obj_size, TRUE)) + FAIL_STACK_ERROR + if(u != 0) + block_mult *= 2; + } /* end for */ + + PASSED() + + /* Close the fractal heap */ + if(H5HF_close(fh) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* All tests passed */ + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_frag_3rd_direct() */ +#endif /* QAK */ + + +/*------------------------------------------------------------------------- + * Function: main + * + * Purpose: Test the fractal heap code + * + * Return: Success: + * + * Failure: + * + * Programmer: Quincey Koziol + * Friday, February 24, 2006 + * + *------------------------------------------------------------------------- + */ +int +main(void) +{ + fheap_test_param_t tparam; /* Testing parameters */ + H5HF_create_t cparam; /* Creation parameters for heap */ + hid_t fapl = -1; /* File access property list for data files */ + fheap_test_type_t curr_test; /* Current test being worked on */ + unsigned nerrors = 0; /* Cumulative error count */ + + /* Reset library */ + h5_reset(); + fapl = h5_fileaccess(); + + /* Initialize heap's creation parameters */ + init_small_cparam(&cparam); + + /* Iterate over the testing parameters */ +#ifndef QAK + for(curr_test = FHEAP_TEST_NORMAL; curr_test < FHEAP_TEST_NTESTS; curr_test++) { +#else /* QAK */ +HDfprintf(stderr, "Uncomment test loop!\n"); +curr_test = FHEAP_TEST_REOPEN; +#endif /* QAK */ + /* Clear the testing parameters */ + HDmemset(&tparam, 0, sizeof(fheap_test_param_t)); + + /* Set appropriate testing parameters for each test */ + switch(curr_test) { + /* "Normal" testing parameters */ + case FHEAP_TEST_NORMAL: + puts("Testing with normal parameters"); + break; + + /* "Re-open heap" testing parameters */ + case FHEAP_TEST_REOPEN: + puts("Testing with reopen heap flag set"); + tparam.reopen_heap = TRUE; + break; + + /* An unknown test? */ + default: + goto error; + } /* end switch */ + + /* Test fractal heap creation */ + nerrors += test_create(fapl, &cparam, &tparam); + nerrors += test_reopen(fapl, &cparam, &tparam); + + /* + * Test fractal heap object insertion + */ +#ifdef ALL_INSERT_TESTS + /* Simple insertion */ + nerrors += test_abs_insert_first(fapl, &cparam, &tparam); + nerrors += test_abs_insert_second(fapl, &cparam, &tparam); + nerrors += test_abs_insert_root_mult(fapl, &cparam, &tparam); + nerrors += test_abs_insert_force_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_insert_fill_second(fapl, &cparam, &tparam); + nerrors += test_abs_insert_third_direct(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_row(fapl, &cparam, &tparam); + nerrors += test_abs_start_second_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_second_row(fapl, &cparam, &tparam); + nerrors += test_abs_start_third_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_fourth_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_all_root_direct(fapl, &cparam, &tparam); + nerrors += test_abs_first_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_second_direct_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_second_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_second_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_recursive_indirect_row(fapl, &cparam, &tparam); + nerrors += test_abs_start_2nd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_recursive_indirect_two_deep(fapl, &cparam, &tparam); + nerrors += test_abs_start_3rd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_3rd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_recursive_indirect_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_all_3rd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_start_4th_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_4th_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_4th_recursive_indirect_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_all_4th_recursive_indirect(fapl, &cparam, &tparam); +#endif /* ALL_INSERT_TESTS */ + /* If this test fails, uncomment the tests above, which build up to this + * level of complexity gradually. -QAK + */ +#ifndef QAK + nerrors += test_abs_start_5th_recursive_indirect(fapl, &cparam, &tparam); +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ + #ifndef QAK - nerrors += test_abs_start_5th_recursive_indirect(fapl, &cparam); + /* Skip blocks insertion */ + nerrors += test_abs_skip_start_block(fapl, &cparam, &tparam); + nerrors += test_abs_skip_start_block_add_back(fapl, &cparam, &tparam); + nerrors += test_abs_skip_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_skip_2nd_block(fapl, &cparam, &tparam); + nerrors += test_abs_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_one_partial_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_indirect_two_rows_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_skip_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(fapl, &cparam, &tparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ + /* Fragmented block insertion */ #ifndef QAK - nerrors += test_abs_skip_start_block(fapl, &cparam); - nerrors += test_abs_skip_start_block_add_back(fapl, &cparam); - nerrors += test_abs_skip_start_block_add_skipped(fapl, &cparam); - nerrors += test_abs_skip_2nd_block(fapl, &cparam); - nerrors += test_abs_skip_2nd_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_one_partial_skip_2nd_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_direct_skip_indirect_start_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_direct_skip_indirect_two_rows_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_2nd_direct_skip_start_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam); - nerrors += test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam); + nerrors += test_abs_frag_simple(fapl, &cparam, &tparam); + nerrors += test_abs_frag_direct(fapl, &cparam, &tparam); + nerrors += test_abs_frag_2nd_direct(fapl, &cparam, &tparam); + nerrors += test_abs_frag_3rd_direct(fapl, &cparam, &tparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ - nerrors += test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(fapl, &cparam); +#ifdef QAK + nerrors += test_abs_frag_3rd_direct_2nd_direct(fapl, &cparam, &tparam); +#endif /* QAK */ +#ifndef QAK + } /* end for */ +#endif /* QAK */ if(nerrors) goto error; -- cgit v0.12