From 49d1901fdde7e3c4ebb2db7f13214793832cba42 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 17 Aug 2006 10:59:14 -0500 Subject: [svn-r12592] Description: Several changes, all mooshed together: - Add support for "tiny" objects - which can be stored in the heap ID itself, instead of in the heap data blocks. - Flesh out support for compressed direct blocks, but comment it out until John's got some metadata cache changes in place to support it. - Add support for applying I/O pipeline filters to 'huge' objects - Refactor 'huge' object code to store information for 'huge' objects directly in the heap ID, when there are I/O pipeline filters applied to the heap (and the heap ID is large enough to hold the information) - Update h5debug tool to correctly handle 'huge' & 'tiny' objects. - Misc. other code cleanups, etc. Tested on: FreeBSD/32 4.11 (sleipnir) Linux/64 2.4 (mir) Solaris/64 2.9 (shanti) --- MANIFEST | 1 + src/H5HF.c | 42 +- src/H5HFbtree2.c | 949 +++++++- src/H5HFcache.c | 239 +- src/H5HFdbg.c | 18 +- src/H5HFhdr.c | 84 +- src/H5HFhuge.c | 559 ++++- src/H5HFiblock.c | 113 +- src/H5HFman.c | 8 +- src/H5HFpkg.h | 130 +- src/H5HFprivate.h | 33 +- src/H5HFstat.c | 2 + src/H5HFtest.c | 210 +- src/H5HFtiny.c | 326 +++ src/Makefile.am | 2 +- src/Makefile.in | 9 +- test/fheap.c | 6472 ++++++++++++++++++++++++++++++++------------------ tools/misc/h5debug.c | 48 + 18 files changed, 6599 insertions(+), 2646 deletions(-) create mode 100644 src/H5HFtiny.c diff --git a/MANIFEST b/MANIFEST index 5a93c8c..3e366ae 100644 --- a/MANIFEST +++ b/MANIFEST @@ -515,6 +515,7 @@ ./src/H5HFspace.c ./src/H5HFstat.c ./src/H5HFtest.c +./src/H5HFtiny.c ./src/H5HG.c ./src/H5HGdbg.c ./src/H5HGpkg.h diff --git a/src/H5HF.c b/src/H5HF.c index 20d1aef..12822d5 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -334,11 +334,18 @@ HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size); /* Get the fractal heap header */ hdr = fh->hdr; - /* Check if object is large enough to be standalone */ + /* Check for 'huge' object */ if(size > hdr->max_man_size) { /* Store 'huge' object in heap */ - if(H5HF_huge_insert(hdr, dxpl_id, size, obj, id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate space for 'managed' object in fractal heap") + /* (Casting away const OK - QAK) */ + if(H5HF_huge_insert(hdr, dxpl_id, size, (void *)obj, id) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't store 'huge' object in fractal heap") + } /* end if */ + /* Check for 'tiny' object */ + else if(size <= hdr->tiny_max_len) { + /* Store 'tiny' object in heap */ + if(H5HF_tiny_insert(hdr, size, obj, id) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't store 'tiny' object in fractal heap") } /* end if */ else { /* Check if we are in "append only" mode, or if there's enough room for the object */ @@ -348,7 +355,7 @@ HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "'write once' managed blocks not su else { /* Allocate space for object in 'managed' heap */ if(H5HF_man_insert(hdr, dxpl_id, size, obj, id) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't allocate space for 'managed' object in fractal heap") + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't store 'managed' object in fractal heap") } /* end else */ } /* end else */ @@ -390,7 +397,7 @@ H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *_id, size_t *obj_len_p) HDassert(obj_len_p); /* Get the ID flags */ - id_flags = *id++; + id_flags = *id; /* Check for correct heap ID version */ if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR) @@ -398,6 +405,9 @@ H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *_id, size_t *obj_len_p) /* Check type of object in heap */ if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_MAN) { + /* Skip over the flag byte */ + id++; + /* Skip over object offset */ id += fh->hdr->heap_off_size; @@ -408,6 +418,10 @@ H5HF_get_obj_len(H5HF_t *fh, hid_t dxpl_id, const void *_id, size_t *obj_len_p) if(H5HF_huge_get_obj_len(fh->hdr, dxpl_id, id, obj_len_p) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get 'huge' object's length") } /* end if */ + else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_TINY) { + if(H5HF_tiny_get_obj_len(fh->hdr, id, obj_len_p) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't get 'tiny' object's length") + } /* end if */ else { HDfprintf(stderr, "%s: Heap ID type not supported yet!\n", FUNC); HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "heap ID type not supported yet") @@ -448,7 +462,7 @@ H5HF_read(H5HF_t *fh, hid_t dxpl_id, const void *_id, void *obj/*out*/) HDassert(obj); /* Get the ID flags */ - id_flags = *id++; + id_flags = *id; /* Check for correct heap ID version */ if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR) @@ -465,6 +479,11 @@ H5HF_read(H5HF_t *fh, hid_t dxpl_id, const void *_id, void *obj/*out*/) if(H5HF_huge_read(fh->hdr, dxpl_id, id, obj) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't read 'huge' object from fractal heap") } /* end if */ + else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_TINY) { + /* Read 'tiny' object from file */ + if(H5HF_tiny_read(fh->hdr, id, obj) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGET, FAIL, "can't read 'tiny' object from fractal heap") + } /* end if */ else { HDfprintf(stderr, "%s: Heap ID type not supported yet!\n", FUNC); HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "heap ID type not supported yet") @@ -505,7 +524,7 @@ H5HF_remove(H5HF_t *fh, hid_t dxpl_id, const void *_id) HDassert(id); /* Get the ID flags */ - id_flags = *id++; + id_flags = *id; /* Check for correct heap ID version */ if((id_flags & H5HF_ID_VERS_MASK) != H5HF_ID_VERS_CURR) @@ -522,6 +541,11 @@ H5HF_remove(H5HF_t *fh, hid_t dxpl_id, const void *_id) if(H5HF_huge_remove(fh->hdr, dxpl_id, id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove 'huge' object from fractal heap") } /* end if */ + else if((id_flags & H5HF_ID_TYPE_MASK) == H5HF_ID_TYPE_TINY) { + /* Remove 'tiny' object from heap statistics */ + if(H5HF_tiny_remove(fh->hdr, id) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove 'tiny' object from fractal heap") + } /* end if */ else { HDfprintf(stderr, "%s: Heap ID type not supported yet!\n", FUNC); HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "heap ID type not supported yet") @@ -596,7 +620,7 @@ HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr- /* Shut down the huge object information */ /* (Can't put this in header "destroy" routine, because it has * has the address of an object in the file, which might be - * by the shutdown routine - QAK) + * modified by the shutdown routine - QAK) */ if(H5HF_huge_term(fh->hdr, dxpl_id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release 'huge' object info") @@ -693,7 +717,7 @@ HDfprintf(stderr, "%s: hdr->huge_bt2_addr = %a\n", FUNC, hdr->huge_bt2_addr); } /* end if */ /* Release header's disk space */ - if(H5MF_xfree(f, H5FD_MEM_FHEAP_HDR, dxpl_id, fh_addr, (hsize_t)H5HF_HEADER_SIZE(hdr)) < 0) + if(H5MF_xfree(f, H5FD_MEM_FHEAP_HDR, dxpl_id, fh_addr, (hsize_t)hdr->heap_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap header") /* Finished deleting header */ diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c index 4a324aa..43fafd1 100644 --- a/src/H5HFbtree2.c +++ b/src/H5HFbtree2.c @@ -59,34 +59,104 @@ /********************/ /* v2 B-tree function callbacks */ -herr_t H5HF_huge_bt2_found(const void *nrecord, void *op_data); -herr_t H5HF_huge_bt2_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data); /* v2 B-tree driver callbacks */ -static herr_t H5HF_huge_btree2_store(const H5B2_class_t *cls, void *native, const void *udata); -static herr_t H5HF_huge_btree2_retrieve(const H5B2_class_t *cls, void *udata, const void *native); -static herr_t H5HF_huge_btree2_compare(const H5B2_class_t *cls, const void *rec1, const void *rec2); -static herr_t H5HF_huge_btree2_encode(const H5F_t *f, const H5B2_class_t *cls, uint8_t *raw, +static herr_t H5HF_huge_btree2_indir_store(void *native, const void *udata); +static herr_t H5HF_huge_btree2_indir_retrieve(void *udata, const void *native); +static herr_t H5HF_huge_btree2_indir_compare(const void *rec1, const void *rec2); +static herr_t H5HF_huge_btree2_indir_encode(const H5F_t *f, uint8_t *raw, const void *native); -static herr_t H5HF_huge_btree2_decode(const H5F_t *f, const H5B2_class_t *cls, const uint8_t *raw, +static herr_t H5HF_huge_btree2_indir_decode(const H5F_t *f, const uint8_t *raw, void *native); -static herr_t H5HF_huge_btree2_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, - int indent, int fwidth, const H5B2_class_t *cls, const void *record, const void *_udata); +static herr_t H5HF_huge_btree2_indir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *_udata); + +static herr_t H5HF_huge_btree2_filt_indir_store(void *native, const void *udata); +static herr_t H5HF_huge_btree2_filt_indir_retrieve(void *udata, const void *native); +static herr_t H5HF_huge_btree2_filt_indir_compare(const void *rec1, const void *rec2); +static herr_t H5HF_huge_btree2_filt_indir_encode(const H5F_t *f, uint8_t *raw, + const void *native); +static herr_t H5HF_huge_btree2_filt_indir_decode(const H5F_t *f, const uint8_t *raw, + void *native); +static herr_t H5HF_huge_btree2_filt_indir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *_udata); + +static herr_t H5HF_huge_btree2_dir_store(void *native, const void *udata); +static herr_t H5HF_huge_btree2_dir_retrieve(void *udata, const void *native); +static herr_t H5HF_huge_btree2_dir_compare(const void *rec1, const void *rec2); +static herr_t H5HF_huge_btree2_dir_encode(const H5F_t *f, uint8_t *raw, + const void *native); +static herr_t H5HF_huge_btree2_dir_decode(const H5F_t *f, const uint8_t *raw, + void *native); +static herr_t H5HF_huge_btree2_dir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *_udata); + +static herr_t H5HF_huge_btree2_filt_dir_store(void *native, const void *udata); +static herr_t H5HF_huge_btree2_filt_dir_retrieve(void *udata, const void *native); +static herr_t H5HF_huge_btree2_filt_dir_compare(const void *rec1, const void *rec2); +static herr_t H5HF_huge_btree2_filt_dir_encode(const H5F_t *f, uint8_t *raw, + const void *native); +static herr_t H5HF_huge_btree2_filt_dir_decode(const H5F_t *f, const uint8_t *raw, + void *native); +static herr_t H5HF_huge_btree2_filt_dir_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *_udata); /*********************/ /* Package Variables */ /*********************/ -const H5B2_class_t H5HF_BTREE2[1]={{ /* B-tree class information */ - H5B2_FHEAP_ID, /* Type of B-tree */ - 0, /* Size of native record */ - /* (computed at run-time for each heap) */ - NULL, /* Class private information */ - H5HF_huge_btree2_store, /* Record storage callback */ - H5HF_huge_btree2_retrieve, /* Record retrieval callback */ - H5HF_huge_btree2_compare, /* Record comparison callback */ - H5HF_huge_btree2_encode, /* Record encoding callback */ - H5HF_huge_btree2_decode, /* Record decoding callback */ - H5HF_huge_btree2_debug /* Record debugging callback */ +/* v2 B-tree class for indirectly accessed 'huge' objects */ +const H5B2_class_t H5HF_BT2_INDIR[1]={{ /* B-tree class information */ + H5B2_FHEAP_HUGE_INDIR_ID, /* Type of B-tree */ + sizeof(H5HF_huge_bt2_indir_rec_t), /* Size of native record */ + H5HF_huge_btree2_indir_store, /* Record storage callback */ + H5HF_huge_btree2_indir_retrieve, /* Record retrieval callback */ + H5HF_huge_btree2_indir_compare, /* Record comparison callback */ + H5HF_huge_btree2_indir_encode, /* Record encoding callback */ + H5HF_huge_btree2_indir_decode, /* Record decoding callback */ + H5HF_huge_btree2_indir_debug /* Record debugging callback */ +}}; + +/* v2 B-tree class for indirectly accessed, filtered 'huge' objects */ +const H5B2_class_t H5HF_BT2_FILT_INDIR[1]={{ /* B-tree class information */ + H5B2_FHEAP_HUGE_FILT_INDIR_ID, /* Type of B-tree */ + sizeof(H5HF_huge_bt2_filt_indir_rec_t), /* Size of native record */ + H5HF_huge_btree2_filt_indir_store, /* Record storage callback */ + H5HF_huge_btree2_filt_indir_retrieve, /* Record retrieval callback */ + H5HF_huge_btree2_filt_indir_compare, /* Record comparison callback */ + H5HF_huge_btree2_filt_indir_encode, /* Record encoding callback */ + H5HF_huge_btree2_filt_indir_decode, /* Record decoding callback */ + H5HF_huge_btree2_filt_indir_debug /* Record debugging callback */ +}}; + +/* v2 B-tree class for directly accessed 'huge' objects */ +const H5B2_class_t H5HF_BT2_DIR[1]={{ /* B-tree class information */ + H5B2_FHEAP_HUGE_DIR_ID, /* Type of B-tree */ + sizeof(H5HF_huge_bt2_dir_rec_t), /* Size of native record */ + H5HF_huge_btree2_dir_store, /* Record storage callback */ + H5HF_huge_btree2_dir_retrieve, /* Record retrieval callback */ + H5HF_huge_btree2_dir_compare, /* Record comparison callback */ + H5HF_huge_btree2_dir_encode, /* Record encoding callback */ + H5HF_huge_btree2_dir_decode, /* Record decoding callback */ + H5HF_huge_btree2_dir_debug /* Record debugging callback */ +}}; + +/* v2 B-tree class for directly accessed, filtered 'huge' objects */ +const H5B2_class_t H5HF_BT2_FILT_DIR[1]={{ /* B-tree class information */ + H5B2_FHEAP_HUGE_FILT_DIR_ID, /* Type of B-tree */ + sizeof(H5HF_huge_bt2_filt_dir_rec_t),/* Size of native record */ + H5HF_huge_btree2_filt_dir_store, /* Record storage callback */ + H5HF_huge_btree2_filt_dir_retrieve, /* Record retrieval callback */ + H5HF_huge_btree2_filt_dir_compare, /* Record comparison callback */ + H5HF_huge_btree2_filt_dir_encode, /* Record encoding callback */ + H5HF_huge_btree2_filt_dir_decode, /* Record decoding callback */ + H5HF_huge_btree2_filt_dir_debug /* Record debugging callback */ }}; /*****************************/ @@ -100,10 +170,10 @@ const H5B2_class_t H5HF_BTREE2[1]={{ /* B-tree class information */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_bt2_found + * Function: H5HF_huge_bt2_indir_found * - * Purpose: Retrieve record for 'huge' object, when it's found in the - * v2 B-tree + * Purpose: Retrieve record for indirectly accessed 'huge' object, when + * it's found in the v2 B-tree * * Return: Success: non-negative * Failure: negative @@ -114,26 +184,27 @@ const H5B2_class_t H5HF_BTREE2[1]={{ /* B-tree class information */ *------------------------------------------------------------------------- */ herr_t -H5HF_huge_bt2_found(const void *nrecord, void *op_data) +H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_found) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_indir_found) #ifdef QAK -HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_store", - ((const H5HF_huge_bt2_rec_t *)nrecord)->addr, - ((const H5HF_huge_bt2_rec_t *)nrecord)->len, - ((const H5HF_huge_bt2_rec_t *)nrecord)->id); +HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_indir_found", + ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->addr, + ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len, + ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->id); #endif /* QAK */ - *(H5HF_huge_bt2_rec_t *)op_data = *(const H5HF_huge_bt2_rec_t *)nrecord; + *(H5HF_huge_bt2_indir_rec_t *)op_data = *(const H5HF_huge_bt2_indir_rec_t *)nrecord; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_huge_bt2_found() */ +} /* H5HF_huge_bt2_indir_found() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_bt2_remove + * Function: H5HF_huge_bt2_indir_remove * - * Purpose: Free space for 'huge' object, as v2 B-tree is being deleted + * Purpose: Free space for indirectly accessed 'huge' object, as v2 B-tree + * is being deleted or v2 B-tree node is removed * * Return: Success: non-negative * Failure: negative @@ -144,32 +215,55 @@ HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %Hu}\n", "H5HF_huge_bt2_store", *------------------------------------------------------------------------- */ herr_t -H5HF_huge_bt2_remove(const void *nrecord, void *_udata) +H5HF_huge_bt2_indir_remove(const void *nrecord, void *_udata) { H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_remove) + FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_indir_remove) /* Free the space in the file for the object being removed */ - if(H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, udata->dxpl_id, ((const H5HF_huge_bt2_rec_t *)nrecord)->addr, ((const H5HF_huge_bt2_rec_t *)nrecord)->len) < 0) + if(H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, udata->dxpl_id, ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->addr, ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk") /* Set the length of the object removed */ - udata->obj_len = ((const H5HF_huge_bt2_rec_t *)nrecord)->len; + udata->obj_len = ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len; done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5HF_huge_bt2_remove() */ +} /* H5HF_huge_bt2_indir_remove() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_btree2_store + * Function: H5HF_huge_btree2_indir_store * * Purpose: Store native information into record for v2 B-tree * * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_indir_store(void *nrecord, const void *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_store) + + *(H5HF_huge_bt2_indir_rec_t *)nrecord = *(const H5HF_huge_bt2_indir_rec_t *)udata; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_indir_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_indir_retrieve + * + * Purpose: Retrieve native information from record for v2 B-tree * + * Return: Success: non-negative * Failure: negative * * Programmer: Quincey Koziol @@ -178,23 +272,319 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_huge_btree2_store(const H5B2_class_t UNUSED *cls, void *nrecord, const void *udata) +H5HF_huge_btree2_indir_retrieve(void *udata, const void *nrecord) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_store) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_retrieve) - *(H5HF_huge_bt2_rec_t *)nrecord = *(const H5HF_huge_bt2_rec_t *)udata; + *(H5HF_huge_bt2_indir_rec_t *)udata = *(const H5HF_huge_bt2_indir_rec_t *)nrecord; FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_huge_btree2_store() */ +} /* H5HF_huge_btree2_indir_retrieve() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_indir_compare + * + * Purpose: Compare two native information records, according to some key + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_indir_compare(const void *_rec1, const void *_rec2) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_compare) + +#ifdef QAK +{ +const H5HF_huge_bt2_indir_rec_t *rec1 = (const H5HF_huge_bt2_indir_rec_t *)_rec1; +const H5HF_huge_bt2_indir_rec_t *rec2 = (const H5HF_huge_bt2_indir_rec_t *)_rec2; + +HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_indir_compare", rec1->addr, rec1->len, rec1->id); +HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_indir_compare", rec2->addr, rec2->len, rec2->id); +} +#endif /* QAK */ + FUNC_LEAVE_NOAPI((herr_t)(((const H5HF_huge_bt2_indir_rec_t *)_rec1)->id - ((const H5HF_huge_bt2_indir_rec_t *)_rec2)->id)) +} /* H5HF_huge_btree2_indir_compare() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_btree2_retrieve + * Function: H5HF_huge_btree2_indir_encode + * + * Purpose: Encode native information into raw form for storing on disk + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_indir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord) +{ + const H5HF_huge_bt2_indir_rec_t *nrecord = (const H5HF_huge_bt2_indir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_encode) + + /* Encode the record's fields */ + H5F_addr_encode(f, &raw, nrecord->addr); + H5F_ENCODE_LENGTH(f, raw, nrecord->len); + H5F_ENCODE_LENGTH(f, raw, nrecord->id); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_indir_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_indir_decode + * + * Purpose: Decode raw disk form of record into native form + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_indir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord) +{ + H5HF_huge_bt2_indir_rec_t *nrecord = (H5HF_huge_bt2_indir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_decode) + + /* Decode the record's fields */ + H5F_addr_decode(f, &raw, &nrecord->addr); + H5F_DECODE_LENGTH(f, raw, nrecord->len); + H5F_DECODE_LENGTH(f, raw, nrecord->id); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_indir_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_indir_debug + * + * Purpose: Debug native form of record + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_nrecord, + const void UNUSED *_udata) +{ + const H5HF_huge_bt2_indir_rec_t *nrecord = (const H5HF_huge_bt2_indir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_indir_debug) + + HDfprintf(stream, "%*s%-*s {%a, %Hu, %Hu}\n", indent, "", fwidth, "Record:", + nrecord->addr, nrecord->len, nrecord->id); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_indir_debug() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_bt2_filt_indir_found + * + * Purpose: Retrieve record for indirectly accessed, filtered 'huge' object, + * when it's found in the v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 8, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_indir_found) + +#ifdef QAK +HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_bt2_filt_indir_found", + ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->addr, + ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->len, + ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->filter_mask, + ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->obj_size, + ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->id); +#endif /* QAK */ + *(H5HF_huge_bt2_filt_indir_rec_t *)op_data = *(const H5HF_huge_bt2_filt_indir_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_bt2_filt_indir_found() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_bt2_filt_indir_remove + * + * Purpose: Free space for indirectly accessed, filtered 'huge' object, as + * v2 B-tree is being deleted or v2 B-tree node is removed + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 8, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *_udata) +{ + H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_filt_indir_remove) + + /* Free the space in the file for the object being removed */ + if(H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, udata->dxpl_id, ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->addr, ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->len) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk") + + /* Set the length of the object removed */ + udata->obj_len = ((const H5HF_huge_bt2_filt_indir_rec_t *)nrecord)->obj_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_huge_bt2_filt_indir_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_indir_store + * + * Purpose: Store native information into record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_indir_store(void *nrecord, const void *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_store) + + *(H5HF_huge_bt2_filt_indir_rec_t *)nrecord = *(const H5HF_huge_bt2_filt_indir_rec_t *)udata; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_indir_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_indir_retrieve * * Purpose: Retrieve native information from record for v2 B-tree * * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_indir_retrieve(void *udata, const void *nrecord) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_retrieve) + + *(H5HF_huge_bt2_filt_indir_rec_t *)udata = *(const H5HF_huge_bt2_filt_indir_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_indir_retrieve() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_indir_compare + * + * Purpose: Compare two native information records, according to some key + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_indir_compare(const void *_rec1, const void *_rec2) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_compare) + +#ifdef QAK +{ +const H5HF_huge_bt2_filt_indir_rec_t *rec1 = (const H5HF_huge_bt2_filt_indir_rec_t *)_rec1; +const H5HF_huge_bt2_filt_indir_rec_t *rec2 = (const H5HF_huge_bt2_filt_indir_rec_t *)_rec2; + +HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_btree2_filt_indir_compare", rec1->addr, rec1->len, rec1->filter_mask, rec1->obj_size, rec1->id); +HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu, %Hu}\n", "H5HF_huge_btree2_filt_indir_compare", rec2->addr, rec2->len, rec2->filter_mask, rec2->obj_size, rec2->id); +} +#endif /* QAK */ + FUNC_LEAVE_NOAPI((herr_t)(((const H5HF_huge_bt2_filt_indir_rec_t *)_rec1)->id - ((const H5HF_huge_bt2_filt_indir_rec_t *)_rec2)->id)) +} /* H5HF_huge_btree2_filt_indir_compare() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_indir_encode + * + * Purpose: Encode native information into raw form for storing on disk + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_indir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord) +{ + const H5HF_huge_bt2_filt_indir_rec_t *nrecord = (const H5HF_huge_bt2_filt_indir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_encode) + + /* Encode the record's fields */ + H5F_addr_encode(f, &raw, nrecord->addr); + H5F_ENCODE_LENGTH(f, raw, nrecord->len); + UINT32ENCODE(raw, nrecord->filter_mask); + H5F_ENCODE_LENGTH(f, raw, nrecord->obj_size); + H5F_ENCODE_LENGTH(f, raw, nrecord->id); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_indir_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_indir_decode + * + * Purpose: Decode raw disk form of record into native form + * + * Return: Success: non-negative * Failure: negative * * Programmer: Quincey Koziol @@ -203,18 +593,136 @@ H5HF_huge_btree2_store(const H5B2_class_t UNUSED *cls, void *nrecord, const void *------------------------------------------------------------------------- */ static herr_t -H5HF_huge_btree2_retrieve(const H5B2_class_t UNUSED *cls, void *udata, const void *nrecord) +H5HF_huge_btree2_filt_indir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_retrieve) + H5HF_huge_bt2_filt_indir_rec_t *nrecord = (H5HF_huge_bt2_filt_indir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_decode) - *(H5HF_huge_bt2_rec_t *)udata = *(const H5HF_huge_bt2_rec_t *)nrecord; + /* Decode the record's fields */ + H5F_addr_decode(f, &raw, &nrecord->addr); + H5F_DECODE_LENGTH(f, raw, nrecord->len); + UINT32DECODE(raw, nrecord->filter_mask); + H5F_DECODE_LENGTH(f, raw, nrecord->obj_size); + H5F_DECODE_LENGTH(f, raw, nrecord->id); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_huge_btree2_retrieve() */ +} /* H5HF_huge_btree2_filt_indir_decode() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_btree2_compare + * Function: H5HF_huge_btree2_filt_indir_debug + * + * Purpose: Debug native form of record + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_indir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_nrecord, + const void UNUSED *_udata) +{ + const H5HF_huge_bt2_filt_indir_rec_t *nrecord = (const H5HF_huge_bt2_filt_indir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_indir_debug) + + HDfprintf(stream, "%*s%-*s {%a, %Hu, %x, %Hu, %Hu}\n", indent, "", fwidth, "Record:", + nrecord->addr, nrecord->len, nrecord->filter_mask, nrecord->obj_size, nrecord->id); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_indir_debug() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_bt2_dir_remove + * + * Purpose: Free space for directly accessed 'huge' object, as v2 B-tree + * is being deleted or v2 B-tree node is being removed + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 8, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_huge_bt2_dir_remove(const void *nrecord, void *_udata) +{ + H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_dir_remove) + + /* Free the space in the file for the object being removed */ + if(H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, udata->dxpl_id, ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->addr, ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk") + + /* Set the length of the object removed */ + udata->obj_len = ((const H5HF_huge_bt2_indir_rec_t *)nrecord)->len; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_huge_bt2_dir_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_dir_store + * + * Purpose: Store native information into record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_dir_store(void *nrecord, const void *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_store) + + *(H5HF_huge_bt2_dir_rec_t *)nrecord = *(const H5HF_huge_bt2_dir_rec_t *)udata; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_dir_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_dir_retrieve + * + * Purpose: Retrieve native information from record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 7, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_dir_retrieve(void *udata, const void *nrecord) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_retrieve) + + *(H5HF_huge_bt2_dir_rec_t *)udata = *(const H5HF_huge_bt2_dir_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_dir_retrieve() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_dir_compare * * Purpose: Compare two native information records, according to some key * @@ -228,47 +736,39 @@ H5HF_huge_btree2_retrieve(const H5B2_class_t UNUSED *cls, void *udata, const voi *------------------------------------------------------------------------- */ static herr_t -H5HF_huge_btree2_compare(const H5B2_class_t *cls, const void *_rec1, const void *_rec2) +H5HF_huge_btree2_dir_compare(const void *_rec1, const void *_rec2) { - const H5HF_huge_bt2_rec_t *rec1 = (const H5HF_huge_bt2_rec_t *)_rec1; - const H5HF_huge_bt2_rec_t *rec2 = (const H5HF_huge_bt2_rec_t *)_rec2; - const H5HF_hdr_t *hdr = (const H5HF_hdr_t *)cls->cls_private; + const H5HF_huge_bt2_dir_rec_t *rec1 = (const H5HF_huge_bt2_dir_rec_t *)_rec1; + const H5HF_huge_bt2_dir_rec_t *rec2 = (const H5HF_huge_bt2_dir_rec_t *)_rec2; herr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_compare) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_compare) #ifdef QAK -HDfprintf(stderr, "%s: hdr->huge_ids_direct = %t\n", "H5HF_huge_btree2_compare", hdr->huge_ids_direct); -HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_compare", rec1->addr, rec1->len, rec1->id); -HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_compare", rec2->addr, rec2->len, rec2->id); +HDfprintf(stderr, "%s: rec1 = {%a, %Hu}\n", "H5HF_huge_btree2_dir_compare", rec1->addr, rec1->len); +HDfprintf(stderr, "%s: rec2 = {%a, %Hu}\n", "H5HF_huge_btree2_dir_compare", rec2->addr, rec2->len); #endif /* QAK */ - /* Sort differently, depending on whether 'huge' object directly reference disk */ - if(hdr->huge_ids_direct) { - if(rec1->addr < rec2->addr) - ret_value = -1; - else if(rec1->addr > rec2->addr) - ret_value = 1; - else if(rec1->len < rec2->len) - ret_value = -1; - else if(rec1->len > rec2->len) - ret_value = 1; - else - ret_value = 0; - } /* end if */ + if(rec1->addr < rec2->addr) + ret_value = -1; + else if(rec1->addr > rec2->addr) + ret_value = 1; + else if(rec1->len < rec2->len) + ret_value = -1; + else if(rec1->len > rec2->len) + ret_value = 1; else - ret_value = (herr_t)(rec1->id - rec2->id); + ret_value = 0; - FUNC_LEAVE_NOAPI(ret_value); -} /* H5HF_huge_btree2_compare() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_huge_btree2_dir_compare() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_btree2_encode + * Function: H5HF_huge_btree2_dir_encode * * Purpose: Encode native information into raw form for storing on disk * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol @@ -277,32 +777,26 @@ HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %Hu}\n", "H5HF_huge_btree2_compare", rec *------------------------------------------------------------------------- */ static herr_t -H5HF_huge_btree2_encode(const H5F_t *f, const H5B2_class_t *cls, uint8_t *raw, const void *_nrecord) +H5HF_huge_btree2_dir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord) { - const H5HF_huge_bt2_rec_t *nrecord = (const H5HF_huge_bt2_rec_t *)_nrecord; - const H5HF_hdr_t *hdr = (const H5HF_hdr_t *)cls->cls_private; + const H5HF_huge_bt2_dir_rec_t *nrecord = (const H5HF_huge_bt2_dir_rec_t *)_nrecord; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_encode) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_encode) - /* Encode the record's common fields */ + /* Encode the record's fields */ H5F_addr_encode(f, &raw, nrecord->addr); H5F_ENCODE_LENGTH(f, raw, nrecord->len); - /* If 'huge' objects in this heap are not accessed directly, encode the ID also */ - if(!hdr->huge_ids_direct) - UINT64ENCODE_VAR(raw, nrecord->id, hdr->huge_id_size) - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_huge_btree2_encode() */ +} /* H5HF_huge_btree2_dir_encode() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_btree2_decode + * Function: H5HF_huge_btree2_dir_decode * * Purpose: Decode raw disk form of record into native form * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol @@ -311,34 +805,26 @@ H5HF_huge_btree2_encode(const H5F_t *f, const H5B2_class_t *cls, uint8_t *raw, c *------------------------------------------------------------------------- */ static herr_t -H5HF_huge_btree2_decode(const H5F_t *f, const H5B2_class_t *cls, const uint8_t *raw, void *_nrecord) +H5HF_huge_btree2_dir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord) { - H5HF_huge_bt2_rec_t *nrecord = (H5HF_huge_bt2_rec_t *)_nrecord; - const H5HF_hdr_t *hdr = (const H5HF_hdr_t *)cls->cls_private; + H5HF_huge_bt2_dir_rec_t *nrecord = (H5HF_huge_bt2_dir_rec_t *)_nrecord; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_decode) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_decode) - /* Decode the record's common fields */ + /* Decode the record's fields */ H5F_addr_decode(f, &raw, &nrecord->addr); H5F_DECODE_LENGTH(f, raw, nrecord->len); - /* If 'huge' objects in this heap are not accessed directly, decode the ID also */ - if(!hdr->huge_ids_direct) - UINT64DECODE_VAR(raw, nrecord->id, hdr->huge_id_size) - else - nrecord->id = 0; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_huge_btree2_decode() */ +} /* H5HF_huge_btree2_dir_decode() */ /*------------------------------------------------------------------------- - * Function: H5HF_huge_btree2_debug + * Function: H5HF_huge_btree2_dir_debug * * Purpose: Debug native form of record * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol @@ -347,24 +833,261 @@ H5HF_huge_btree2_decode(const H5F_t *f, const H5B2_class_t *cls, const uint8_t * *------------------------------------------------------------------------- */ static herr_t -H5HF_huge_btree2_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, - int indent, int fwidth, const H5B2_class_t *cls, const void *_nrecord, +H5HF_huge_btree2_dir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_nrecord, const void UNUSED *_udata) { - const H5HF_huge_bt2_rec_t *nrecord = (const H5HF_huge_bt2_rec_t *)_nrecord; - const H5HF_hdr_t *hdr = (const H5HF_hdr_t *)cls->cls_private; + const H5HF_huge_bt2_dir_rec_t *nrecord = (const H5HF_huge_bt2_dir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_dir_debug) + + HDfprintf(stream, "%*s%-*s {%a, %Hu}\n", indent, "", fwidth, "Record:", + nrecord->addr, nrecord->len); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_dir_debug() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_bt2_filt_dir_found + * + * Purpose: Retrieve record for directly accessed, filtered 'huge' object, + * when it's found in the v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_bt2_filt_dir_found) + +#ifdef QAK +HDfprintf(stderr, "%s: nrecord = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_bt2_filt_dir_found", + ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->addr, + ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->len, + ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->filter_mask, + ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->obj_size); +#endif /* QAK */ + *(H5HF_huge_bt2_filt_dir_rec_t *)op_data = *(const H5HF_huge_bt2_filt_dir_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_bt2_filt_dir_found() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_bt2_filt_dir_remove + * + * Purpose: Free space for directly accessed, filtered 'huge' object, as + * v2 B-tree is being deleted or v2 B-tree node is removed + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *_udata) +{ + H5HF_huge_remove_ud1_t *udata = (H5HF_huge_remove_ud1_t *)_udata; /* User callback data */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_bt2_filt_dir_remove) + + /* Free the space in the file for the object being removed */ + if(H5MF_xfree(udata->hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, udata->dxpl_id, ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->addr, ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->len) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free space for huge object on disk") + + /* Set the length of the object removed */ + udata->obj_len = ((const H5HF_huge_bt2_filt_dir_rec_t *)nrecord)->obj_size; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_huge_bt2_filt_dir_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_dir_store + * + * Purpose: Store native information into record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_dir_store(void *nrecord, const void *udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_store) + + *(H5HF_huge_bt2_filt_dir_rec_t *)nrecord = *(const H5HF_huge_bt2_filt_dir_rec_t *)udata; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_dir_store() */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_debug) + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_dir_retrieve + * + * Purpose: Retrieve native information from record for v2 B-tree + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_dir_retrieve(void *udata, const void *nrecord) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_retrieve) + + *(H5HF_huge_bt2_filt_dir_rec_t *)udata = *(const H5HF_huge_bt2_filt_dir_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_dir_retrieve() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_dir_compare + * + * Purpose: Compare two native information records, according to some key + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_dir_compare(const void *_rec1, const void *_rec2) +{ + const H5HF_huge_bt2_filt_dir_rec_t *rec1 = (const H5HF_huge_bt2_filt_dir_rec_t *)_rec1; + const H5HF_huge_bt2_filt_dir_rec_t *rec2 = (const H5HF_huge_bt2_filt_dir_rec_t *)_rec2; + herr_t ret_value; /* Return value */ - HDassert(nrecord); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_compare) - if(hdr->huge_ids_direct) - HDfprintf(stream, "%*s%-*s {%a, %Hu}\n", indent, "", fwidth, "Record:", - nrecord->addr, nrecord->len); +#ifdef QAK +HDfprintf(stderr, "%s: rec1 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_btree2_filt_dir_compare", rec1->addr, rec1->len, rec1->filter_mask, rec1->obj_size); +HDfprintf(stderr, "%s: rec2 = {%a, %Hu, %x, %Hu}\n", "H5HF_huge_btree2_filt_dir_compare", rec2->addr, rec2->len, rec2->filter_mask, rec2->obj_size); +#endif /* QAK */ + if(rec1->addr < rec2->addr) + ret_value = -1; + else if(rec1->addr > rec2->addr) + ret_value = 1; + else if(rec1->len < rec2->len) + ret_value = -1; + else if(rec1->len > rec2->len) + ret_value = 1; else - HDfprintf(stream, "%*s%-*s {%a, %Hu, %Hu}\n", indent, "", fwidth, "Record:", - nrecord->addr, nrecord->len, nrecord->id); + ret_value = 0; + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_huge_btree2_filt_dir_compare() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_dir_encode + * + * Purpose: Encode native information into raw form for storing on disk + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_dir_encode(const H5F_t *f, uint8_t *raw, const void *_nrecord) +{ + const H5HF_huge_bt2_filt_dir_rec_t *nrecord = (const H5HF_huge_bt2_filt_dir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_encode) + + /* Encode the record's fields */ + H5F_addr_encode(f, &raw, nrecord->addr); + H5F_ENCODE_LENGTH(f, raw, nrecord->len); + UINT32ENCODE(raw, nrecord->filter_mask); + H5F_ENCODE_LENGTH(f, raw, nrecord->obj_size); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_dir_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_dir_decode + * + * Purpose: Decode raw disk form of record into native form + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_dir_decode(const H5F_t *f, const uint8_t *raw, void *_nrecord) +{ + H5HF_huge_bt2_filt_dir_rec_t *nrecord = (H5HF_huge_bt2_filt_dir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_decode) + + /* Decode the record's fields */ + H5F_addr_decode(f, &raw, &nrecord->addr); + H5F_DECODE_LENGTH(f, raw, nrecord->len); + UINT32DECODE(raw, nrecord->filter_mask); + H5F_DECODE_LENGTH(f, raw, nrecord->obj_size); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_huge_btree2_filt_dir_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_btree2_filt_dir_debug + * + * Purpose: Debug native form of record + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, August 15, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_huge_btree2_filt_dir_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_nrecord, const void UNUSED *_udata) +{ + const H5HF_huge_bt2_filt_dir_rec_t *nrecord = (const H5HF_huge_bt2_filt_dir_rec_t *)_nrecord; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_huge_btree2_filt_dir_debug) + + HDfprintf(stream, "%*s%-*s {%a, %Hu, %x, %Hu}\n", indent, "", fwidth, "Record:", + nrecord->addr, nrecord->len, nrecord->filter_mask, nrecord->obj_size); FUNC_LEAVE_NOAPI(SUCCEED) -} /* H5HF_huge_btree2_debug() */ +} /* H5HF_huge_btree2_filt_dir_debug() */ diff --git a/src/H5HFcache.c b/src/H5HFcache.c index e174260..63e4e46 100644 --- a/src/H5HFcache.c +++ b/src/H5HFcache.c @@ -35,6 +35,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ #include "H5HFpkg.h" /* Fractal heaps */ +#include "H5MMprivate.h" /* Memory management */ #include "H5Vprivate.h" /* Vectors and arrays */ /****************/ @@ -309,8 +310,9 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); if(metadata_chksum != 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect metadata checksum for fractal heap header") - /* Heap ID length */ - UINT16DECODE(p, hdr->id_len); + /* General heap information */ + UINT16DECODE(p, hdr->id_len); /* Heap ID length */ + UINT16DECODE(p, hdr->filter_len); /* I/O filters' encoded length */ /* Heap status flags */ /* (bit 0: "huge" object IDs have wrapped) */ @@ -333,13 +335,62 @@ HDfprintf(stderr, "%s: Load heap header, addr = %a\n", FUNC, addr); H5F_DECODE_LENGTH(f, p, hdr->man_nobjs); H5F_DECODE_LENGTH(f, p, hdr->huge_size); H5F_DECODE_LENGTH(f, p, hdr->huge_nobjs); + H5F_DECODE_LENGTH(f, p, hdr->tiny_size); + H5F_DECODE_LENGTH(f, p, hdr->tiny_nobjs); /* Managed objects' doubling-table info */ if(H5HF_dtable_decode(hdr->f, &p, &(hdr->man_dtable)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, NULL, "unable to encode managed obj. doubling table info") + /* Sanity check */ HDassert((size_t)(p - buf) == size); + /* Check for I/O filter information to decode */ + if(hdr->filter_len > 0) { + size_t filter_info_size; /* Size of filter information */ + H5O_pline_t *pline; /* Pipeline information from the header on disk */ + + /* Compute the size of the extra filter information */ + filter_info_size = hdr->sizeof_size /* Size of size for filtered root direct block */ + + 4 /* Size of filter mask for filtered root direct block */ + + hdr->filter_len; /* Size of encoded I/O filter info */ + + /* Check if the current buffer can be re-used, or needs to be re-sized */ + if(filter_info_size > size) { + if((buf = H5FL_BLK_REALLOC(header_block, buf, filter_info_size)) == NULL) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, NULL, "can't allocate space to decode I/O pipeline filters") + } /* end if */ + + /* Read in I/O filter information */ + if(H5F_block_read(f, H5FD_MEM_FHEAP_HDR, (addr + size), filter_info_size, dxpl_id, buf) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_READERROR, NULL, "can't read fractal heap header's I/O pipeline filter info") + + p = buf; + + /* Decode the size of a filtered root direct block */ + H5F_DECODE_LENGTH(f, p, hdr->pline_root_direct_size); + + /* Decode the filter mask for a filtered root direct block */ + UINT32DECODE(p, hdr->pline_root_direct_filter_mask); + + /* Decode I/O filter information */ + if(NULL == (pline = H5O_decode(hdr->f, p, H5O_PLINE_ID))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't decode I/O pipeline filters") + + /* Copy the information into the header's I/O pipeline structure */ + if(NULL == H5O_copy(H5O_PLINE_ID, pline, &(hdr->pline))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, NULL, "can't copy I/O filter pipeline") + + /* Release the space allocated for the I/O pipeline filters */ + H5O_free(H5O_PLINE_ID, pline); + + /* Compute the heap header's size */ + hdr->heap_size = size + filter_info_size; + } /* end if */ + else + /* Set the heap header's size */ + hdr->heap_size = size; + /* Finish initialization of heap header */ if(H5HF_hdr_finish_init(hdr) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, NULL, "can't finish initializing shared fractal heap header") @@ -398,7 +449,7 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a HDassert(hdr->dirty); /* Compute the size of the heap header on disk */ - size = H5HF_HEADER_SIZE(hdr); + size = hdr->heap_size; /* Allocate temporary buffer */ if((buf = H5FL_BLK_MALLOC(header_block, size)) == NULL) @@ -422,8 +473,9 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a HDmemset(p, 0, (size_t)4); p += 4; - /* Heap ID length */ - UINT16ENCODE(p, hdr->id_len); + /* General heap information */ + UINT16ENCODE(p, hdr->id_len); /* Heap ID length */ + UINT16ENCODE(p, hdr->filter_len); /* I/O filters' encoded length */ /* Heap status flags */ /* (bit 0: "huge" object IDs have wrapped) */ @@ -447,11 +499,27 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a H5F_ENCODE_LENGTH(f, p, hdr->man_nobjs); H5F_ENCODE_LENGTH(f, p, hdr->huge_size); H5F_ENCODE_LENGTH(f, p, hdr->huge_nobjs); + H5F_ENCODE_LENGTH(f, p, hdr->tiny_size); + H5F_ENCODE_LENGTH(f, p, hdr->tiny_nobjs); /* Managed objects' doubling-table info */ if(H5HF_dtable_encode(hdr->f, &p, &(hdr->man_dtable)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "unable to encode managed obj. doubling table info") + /* Check for I/O filter information to encode */ + if(hdr->filter_len > 0) { + /* Encode the size of a filtered root direct block */ + H5F_ENCODE_LENGTH(f, p, hdr->pline_root_direct_size); + + /* Encode the filter mask for a filtered root direct block */ + UINT32ENCODE(p, hdr->pline_root_direct_filter_mask); + + /* Encode I/O filter information */ + if(H5O_encode(hdr->f, p, &(hdr->pline), H5O_PLINE_ID) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTENCODE, FAIL, "can't encode I/O pipeline fiters") + p += hdr->filter_len; + } /* end if */ + /* Write the heap header. */ HDassert((size_t)(p - buf) == size); if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0) @@ -500,6 +568,10 @@ H5HF_cache_hdr_dest(H5F_t UNUSED *f, H5HF_hdr_t *hdr) /* Free the block size lookup table for the doubling table */ H5HF_dtable_dest(&hdr->man_dtable); + /* Release any I/O pipeline filter information */ + if(hdr->pline.nused) + H5O_reset(H5O_PLINE_ID, &(hdr->pline)); + /* Free the shared info itself */ H5FL_FREE(H5HF_hdr_t, hdr); @@ -570,7 +642,7 @@ H5HF_cache_hdr_size(const H5F_t UNUSED *f, const H5HF_hdr_t *hdr, size_t *size_p HDassert(size_ptr); /* Set size value */ - *size_ptr = H5HF_HEADER_SIZE(hdr); + *size_ptr = hdr->heap_size; FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_cache_hdr_size() */ @@ -595,6 +667,7 @@ static H5HF_direct_t * 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_hdr_t *hdr; /* Shared fractal heap 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 */ @@ -614,11 +687,22 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemset(&dblock->cache_info, 0, sizeof(H5AC_info_t)); + /* Get the pointer to the shared heap header */ + hdr = par_info->hdr; + /* Share common heap information */ - dblock->hdr = par_info->hdr; - if(H5HF_hdr_incr(dblock->hdr) < 0) + dblock->hdr = hdr; + if(H5HF_hdr_incr(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") +#ifdef LATER + /* Check for I/O filters on this heap */ + if(hdr->filter_len > 0) { +HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, NULL, "I/O filters not supported yet") + } /* end if */ +#endif /* LATER */ + /* Set block's internal information */ dblock->size = *size; dblock->blk_off_size = H5HF_SIZEOF_OFFSET_LEN(dblock->size); @@ -656,7 +740,7 @@ 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, dblock->hdr->heap_addr)) + if(H5F_addr_ne(heap_addr, hdr->heap_addr)) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") /* Address of parent block */ @@ -669,7 +753,7 @@ H5HF_cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_size, } /* end if */ /* Offset of heap within the heap's address space */ - UINT64DECODE_VAR(p, dblock->block_off, dblock->hdr->heap_off_size); + UINT64DECODE_VAR(p, dblock->block_off, hdr->heap_off_size); /* Set return value */ ret_value = dblock; @@ -709,6 +793,8 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, if(dblock->cache_info.is_dirty) { H5HF_hdr_t *hdr; /* Shared fractal heap information */ + void *write_buf; /* Pointer to buffer to write out */ + size_t write_size; /* Size of buffer to write out */ uint8_t *p; /* Pointer into raw data buffer */ /* Get the pointer to the shared heap header */ @@ -742,10 +828,46 @@ H5HF_cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, /* Sanity check */ HDassert((size_t)(p - dblock->blk) == H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr)); +#ifdef LATER + /* Check for I/O filters on this heap */ + if(hdr->filter_len > 0) { + H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */ + size_t nbytes; /* Number of bytes used */ + unsigned filter_mask; /* Filter mask for block */ + + /* Allocate buffer to perform I/O filtering on */ + write_size = dblock->size; + if(NULL == (write_buf = H5MM_malloc(write_size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") + HDmemcpy(write_buf, dblock->blk, write_size); + + /* Push direct block data through I/O filter pipeline */ + nbytes = write_size; + if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_ENABLE_EDC, + filter_cb, &nbytes, &write_size, &write_buf) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "output pipeline failed") +HDfprintf(stderr, "%s: nbytes = %Zu, write_size = %Zu, write_buf = %p\n", FUNC, nbytes, write_size, write_buf); +HDfprintf(stderr, "%s: dblock->size = %Zu, dblock->blk = %p\n", FUNC, dblock->size, dblock->blk); + +HDfprintf(stderr, "%s: I/O filters not supported yet!\n", FUNC); +HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "I/O filters not supported yet") + } /* end if */ + else { +#endif /* LATER */ + write_buf = dblock->blk; + write_size = dblock->size; +#ifdef LATER + } /* end else */ +#endif /* LATER */ + /* Write the direct block */ - if(H5F_block_write(f, H5FD_MEM_FHEAP_DBLOCK, addr, (size_t)dblock->size, dxpl_id, dblock->blk) < 0) + if(H5F_block_write(f, H5FD_MEM_FHEAP_DBLOCK, addr, write_size, dxpl_id, write_buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap direct block to disk") + /* Release the write buffer, if it was allocated */ + if(write_buf != dblock->blk) + H5MM_xfree(write_buf); + dblock->cache_info.is_dirty = FALSE; } /* end if */ @@ -892,6 +1014,7 @@ H5HF_cache_dblock_size(const H5F_t UNUSED *f, const H5HF_direct_t *dblock, size_ static H5HF_indirect_t * H5HF_cache_iblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_nrows, void *_par_info) { + H5HF_hdr_t *hdr; /* Shared fractal heap information */ const unsigned *nrows = (const unsigned *)_nrows; /* # of rows in indirect block */ H5HF_parent_t *par_info = (H5HF_parent_t *)_par_info; /* Shared parent information */ H5HF_indirect_t *iblock = NULL; /* Indirect block info */ @@ -917,9 +1040,12 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") HDmemset(&iblock->cache_info, 0, sizeof(H5AC_info_t)); + /* Get the pointer to the shared heap header */ + hdr = par_info->hdr; + /* Share common heap information */ - iblock->hdr = par_info->hdr; - if(H5HF_hdr_incr(iblock->hdr) < 0) + iblock->hdr = hdr; + if(H5HF_hdr_incr(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") /* Set block's internal information */ @@ -929,7 +1055,7 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); iblock->nchildren = 0; /* Compute size of indirect block */ - iblock->size = H5HF_MAN_INDIRECT_SIZE(iblock->hdr, iblock); + iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); /* Allocate buffer to decode block */ /* XXX: Use free list factories? */ @@ -964,7 +1090,7 @@ 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, iblock->hdr->heap_addr)) + if(H5F_addr_ne(heap_addr, hdr->heap_addr)) HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "incorrect heap header address for direct block") /* Address of parent block */ @@ -980,31 +1106,59 @@ HDfprintf(stderr, "%s: Load indirect block, addr = %a\n", FUNC, addr); } /* end if */ else { /* Set max. # of rows in this block */ - iblock->max_rows = iblock->hdr->man_dtable.max_root_rows; + iblock->max_rows = hdr->man_dtable.max_root_rows; } /* end else */ /* Offset of heap within the heap's address space */ - UINT64DECODE_VAR(p, iblock->block_off, iblock->hdr->heap_off_size); + UINT64DECODE_VAR(p, iblock->block_off, hdr->heap_off_size); - /* Allocate & decode indirect block entry tables */ + /* Allocate & decode child block entry tables */ HDassert(iblock->nrows > 0); - if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (size_t)(iblock->nrows * iblock->hdr->man_dtable.cparam.width)))) + if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for direct entries") - for(u = 0; u < (iblock->nrows * iblock->hdr->man_dtable.cparam.width); u++) { + if(hdr->filter_len > 0) { + unsigned dir_rows; /* Number of direct rows in this indirect block */ + + /* Compute the number of direct rows for this indirect block */ + dir_rows = MIN(iblock->nrows, hdr->man_dtable.max_direct_rows); + + /* Allocate indirect block filtered entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_MALLOC(H5HF_indirect_filt_ent_t, (size_t)(dir_rows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for block entries") + } /* end if */ + else + iblock->filt_ents = NULL; + for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) { /* Decode child block address */ H5F_addr_decode(f, &p, &(iblock->ents[u].addr)); + /* Check for heap with I/O filters */ + if(hdr->filter_len > 0) { + /* Sanity check */ + HDassert(iblock->filt_ents); + + /* Decode extra information for direct blocks */ + if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) { + /* Size of filtered direct block */ + H5F_DECODE_LENGTH(f, p, iblock->filt_ents[u].size); + + /* Sanity check */ + /* (either both the address & size are defined or both are + * not defined) + */ + HDassert((H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size) + || (!H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size == 0)); + + /* I/O filter mask for filtered direct block */ + UINT32DECODE(p, iblock->filt_ents[u].filter_mask); + } /* end if */ + } /* end if */ + /* Count child blocks */ if(H5F_addr_defined(iblock->ents[u].addr)) { iblock->nchildren++; iblock->max_child = u; } /* end if */ - -#ifdef LATER - /* Decode direct & indirect blocks differently (later, when direct blocks can be compressed) */ - 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) -#endif /* LATER */ #ifdef QAK HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].addr); #endif /* QAK */ @@ -1113,6 +1267,31 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add /* Encode child block address */ H5F_addr_encode(f, &p, iblock->ents[u].addr); + /* Check for heap with I/O filters */ + if(hdr->filter_len > 0) { + /* Sanity check */ + HDassert(iblock->filt_ents); + + /* Encode extra information for direct blocks */ + if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) { +#ifdef QAK +HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->filt_ents[u].size, iblock->filt_ents[u].filter_mask); +#endif /* QAK */ + /* Sanity check */ + /* (either both the address & size are defined or both are + * not defined) + */ + HDassert((H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size) + || (!H5F_addr_defined(iblock->ents[u].addr) && iblock->filt_ents[u].size == 0)); + + /* Size of filtered direct block */ + H5F_ENCODE_LENGTH(f, p, iblock->filt_ents[u].size); + + /* I/O filter mask for filtered direct block */ + UINT32ENCODE(p, iblock->filt_ents[u].filter_mask); + } /* end if */ + } /* end if */ + #ifndef NDEBUG /* Count child blocks */ if(H5F_addr_defined(iblock->ents[u].addr)) { @@ -1121,12 +1300,6 @@ HDfprintf(stderr, "%s: iblock->ents[%Zu] = {%a}\n", FUNC, u, iblock->ents[u].add max_child = u; } /* end if */ #endif /* NDEBUG */ - -#ifdef LATER - /* Encode direct & indirect blocks differently (when direct blocks can be compressed) */ - if(u < (hdr->man_dtable.max_direct_rows * hdr->man_dtable.cparam.width)) - UINT32ENCODE_VAR(p, iblock->ents[u].free_space, hdr->man_dtable.max_dir_blk_off_size) -#endif /* LATER */ } /* end for */ /* Sanity check */ @@ -1197,6 +1370,8 @@ HDfprintf(stderr, "%s: Destroying indirect block\n", FUNC); /* Release entry tables */ if(iblock->ents) H5FL_SEQ_FREE(H5HF_indirect_ent_t, iblock->ents); + if(iblock->filt_ents) + H5FL_SEQ_FREE(H5HF_indirect_filt_ent_t, iblock->filt_ents); /* Free fractal heap indirect block info */ H5FL_FREE(H5HF_indirect_t, iblock); diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c index cfff2ca..b7d8b79 100644 --- a/src/H5HFdbg.c +++ b/src/H5HFdbg.c @@ -216,9 +216,6 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, "Objects stored in 'debugging' format:", hdr->debug_objs); HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth, - "I/O filters present:", - hdr->have_io_filter); - HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth, "'Write once' flag:", hdr->write_once); HDfprintf(stream, "%*s%-*s %t\n", indent, "", fwidth, @@ -257,9 +254,22 @@ H5HF_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, "Address of v2 B-tree for 'huge' objects:", hdr->huge_bt2_addr); + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "'Tiny' object space used:", + hdr->tiny_size); + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "Number of 'tiny' objects in heap:", + hdr->tiny_nobjs); HDfprintf(stream, "%*sManaged Objects Doubling-Table Info...\n", indent, ""); - H5HF_dtable_debug(&hdr->man_dtable, stream, indent + 3, MAX(0, fwidth -3)); + H5HF_dtable_debug(&hdr->man_dtable, stream, indent + 3, MAX(0, fwidth - 3)); + + /* Print information about I/O filters */ + if(hdr->filter_len > 0) { + HDfprintf(stream, "%*sI/O filter Info...\n", indent, ""); + H5O_debug_id(H5O_PLINE_ID, f, dxpl_id, &(hdr->pline), stream, + indent + 3, MAX(0, fwidth - 3)); + } /* end if */ done: if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0) diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index a0af4b1..8376da4 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -232,7 +232,7 @@ done: /*------------------------------------------------------------------------- - * Function: H5HF_hdr_finish_init_pahse2 + * Function: H5HF_hdr_finish_init_phase2 * * Purpose: Second phase to finish initializing info in shared heap header * @@ -281,7 +281,11 @@ HDfprintf(stderr, "%s: row_max_dblock_free[%Zu] = %Zu\n", FUNC, u, hdr->man_dtab /* Initialize the information for tracking 'huge' objects */ if(H5HF_huge_init(hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't informan for tracking huge objects") + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize info for tracking huge objects") + + /* Initialize the information for tracking 'tiny' objects */ + if(H5HF_tiny_init(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize info for tracking tiny objects") done: FUNC_LEAVE_NOAPI(ret_value) @@ -343,7 +347,6 @@ haddr_t H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) { H5HF_hdr_t *hdr = NULL; /* The new fractal heap header information */ - haddr_t hdr_addr; /* Heap header address */ size_t dblock_overhead; /* Direct block's overhead */ haddr_t ret_value; /* Return value */ @@ -388,12 +391,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, HADDR_UNDEF, "max. heap size too large for file") #endif /* NDEBUG */ - /* Allocate space for the header on disk */ - 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, HADDR_UNDEF, "file allocation failed for fractal heap header") - /* Set the creation parameters for the heap */ - hdr->heap_addr = hdr_addr; hdr->max_man_size = cparam->max_man_size; HDmemcpy(&(hdr->man_dtable.cparam), &(cparam->managed), sizeof(H5HF_dtable_cparam_t)); @@ -410,9 +408,37 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) hdr->dirty = TRUE; /* First phase of header final initialization */ + /* (doesn't need ID length set up) */ if(H5HF_hdr_finish_init_phase1(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #1 of header final initialization") + /* Copy any I/O filter pipeline */ + /* (This code is not in the "finish init phase" routines because those + * routines are also called from the cache 'load' callback, and the filter + * length is already set in that case (its stored in the header on disk)) + */ + if(cparam->pline.nused > 0) { + /* Copy the I/O filter pipeline from the creation parameters to the header */ + if(NULL == H5O_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline") + + /* Compute the I/O filters' encoded size */ + if(0 == (hdr->filter_len = H5O_raw_size(H5O_PLINE_ID, hdr->f, &(hdr->pline)))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTGETSIZE, HADDR_UNDEF, "can't get I/O filter pipeline size") +#ifdef QAK +HDfprintf(stderr, "%s: hdr->filter_len = %u\n", FUNC, hdr->filter_len); +#endif /* QAK */ + + /* Compute size of header on disk */ + hdr->heap_size = H5HF_HEADER_SIZE(hdr) /* Base header size */ + + hdr->sizeof_size /* Size of size for filtered root direct block */ + + 4 /* Size of filter mask for filtered root direct block */ + + hdr->filter_len; /* Size of encoded I/O filter info */ + } /* end if */ + else + /* Set size of header on disk */ + hdr->heap_size = H5HF_HEADER_SIZE(hdr); + /* Set the length of IDs in the heap */ /* (This code is not in the "finish init phase" routines because those * routines are also called from the cache 'load' callback, and the ID @@ -423,39 +449,55 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) hdr->id_len = 1 + hdr->heap_off_size + hdr->heap_len_size; break; - case 1: /* Set the length of heap IDs to just enough to hold the file offset & length of 'huge' objects in the heap */ - hdr->id_len = 1 + hdr->sizeof_size + hdr->sizeof_addr; + case 1: /* Set the length of heap IDs to just enough to hold the information needed to directly access 'huge' objects in the heap */ + if(hdr->filter_len > 0) + hdr->id_len = 1 /* ID flags */ + + hdr->sizeof_addr /* Address of filtered object */ + + hdr->sizeof_size /* Length of filtered object */ + + 4 /* Filter mask for filtered object */ + + hdr->sizeof_size; /* Size of de-filtered object in memory */ + else + hdr->id_len = 1 /* ID flags */ + + hdr->sizeof_addr /* Address of object */ + + hdr->sizeof_size; /* Length of object */ break; default: /* Use the requested size for the heap ID */ -/* XXX: Limit heap ID length to 4096 + 1, due to # of bits required to store - * length of 'tiny' objects (12 bits) - */ -HDfprintf(stderr, "%s: Varying size of heap IDs not supported yet!\n", FUNC); -HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, HADDR_UNDEF, "varying size of heap IDs not supported yet") + /* Check boundaries */ + if(cparam->id_len < (1 + hdr->heap_off_size + hdr->heap_len_size)) + HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, HADDR_UNDEF, "ID length not large enough to hold object IDs") + else if(cparam->id_len > H5HF_MAX_ID_LEN) + HGOTO_ERROR(H5E_HEAP, H5E_BADRANGE, HADDR_UNDEF, "ID length too large to store tiny object lengths") + + /* Use the requested size for the heap ID */ + hdr->id_len = cparam->id_len; break; } /* end switch */ +#ifdef QAK +HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); +#endif /* QAK */ /* Second phase of header final initialization */ + /* (needs ID and filter lengths set up) */ if(H5HF_hdr_finish_init_phase2(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #2 of header final initialization") -#ifdef QAK -HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); -#endif /* QAK */ - /* Extra checking for possible gap between max. direct block size minus * overhead and "huge" object size */ dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); if((cparam->managed.max_direct_size - dblock_overhead) < cparam->max_man_size) HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, HADDR_UNDEF, "max. direct block size not large enough to hold all managed blocks") + /* Allocate space for the header on disk */ + if(HADDR_UNDEF == (hdr->heap_addr = H5MF_alloc(f, H5FD_MEM_FHEAP_HDR, dxpl_id, (hsize_t)hdr->heap_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, HADDR_UNDEF, "file allocation failed for fractal heap header") + /* Cache the new fractal heap header */ - if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache") /* Set address of heap header to return */ - ret_value = hdr_addr; + ret_value = hdr->heap_addr; done: if(!H5F_addr_defined(ret_value)) diff --git a/src/H5HFhuge.c b/src/H5HFhuge.c index 7a47dba..cc5b824 100644 --- a/src/H5HFhuge.c +++ b/src/H5HFhuge.c @@ -37,6 +37,7 @@ #include "H5Eprivate.h" /* Error handling */ #include "H5HFpkg.h" /* Fractal heaps */ #include "H5MFprivate.h" /* File memory management */ +#include "H5MMprivate.h" /* Memory management */ /****************/ @@ -63,20 +64,25 @@ /* Local Prototypes */ /********************/ -/* local v2 B-tree operations */ +/* Local v2 B-tree operations */ static herr_t H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id); /* v2 B-tree function callbacks (in H5HFbtree2.c) */ -herr_t H5HF_huge_bt2_found(const void *nrecord, void *op_data); -herr_t H5HF_huge_bt2_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_indir_found(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_indir_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_indir_found(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_indir_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_dir_remove(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_dir_found(const void *nrecord, void *op_data); +herr_t H5HF_huge_bt2_filt_dir_remove(const void *nrecord, void *op_data); + +/* Local 'huge' object support routines */ +static hsize_t H5HF_huge_new_id(H5HF_hdr_t *hdr); /*********************/ /* Package Variables */ /*********************/ -/* The v2 B-tree class for tracking huge objects */ -H5_DLLVAR const H5B2_class_t H5HF_BTREE2[1]; - /*****************************/ /* Library Private Variables */ @@ -104,6 +110,7 @@ H5_DLLVAR const H5B2_class_t H5HF_BTREE2[1]; static herr_t H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id) { + const H5B2_class_t *bt2_class; /* v2 B-tree class to use */ size_t rrec_size; /* Size of 'raw' records on disk */ herr_t ret_value = SUCCEED; /* Return value */ @@ -115,13 +122,45 @@ H5HF_huge_bt2_create(H5HF_hdr_t *hdr, hid_t dxpl_id) HDassert(hdr); /* Compute the size of 'raw' records on disk */ - if(hdr->huge_ids_direct) - rrec_size = hdr->sizeof_addr + hdr->sizeof_size; - else - rrec_size = hdr->sizeof_addr + hdr->sizeof_size + hdr->huge_id_size; + /* (Note: the size for huge IDs could be set to 'huge_id_size', instead + * of 'sizeof_size', but that would make the v2 B-tree callback routines + * depend on the heap header, which makes the v2 B-tree flush routines + * difficult to write. "Waste" an extra byte or for small heaps (where + * the 'huge_id_size' is < 'sizeof_size' in order to make this easier -QAK) + */ + if(hdr->huge_ids_direct) { + if(hdr->filter_len > 0) { + rrec_size = hdr->sizeof_addr /* Address of object */ + + hdr->sizeof_size /* Length of object */ + + 4 /* Filter mask for filtered object */ + + hdr->sizeof_size; /* Size of de-filtered object in memory */ + bt2_class = H5HF_BT2_FILT_DIR; + } /* end if */ + else { + rrec_size = hdr->sizeof_addr /* Address of object */ + + hdr->sizeof_size; /* Length of object */ + bt2_class = H5HF_BT2_DIR; + } /* end else */ + } /* end if */ + else { + if (hdr->filter_len > 0) { + rrec_size = hdr->sizeof_addr /* Address of filtered object */ + + hdr->sizeof_size /* Length of filtered object */ + + 4 /* Filter mask for filtered object */ + + hdr->sizeof_size /* Size of de-filtered object in memory */ + + hdr->sizeof_size; /* Unique ID for object */ + bt2_class = H5HF_BT2_FILT_INDIR; + } /* end if */ + else { + rrec_size = hdr->sizeof_addr /* Address of object */ + + hdr->sizeof_size /* Length of object */ + + hdr->sizeof_size; /* Unique ID for object */ + bt2_class = H5HF_BT2_INDIR; + } /* end else */ + } /* end else */ /* Create v2 B-tree for tracking 'huge' objects */ - if(H5B2_create(hdr->f, dxpl_id, &hdr->huge_bt2_class, (size_t)H5HF_HUGE_BT2_NODE_SIZE, rrec_size, + if(H5B2_create(hdr->f, dxpl_id, bt2_class, (size_t)H5HF_HUGE_BT2_NODE_SIZE, rrec_size, H5HF_HUGE_BT2_SPLIT_PERC, H5HF_HUGE_BT2_MERGE_PERC, &hdr->huge_bt2_addr/*out*/) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects") @@ -156,22 +195,38 @@ H5HF_huge_init(H5HF_hdr_t *hdr) /* Compute information about 'huge' objects for the heap */ /* Check if we can completely hold the 'huge' object's offset & length in - * the file in the heap ID (which will speed up accessing it) + * the file in the heap ID (which will speed up accessing it) and we don't + * have any I/O pipeline filters. */ #ifdef QAK HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_len); +HDfprintf(stderr, "%s: hdr->filter_len = %u\n", "H5HF_huge_init", (unsigned)hdr->filter_len); #endif /* QAK */ - if((hdr->sizeof_addr + hdr->sizeof_size) <= (hdr->id_len - 1)) { - /* Indicate that v2 B-tree doesn't have to be used to locate object */ - hdr->huge_ids_direct = TRUE; - - /* Set the size of 'huge' object IDs */ - hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size; + if(hdr->filter_len > 0) { + if((hdr->id_len - 1) >= (hdr->sizeof_addr + hdr->sizeof_size + 4 + hdr->sizeof_size)) { + /* Indicate that v2 B-tree doesn't have to be used to locate object */ + hdr->huge_ids_direct = TRUE; + + /* Set the size of 'huge' object IDs */ + hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size + hdr->sizeof_size; + } /* end if */ + else + /* Indicate that v2 B-tree must be used to access object */ + hdr->huge_ids_direct = FALSE; } /* end if */ else { - /* Indicate that v2 B-tree must be used to locate object */ - hdr->huge_ids_direct = FALSE; - + if((hdr->sizeof_addr + hdr->sizeof_size) <= (hdr->id_len - 1)) { + /* Indicate that v2 B-tree doesn't have to be used to locate object */ + hdr->huge_ids_direct = TRUE; + + /* Set the size of 'huge' object IDs */ + hdr->huge_id_size = hdr->sizeof_addr + hdr->sizeof_size; + } /* end if */ + else + /* Indicate that v2 B-tree must be used to locate object */ + hdr->huge_ids_direct = FALSE; + } /* end else */ + if(!hdr->huge_ids_direct) { /* Set the size and maximum value of 'huge' object ID */ if((hdr->id_len - 1) < sizeof(hsize_t)) { hdr->huge_id_size = hdr->id_len - 1; @@ -181,28 +236,65 @@ HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_ hdr->huge_id_size = sizeof(hsize_t); hdr->huge_max_id = HSIZET_MAX; } /* end else */ - } /* end else */ + } /* end if */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_huge_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_huge_new_id + * + * Purpose: Determine a new ID for an indirectly accessed 'huge' object + * (either filtered or not) + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 15 2006 + * + *------------------------------------------------------------------------- + */ +static hsize_t +H5HF_huge_new_id(H5HF_hdr_t *hdr) +{ + hsize_t new_id; /* New object's ID */ + hsize_t ret_value; /* Return value */ + FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_new_id) - /* Set up the v2 B-tree for tracking 'huge' objects in the heap */ + /* + * Check arguments. + */ + HDassert(hdr); - /* Copy the standard v2 B-tree class */ - HDmemcpy(&hdr->huge_bt2_class, H5HF_BTREE2, sizeof(H5B2_class_t)); + /* Check for wrapping around 'huge' object ID space */ + if(hdr->huge_ids_wrapped) + /* Fail for now - eventually should iterate through v2 B-tree, looking for available ID */ + HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, 0, "wrapping 'huge' object IDs not supported yet") + else { + /* Get new 'huge' object ID to use for object */ + /* (avoids using ID 0) */ + new_id = ++hdr->huge_next_id; - /* Set the native record size for the v2 B-tree */ - hdr->huge_bt2_class.nrec_size = sizeof(H5HF_huge_bt2_rec_t); + /* Check for wrapping 'huge' object IDs around */ + if(hdr->huge_next_id == hdr->huge_max_id) + hdr->huge_ids_wrapped = TRUE; + } /* end else */ - /* Set v2 B-tree class's "class private" pointer to the heap header */ - hdr->huge_bt2_class.cls_private = hdr; + /* Set return value */ + ret_value = new_id; - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HF_huge_init() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_huge_new_id() */ /*------------------------------------------------------------------------- * Function: H5HF_huge_insert * - * Purpose: Insert a huge object into the file and track it + * Purpose: Insert a 'huge' object into the file and track it * * Return: SUCCEED/FAIL * @@ -213,12 +305,14 @@ HDfprintf(stderr, "%s: hdr->id_len = %u\n", "H5HF_huge_init", (unsigned)hdr->id_ *------------------------------------------------------------------------- */ herr_t -H5HF_huge_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, const void *obj, +H5HF_huge_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, void *obj, void *_id) { - H5HF_huge_bt2_rec_t obj_rec; /* Record for tracking object */ uint8_t *id = (uint8_t *)_id; /* Pointer to ID buffer */ haddr_t obj_addr; /* Address of object in the file */ + void *write_buf; /* Pointer to buffer to write */ + size_t write_size; /* Size of [possibly filtered] object written to file */ + unsigned filter_mask = 0; /* Filter mask for object (only used for filtered objects) */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_insert) @@ -239,54 +333,142 @@ HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); if(H5HF_huge_bt2_create(hdr, dxpl_id) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking 'huge' heap objects") + /* Check for I/O pipeline filter on heap */ + if(hdr->filter_len > 0) { + H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */ + size_t nbytes; /* Number of bytes used */ + + /* Allocate buffer to perform I/O filtering on */ + write_size = obj_size; + if(NULL == (write_buf = H5MM_malloc(write_size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") + HDmemcpy(write_buf, obj, write_size); + + /* Push direct block data through I/O filter pipeline */ + nbytes = write_size; + if(H5Z_pipeline(&(hdr->pline), 0, &filter_mask, H5Z_NO_EDC, + filter_cb, &nbytes, &write_size, &write_buf) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "output pipeline failed") +#ifdef QAK +HDfprintf(stderr, "%s: nbytes = %Zu, write_size = %Zu, write_buf = %p\n", FUNC, nbytes, write_size, write_buf); +HDfprintf(stderr, "%s: obj_size = %Zu, obj = %p\n", FUNC, obj_size, obj); +#endif /* QAK */ + + /* Update size of object on disk */ + write_size = nbytes; + } /* end if */ + else { + write_buf = obj; + write_size = obj_size; + } /* end else */ + /* Allocate space in the file for storing the 'huge' object */ - if(HADDR_UNDEF == (obj_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, dxpl_id, (hsize_t)obj_size))) + if(HADDR_UNDEF == (obj_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, dxpl_id, (hsize_t)write_size))) HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap huge object") /* Write the object's data to disk */ - if(H5F_block_write(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, obj_size, dxpl_id, obj) < 0) + if(H5F_block_write(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, write_size, dxpl_id, write_buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "writing 'huge' object to file failed") - /* Initialize shared part of record for tracking object in v2 B-tree */ - obj_rec.addr = obj_addr; - obj_rec.len = obj_size; + /* Release buffer for writing, if we had one */ + if(write_buf != obj) { + HDassert(hdr->filter_len > 0); + H5MM_xfree(write_buf); + } /* end if */ + + /* Perform different actions for directly & indirectly accessed 'huge' objects */ + if(hdr->huge_ids_direct) { + if(hdr->filter_len > 0) { + H5HF_huge_bt2_filt_dir_rec_t obj_rec; /* Record for tracking object */ + + /* Initialize record for tracking object in v2 B-tree */ + obj_rec.addr = obj_addr; + obj_rec.len = write_size; + obj_rec.filter_mask = filter_mask; + obj_rec.obj_size = obj_size; +#ifdef QAK +HDfprintf(stderr, "%s: obj_rec = {%a, %Hu, %x, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len, obj_rec.filter_mask, obj_rec.obj_size); +#endif /* QAK */ - /* If the 'huge' object will be indirectly accessed, through the v2 B-tree, - * create an ID for it, otherwise put a zero in for ID - */ - if(hdr->huge_ids_direct) - obj_rec.id = 0; - else { - /* Check for wrapping around 'huge' object ID space */ - if(hdr->huge_ids_wrapped) - /* Fail for now - eventually should iterate through v2 B-tree, looking for available ID */ - HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "wrapping 'huge' object IDs not supported yet") + /* Insert record for object in v2 B-tree */ + if(H5B2_insert(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, &obj_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") + + /* Encode ID for user */ + *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE; + H5F_addr_encode(hdr->f, &id, obj_addr); + H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)write_size); + UINT32ENCODE(id, filter_mask); + H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)obj_size); + } /* end if */ else { - /* Get new 'huge' object ID to use for object */ - /* (avoid using ID 0) */ - obj_rec.id = ++hdr->huge_next_id; + H5HF_huge_bt2_dir_rec_t obj_rec; /* Record for tracking object */ - /* Check for wrapping 'huge' object IDs around */ - if(hdr->huge_next_id == hdr->huge_max_id) - hdr->huge_ids_wrapped = TRUE; - } /* end else */ - } /* end else */ + /* Initialize record for tracking object in v2 B-tree */ + obj_rec.addr = obj_addr; + obj_rec.len = write_size; #ifdef QAK -HDfprintf(stderr, "%s: obj_rec = {%a, %Hu, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len, obj_rec.id); +HDfprintf(stderr, "%s: obj_rec = {%a, %Hu}\n", FUNC, obj_rec.addr, obj_rec.len); #endif /* QAK */ - /* Insert record for object in v2 B-tree */ - if(H5B2_insert(hdr->f, dxpl_id, &hdr->huge_bt2_class, hdr->huge_bt2_addr, &obj_rec) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") + /* Insert record for object in v2 B-tree */ + if(H5B2_insert(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, &obj_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") - /* Encode ID for user */ - *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE; - if(hdr->huge_ids_direct) { - H5F_addr_encode(hdr->f, &id, obj_addr); - H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)obj_size); + /* Encode ID for user */ + *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE; + H5F_addr_encode(hdr->f, &id, obj_addr); + H5F_ENCODE_LENGTH(hdr->f, id, (hsize_t)write_size); + } /* end if */ } /* end if */ - else - UINT64ENCODE_VAR(id, obj_rec.id, hdr->huge_id_size) + else { + H5HF_huge_bt2_filt_indir_rec_t filt_indir_rec; /* Record for tracking filtered object */ + H5HF_huge_bt2_indir_rec_t indir_rec; /* Record for tracking non-filtered object */ + const H5B2_class_t *bt2_class; /* v2 B-tree class to use */ + void *ins_rec; /* Pointer to record to insert */ + hsize_t new_id; /* New ID for object */ + + /* Get new ID for object */ + if(0 == (new_id = H5HF_huge_new_id(hdr))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't generate new ID for object") + + if(hdr->filter_len > 0) { + /* Initialize record for object in v2 B-tree */ + filt_indir_rec.addr = obj_addr; + filt_indir_rec.len = write_size; + filt_indir_rec.filter_mask = filter_mask; + filt_indir_rec.obj_size = obj_size; + filt_indir_rec.id = new_id; +#ifdef QAK +HDfprintf(stderr, "%s: filt_indir_rec = {%a, %Hu, %x, %Hu, %Hu}\n", FUNC, filt_indir_rec.addr, filt_indir_rec.len, filt_indir_rec.filter_mask, filt_indir_rec.obj_size, filt_indir_rec.id); +#endif /* QAK */ + + /* Set pointer to record to insert */ + ins_rec = &filt_indir_rec; + bt2_class = H5HF_BT2_FILT_INDIR; + } /* end if */ + else { + /* Initialize record for object in v2 B-tree */ + indir_rec.addr = obj_addr; + indir_rec.len = write_size; + indir_rec.id = new_id; +#ifdef QAK +HDfprintf(stderr, "%s: indir_rec = {%a, %Hu, %Hu}\n", FUNC, indir_rec.addr, indir_rec.len, indir_rec.id); +#endif /* QAK */ + + /* Set pointer to record to insert */ + ins_rec = &indir_rec; + bt2_class = H5HF_BT2_INDIR; + } /* end else */ + + /* Insert record for tracking object in v2 B-tree */ + if(H5B2_insert(hdr->f, dxpl_id, bt2_class, hdr->huge_bt2_addr, ins_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "couldn't insert object tracking record in v2 B-tree") + + /* Encode ID for user */ + *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_HUGE; + UINT64ENCODE_VAR(id, new_id, hdr->huge_id_size) + } /* end else */ /* Update statistics about heap */ hdr->huge_size += obj_size; @@ -320,7 +502,7 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, { herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5HF_huge_get_obj_len, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_get_obj_len) /* * Check arguments. @@ -330,28 +512,57 @@ H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, HDassert(id); HDassert(obj_len_p); + /* Skip over the flag byte */ + id++; + /* Check if 'huge' object ID encodes address & length directly */ if(hdr->huge_ids_direct) { - /* Skip over object offset in file */ - id += hdr->sizeof_addr; + if(hdr->filter_len > 0) { + /* Skip over filtered object info */ + id += hdr->sizeof_addr + hdr->sizeof_size + 4; + + /* Retrieve the object's length */ + H5F_DECODE_LENGTH(hdr->f, id, *obj_len_p); + } /* end if */ + else { + /* Skip over object offset in file */ + id += hdr->sizeof_addr; - /* Retrieve the object's length */ - H5F_DECODE_LENGTH(hdr->f, id, *obj_len_p); + /* Retrieve the object's length */ + H5F_DECODE_LENGTH(hdr->f, id, *obj_len_p); + } /* end else */ } /* end if */ else { - H5HF_huge_bt2_rec_t found_rec; /* Record found from tracking object */ - H5HF_huge_bt2_rec_t search_rec; /* Record for searching for object */ + if(hdr->filter_len > 0) { + H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */ + H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */ + + /* Get ID for looking up 'huge' object in v2 B-tree */ + UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) + + /* Look up object in v2 B-tree */ + if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + + /* Retrieve the object's length */ + *obj_len_p = (size_t)found_rec.obj_size; + } /* end if */ + else { + H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */ + H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */ - /* Get ID for looking up 'huge' object in v2 B-tree */ - UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) + /* Get ID for looking up 'huge' object in v2 B-tree */ + UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) - /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, &hdr->huge_bt2_class, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_found, &found_rec) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + /* Look up object in v2 B-tree */ + if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") - /* Retrieve the object's length */ - *obj_len_p = (size_t)found_rec.len; + /* Retrieve the object's length */ + *obj_len_p = (size_t)found_rec.len; + } /* end else */ } /* end else */ done: @@ -375,8 +586,10 @@ done: herr_t H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj) { + void *read_buf; /* Pointer to buffer for reading */ haddr_t obj_addr; /* Object's address in the file */ hsize_t obj_size = 0; /* Object's size in the file */ + unsigned filter_mask = 0; /* Filter mask for object (only used for filtered objects) */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_huge_read) @@ -388,33 +601,85 @@ H5HF_huge_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj) HDassert(id); HDassert(obj); + /* Skip over the flag byte */ + id++; + /* Check for 'huge' object ID that encodes address & length directly */ if(hdr->huge_ids_direct) { - /* Retrieve the object's address and length */ + /* Retrieve the object's address and length (common) */ H5F_addr_decode(hdr->f, &id, &obj_addr); H5F_DECODE_LENGTH(hdr->f, id, obj_size); + + /* Retrieve extra information needed for filtered objects */ + if(hdr->filter_len > 0) + UINT32DECODE(id, filter_mask); } /* end if */ else { - H5HF_huge_bt2_rec_t found_rec; /* Record found from tracking object */ - H5HF_huge_bt2_rec_t search_rec; /* Record for searching for object */ + if(hdr->filter_len > 0) { + H5HF_huge_bt2_filt_indir_rec_t found_rec; /* Record found from tracking object */ + H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */ + + /* Get ID for looking up 'huge' object in v2 B-tree */ + UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) + + /* Look up object in v2 B-tree */ + if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_filt_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + + /* Retrieve the object's address & length */ + obj_addr = found_rec.addr; + obj_size = found_rec.len; + filter_mask = found_rec.filter_mask; + } /* end if */ + else { + H5HF_huge_bt2_indir_rec_t found_rec; /* Record found from tracking object */ + H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */ - /* Get ID for looking up 'huge' object in v2 B-tree */ - UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) + /* Get ID for looking up 'huge' object in v2 B-tree */ + UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) - /* Look up object in v2 B-tree */ - if(H5B2_find(hdr->f, dxpl_id, &hdr->huge_bt2_class, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_found, &found_rec) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") + /* Look up object in v2 B-tree */ + if(H5B2_find(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_indir_found, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in B-tree") - /* Retrieve the object's address & length */ - obj_addr = found_rec.addr; - obj_size = found_rec.len; + /* Retrieve the object's address & length */ + obj_addr = found_rec.addr; + obj_size = found_rec.len; + } /* end else */ } /* end else */ - /* Read the object's data from the file */ - if (H5F_block_read(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, (size_t)obj_size, dxpl_id, obj) < 0) + /* Set up buffer for reading */ + if(hdr->filter_len > 0) { + if(NULL == (read_buf = H5MM_malloc((size_t)obj_size))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for pipeline buffer") + } /* end if */ + else + read_buf = obj; + + /* Read the object's (possibly filtered) data from the file */ + if(H5F_block_read(hdr->f, H5FD_MEM_FHEAP_HUGE_OBJ, obj_addr, (size_t)obj_size, dxpl_id, read_buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_READERROR, FAIL, "can't read 'huge' object's data from the file") + /* Check for I/O pipeline filter on heap */ + if(hdr->filter_len > 0) { + H5Z_cb_t filter_cb = {NULL, NULL}; /* Filter callback structure */ + size_t read_size; /* Object's size in the file */ + size_t nbytes; /* Number of bytes used */ + + /* De-filter the object */ + read_size = nbytes = obj_size; + if(H5Z_pipeline(&(hdr->pline), H5Z_FLAG_REVERSE, &filter_mask, H5Z_NO_EDC, filter_cb, &nbytes, &read_size, &read_buf) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFILTER, FAIL, "input filter failed") + + /* Copy object to user's buffer */ + HDmemcpy(obj, read_buf, nbytes); + + /* Release read buffer */ + H5MM_xfree(read_buf); + } /* end if */ + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_huge_read() */ @@ -436,7 +701,6 @@ done: herr_t H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) { - H5HF_huge_bt2_rec_t search_rec; /* Record for searching for object */ H5HF_huge_remove_ud1_t udata; /* User callback data for v2 B-tree remove call */ herr_t ret_value = SUCCEED; /* Return value */ @@ -448,26 +712,70 @@ H5HF_huge_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) HDassert(hdr); HDassert(id); + /* Skip over the flag byte */ + id++; + + /* Set up the common callback info */ + udata.hdr = hdr; + udata.dxpl_id = dxpl_id; + /* Check for 'huge' object ID that encodes address & length directly */ if(hdr->huge_ids_direct) { - /* Retrieve the object's address and length */ - /* (used as key in v2 B-tree record) */ - H5F_addr_decode(hdr->f, &id, &search_rec.addr); - H5F_DECODE_LENGTH(hdr->f, id, search_rec.len); + if(hdr->filter_len > 0) { + H5HF_huge_bt2_filt_dir_rec_t search_rec; /* Record for searching for object */ + + /* Retrieve the object's address and length */ + /* (used as key in v2 B-tree record) */ + H5F_addr_decode(hdr->f, &id, &search_rec.addr); + H5F_DECODE_LENGTH(hdr->f, id, search_rec.len); + + /* Remove the record for tracking the 'huge' object from the v2 B-tree */ + /* (space in the file for the object is freed in the 'remove' callback) */ + if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_filt_dir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + } /* end if */ + else { + H5HF_huge_bt2_dir_rec_t search_rec; /* Record for searching for object */ + + /* Retrieve the object's address and length */ + /* (used as key in v2 B-tree record) */ + H5F_addr_decode(hdr->f, &id, &search_rec.addr); + H5F_DECODE_LENGTH(hdr->f, id, search_rec.len); + + /* Remove the record for tracking the 'huge' object from the v2 B-tree */ + /* (space in the file for the object is freed in the 'remove' callback) */ + if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_dir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + } /* end else */ } /* end if */ - else - /* Get ID for looking up 'huge' object in v2 B-tree */ - UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) + else { + if(hdr->filter_len > 0) { + H5HF_huge_bt2_filt_indir_rec_t search_rec; /* Record for searching for object */ + + /* Get ID for looking up 'huge' object in v2 B-tree */ + UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) + + /* Remove the record for tracking the 'huge' object from the v2 B-tree */ + /* (space in the file for the object is freed in the 'remove' callback) */ + if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_filt_indir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + } /* end if */ + else { + H5HF_huge_bt2_indir_rec_t search_rec; /* Record for searching for object */ - /* Set up the callback info */ - udata.hdr = hdr; - udata.dxpl_id = dxpl_id; + /* Get ID for looking up 'huge' object in v2 B-tree */ + UINT64DECODE_VAR(id, search_rec.id, hdr->huge_id_size) - /* Remove the record for tracking the 'huge' object from the v2 B-tree */ - /* (space in the file for the object is freed in the 'remove' callback) */ - if(H5B2_remove(hdr->f, dxpl_id, &hdr->huge_bt2_class, hdr->huge_bt2_addr, - &search_rec, H5HF_huge_bt2_remove, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + /* Remove the record for tracking the 'huge' object from the v2 B-tree */ + /* (space in the file for the object is freed in the 'remove' callback) */ + if(H5B2_remove(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, + &search_rec, H5HF_huge_bt2_indir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + } /* end else */ + } /* end else */ /* Update statistics about heap */ hdr->huge_size -= udata.obj_len; @@ -515,7 +823,8 @@ H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id) HDassert(hdr->huge_size == 0); /* Delete the v2 B-tree */ - if(H5B2_delete(hdr->f, dxpl_id, &hdr->huge_bt2_class, hdr->huge_bt2_addr, NULL, NULL) < 0) + /* (any v2 B-tree class will work here) */ + if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, NULL, NULL) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") /* Reset the information about 'huge' objects in the file */ @@ -568,8 +877,26 @@ H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) udata.dxpl_id = dxpl_id; /* Delete the v2 B-tree */ - if(H5B2_delete(hdr->f, dxpl_id, &hdr->huge_bt2_class, hdr->huge_bt2_addr, H5HF_huge_bt2_remove, &udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + if(hdr->huge_ids_direct) { + if(hdr->filter_len > 0) { + if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_FILT_DIR, hdr->huge_bt2_addr, H5HF_huge_bt2_filt_dir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + } /* end if */ + else { + if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_DIR, hdr->huge_bt2_addr, H5HF_huge_bt2_dir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + } /* end else */ + } /* end if */ + else { + if(hdr->filter_len > 0) { + if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_FILT_INDIR, hdr->huge_bt2_addr, H5HF_huge_bt2_filt_indir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + } /* end if */ + else { + if(H5B2_delete(hdr->f, dxpl_id, H5HF_BT2_INDIR, hdr->huge_bt2_addr, H5HF_huge_bt2_indir_remove, &udata) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + } /* end else */ + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 7bb7884..70e3aac 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -70,6 +70,9 @@ H5FL_DEFINE(H5HF_indirect_t); /* Declare a free list to manage the H5HF_indirect_ent_t sequence information */ H5FL_SEQ_DEFINE(H5HF_indirect_ent_t); +/* Declare a free list to manage the H5HF_indirect_filt_ent_t sequence information */ +H5FL_SEQ_DEFINE(H5HF_indirect_filt_ent_t); + /*****************************/ /* Library Private Variables */ @@ -154,24 +157,12 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off); /* Mark block as evictable again when no child blocks depend on it */ if(iblock->rc == 0) { - H5HF_indirect_t *tmp_iblock = NULL; /* Temporary pointer to indirect block */ - #ifdef QAK HDfprintf(stderr, "%s: indirect block ref. count at zero, iblock->addr = %a\n", FUNC, iblock->addr); #endif /* QAK */ - /* Lock indirect block */ - if(iblock->nchildren == 0) { - if(NULL == (tmp_iblock = H5HF_man_iblock_protect(iblock->hdr, H5AC_dxpl_id, iblock->addr, iblock->nrows, NULL, 0, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") - HDassert(tmp_iblock == iblock); - } /* end if */ - if(H5AC_unpin_entry(iblock->hdr->f, iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block") -/* XXX: If the indirect block has no children, delete indirect block's entry - * from cache. - */ if(iblock->nchildren == 0) { #ifdef QAK HDfprintf(stderr, "%s: Removing indirect block from cache, iblock->addr = %a\n", FUNC, iblock->addr); @@ -200,10 +191,9 @@ HDfprintf(stderr, "%s: Removing indirect block from cache, iblock->addr = %a\n", if(H5MF_xfree(iblock->hdr->f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block disk space") - /* Unlock indirect block with delete flag */ - if(H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, tmp_iblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") - tmp_iblock = NULL; + /* Evict the indirect block from the metadata cache */ + if(H5AC_expunge_entry(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove indirect block from cache") } /* end if */ } /* end if */ @@ -488,15 +478,14 @@ HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, ib iblock->addr = new_addr; } /* end if */ - /* Re-allocate direct block entry table */ + /* Re-allocate child block entry array */ if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries") + HGOTO_ERROR(H5E_HEAP, 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_hdr_skip_blocks(hdr, dxpl_id, iblock, next_entry, - (new_next_entry - next_entry)) < 0) + if(H5HF_hdr_skip_blocks(hdr, dxpl_id, iblock, 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 */ @@ -509,6 +498,26 @@ HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, ib acc_dblock_free += hdr->man_dtable.row_tot_dblock_free[row]; } /* end for */ + /* Check for needing to re-allocate filtered entry array */ + if(hdr->filter_len > 0 && old_nrows < hdr->man_dtable.max_direct_rows) { + unsigned dir_rows; /* Number of direct rows in this indirect block */ + + /* Compute the number of direct rows for this indirect block */ + dir_rows = MIN(iblock->nrows, hdr->man_dtable.max_direct_rows); +HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows); + HDassert(dir_rows > old_nrows); + + /* Re-allocate filtered direct block entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_REALLOC(H5HF_indirect_filt_ent_t, iblock->filt_ents, (size_t)(dir_rows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries") + + /* Initialize new entries allocated */ + for(u = (old_nrows * hdr->man_dtable.cparam.width); u < (dir_rows * hdr->man_dtable.cparam.width); u++) { + iblock->filt_ents[u].size = 0; + iblock->filt_ents[u].filter_mask = 0; + } /* end for */ + } /* end if */ + /* 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") @@ -612,10 +621,17 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr); iblock->addr = new_addr; } /* end if */ - /* Re-allocate direct block entry table */ + /* Re-allocate child block entry array */ 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 needing to re-allocate filtered entry array */ + if(hdr->filter_len > 0 && new_nrows < hdr->man_dtable.max_direct_rows) { + /* Re-allocate filtered direct block entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_REALLOC(H5HF_indirect_filt_ent_t, iblock->filt_ents, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries") + } /* end if */ + /* 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") @@ -842,7 +858,7 @@ HDfprintf(stderr, "%s: nrows = %u, max_rows = %u\n", FUNC, nrows, max_rows); /* Compute size of buffer needed for indirect block */ iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); - /* Allocate indirect block entry tables */ + /* Allocate child block entry array */ if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries") @@ -850,6 +866,23 @@ HDfprintf(stderr, "%s: nrows = %u, max_rows = %u\n", FUNC, nrows, max_rows); for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) iblock->ents[u].addr = HADDR_UNDEF; + /* Check for I/O filters to apply to this heap */ + if(hdr->filter_len > 0) { + unsigned dir_rows; /* Number of direct rows in this indirect block */ + + /* Compute the number of direct rows for this indirect block */ + dir_rows = MIN(iblock->nrows, hdr->man_dtable.max_direct_rows); +#ifdef QAK +HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows); +#endif /* QAK */ + + /* Allocate & initialize indirect block filtered entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_CALLOC(H5HF_indirect_filt_ent_t, (size_t)(dir_rows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries") + } /* end if */ + else + iblock->filt_ents = NULL; + /* Allocate space for the indirect block on disk */ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") @@ -979,6 +1012,21 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, /* Point at the direct block */ iblock->ents[entry].addr = child_addr; + /* Check for I/O filters on this heap */ + if(iblock->hdr->filter_len > 0) { + unsigned row; /* Row for entry */ + + /* Sanity check */ + HDassert(iblock->filt_ents); + + /* Compute row for entry */ + row = entry / iblock->hdr->man_dtable.cparam.width; + + /* If this is a direct block, set its initial size */ + if(row < iblock->hdr->man_dtable.max_direct_rows) + iblock->filt_ents[entry].size = iblock->hdr->man_dtable.row_block_size[row]; + } /* end if */ + /* Check for max. entry used */ if(entry > iblock->max_child) iblock->max_child = entry; @@ -1028,9 +1076,26 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, /* Reset address of entry */ iblock->ents[entry].addr = HADDR_UNDEF; + /* Check for I/O filters on this heap */ + if(iblock->hdr->filter_len > 0) { + unsigned row; /* Row for entry */ + + /* Sanity check */ + HDassert(iblock->filt_ents); + + /* Compute row for entry */ + row = entry / iblock->hdr->man_dtable.cparam.width; + + /* If this is a direct block, set its initial size */ + if(row < iblock->hdr->man_dtable.max_direct_rows) { + iblock->filt_ents[entry].size = 0; + iblock->filt_ents[entry].filter_mask = 0; + } /* end if */ + } /* end if */ + /* Decrement the # of child blocks */ /* (If the number of children drop to 0, the indirect block will be - * removed from the heap when it's ref. count drops to zero and the + * removed from the heap when its ref. count drops to zero and the * metadata cache calls the indirect block destructor) */ iblock->nchildren--; @@ -1113,7 +1178,7 @@ H5HF_man_iblock_entry_addr(H5HF_indirect_t *iblock, unsigned entry, haddr_t *chi HDassert(iblock); HDassert(child_addr); - /* Reset address of entry */ + /* Retrieve address of entry */ *child_addr = iblock->ents[entry].addr; FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5HFman.c b/src/H5HFman.c index 30eb31c..38e8d43 100644 --- a/src/H5HFman.c +++ b/src/H5HFman.c @@ -18,7 +18,7 @@ * Feb 24 2006 * Quincey Koziol * - * Purpose: "Internal" routines for fractal heaps. + * Purpose: "Managed" object routines for fractal heaps. * *------------------------------------------------------------------------- */ @@ -394,6 +394,9 @@ H5HF_man_read(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, void *obj) HDassert(id); HDassert(obj); + /* Skip over the flag byte */ + id++; + /* Decode the object offset within the heap & it's length */ UINT64DECODE_VAR(id, obj_off, hdr->heap_off_size); UINT64DECODE_VAR(id, obj_len, hdr->heap_len_size); @@ -494,6 +497,9 @@ H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id) HDassert(hdr); HDassert(id); + /* Skip over the flag byte */ + id++; + /* Decode the object offset within the heap & it's length */ #ifdef QAK HDfprintf(stderr, "%s: fh->hdr->heap_off_size = %u, fh->hdr->heap_len_size = %u\n", FUNC, (unsigned)fh->hdr->heap_off_size, (unsigned)fh->hdr->heap_len_size); diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index 21e5468..947f3ad 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -72,6 +72,9 @@ #define H5HF_HDR_FLAGS_HUGE_ID_WRAPPED 0x01 /* Size of the fractal heap header on disk */ +/* (this is the fixed-len portion, the variable-len I/O filter information + * follows this information, if there are I/O filters for the heap) + */ #define H5HF_HEADER_SIZE(h) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE \ @@ -80,6 +83,7 @@ \ /* General heap information */ \ + 2 /* Heap ID len */ \ + + 2 /* I/O filters' encoded len */ \ + 1 /* Status flags */ \ \ /* "Huge" object fields */ \ @@ -98,6 +102,8 @@ + (h)->sizeof_size /* Number of man. objects in heap */ \ + (h)->sizeof_size /* Size of huge space in heap */ \ + (h)->sizeof_size /* Number of huge objects in heap */ \ + + (h)->sizeof_size /* Size of tiny space in heap */ \ + + (h)->sizeof_size /* Number of tiny objects in heap */ \ \ /* "Managed" object doubling table info */ \ + H5HF_DTABLE_INFO_SIZE(h) /* Size of managed obj. doubling-table info */ \ @@ -113,7 +119,14 @@ + (h)->heap_off_size /* Offset of the block in the heap */ \ ) -/* Size of managed indirect block (absolute & mapped) */ +/* Size of managed indirect block entry for a child direct block */ +#define H5HF_MAN_INDIRECT_CHILD_DIR_ENTRY_SIZE(h) ( \ + ((h)->filter_len > 0 ? \ + ((h)->sizeof_addr + (h)->sizeof_size + 4) : /* Size of entries for filtered direct blocks */ \ + (h)->sizeof_addr) /* Size of entries for un-filtered direct blocks */ \ + ) + +/* Size of managed indirect block */ #define H5HF_MAN_INDIRECT_SIZE(h, i) ( \ /* General metadata fields */ \ H5HF_METADATA_PREFIX_SIZE \ @@ -121,7 +134,7 @@ /* Fractal heap managed, absolutely mapped indirect block specific fields */ \ + (h)->sizeof_addr /* File address of heap owning the block */ \ + (h)->heap_off_size /* Offset of the block in the heap */ \ - + (MIN((i)->nrows, (h)->man_dtable.max_direct_rows) * (h)->man_dtable.cparam.width * (h)->sizeof_addr) /* Size of entries for direct blocks */ \ + + (MIN((i)->nrows, (h)->man_dtable.max_direct_rows) * (h)->man_dtable.cparam.width * H5HF_MAN_INDIRECT_CHILD_DIR_ENTRY_SIZE(h)) /* 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) /* Size of entries for indirect blocks */ \ ) @@ -289,12 +302,12 @@ typedef struct H5HF_hdr_t { /* General header information (stored in header) */ unsigned id_len; /* Size of heap IDs (in bytes) */ + unsigned filter_len; /* Size of I/O filter information (in bytes) */ /* Flags for heap settings (stored in status byte in header) */ 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? */ - hbool_t huge_ids_wrapped; /* Have "huge" object IDs wrapped around? */ + hbool_t huge_ids_wrapped; /* Have "huge" object IDs wrapped around? */ /* Doubling table information (partially stored in header) */ /* (Partially set by user, partially derived/updated internally) */ @@ -309,38 +322,54 @@ typedef struct H5HF_hdr_t { hsize_t huge_next_id; /* Next ID to use for indirectly tracked 'huge' object */ haddr_t huge_bt2_addr; /* Address of v2 B-tree for tracking "huge" object info */ + /* I/O filter support (stored in header, if any are used) */ + H5O_pline_t pline; /* I/O filter pipeline for heap objects */ + size_t pline_root_direct_size; /* Size of filtered root direct block */ + unsigned pline_root_direct_filter_mask; /* I/O filter mask for filtered root direct block */ + /* Statistics for heap (stored in header) */ - 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 man_iter_off; /* Offset of iterator in managed heap space */ - hsize_t man_nobjs; /* Number of "managed" objects in heap */ - hsize_t huge_size; /* Total size of "huge" objects in heap */ - hsize_t huge_nobjs; /* Number of "huge" objects in heap */ + 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 man_iter_off; /* Offset of iterator in 'managed' heap space */ + hsize_t man_nobjs; /* Number of 'managed' objects in heap */ + hsize_t huge_size; /* Total size of 'huge' objects in heap */ + hsize_t huge_nobjs; /* Number of 'huge' objects in heap */ + hsize_t tiny_size; /* Total size of 'tiny' objects in heap */ + hsize_t tiny_nobjs; /* Number of 'tiny' objects in heap */ /* Cached/computed values (not stored in header) */ size_t rc; /* Reference count of objects using heap header */ hbool_t dirty; /* Shared info is modified */ haddr_t heap_addr; /* Address of heap header in the file */ + size_t heap_size; /* Size 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 */ H5FS_t *fspace; /* Free space list for objects in heap */ H5HF_block_iter_t next_block; /* Block iterator for searching for next block with space */ - H5B2_class_t huge_bt2_class; /* v2 B-tree class information for "huge" object tracking */ hsize_t huge_max_id; /* Max. 'huge' heap ID before rolling 'huge' heap IDs over */ hbool_t huge_ids_direct; /* Flag to indicate that 'huge' object's offset & length are stored directly in heap ID */ - unsigned char huge_id_size; /* Size of 'huge' heap IDs (in bytes) */ + size_t tiny_max_len; /* Max. size of tiny objects for this heap */ + hbool_t tiny_len_extended; /* Flag to indicate that 'tiny' object's length is stored in extended form (i.e. w/extra byte) */ + unsigned char huge_id_size; /* Size of 'huge' heap IDs (in bytes) */ unsigned char heap_off_size; /* Size of heap offsets (in bytes) */ unsigned char heap_len_size; /* Size of heap ID lengths (in bytes) */ } H5HF_hdr_t; -/* Indirect block entry */ +/* Common indirect block doubling table entry */ +/* (common between entries pointing to direct & indirect child blocks) */ typedef struct H5HF_indirect_ent_t { haddr_t addr; /* Direct block's address */ -/* XXX: Will need space for block size, for blocks with I/O filters */ } H5HF_indirect_ent_t; +/* Extern indirect block doubling table entry for compressed direct blocks */ +/* (only exists for indirect blocks in heaps that have I/O filters) */ +typedef struct H5HF_indirect_filt_ent_t { + size_t size; /* Size of child direct block, after passing though I/O filters */ + unsigned filter_mask; /* Excluded filters for child direct block */ +} H5HF_indirect_filt_ent_t; + /* Fractal heap indirect block */ struct H5HF_indirect_t { /* Information for H5AC cache functions, _must_ be first field in structure */ @@ -361,6 +390,7 @@ struct H5HF_indirect_t { /* Stored values */ hsize_t block_off; /* Offset of the block within the heap's address space */ H5HF_indirect_ent_t *ents; /* Pointer to block entry table */ + H5HF_indirect_filt_ent_t *filt_ents; /* Pointer to filtered information for direct blocks */ }; /* A fractal heap direct block */ @@ -393,6 +423,36 @@ typedef struct H5HF_parent_t { unsigned entry; /* Location of block in parent's entry table */ } H5HF_parent_t; +/* Typedef for indirectly accessed 'huge' object's records in the v2 B-tree */ +typedef struct H5HF_huge_bt2_indir_rec_t { + haddr_t addr; /* Address of the object in the file */ + hsize_t len; /* Length of the object in the file */ + hsize_t id; /* ID used for object (not used for 'huge' objects directly accessed) */ +} H5HF_huge_bt2_indir_rec_t; + +/* Typedef for indirectly accessed, filtered 'huge' object's records in the v2 B-tree */ +typedef struct H5HF_huge_bt2_filt_indir_rec_t { + haddr_t addr; /* Address of the filtered object in the file */ + hsize_t len; /* Length of the filtered object in the file */ + unsigned filter_mask; /* I/O pipeline filter mask for filtered object in the file */ + hsize_t obj_size; /* Size of the de-filtered object in memory */ + hsize_t id; /* ID used for object (not used for 'huge' objects directly accessed) */ +} H5HF_huge_bt2_filt_indir_rec_t; + +/* Typedef for directly accessed 'huge' object's records in the v2 B-tree */ +typedef struct H5HF_huge_bt2_dir_rec_t { + haddr_t addr; /* Address of the object in the file */ + hsize_t len; /* Length of the object in the file */ +} H5HF_huge_bt2_dir_rec_t; + +/* Typedef for directly accessed, filtered 'huge' object's records in the v2 B-tree */ +typedef struct H5HF_huge_bt2_filt_dir_rec_t { + haddr_t addr; /* Address of the filtered object in the file */ + hsize_t len; /* Length of the filtered object in the file */ + unsigned filter_mask; /* I/O pipeline filter mask for filtered object in the file */ + hsize_t obj_size; /* Size of the de-filtered object in memory */ +} H5HF_huge_bt2_filt_dir_rec_t; + /* User data for free space section 'add' callback */ typedef struct { H5HF_hdr_t *hdr; /* Fractal heap header */ @@ -406,13 +466,6 @@ typedef struct { hsize_t obj_len; /* Length of object removed (out) */ } H5HF_huge_remove_ud1_t; -/* Typedef for 'huge' object's records in the v2 B-tree */ -typedef struct H5HF_huge_bt2_rec_t { - haddr_t addr; /* Address of the object in the file */ - hsize_t len; /* Length of the object in the file */ - hsize_t id; /* ID used for object (not used for 'huge' objects directly accessed) */ -} H5HF_huge_bt2_rec_t; - /*****************************/ /* Package Private Variables */ /*****************************/ @@ -426,6 +479,18 @@ 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]; +/* The v2 B-tree class for tracking indirectly accessed 'huge' objects */ +H5_DLLVAR const H5B2_class_t H5HF_BT2_INDIR[1]; + +/* The v2 B-tree class for tracking indirectly accessed filtered 'huge' objects */ +H5_DLLVAR const H5B2_class_t H5HF_BT2_FILT_INDIR[1]; + +/* The v2 B-tree class for tracking directly accessed 'huge' objects */ +H5_DLLVAR const H5B2_class_t H5HF_BT2_DIR[1]; + +/* The v2 B-tree class for tracking directly accessed filtered 'huge' objects */ +H5_DLLVAR const H5B2_class_t H5HF_BT2_FILT_DIR[1]; + /* H5HF single section inherits serializable properties from H5FS_section_class_t */ H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_SINGLE[1]; @@ -453,6 +518,9 @@ H5FL_EXTERN(H5HF_indirect_t); /* Declare a free list to manage the H5HF_indirect_ent_t sequence information */ H5FL_SEQ_EXTERN(H5HF_indirect_ent_t); +/* Declare a free list to manage the H5HF_indirect_filt_ent_t sequence information */ +H5FL_SEQ_EXTERN(H5HF_indirect_filt_ent_t); + /******************************/ /* Package Private Prototypes */ @@ -543,10 +611,10 @@ H5_DLL herr_t H5HF_man_read(H5HF_hdr_t *fh, hid_t dxpl_id, const uint8_t *id, void *obj); H5_DLL herr_t H5HF_man_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id); -/* "Huge" object routines */ +/* 'Huge' object routines */ H5_DLL herr_t H5HF_huge_init(H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_huge_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, size_t obj_size, - const void *obj, void *id); + void *obj, void *id); H5_DLL herr_t H5HF_huge_get_obj_len(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *id, size_t *obj_len_p); H5_DLL herr_t H5HF_huge_read(H5HF_hdr_t *fh, hid_t dxpl_id, const uint8_t *id, @@ -555,6 +623,15 @@ H5_DLL herr_t H5HF_huge_remove(H5HF_hdr_t *fh, hid_t dxpl_id, const uint8_t *id) H5_DLL herr_t H5HF_huge_term(H5HF_hdr_t *hdr, hid_t dxpl_id); H5_DLL herr_t H5HF_huge_delete(H5HF_hdr_t *hdr, hid_t dxpl_id); +/* 'Tiny' object routines */ +H5_DLL herr_t H5HF_tiny_init(H5HF_hdr_t *hdr); +H5_DLL herr_t H5HF_tiny_insert(H5HF_hdr_t *hdr, size_t obj_size, const void *obj, + void *id); +H5_DLL herr_t H5HF_tiny_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, + size_t *obj_len_p); +H5_DLL herr_t H5HF_tiny_read(H5HF_hdr_t *fh, const uint8_t *id, void *obj); +H5_DLL herr_t H5HF_tiny_remove(H5HF_hdr_t *fh, const uint8_t *id); + /* Metadata cache callbacks */ H5_DLL herr_t H5HF_cache_hdr_dest(H5F_t *f, H5HF_hdr_t *hdr); H5_DLL herr_t H5HF_cache_dblock_dest(H5F_t *f, H5HF_direct_t *dblock); @@ -619,6 +696,7 @@ H5_DLL herr_t H5HF_sect_indirect_add(H5HF_hdr_t *hdr, hid_t dxpl_id, /* Testing routines */ #ifdef H5HF_TESTING H5_DLL herr_t H5HF_get_cparam_test(const H5HF_t *fh, H5HF_create_t *cparam); +H5_DLL int H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2); H5_DLL unsigned H5HF_get_max_root_rows(const H5HF_t *fh); H5_DLL unsigned H5HF_get_dtable_width_test(const H5HF_t *fh); H5_DLL unsigned H5HF_get_dtable_max_drows_test(const H5HF_t *fh); @@ -626,6 +704,12 @@ H5_DLL unsigned H5HF_get_iblock_max_drows_test(const H5HF_t *fh, unsigned pos); H5_DLL hsize_t H5HF_get_dblock_size_test(const H5HF_t *fh, unsigned row); H5_DLL hsize_t H5HF_get_dblock_free_test(const H5HF_t *fh, unsigned row); H5_DLL herr_t H5HF_get_id_off_test(const H5HF_t *fh, const void *id, hsize_t *obj_off); +H5_DLL herr_t H5HF_get_id_type_test(const H5HF_t *fh, const void *id, + unsigned char *obj_type); +H5_DLL herr_t H5HF_get_tiny_info_test(const H5HF_t *fh, size_t *max_len, + hbool_t *len_extended); +H5_DLL herr_t H5HF_get_huge_info_test(const H5HF_t *fh, hsize_t *next_id, + hbool_t *ids_direct); #endif /* H5HF_TESTING */ #endif /* _H5HFpkg_H */ diff --git a/src/H5HFprivate.h b/src/H5HFprivate.h index 1c9a3ba..20415c1 100644 --- a/src/H5HFprivate.h +++ b/src/H5HFprivate.h @@ -31,11 +31,17 @@ /* Private headers needed by this file */ #include "H5Fprivate.h" /* File access */ +#include "H5Oprivate.h" /* Object headers */ /**************************/ /* Library Private Macros */ /**************************/ +/* Limit heap ID length to 4096 + 1, due to # of bits required to store + * length of 'tiny' objects (12 bits) + */ +#define H5HF_MAX_ID_LEN (4096 + 1) + /****************************/ /* Library Private Typedefs */ @@ -60,22 +66,27 @@ typedef struct H5HF_create_t { /* (i.e. min. size of object to store standalone) */ uint16_t id_len; /* Length of IDs to use for heap objects */ /* (0 - make ID just large enough to hold length & offset of object in the heap) */ - /* (1 - make ID just large enough to allow 'huge' objects to hold the file address & length of the 'huge' object) */ + /* (1 - make ID just large enough to allow 'huge' objects to be accessed directly) */ /* (n - make ID 'n' bytes in size) */ + H5O_pline_t pline; /* I/O filter pipeline to apply to direct blocks & 'huge' objects */ } H5HF_create_t; /* Fractal heap metadata statistics info */ typedef struct H5HF_stat_t { - /* "Managed" object info */ - hsize_t man_size; /* Size of managed space in heap */ - hsize_t man_alloc_size; /* Size of managed space allocated in heap */ - hsize_t man_iter_off; /* Offset of "new block" iterator in managed heap space */ - hsize_t man_free_space; /* Free space within managed heap blocks */ - hsize_t man_nobjs; /* Number of "managed" objects in heap */ - - /* "Huge" object info */ - hsize_t huge_size; /* Size of "huge" objects in heap */ - hsize_t huge_nobjs; /* Number of "huge" objects in heap */ + /* 'Managed' object info */ + hsize_t man_size; /* Size of 'managed' space in heap */ + hsize_t man_alloc_size; /* Size of 'managed' space allocated in heap */ + hsize_t man_iter_off; /* Offset of "new block" iterator in 'managed' heap space */ + hsize_t man_free_space; /* Free space within 'managed' heap blocks */ + hsize_t man_nobjs; /* Number of 'managed' objects in heap */ + + /* 'Huge' object info */ + hsize_t huge_size; /* Size of 'huge' objects in heap */ + hsize_t huge_nobjs; /* Number of 'huge' objects in heap */ + + /* 'Tiny' object info */ + hsize_t tiny_size; /* Size of 'tiny' objects in heap */ + hsize_t tiny_nobjs; /* Number of 'tiny' objects in heap */ } H5HF_stat_t; /* Fractal heap info (forward decl - defined in H5HFpkg.h) */ diff --git a/src/H5HFstat.c b/src/H5HFstat.c index 0924dae..1c6e887 100644 --- a/src/H5HFstat.c +++ b/src/H5HFstat.c @@ -99,6 +99,8 @@ H5HF_stat_info(const H5HF_t *fh, H5HF_stat_t *stats) stats->man_free_space = fh->hdr->total_man_free; stats->huge_size = fh->hdr->huge_size; stats->huge_nobjs = fh->hdr->huge_nobjs; + stats->tiny_size = fh->hdr->tiny_size; + stats->tiny_nobjs = fh->hdr->tiny_nobjs; /* XXX: Add more metadata statistics for the heap */ FUNC_LEAVE_NOAPI(SUCCEED) diff --git a/src/H5HFtest.c b/src/H5HFtest.c index d1daa2b..bbe93ca 100644 --- a/src/H5HFtest.c +++ b/src/H5HFtest.c @@ -93,14 +93,122 @@ H5HF_get_cparam_test(const H5HF_t *fh, H5HF_create_t *cparam) HDassert(cparam); /* Get fractal heap creation parameters */ + if(fh->hdr->id_len == (unsigned)(1 + fh->hdr->heap_off_size + fh->hdr->heap_len_size)) + cparam->id_len = 0; + else if(fh->hdr->id_len == (1 + fh->hdr->sizeof_size + fh->hdr->sizeof_addr)) + cparam->id_len = 1; + else + cparam->id_len = fh->hdr->id_len; cparam->max_man_size = fh->hdr->max_man_size; HDmemcpy(&(cparam->managed), &(fh->hdr->man_dtable.cparam), sizeof(H5HF_dtable_cparam_t)); + H5O_copy(H5O_PLINE_ID, &(fh->hdr->pline), &(cparam->pline)); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_get_cparam_test() */ /*------------------------------------------------------------------------- + * Function: H5HF_cmp_cparam_test + * + * Purpose: Compare the parameters used to create the fractal heap + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 14, 2006 + * + *------------------------------------------------------------------------- + */ +int +H5HF_cmp_cparam_test(const H5HF_create_t *cparam1, const H5HF_create_t *cparam2) +{ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_cmp_cparam_test) + + /* Check arguments. */ + HDassert(cparam1); + HDassert(cparam2); + + /* Compare doubling table parameters */ + if((ret_value = HDmemcmp(&(cparam1->managed), &(cparam2->managed), sizeof(H5HF_dtable_cparam_t)))) + HGOTO_DONE(ret_value) + + /* Compare other general parameters for heap */ + if(cparam1->max_man_size < cparam2->max_man_size) + HGOTO_DONE(-1) + else if(cparam1->max_man_size > cparam2->max_man_size) + HGOTO_DONE(1) + if(cparam1->id_len < cparam2->id_len) + HGOTO_DONE(-1) + else if(cparam1->id_len > cparam2->id_len) + HGOTO_DONE(1) + + /* Compare "important" parameters for any I/O pipeline filters */ + if(cparam1->pline.nused < cparam2->pline.nused) + HGOTO_DONE(-1) + else if(cparam1->pline.nused > cparam2->pline.nused) + HGOTO_DONE(1) + else { + size_t u, v; /* Local index variables */ + + /* Compare each filter */ + for(u = 0; u < cparam1->pline.nused; u++) { + /* Check filter ID */ + if(cparam1->pline.filter[u].id < cparam2->pline.filter[u].id) + HGOTO_DONE(-1) + else if(cparam1->pline.filter[u].id > cparam2->pline.filter[u].id) + HGOTO_DONE(1) + + /* Check filter flags */ + if(cparam1->pline.filter[u].flags < cparam2->pline.filter[u].flags) + HGOTO_DONE(-1) + else if(cparam1->pline.filter[u].flags > cparam2->pline.filter[u].flags) + HGOTO_DONE(1) + +/* Don't worry about comparing the filter names right now... */ +/* (they are expanded during the encode/decode process, but aren't copied + * during the H5Z_append operation, generating false positive failures) + */ +#ifdef QAK + /* Check filter name */ +HDfprintf(stderr, "%s: Check 1.0\n", "H5HF_cmp_cparam_test"); +HDfprintf(stderr, "%s: cparam1->pline.filter[%Zu].name = %s\n", "H5HF_cmp_cparam_test", u, (cparam1->pline.filter[u].name ? cparam1->pline.filter[u].name : "")); +HDfprintf(stderr, "%s: cparam2->pline.filter[%Zu].name = %s\n", "H5HF_cmp_cparam_test", u, (cparam2->pline.filter[u].name ? cparam2->pline.filter[u].name : "")); + if(!cparam1->pline.filter[u].name && cparam2->pline.filter[u].name) + HGOTO_DONE(-1) + else if(cparam1->pline.filter[u].name && !cparam2->pline.filter[u].name) + HGOTO_DONE(1) + else if(cparam1->pline.filter[u].name && cparam2->pline.filter[u].name) { + if((ret_value = HDstrcmp(cparam1->pline.filter[u].name, cparam2->pline.filter[u].name))) + HGOTO_DONE(ret_value) + } /* end if */ +#endif /* QAK */ + + /* Check # of filter parameters */ + if(cparam1->pline.filter[u].cd_nelmts < cparam2->pline.filter[u].cd_nelmts) + HGOTO_DONE(-1) + else if(cparam1->pline.filter[u].cd_nelmts > cparam2->pline.filter[u].cd_nelmts) + HGOTO_DONE(1) + + /* Check filter parameters */ + for(v = 0; v < cparam1->pline.filter[u].cd_nelmts; v++) { + if(cparam1->pline.filter[u].cd_values[v] < cparam2->pline.filter[u].cd_values[v]) + HGOTO_DONE(-1) + else if(cparam1->pline.filter[u].cd_values[v] > cparam2->pline.filter[u].cd_values[v]) + HGOTO_DONE(1) + } /* end for */ + + } /* end for */ + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_get_cparam_test() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_get_max_root_rows * * Purpose: Retrieve the max. # of rows in the root indirect block @@ -296,7 +404,7 @@ H5HF_get_dblock_free_test(const H5HF_t *fh, unsigned row) /*------------------------------------------------------------------------- * Function: H5HF_get_id_off_test * - * Purpose: Retrieve the offset for a heap ID + * Purpose: Retrieve the offset for a [managed] heap ID * * Return: Success: non-negative * @@ -322,8 +430,106 @@ H5HF_get_id_off_test(const H5HF_t *fh, const void *_id, hsize_t *obj_off) /* Get the offset for a 'normal' heap ID */ id++; - UINT64DECODE_VAR(id, *obj_off, fh->hdr->heap_off_size); \ + UINT64DECODE_VAR(id, *obj_off, fh->hdr->heap_off_size); FUNC_LEAVE_NOAPI(SUCCEED) } /* H5HF_get_id_off_test() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_get_id_type_test + * + * Purpose: Retrieve the type of a heap ID + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 14, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_get_id_type_test(const H5HF_t *fh, const void *_id, unsigned char *obj_type) +{ + const uint8_t *id = (const uint8_t *)_id; /* Object ID */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_get_id_type_test) + + /* Check arguments. */ + HDassert(fh); + HDassert(fh->hdr); + HDassert(id); + HDassert(obj_type); + + /* Get the type for a heap ID */ + *obj_type = *id & H5HF_ID_TYPE_MASK; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_get_id_type_test() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_get_tiny_info_test + * + * Purpose: Retrieve information about tiny object's ID length + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 14, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_get_tiny_info_test(const H5HF_t *fh, size_t *max_len, + hbool_t *len_extended) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_get_tiny_info_test) + + /* Check arguments. */ + HDassert(fh); + HDassert(fh->hdr); + HDassert(max_len); + HDassert(len_extended); + + /* Retrieve information about tiny object's ID encoding in a heap */ + *max_len = fh->hdr->tiny_max_len; + *len_extended = fh->hdr->tiny_len_extended; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_get_tiny_info_test() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_get_huge_info_test + * + * Purpose: Retrieve information about huge object's ID length + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Monday, August 14, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_get_huge_info_test(const H5HF_t *fh, hsize_t *next_id, hbool_t *ids_direct) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_get_huge_info_test) + + /* Check arguments. */ + HDassert(fh); + HDassert(fh->hdr); + HDassert(ids_direct); + + /* Retrieve information about tiny object's ID encoding in a heap */ + if(next_id) + *next_id = fh->hdr->huge_next_id; + *ids_direct = fh->hdr->huge_ids_direct; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_get_huge_info_test() */ + diff --git a/src/H5HFtiny.c b/src/H5HFtiny.c new file mode 100644 index 0000000..5183a39 --- /dev/null +++ b/src/H5HFtiny.c @@ -0,0 +1,326 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: H5HFtiny.c + * Aug 14 2006 + * Quincey Koziol + * + * Purpose: Routines for "tiny" objects in fractal heap + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* 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 */ + + +/****************/ +/* Local Macros */ +/****************/ + +/* Tiny object length information */ +#define H5HF_TINY_LEN_SHORT 16 /* Max. length able to be encoded in first heap ID byte */ +#define H5HF_TINY_MASK_SHORT 0x0F /* Mask for length in first heap ID byte */ +#define H5HF_TINY_MASK_EXT 0x0FFF /* Mask for length in two heap ID bytes */ +#define H5HF_TINY_MASK_EXT_1 0x0F00 /* Mask for length in first byte of two heap ID bytes */ +#define H5HF_TINY_MASK_EXT_2 0x00FF /* Mask for length in second byte of two heap ID bytes */ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + +/*------------------------------------------------------------------------- + * Function: H5HF_tiny_init + * + * Purpose: Initialize information for tracking 'tiny' objects + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 14 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_tiny_init(H5HF_hdr_t *hdr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_tiny_init) + + /* + * Check arguments. + */ + HDassert(hdr); + + /* Compute information about 'tiny' objects for the heap */ + + /* Check if tiny objects need an extra byte for their length */ + /* (account for boundary condition when length of an object would need an + * extra byte, but using that byte means that the extra length byte is + * unneccessary) + */ + if((hdr->id_len - 1) <= H5HF_TINY_LEN_SHORT) { + hdr->tiny_max_len = hdr->id_len - 1; + hdr->tiny_len_extended = FALSE; + } /* end if */ + else if((hdr->id_len - 1) == (H5HF_TINY_LEN_SHORT + 1)) { + hdr->tiny_max_len = H5HF_TINY_LEN_SHORT; + hdr->tiny_len_extended = FALSE; + } /* end if */ + else { + hdr->tiny_max_len = hdr->id_len - 2; + hdr->tiny_len_extended = TRUE; + } /* end else */ + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_tiny_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_tiny_insert + * + * Purpose: Pack a 'tiny' object in a heap ID + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 14 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_tiny_insert(H5HF_hdr_t *hdr, size_t obj_size, const void *obj, void *_id) +{ + uint8_t *id = (uint8_t *)_id; /* Pointer to ID buffer */ + size_t enc_obj_size; /* Encoded object size */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_tiny_insert) +#ifdef QAK +HDfprintf(stderr, "%s: obj_size = %Zu\n", FUNC, obj_size); +#endif /* QAK */ + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(obj_size <= hdr->tiny_max_len); + HDassert(obj_size <= (H5HF_TINY_MASK_EXT + 1)); + HDassert(obj); + HDassert(id); + + /* Adjust object's size for encoding it */ + enc_obj_size = obj_size - 1; + + /* Encode object into ID */ + if(!hdr->tiny_len_extended) { + *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_TINY | + (enc_obj_size & H5HF_TINY_MASK_SHORT); + } /* end if */ + else { + *id++ = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_TINY | + ((enc_obj_size & H5HF_TINY_MASK_EXT_1) >> 8); + *id++ = enc_obj_size & H5HF_TINY_MASK_EXT_2; + } /* end else */ + HDmemcpy(id, obj, obj_size); + + /* Update statistics about heap */ + hdr->tiny_size += obj_size; + hdr->tiny_nobjs++; + + /* Mark heap header as modified */ + if(H5HF_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_tiny_insert() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_tiny_get_obj_len + * + * Purpose: Get the size of a 'tiny' object in a fractal heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 14 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_tiny_get_obj_len(H5HF_hdr_t *hdr, const uint8_t *id, size_t *obj_len_p) +{ + size_t enc_obj_size; /* Encoded object size */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_tiny_get_obj_len) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(id); + HDassert(obj_len_p); + + /* Check if 'tiny' object ID is in extended form, and retrieve encoded size */ + if(!hdr->tiny_len_extended) + enc_obj_size = *id & H5HF_TINY_MASK_SHORT; + else + enc_obj_size = ((*id & H5HF_TINY_MASK_EXT_1) << 8) | (*(id + 1) & H5HF_TINY_MASK_EXT_2); + + /* Set the object's length */ + *obj_len_p = enc_obj_size + 1; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_tiny_get_obj_len() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_tiny_read + * + * Purpose: Read a 'tiny' object from the heap + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 8 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_tiny_read(H5HF_hdr_t *hdr, const uint8_t *id, void *obj) +{ + size_t enc_obj_size; /* Encoded object size */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_tiny_read) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(id); + HDassert(obj); + + /* Check if 'tiny' object ID is in extended form */ + if(!hdr->tiny_len_extended) { + /* Retrieve the object's encoded length */ + enc_obj_size = *id & H5HF_TINY_MASK_SHORT; + + /* Advance past flag byte(s) */ + id++; + } /* end if */ + else { + /* Retrieve the object's encoded length */ + enc_obj_size = ((*id & H5HF_TINY_MASK_EXT_1) << 8) | (*(id + 1) & H5HF_TINY_MASK_EXT_2); + + /* Advance past flag byte(s) */ + id+=2; + } /* end else */ + + /* Retrieve the object's data */ + HDmemcpy(obj, id, (enc_obj_size + 1)); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_tiny_read() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_tiny_remove + * + * Purpose: Remove a 'tiny' object from the heap statistics + * + * Return: SUCCEED/FAIL + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Aug 14 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_tiny_remove(H5HF_hdr_t *hdr, const uint8_t *id) +{ + size_t enc_obj_size; /* Encoded object size */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_tiny_remove) + + /* + * Check arguments. + */ + HDassert(hdr); + HDassert(id); + + /* Check if 'tiny' object ID is in extended form */ + if(!hdr->tiny_len_extended) + enc_obj_size = *id & H5HF_TINY_MASK_SHORT; + else + enc_obj_size = ((*id & H5HF_TINY_MASK_EXT_1) << 8) | (*(id + 1) & H5HF_TINY_MASK_EXT_2); + + /* Update statistics about heap */ + hdr->tiny_size -= (enc_obj_size + 1); + hdr->tiny_nobjs--; + + /* Mark heap header as modified */ + if(H5HF_hdr_dirty(hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5HF_tiny_remove() */ + diff --git a/src/Makefile.am b/src/Makefile.am index 4d464bb..86ce039 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,7 +53,7 @@ libhdf5_la_SOURCES= H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c H5Gtraverse.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ - H5HFspace.c H5HFstat.c H5HFtest.c \ + H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 990023b..6b5d981 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -96,9 +96,9 @@ am_libhdf5_la_OBJECTS = H5.lo H5dbg.lo H5A.lo H5AC.lo H5B.lo \ H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo H5HFhdr.lo H5HFhuge.lo \ H5HFiblock.lo H5HFiter.lo H5HFman.lo H5HFsection.lo \ - H5HFspace.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 H5L.lo H5Lexternal.lo H5O.lo H5Oattr.lo \ + H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HFtiny.lo H5HG.lo \ + H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5MF.lo H5MM.lo \ + H5MP.lo H5MPtest.lo H5L.lo H5Lexternal.lo H5O.lo H5Oattr.lo \ H5Obogus.lo H5Ocache.lo H5Ocont.lo H5Odtype.lo H5Oefl.lo \ H5Ofill.lo H5Oginfo.lo H5Olayout.lo H5Olinfo.lo H5Olink.lo \ H5Omtime.lo H5Oname.lo H5Onull.lo H5Opline.lo H5Osdspace.lo \ @@ -402,7 +402,7 @@ libhdf5_la_SOURCES = H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c H5Gtraverse.c \ H5HF.c H5HFbtree2.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFhuge.c H5HFiblock.c H5HFiter.c H5HFman.c H5HFsection.c \ - H5HFspace.c H5HFstat.c H5HFtest.c \ + H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ @@ -624,6 +624,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HFspace.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)/H5HFtiny.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HG.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HGdbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HL.Plo@am__quote@ diff --git a/test/fheap.c b/test/fheap.c index 49baf02..ade01a5 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -111,6 +111,8 @@ typedef struct fheap_heap_state_t { hsize_t man_free_space; /* Managed object free space within heap */ size_t huge_nobjs; /* # of 'huge' objects within heap */ hsize_t huge_size; /* Size of 'huge' object heap */ + size_t tiny_nobjs; /* # of 'tiny' objects within heap */ + hsize_t tiny_size; /* Size of 'tiny' object heap */ } fheap_heap_state_t; /* Heap IDs to retain */ @@ -220,6 +222,14 @@ check_stats(const H5HF_t *fh, const fheap_heap_state_t *state) HDfprintf(stdout, "heap_stats.huge_size = %Hu, state->huge_size = %Hu\n", heap_stats.huge_size, state->huge_size); FAIL_STACK_ERROR } /* end if */ + if(heap_stats.tiny_nobjs != state->tiny_nobjs) { + HDfprintf(stdout, "heap_stats.tiny_nobjs = %Hu, state->tiny_nobjs = %Hu\n", heap_stats.tiny_nobjs, state->tiny_nobjs); + FAIL_STACK_ERROR + } /* end if */ + if(heap_stats.tiny_size != state->tiny_size) { + HDfprintf(stdout, "heap_stats.tiny_size = %Hu, state->tiny_size = %Hu\n", heap_stats.tiny_size, state->tiny_size); + FAIL_STACK_ERROR + } /* end if */ /* All tests passed */ return(0); @@ -1684,7 +1694,7 @@ test_create(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t UNUSED *tparam 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))) + if(H5HF_cmp_cparam_test(cparam, &test_cparam)) TEST_ERROR /* Close the fractal heap */ @@ -1792,7 +1802,7 @@ test_reopen(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t UNUSED *tparam 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))) + if(H5HF_cmp_cparam_test(cparam, &test_cparam)) TEST_ERROR /* Close the fractal heap */ @@ -1817,33 +1827,34 @@ error: return(1); } /* test_reopen() */ -#ifdef ALL_INSERT_TESTS /*------------------------------------------------------------------------- - * Function: test_man_insert_first + * Function: test_id_limits * - * Purpose: Test inserting first object into absolute heap + * Purpose: Test limits for heap ID lengths * * Return: Success: 0 - * * Failure: 1 * * Programmer: Quincey Koziol - * Friday, February 24, 2006 + * Monday, August 14, 2006 * *------------------------------------------------------------------------- */ static int -test_man_insert_first(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_id_limits(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[FHEAP_FILENAME_LEN]; /* 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 */ + H5HF_create_t tmp_cparam; /* Local heap creation parameters */ + unsigned deflate_level; /* Deflation level */ size_t id_len; /* Size of fractal heap IDs */ - fheap_heap_state_t state; /* State of fractal heap */ + size_t tiny_max_len; /* Max. length of tiny objects */ + hbool_t tiny_len_extended; /* Do tiny objects use two bytes for the length? */ + hbool_t huge_ids_direct; /* Are 'huge' objects directly acccessed? */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -1856,141 +1867,292 @@ test_man_insert_first(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa if(NULL == (f = H5I_object(file))) FAIL_STACK_ERROR + /* Display testing message */ + TESTING("limits of heap ID lengths") + + /* Copy heap creation properties */ + HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t)); + + + /* Set the 'default' heap ID length */ + tmp_cparam.id_len = 0; + /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, dxpl, cparam))) + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) FAIL_STACK_ERROR + + /* Test ID length information for heap */ if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR - if(id_len > HEAP_ID_LEN) - TEST_ERROR - if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + if(id_len != HEAP_ID_LEN) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) + FAIL_STACK_ERROR + if(tiny_max_len != (HEAP_ID_LEN - 1)) TEST_ERROR - HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - if(check_stats(fh, &state)) + if(tiny_len_extended != FALSE) TEST_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != FALSE) TEST_ERROR - /* - * Test inserting first (small) object into absolute heap - */ - TESTING("inserting first (small) object into absolute heap"); - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) FAIL_STACK_ERROR + fh = NULL; - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - /* Check for correctly sized heap */ - if(check_stats(fh, &state)) + /* Set the heap ID length to the size needed for directly accessing 'huge' objects */ + /* (with no I/O pipeline filters) */ + tmp_cparam.id_len = 1; + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) + FAIL_STACK_ERROR + + /* Test ID length information for heap */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != 17) + FAIL_STACK_ERROR + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) FAIL_STACK_ERROR + if(tiny_max_len != 16) + TEST_ERROR + if(tiny_len_extended != FALSE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != TRUE) + TEST_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_ERROR + fh = NULL; - /* Close the file */ - if(H5Fclose(file) < 0) + + /* Set the heap ID length to the size needed for directly accessing 'huge' objects */ + /* (with I/O pipeline filters) */ + tmp_cparam.id_len = 1; + + /* Set an I/O filter for heap data */ + deflate_level = 6; + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + FAIL_STACK_ERROR + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) + FAIL_STACK_ERROR + + /* Test ID length information for heap */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != 29) + FAIL_STACK_ERROR + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) + FAIL_STACK_ERROR + if(tiny_max_len != 27) + TEST_ERROR + if(tiny_len_extended != TRUE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != TRUE) TEST_ERROR - /* All tests passed */ - PASSED() + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; - return(0); + /* Release the I/O pipeline filter information */ + H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); -error: + + /* Set the heap ID length to a size that's too small for 'managed' heap IDs */ + tmp_cparam.id_len = 3; + + /* Create absolute heap */ H5E_BEGIN_TRY { - if(fh) - H5HF_close(fh, dxpl); - H5Fclose(file); + fh = H5HF_create(f, dxpl, &tmp_cparam); } H5E_END_TRY; - return(1); -} /* test_man_insert_first() */ + if(NULL != fh) + FAIL_STACK_ERROR - -/*------------------------------------------------------------------------- - * Function: test_man_insert_second - * - * Purpose: Test inserting two objects into absolute heap - * - * Return: Success: 0 - * - * Failure: 1 - * - * Programmer: Quincey Koziol - * Monday, March 6, 2006 - * - *------------------------------------------------------------------------- - */ -static int -test_man_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[FHEAP_FILENAME_LEN]; /* 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 */ - fheap_heap_state_t state; /* State of fractal heap */ - /* Set the filename to use for this test (dependent on fapl) */ - h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + /* Set the heap ID length a size that's large enough for 'tiny' & 'managed' + * objects, but too small for directly accessing 'huge' objects + */ + tmp_cparam.id_len = 8; - /* Create the file to work on */ - if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) + FAIL_STACK_ERROR + + /* Test ID length information for heap */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != 8) + FAIL_STACK_ERROR + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) + FAIL_STACK_ERROR + if(tiny_max_len != 7) + TEST_ERROR + if(tiny_len_extended != FALSE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != FALSE) TEST_ERROR - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + + /* Set the heap ID length a size that's large enough for directly + * directly accessing 'huge' objects + */ + tmp_cparam.id_len = 17; /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, dxpl, cparam))) + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) FAIL_STACK_ERROR + + /* Test ID length information for heap */ if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR - if(id_len > HEAP_ID_LEN) + if(id_len != 17) FAIL_STACK_ERROR - if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(tiny_max_len != 16) + TEST_ERROR + if(tiny_len_extended != FALSE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) FAIL_STACK_ERROR - HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(huge_ids_direct != TRUE) + TEST_ERROR - /* - * Test inserting first (small) object into absolute heap + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + + /* Set the heap ID length to the low side of the boundary condition for + * encoding 'tiny' objects in one byte */ - TESTING("inserting two (small) objects into absolute heap"); - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + tmp_cparam.id_len = 18; + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + /* Test ID length information for heap */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != 18) + FAIL_STACK_ERROR + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) + FAIL_STACK_ERROR + if(tiny_max_len != 16) + TEST_ERROR + if(tiny_len_extended != FALSE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != TRUE) TEST_ERROR - /* Insert second object */ - if(add_obj(fh, dxpl, (size_t)20, SMALL_OBJ_SIZE2, &state, NULL)) + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + + /* Set the heap ID length to the high side of the boundary condition for + * encoding 'tiny' objects in one byte + */ + tmp_cparam.id_len = 19; + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) + FAIL_STACK_ERROR + + /* Test ID length information for heap */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != 19) + FAIL_STACK_ERROR + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) FAIL_STACK_ERROR + if(tiny_max_len != 17) + TEST_ERROR + if(tiny_len_extended != TRUE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != TRUE) + TEST_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + + /* Set the heap ID length a size that's larger than what is needed for + * directly accessing 'huge' objects + */ + tmp_cparam.id_len = 45; + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) + FAIL_STACK_ERROR + + /* Test ID length information for heap */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != 45) + FAIL_STACK_ERROR + if(H5HF_get_tiny_info_test(fh, &tiny_max_len, &tiny_len_extended) < 0) + FAIL_STACK_ERROR + if(tiny_max_len != 43) + TEST_ERROR + if(tiny_len_extended != TRUE) + TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(huge_ids_direct != TRUE) TEST_ERROR + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + + /* Set the heap ID length to a size that's too large to encode the length + * of 'tiny' objects + */ + tmp_cparam.id_len = H5HF_MAX_ID_LEN + 1; + + /* Create absolute heap */ + H5E_BEGIN_TRY { + fh = H5HF_create(f, dxpl, &tmp_cparam); + } H5E_END_TRY; + if(NULL != fh) + FAIL_STACK_ERROR + + /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + FAIL_STACK_ERROR /* All tests passed */ PASSED() @@ -2004,26 +2166,24 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_insert_second() */ +} /* test_id_limits() */ /*------------------------------------------------------------------------- - * Function: test_man_insert_root_mult + * Function: test_filtered_create * - * Purpose: Test inserting mult. objects into absolute heap, up to the - * limit of a root direct block + * Purpose: Test creating a heap with I/O filters * * Return: Success: 0 - * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 6, 2006 + * Monday, August 14, 2006 * *------------------------------------------------------------------------- */ static int -test_man_insert_root_mult(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_filtered_create(hid_t fapl, H5HF_create_t *cparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -2031,60 +2191,87 @@ test_man_insert_root_mult(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ - fheap_heap_state_t state; /* State of fractal heap */ + H5HF_create_t tmp_cparam; /* Local heap creation parameters */ + H5HF_create_t test_cparam; /* Temporary local heap creation parameters */ + unsigned deflate_level; /* Deflation level */ /* 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 + FAIL_STACK_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, dxpl, cparam))) FAIL_STACK_ERROR - if(H5HF_get_id_len(fh, &id_len) < 0) + + /* Display testing message */ + TESTING("creating heaps with I/O filters") + + /* Copy heap creation properties */ + HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t)); + + + /* Set an I/O filter for heap data */ + deflate_level = 6; + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) FAIL_STACK_ERROR - if(id_len > HEAP_ID_LEN) + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, &tmp_cparam))) FAIL_STACK_ERROR + + /* Get heap's address */ if(H5HF_get_heap_addr(fh, &fh_addr) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) - FAIL_STACK_ERROR - HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + TEST_ERROR - /* - * Test inserting mult. (small) object into absolute heap - */ - TESTING("inserting objects to fill absolute heap's root direct block"); +/* XXX: Check heap's I/O filter settings? */ - /* Retrieve "bulk" filling object size */ - fill_size = get_fill_size(tparam); + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; - /* Fill the heap up */ - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) + /* Close the file */ + if(H5Fclose(file) < 0) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Re-open the heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR + + /* Query the heap creation parameters */ + HDmemset(&test_cparam, 0, sizeof(H5HF_create_t)); + if(H5HF_get_cparam_test(fh, &test_cparam) < 0) + FAIL_STACK_ERROR + if(H5HF_cmp_cparam_test(&tmp_cparam, &test_cparam)) + FAIL_STACK_ERROR + +/* XXX: Check heap's I/O filter settings? */ /* Close the fractal heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + if(H5HF_close(fh, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + FAIL_STACK_ERROR + + /* Release the I/O pipeline filter information */ + H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); + H5O_reset(H5O_PLINE_ID, &test_cparam.pline); /* All tests passed */ PASSED() @@ -2098,27 +2285,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_insert_root_mult() */ +} /* test_filtered_create() */ +#ifdef ALL_INSERT_TESTS /*------------------------------------------------------------------------- - * Function: test_man_insert_force_indirect + * Function: test_man_insert_first * - * Purpose: Test inserting mult. objects into absolute heap, filling the - * root direct block and forcing the root block to be converted - * into an indirect block + * Purpose: Test inserting first object into absolute heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 6, 2006 + * Friday, February 24, 2006 * *------------------------------------------------------------------------- */ static int -test_man_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2127,7 +2313,6 @@ test_man_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_par H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ /* Set the filename to use for this test (dependent on fapl) */ @@ -2135,49 +2320,47 @@ test_man_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_par /* Create the file to work on */ if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) - TEST_ERROR + FAIL_STACK_ERROR /* Get a pointer to the internal file object */ if(NULL == (f = H5I_object(file))) - STACK_ERROR + FAIL_STACK_ERROR /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + if(NULL == (fh = H5HF_create(f, dxpl, 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 + TEST_ERROR if(H5HF_get_heap_addr(fh, &fh_addr) < 0) FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) - FAIL_STACK_ERROR + TEST_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR /* - * Test forcing creation of indirect root block & second direct block + * Test inserting first (small) object into absolute heap */ - TESTING("inserting objects to create root indirect block"); - - /* Retrieve "bulk" filling object size */ - fill_size = get_fill_size(tparam); - - /* Fill the heap up */ + TESTING("inserting first (small) object into absolute heap"); state.man_size = DBLOCK_SIZE(fh, 0); state.man_alloc_size = DBLOCK_SIZE(fh, 0); state.man_free_space = DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force root indirect block creation */ - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check for correctly sized heap */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -2200,27 +2383,25 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_insert_force_indirect() */ +} /* test_man_insert_first() */ /*------------------------------------------------------------------------- - * Function: test_man_insert_fill_second + * Function: test_man_insert_second * - * Purpose: Test inserting mult. objects into absolute heap, filling the - * root direct block, forcing the root block to be converted - * into an indirect block and filling the secnod indirect block + * Purpose: Test inserting two objects into absolute heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 7, 2006 + * Monday, March 6, 2006 * *------------------------------------------------------------------------- */ static int -test_man_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2229,7 +2410,6 @@ test_man_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ size_t id_len; /* Size of fractal heap IDs */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ /* Set the filename to use for this test (dependent on fapl) */ @@ -2244,7 +2424,7 @@ test_man_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ STACK_ERROR /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + if(NULL == (fh = H5HF_create(f, dxpl, cparam))) FAIL_STACK_ERROR if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR @@ -2257,29 +2437,21 @@ test_man_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill second direct block + * Test inserting first (small) object into absolute heap */ - TESTING("inserting objects to fill second direct block"); - - /* Retrieve "bulk" filling object size */ - fill_size = get_fill_size(tparam); - - /* Fill the first direct block heap up */ + TESTING("inserting two (small) objects into absolute heap"); state.man_size = DBLOCK_SIZE(fh, 0); state.man_alloc_size = DBLOCK_SIZE(fh, 0); state.man_free_space = DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill the second direct block heap up (also creates initial root indirect block) */ - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) + /* Insert second object */ + if(add_obj(fh, dxpl, (size_t)20, SMALL_OBJ_SIZE2, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -2302,28 +2474,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_insert_fill_second() */ +} /* test_man_insert_second() */ /*------------------------------------------------------------------------- - * Function: test_man_insert_third_direct + * Function: test_man_insert_root_mult * - * Purpose: Test inserting mult. objects into absolute heap, filling the - * root direct block, forcing the root block to be converted - * into an indirect block, filling the secnod indirect block and - * creating a third direct block + * Purpose: Test inserting mult. objects into absolute heap, up to the + * limit of a root direct block * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 7, 2006 + * Monday, March 6, 2006 * *------------------------------------------------------------------------- */ static int -test_man_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2347,7 +2517,7 @@ test_man_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param STACK_ERROR /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + if(NULL == (fh = H5HF_create(f, dxpl, cparam))) FAIL_STACK_ERROR if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR @@ -2360,36 +2530,24 @@ test_man_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to create third direct block + * Test inserting mult. (small) object into absolute heap */ - TESTING("inserting objects to create third direct block"); + TESTING("inserting objects to fill absolute heap's root direct block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill the first direct block up */ + /* Fill the heap up */ state.man_size = DBLOCK_SIZE(fh, 0); state.man_alloc_size = DBLOCK_SIZE(fh, 0); state.man_free_space = DBLOCK_FREE(fh, 0); if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill the second direct block heap up (also creates initial root indirect block) */ - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of third direct block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -2410,27 +2568,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_insert_third_direct() */ +} /* test_man_insert_root_mult() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_first_row + * Function: test_man_insert_force_indirect * - * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill first row of root indirect - * block. + * Purpose: Test inserting mult. objects into absolute heap, filling the + * root direct block and forcing the root block to be converted + * into an indirect block * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 13, 2006 + * Monday, March 6, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2467,21 +2625,31 @@ test_man_fill_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill first row in root indirect block + * Test forcing creation of indirect root block & second direct block */ - TESTING("inserting objects to fill first row of root indirect block"); + TESTING("inserting objects to create root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill first row of [root] indirect block */ - if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) + /* Fill the heap up */ + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Insert one more object, to force root indirect block creation */ + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + FAIL_STACK_ERROR + /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -2502,27 +2670,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_first_row() */ +} /* test_man_insert_force_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_start_second_row + * Function: test_man_insert_fill_second * - * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill first row of root indirect - * block, then add another object to start second row. + * Purpose: Test inserting mult. objects into absolute heap, filling the + * root direct block, forcing the root block to be converted + * into an indirect block and filling the secnod indirect block * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 14, 2006 + * Tuesday, March 7, 2006 * *------------------------------------------------------------------------- */ static int -test_man_start_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2559,26 +2727,29 @@ test_man_start_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to start second row in root indirect block + * Test inserting mult. (small) objects to fill second direct block */ - TESTING("inserting objects to start second row of root indirect block"); + TESTING("inserting objects to fill second direct block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill first root indirect row */ - if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) + /* Fill the first direct block heap up */ + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force expanding root indirect block to two rows */ - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.man_alloc_size += DBLOCK_SIZE(fh, 1); - state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 1); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill the second direct block heap up (also creates initial root indirect block) */ + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -2601,27 +2772,28 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_start_second_row() */ +} /* test_man_insert_fill_second() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_second_row + * Function: test_man_insert_third_direct * - * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill first row of root indirect - * block, then fill the second row also. + * Purpose: Test inserting mult. objects into absolute heap, filling the + * root direct block, forcing the root block to be converted + * into an indirect block, filling the secnod indirect block and + * creating a third direct block * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 14, 2006 + * Tuesday, March 7, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2658,23 +2830,34 @@ test_man_fill_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to start second row in root indirect block + * Test inserting mult. (small) objects to create third direct block */ - TESTING("inserting objects to fill second row of root indirect block"); + TESTING("inserting objects to create third direct block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill first root indirect row */ - if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) + /* Fill the first direct block up */ + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Fill second root indirect row */ - if(fill_root_row(fh, dxpl, 1, fill_size, &state, NULL)) + /* Fill the second direct block heap up (also creates initial root indirect block) */ + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Insert one more object, to force creation of third direct block */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -2697,28 +2880,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_second_row() */ +} /* test_man_insert_third_direct() */ /*------------------------------------------------------------------------- - * Function: test_man_start_third_row + * Function: test_man_fill_first_row * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill first row of root indirect - * block, fill the second row also, then add another object to - * start the third row. + * block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 20, 2006 + * Monday, March 13, 2006 * *------------------------------------------------------------------------- */ static int -test_man_start_third_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2755,35 +2937,21 @@ test_man_start_third_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to start third row in root indirect block + * Test inserting mult. (small) objects to fill first row in root indirect block */ - TESTING("inserting objects to start third row of root indirect block"); + TESTING("inserting objects to fill first row of root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill first root indirect row */ + /* Fill first row of [root] indirect block */ if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill second root indirect row */ - if(fill_root_row(fh, dxpl, 1, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force expanding root indirect block to four rows */ - /* (Goes to four rows because it's doubling) */ - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); - state.man_alloc_size += DBLOCK_SIZE(fh, 2); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -2804,27 +2972,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_start_third_row() */ +} /* test_man_fill_first_row() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_fourth_row + * Function: test_man_start_second_row * * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill first four rows of root indirect - * block. + * enough direct blocks to fill first row of root indirect + * block, then add another object to start second row. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 20, 2006 + * Tuesday, March 14, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2835,7 +3003,6 @@ test_man_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * size_t id_len; /* Size of fractal heap IDs */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal 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)); @@ -2862,22 +3029,28 @@ test_man_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill four rows in root indirect block + * Test inserting mult. (small) objects to start second row in root indirect block */ - TESTING("inserting objects to fill four rows of root indirect block"); + TESTING("inserting objects to start second row of root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Loop over rows */ - for(u = 0; u < 4; u++) - if(fill_root_row(fh, dxpl, u, fill_size, &state, NULL)) - FAIL_STACK_ERROR + /* Fill first root indirect row */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Insert one more object, to force expanding root indirect block to two rows */ + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.man_alloc_size += DBLOCK_SIZE(fh, 1); + state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 1); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + FAIL_STACK_ERROR + /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -2898,27 +3071,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_fourth_row() */ +} /* test_man_start_second_row() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_all_root_direct + * Function: test_man_fill_second_row * * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill all direct rows of root indirect - * block. + * enough direct blocks to fill first row of root indirect + * block, then fill the second row also. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 20, 2006 + * Tuesday, March 14, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -2955,21 +3128,25 @@ test_man_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_para HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill all direct rows in root indirect block + * Test inserting mult. (small) objects to start second row in root indirect block */ - TESTING("inserting objects to fill all direct rows of root indirect block"); + TESTING("inserting objects to fill second row of root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill all direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) + /* Fill first root indirect row */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Fill second root indirect row */ + if(fill_root_row(fh, dxpl, 1, fill_size, &state, NULL)) + FAIL_STACK_ERROR + /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -2990,15 +3167,16 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_all_root_direct() */ +} /* test_man_fill_second_row() */ /*------------------------------------------------------------------------- - * Function: test_man_first_recursive_indirect + * Function: test_man_start_third_row * * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill all direct rows of root indirect - * block and create first recursive indirect block. + * enough direct blocks to fill first row of root indirect + * block, fill the second row also, then add another object to + * start the third row. * * Return: Success: 0 * @@ -3010,7 +3188,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3047,23 +3225,32 @@ test_man_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_ HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to force creation of first recursive indirect block + * Test inserting mult. (small) objects to start third row in root indirect block */ - TESTING("inserting objects to create first recursive indirect block"); + TESTING("inserting objects to start third row of root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up */ - if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) + /* Fill first root indirect row */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) + FAIL_STACK_ERROR + + /* Fill second root indirect row */ + if(fill_root_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of first recursive indirect block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); + /* Insert one more object, to force expanding root indirect block to four rows */ + /* (Goes to four rows because it's doubling) */ + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); + state.man_alloc_size += DBLOCK_SIZE(fh, 2); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR @@ -3087,28 +3274,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_first_recursive_indirect() */ +} /* test_man_start_third_row() */ /*------------------------------------------------------------------------- - * Function: test_man_second_direct_recursive_indirect + * Function: test_man_fill_fourth_row * * Purpose: Test inserting mult. objects into absolute heap, creating - * enough direct blocks to fill all direct rows of root indirect - * block, create first recursive indirect block and start second - * direct block in that indirect block. + * enough direct blocks to fill first four rows of root indirect + * block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 21, 2006 + * Monday, March 20, 2006 * *------------------------------------------------------------------------- */ static int -test_man_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3119,6 +3305,7 @@ test_man_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhe size_t id_len; /* Size of fractal heap IDs */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal 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)); @@ -3145,34 +3332,22 @@ test_man_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhe HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to force creation of second direct - * block in first recursive indirect block + * Test inserting mult. (small) objects to fill four rows in root indirect block */ - TESTING("inserting objects to create second direct block in first recursive indirect block"); + TESTING("inserting objects to fill four rows of root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up */ - if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill the first direct block in the recursive indirect block up */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) - FAIL_STACK_ERROR + /* Loop over rows */ + for(u = 0; u < 4; u++) + if(fill_root_row(fh, dxpl, u, fill_size, &state, NULL)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of second direct block in - * first recursive indirect block - */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -3193,28 +3368,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_second_direct_recursive_indirect() */ +} /* test_man_fill_fourth_row() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_first_recursive_indirect + * Function: test_man_fill_all_root_direct * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, create first recursive indirect block and filling all - * direct blocks in that indirect block. + * block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 21, 2006 + * Monday, March 20, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3251,15 +3425,14 @@ test_man_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_ HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill all direct - * blocks in first recursive indirect block + * Test inserting mult. (small) objects to fill all direct rows in root indirect block */ - TESTING("inserting objects to fill all direct blocks in first recursive indirect block"); + TESTING("inserting objects to fill all direct rows of root indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up in root indirect block */ + /* Fill all direct blocks in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR @@ -3267,10 +3440,6 @@ test_man_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill first recursive indirect block */ - if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -3291,29 +3460,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_first_recursive_indirect() */ +} /* test_man_fill_all_root_direct() */ /*------------------------------------------------------------------------- - * Function: test_man_second_recursive_indirect + * Function: test_man_first_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, create first recursive indirect block, filling all - * direct blocks in that indirect block and adding another - * object to force creation of second recursive indirect block. + * block and create first recursive indirect block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 21, 2006 + * Monday, March 20, 2006 * *------------------------------------------------------------------------- */ static int -test_man_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3350,29 +3517,22 @@ test_man_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill all direct - * blocks in first recursive indirect block + * Test inserting mult. (small) objects to force creation of first recursive indirect block */ - TESTING("inserting objects to start second recursive indirect block"); + TESTING("inserting objects to create first recursive indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up in root indirect block */ + /* Fill direct blocks up */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill first recursive indirect block */ - if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of second - * recursive indirect block - */ + /* Insert one more object, to force creation of first recursive indirect block */ state.man_alloc_size += DBLOCK_SIZE(fh, 0); if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR @@ -3397,18 +3557,16 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_second_recursive_indirect() */ +} /* test_man_first_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_second_recursive_indirect + * Function: test_man_second_direct_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, create first recursive indirect block, filling all - * direct blocks in that indirect block and then create second - * recursive indirect block and fill all direct blocks in that - * indirect block. + * block, create first recursive indirect block and start second + * direct block in that indirect block. * * Return: Success: 0 * @@ -3420,7 +3578,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3457,28 +3615,32 @@ test_man_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap HDmemset(&state, 0, sizeof(fheap_heap_state_t)); /* - * Test inserting mult. (small) objects to fill all direct - * blocks in first recursive indirect block + * Test inserting mult. (small) objects to force creation of second direct + * block in first recursive indirect block */ - TESTING("inserting objects to fill all direct blocks in second recursive indirect block"); + TESTING("inserting objects to create second direct block in first recursive indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up in root indirect block */ + /* Fill direct blocks up */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill first recursive indirect block */ - if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) + /* Fill the first direct block in the recursive indirect block up */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill 2nd recursive indirect block */ - if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) + /* Insert one more object, to force creation of second direct block in + * first recursive indirect block + */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3501,18 +3663,16 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_second_recursive_indirect() */ +} /* test_man_second_direct_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_recursive_indirect_row + * Function: test_man_fill_first_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, create first recursive indirect block, filling all - * direct blocks in that indirect block and then create second - * recursive indirect block and fill all direct blocks in that - * indirect block. + * block, create first recursive indirect block and filling all + * direct blocks in that indirect block. * * Return: Success: 0 * @@ -3524,7 +3684,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3564,12 +3724,12 @@ test_man_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_te * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill all direct blocks in first row of recursive indirect block"); + TESTING("inserting objects to fill all direct blocks in first recursive indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks in root indirect block up */ + /* Fill direct blocks up in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR @@ -3577,8 +3737,8 @@ test_man_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_te if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill row of recursive indirect blocks */ - if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) + /* Fill first recursive indirect block */ + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3601,28 +3761,29 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_recursive_indirect_row() */ +} /* test_man_fill_first_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_start_2nd_recursive_indirect + * Function: test_man_second_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, fill all direct blocks in the first row of indirect - * blocks and start on first block in second row of indirect blocks + * block, create first recursive indirect block, filling all + * direct blocks in that indirect block and adding another + * object to force creation of second recursive indirect block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 27, 2006 + * Tuesday, March 21, 2006 * *------------------------------------------------------------------------- */ static int -test_man_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3662,17 +3823,17 @@ test_man_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to start second row of recursive indirect blocks"); + TESTING("inserting objects to start second recursive indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks in root indirect block up */ + /* Fill direct blocks up in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill row of recursive indirect blocks */ - if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) + /* Fill first recursive indirect block */ + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3706,28 +3867,30 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_start_2nd_recursive_indirect() */ +} /* test_man_second_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_recursive_indirect_two_deep + * Function: test_man_fill_second_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep + * block, create first recursive indirect block, filling all + * direct blocks in that indirect block and then create second + * recursive indirect block and fill all direct blocks in that + * indirect block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 27, 2006 + * Tuesday, March 21, 2006 * *------------------------------------------------------------------------- */ static int -test_man_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3767,7 +3930,7 @@ test_man_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_te * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill recursive indirect blocks two levels deep"); + TESTING("inserting objects to fill all direct blocks in second recursive indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -3776,12 +3939,16 @@ test_man_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_te if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR + /* Fill first recursive indirect block */ + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) + FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) + /* Fill 2nd recursive indirect block */ + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3804,29 +3971,30 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_recursive_indirect_two_deep() */ +} /* test_man_fill_second_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_start_3rd_recursive_indirect + * Function: test_man_fill_recursive_indirect_row * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep and start first direct block - * in 3rd level of indirect blocks + * block, create first recursive indirect block, filling all + * direct blocks in that indirect block and then create second + * recursive indirect block and fill all direct blocks in that + * indirect block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 27, 2006 + * Tuesday, March 21, 2006 * *------------------------------------------------------------------------- */ static int -test_man_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3866,28 +4034,21 @@ test_man_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to start recursive indirect blocks three levels deep"); + TESTING("inserting objects to fill all direct blocks in first row of recursive indirect block"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up in root indirect block */ + /* Fill direct blocks in root indirect block up */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of third level deep - * recursive indirect block - */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill row of recursive indirect blocks */ + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3910,17 +4071,16 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_start_3rd_recursive_indirect() */ +} /* test_man_fill_recursive_indirect_row() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_first_3rd_recursive_indirect + * Function: test_man_start_2nd_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect - * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep and fill first indirect block - * in 3rd level of indirect blocks + * block, fill all direct blocks in the first row of indirect + * blocks and start on first block in second row of indirect blocks * * Return: Success: 0 * @@ -3932,7 +4092,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -3972,29 +4132,28 @@ test_man_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill first indirect block of recursive indirect blocks three levels deep"); + TESTING("inserting objects to start second row of recursive indirect blocks"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Fill direct blocks up in root indirect block */ + /* Fill direct blocks in root indirect block up */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(fh, dxpl, fill_size, &state, NULL)) + /* Fill row of recursive indirect blocks */ + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill row of recursive indirect blocks in third level indirect block */ - if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) + /* Insert one more object, to force creation of second + * recursive indirect block + */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4017,17 +4176,16 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_first_3rd_recursive_indirect() */ +} /* test_man_start_2nd_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_3rd_recursive_indirect_row + * Function: test_man_recursive_indirect_two_deep * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep and fill all indirect blocks - * first row of 3rd level of indirect blocks + * blocks that are 2 levels deep * * Return: Success: 0 * @@ -4039,7 +4197,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4079,7 +4237,7 @@ test_man_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep"); + TESTING("inserting objects to fill recursive indirect blocks two levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4088,16 +4246,12 @@ test_man_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill 1st row of 3rd level indirect blocks */ - if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4120,17 +4274,17 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_3rd_recursive_indirect_row() */ +} /* test_man_recursive_indirect_two_deep() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_all_3rd_recursive_indirect + * Function: test_man_start_3rd_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep and fill all indirect blocks - * that are three levels deep + * blocks that are 2 levels deep and start first direct block + * in 3rd level of indirect blocks * * Return: Success: 0 * @@ -4142,7 +4296,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4182,7 +4336,7 @@ test_man_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep"); + TESTING("inserting objects to start recursive indirect blocks three levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4199,8 +4353,11 @@ test_man_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) + /* Insert one more object, to force creation of third level deep + * recursive indirect block + */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4223,18 +4380,17 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_all_3rd_recursive_indirect() */ +} /* test_man_start_3rd_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_start_4th_recursive_indirect + * Function: test_man_fill_first_3rd_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep, fill all indirect blocks - * that are three levels deep and start first direct block that - * is four levels deep + * blocks that are 2 levels deep and fill first indirect block + * in 3rd level of indirect blocks * * Return: Success: 0 * @@ -4246,7 +4402,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4286,7 +4442,7 @@ test_man_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to start first direct block in recursive indirect blocks four levels deep"); + TESTING("inserting objects to fill first indirect block of recursive indirect blocks three levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4299,19 +4455,16 @@ test_man_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of four level deep - * recursive indirect block - */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill row of recursive indirect blocks in third level indirect block */ + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4334,18 +4487,17 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_start_4th_recursive_indirect() */ +} /* test_man_fill_first_3rd_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_first_4th_recursive_indirect + * Function: test_man_fill_3rd_recursive_indirect_row * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep, fill all indirect blocks - * that are three levels deep and fill the first (3rd level) - * indirect block that is four levels deep + * blocks that are 2 levels deep and fill all indirect blocks + * first row of 3rd level of indirect blocks * * Return: Success: 0 * @@ -4357,7 +4509,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4397,7 +4549,7 @@ test_man_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill first (3rd level) indirect block in recursive indirect block four levels deep"); + TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4410,23 +4562,11 @@ test_man_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill direct block rows in fourth level indirect block */ - if(fill_all_direct(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill all rows of 2nd level deep indirect blocks in fourth level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill first row of 3rd level deep indirect blocks in fourth level indirect block */ + /* Fill 1st row of 3rd level indirect blocks */ if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR @@ -4450,18 +4590,17 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_first_4th_recursive_indirect() */ +} /* test_man_fill_3rd_recursive_indirect_row() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_4th_recursive_indirect_row + * Function: test_man_fill_all_3rd_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect - * blocks that are 2 levels deep, fill all indirect blocks - * that are three levels deep and fill the first row of - * indirect block that is four levels deep + * blocks that are 2 levels deep and fill all indirect blocks + * that are three levels deep * * Return: Success: 0 * @@ -4473,7 +4612,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4513,7 +4652,7 @@ test_man_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea * Test inserting mult. (small) objects to fill all direct * blocks in first recursive indirect block */ - TESTING("inserting objects to fill first row of recursive indirect blocks four levels deep"); + TESTING("inserting objects to fill row of indirect blocks in recursive indirect blocks three levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4526,16 +4665,12 @@ test_man_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill 1st row of 4th level indirect blocks */ - if(fill_4th_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4558,18 +4693,18 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_4th_recursive_indirect_row() */ +} /* test_man_fill_all_3rd_recursive_indirect() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_all_4th_recursive_indirect + * Function: test_man_start_4th_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect * blocks that are 2 levels deep, fill all indirect blocks - * that are three levels deep and fill all rows of - * indirect blocks that are four levels deep + * that are three levels deep and start first direct block that + * is four levels deep * * Return: Success: 0 * @@ -4581,7 +4716,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4619,9 +4754,9 @@ test_man_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea /* * Test inserting mult. (small) objects to fill all direct - * blocks in recursive indirect blocks four levels deep + * blocks in first recursive indirect block */ - TESTING("inserting objects to fill all rows of recursive indirect blocks four levels deep"); + TESTING("inserting objects to start first direct block in recursive indirect blocks four levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4642,8 +4777,11 @@ test_man_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 4th level indirect blocks */ - if(fill_all_4th_indirect_rows(fh, dxpl, fill_size, &state, NULL)) + /* Insert one more object, to force creation of four level deep + * recursive indirect block + */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4666,22 +4804,18 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_all_4th_recursive_indirect() */ -#endif /* ALL_INSERT_TESTS */ +} /* test_man_start_4th_recursive_indirect() */ -#ifndef QAK2 -#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_start_5th_recursive_indirect + * Function: test_man_fill_first_4th_recursive_indirect * * Purpose: Test inserting mult. objects into absolute heap, creating * enough direct blocks to fill all direct rows of root indirect * block, fill all direct blocks in the row of indirect * blocks that are 2 levels deep, fill all indirect blocks - * that are three levels deep, fill all rows of indirect blocks - * that are four levels deep and start first direct block in - * indirect blocks five levels deep + * that are three levels deep and fill the first (3rd level) + * indirect block that is four levels deep * * Return: Success: 0 * @@ -4693,7 +4827,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4731,10 +4865,9 @@ test_man_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t /* * Test inserting mult. (small) objects to fill all direct - * blocks in recursive indirect blocks four levels deep and add one more - * block, to make a five level deep structure + * blocks in first recursive indirect block */ - TESTING("inserting objects to create first direct block in recursive indirect blocks five levels deep"); + TESTING("inserting objects to fill first (3rd level) indirect block in recursive indirect block four levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); @@ -4743,39 +4876,28 @@ test_man_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - /* Fill all rows of 3rd level indirect blocks */ if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Fill direct block rows in fourth level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, NULL)) + FAIL_STACK_ERROR - /* Fill all rows of 4th level indirect blocks */ - if(fill_all_4th_indirect_rows(fh, dxpl, fill_size, &state, NULL)) + /* Fill all rows of 2nd level deep indirect blocks in fourth level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert one more object, to force creation of five level deep - * recursive indirect block - */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill first row of 3rd level deep indirect blocks in fourth level indirect block */ + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4798,27 +4920,30 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_start_5th_recursive_indirect() */ -#endif /* QAK */ +} /* test_man_fill_first_4th_recursive_indirect() */ -#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_remove_bogus + * Function: test_man_fill_4th_recursive_indirect_row * - * Purpose: Test removing bogus heap IDs + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep and fill the first row of + * indirect block that is four levels deep * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 15, 2006 + * Monday, March 27, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4826,14 +4951,9 @@ test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ - unsigned long seed = 0; /* Random # seed */ size_t id_len; /* Size of fractal heap IDs */ - hsize_t obj_off; /* Offset of object in heap */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - unsigned u; /* Local index variable */ - herr_t ret; /* Generic return value */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -4847,7 +4967,7 @@ test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa STACK_ERROR /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, dxpl, cparam))) + 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 @@ -4858,66 +4978,34 @@ test_man_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR /* - * Test removing bogus IDs from heap + * Test inserting mult. (small) objects to fill all direct + * blocks in first recursive indirect block */ - TESTING("removing bad heap IDs from absolute heap"); + TESTING("inserting objects to fill first row of recursive indirect blocks four levels deep"); /* Retrieve "bulk" filling object size */ fill_size = get_fill_size(tparam); - /* Choose random # seed */ - seed = (unsigned long)HDtime(NULL); -#ifdef QAK -/* seed = (unsigned long)1155438845; */ -HDfprintf(stderr, "Random # seed was: %lu\n", seed); -#endif /* QAK */ - HDsrandom(seed); - - /* Set heap ID to random (non-null) value */ - heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN; - for(u = 1; u < HEAP_ID_LEN; u++) - heap_id[u] = HDrandom() + 1; - - /* Try removing bogus heap ID from empty heap */ - H5E_BEGIN_TRY { - ret = H5HF_remove(fh, dxpl, heap_id); - } H5E_END_TRY; - if(ret >= 0) - FAIL_STACK_ERROR - - /* Fill root direct blocks */ + /* Fill direct blocks up in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Get offset of random heap ID */ - if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Make certain we can't accidentally use a valid heap ID */ - while(obj_off < state.man_size) { - /* Set heap ID to random (non-null) value */ - heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN; - for(u = 1; u < HEAP_ID_LEN; u++) - heap_id[u] = HDrandom() + 1; + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) + FAIL_STACK_ERROR - /* Get offset of random heap ID */ - if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) - FAIL_STACK_ERROR - } /* end while */ + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Try removing bogus heap ID from heap w/objects */ - H5E_BEGIN_TRY { - ret = H5HF_remove(fh, dxpl, heap_id); - } H5E_END_TRY; - if(ret >= 0) + /* Fill 1st row of 4th level indirect blocks */ + if(fill_4th_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4934,32 +5022,36 @@ HDfprintf(stderr, "Random # seed was: %lu\n", seed); return(0); error: - HDfprintf(stderr, "Random # seed was: %lu\n", seed); H5E_BEGIN_TRY { if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_bogus() */ +} /* test_man_fill_4th_recursive_indirect_row() */ /*------------------------------------------------------------------------- - * Function: test_man_remove_one + * Function: test_man_fill_all_4th_recursive_indirect * - * Purpose: Test removing single object from heap + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep and fill all rows of + * indirect blocks that are four levels deep * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 15, 2006 + * Monday, March 27, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -4967,13 +5059,9 @@ test_man_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ - unsigned char obj[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */ size_t id_len; /* Size of fractal heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - off_t file_size; /* Size of file currently */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -4987,7 +5075,7 @@ test_man_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara STACK_ERROR /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, dxpl, cparam))) + 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 @@ -4998,73 +5086,34 @@ test_man_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Prepare for querying the size of a file with an empty heap */ - - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; - - /* Get the size of a file w/empty heap*/ - if((empty_size = h5_get_file_size(filename)) == 0) - TEST_ERROR - - /* Re-open the file */ - if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) - TEST_ERROR - - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR /* - * Test removing first (small) object from absolute heap + * Test inserting mult. (small) objects to fill all direct + * blocks in recursive indirect blocks four levels deep */ - TESTING("removing single object from absolute heap"); + TESTING("inserting objects to fill all rows of recursive indirect blocks four levels deep"); - /* Initialize the buffer for objects to insert */ - for(u = 0; u < sizeof(obj); u++) - obj[u] = u; + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id) < 0) + /* Fill direct blocks up in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0) - sizeof(obj); - state.man_nobjs = 1; - if(check_stats(fh, &state)) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Remove object from heap */ - if(H5HF_remove(fh, dxpl, heap_id) < 0) + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Check up on heap... */ - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.man_nobjs = 0; - if(check_stats(fh, &state)) + /* Fill all rows of 4th level indirect blocks */ + if(fill_all_4th_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -5075,14 +5124,6 @@ test_man_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara if(H5Fclose(file) < 0) TEST_ERROR - /* Get the size of the file */ - if((file_size = h5_get_file_size(filename)) == 0) - TEST_ERROR - - /* Verify the file is correct size */ - if(file_size != empty_size) - TEST_ERROR - /* All tests passed */ PASSED() @@ -5095,25 +5136,34 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_one() */ +} /* test_man_fill_all_4th_recursive_indirect() */ +#endif /* ALL_INSERT_TESTS */ +#ifndef QAK2 +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_remove_two + * Function: test_man_start_5th_recursive_indirect * - * Purpose: Test removing two objects from heap + * Purpose: Test inserting mult. objects into absolute heap, creating + * enough direct blocks to fill all direct rows of root indirect + * block, fill all direct blocks in the row of indirect + * blocks that are 2 levels deep, fill all indirect blocks + * that are three levels deep, fill all rows of indirect blocks + * that are four levels deep and start first direct block in + * indirect blocks five levels deep * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 22, 2006 + * Monday, March 27, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -5121,14 +5171,9 @@ test_man_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */ - unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ - unsigned char obj[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */ size_t id_len; /* Size of fractal heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - off_t file_size; /* Size of file currently */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5142,7 +5187,7 @@ test_man_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara STACK_ERROR /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, dxpl, cparam))) + 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 @@ -5153,101 +5198,54 @@ test_man_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Prepare for querying the size of a file with an empty heap */ - - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; - - /* Get the size of a file w/empty heap*/ - if((empty_size = h5_get_file_size(filename)) == 0) - TEST_ERROR - - /* Re-open the file */ - if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) - TEST_ERROR - - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR /* - * Test removing two (small) objects from absolute heap + * Test inserting mult. (small) objects to fill all direct + * blocks in recursive indirect blocks four levels deep and add one more + * block, to make a five level deep structure */ - TESTING("removing two objects from absolute heap"); + TESTING("inserting objects to create first direct block in recursive indirect blocks five levels deep"); - /* Initialize the buffer for objects to insert */ - for(u = 0; u < sizeof(obj); u++) - obj[u] = u; + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* Insert first object into heap */ - if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id1) < 0) + /* Fill direct blocks up in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Check up on heap... */ - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0) - sizeof(obj); - state.man_nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Insert second object into heap */ - if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id2) < 0) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Check up on heap... */ - state.man_free_space -= sizeof(obj); - state.man_nobjs++; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Check up on heap... */ - state.man_free_space += sizeof(obj); - state.man_nobjs--; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) + /* Fill all rows of 4th level indirect blocks */ + if(fill_all_4th_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Check up on heap... */ - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.man_nobjs = 0; - if(check_stats(fh, &state)) + /* Insert one more object, to force creation of five level deep + * recursive indirect block + */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, (size_t)SMALL_OBJ_SIZE1, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -5258,14 +5256,6 @@ test_man_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara if(H5Fclose(file) < 0) TEST_ERROR - /* Get the size of the file */ - if((file_size = h5_get_file_size(filename)) == 0) - TEST_ERROR - - /* Verify the file is correct size */ - if(file_size != empty_size) - TEST_ERROR - /* All tests passed */ PASSED() @@ -5278,26 +5268,27 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_two() */ +} /* test_man_start_5th_recursive_indirect() */ +#endif /* QAK */ +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_remove_one_larger + * Function: test_man_remove_bogus * - * Purpose: Test removing single larger (but < standalone size) object - * from heap + * Purpose: Test removing bogus heap IDs * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, June 6, 2006 + * Monday, May 15, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_remove_bogus(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 */ @@ -5306,13 +5297,13 @@ test_man_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ - unsigned char *obj; /* Buffer for object to insert */ - size_t obj_len; /* Length of object to insert */ + unsigned long seed = 0; /* Random # seed */ size_t id_len; /* Size of fractal heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - off_t file_size; /* Size of file currently */ + hsize_t obj_off; /* Offset of object in heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ unsigned u; /* Local index variable */ + herr_t ret; /* Generic return value */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5340,89 +5331,71 @@ test_man_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Prepare for querying the size of a file with an empty heap */ - - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + /* + * Test removing bogus IDs from heap + */ + TESTING("removing bad heap IDs from absolute heap"); - /* Get the size of a file w/empty heap*/ - if((empty_size = h5_get_file_size(filename)) == 0) - TEST_ERROR + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* Re-open the file */ - if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) - TEST_ERROR + /* Choose random # seed */ + seed = (unsigned long)HDtime(NULL); +#ifdef QAK +/* seed = (unsigned long)1155438845; */ +HDfprintf(stderr, "Random # seed was: %lu\n", seed); +#endif /* QAK */ + HDsrandom(seed); - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR + /* Set heap ID to random (non-null) value */ + heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN; + for(u = 1; u < HEAP_ID_LEN; u++) + heap_id[u] = HDrandom() + 1; - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Try removing bogus heap ID from empty heap */ + H5E_BEGIN_TRY { + ret = H5HF_remove(fh, dxpl, heap_id); + } H5E_END_TRY; + if(ret >= 0) FAIL_STACK_ERROR - /* - * Test removing one larger object from absolute heap - */ - TESTING("removing single larger object from absolute heap"); - - /* Set up object to insert */ - obj_len = DBLOCK_SIZE(fh, 2) + 1; - obj = shared_wobj_g; - - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id) < 0) + /* Fill root direct blocks */ + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - for(u = 0; u < 4; u++) { - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size = DBLOCK_SIZE(fh, 3); - state.man_free_space -= obj_len; - state.man_nobjs = 1; - if(check_stats(fh, &state)) + /* Get offset of random heap ID */ + if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) FAIL_STACK_ERROR - /* Remove object from heap */ - if(H5HF_remove(fh, dxpl, heap_id) < 0) - FAIL_STACK_ERROR + /* Make certain we can't accidentally use a valid heap ID */ + while(obj_off < state.man_size) { + /* Set heap ID to random (non-null) value */ + heap_id[0] = H5HF_ID_VERS_CURR | H5HF_ID_TYPE_MAN; + for(u = 1; u < HEAP_ID_LEN; u++) + heap_id[u] = HDrandom() + 1; - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Get offset of random heap ID */ + if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) + FAIL_STACK_ERROR + } /* end while */ - /* Check up on heap... */ - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.man_nobjs = 0; - if(check_stats(fh, &state)) + /* Try removing bogus heap ID from heap w/objects */ + H5E_BEGIN_TRY { + ret = H5HF_remove(fh, dxpl, heap_id); + } H5E_END_TRY; + if(ret >= 0) FAIL_STACK_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - FAIL_STACK_ERROR + TEST_ERROR /* Close the file */ if(H5Fclose(file) < 0) - FAIL_STACK_ERROR - - /* Get the size of the file */ - if((file_size = h5_get_file_size(filename)) == 0) - TEST_ERROR - - /* Verify the file is correct size */ - if(file_size != empty_size) TEST_ERROR /* All tests passed */ @@ -5431,32 +5404,32 @@ test_man_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t return(0); error: + HDfprintf(stderr, "Random # seed was: %lu\n", seed); H5E_BEGIN_TRY { if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_one_larger() */ +} /* test_man_remove_bogus() */ /*------------------------------------------------------------------------- - * Function: test_man_remove_two_larger + * Function: test_man_remove_one * - * Purpose: Test removing two larger (but < standalone size) objects - * from heap + * Purpose: Test removing single object from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, June 10, 2006 + * Monday, May 15, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_remove_one(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 */ @@ -5464,10 +5437,8 @@ test_man_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */ - unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ - unsigned char *obj; /* Buffer for object to insert */ - size_t obj_len; /* Length of object to insert */ + unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ + unsigned char obj[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */ size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ @@ -5526,19 +5497,16 @@ test_man_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t FAIL_STACK_ERROR /* - * Test removing two larger objects from absolute heap + * Test removing first (small) object from absolute heap */ - if(tparam->del_dir == FHEAP_DEL_FORWARD) - TESTING("removing two larger objects from absolute heap (forward)") - else - TESTING("removing two larger objects from absolute heap (reverse)") + TESTING("removing single object from absolute heap"); - /* Set up first object to insert */ - obj_len = DBLOCK_SIZE(fh, 2) + 1; - obj = shared_wobj_g; + /* Initialize the buffer for objects to insert */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u; /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id1) < 0) + if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5546,87 +5514,17 @@ test_man_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t TEST_ERROR /* Check up on heap... */ - for(u = 0; u < 4; u++) { - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size = DBLOCK_SIZE(fh, 3); - state.man_free_space -= obj_len; + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0) - sizeof(obj); state.man_nobjs = 1; if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Set up second object to insert */ - obj_len = DBLOCK_SIZE(fh, 4) + 1; - obj = shared_wobj_g; - - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id2) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - /* (Goes to 8 rows because of doubling) */ - for(u = 4; u < 8; u++) { - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size += DBLOCK_SIZE(fh, 5); - state.man_free_space -= obj_len; - state.man_nobjs = 2; - if(check_stats(fh, &state)) + /* Remove object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) FAIL_STACK_ERROR - /* Remove objects in different orders */ - if(tparam->del_dir == FHEAP_DEL_FORWARD) { - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.man_alloc_size -= DBLOCK_SIZE(fh, 3); - state.man_free_space += DBLOCK_SIZE(fh, 2) + 1; - state.man_nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_ERROR - } /* end if */ - else { - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - /* (Goes to 4 rows because of halving) */ - for(u = 4; u < 8; u++) { - state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size -= DBLOCK_SIZE(fh, 5); - state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; - state.man_nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) - FAIL_STACK_ERROR - } /* end else */ - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR @@ -5652,10 +5550,6 @@ test_man_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t TEST_ERROR /* Verify the file is correct size */ -#ifdef QAK -HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); -HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); -#endif /* QAK */ if(file_size != empty_size) TEST_ERROR @@ -5671,26 +5565,25 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_two_larger() */ +} /* test_man_remove_one() */ /*------------------------------------------------------------------------- - * Function: test_man_remove_three_larger + * Function: test_man_remove_two * - * Purpose: Test removing three larger (but < standalone size) objects - * from heap + * Purpose: Test removing two objects from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, June 12, 2006 + * Monday, May 22, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_remove_two(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 */ @@ -5700,9 +5593,7 @@ test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param haddr_t fh_addr; /* Address of fractal heap */ unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */ unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ - unsigned char heap_id3[HEAP_ID_LEN]; /* Heap ID for third object */ - unsigned char *obj; /* Buffer for object to insert */ - size_t obj_len; /* Length of object to insert */ + unsigned char obj[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */ size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ @@ -5761,19 +5652,16 @@ test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param FAIL_STACK_ERROR /* - * Test removing three larger objects from absolute heap + * Test removing two (small) objects from absolute heap */ - if(tparam->del_dir == FHEAP_DEL_FORWARD) - TESTING("removing three larger objects from absolute heap (forward)") - else - TESTING("removing three larger objects from absolute heap (reverse)") + TESTING("removing two objects from absolute heap"); - /* Set up first object to insert */ - obj_len = DBLOCK_SIZE(fh, 2) + 1; - obj = shared_wobj_g; + /* Initialize the buffer for objects to insert */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u; - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id1) < 0) + /* Insert first object into heap */ + if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id1) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5781,22 +5669,15 @@ test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param TEST_ERROR /* Check up on heap... */ - for(u = 0; u < 4; u++) { - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size = DBLOCK_SIZE(fh, 3); - state.man_free_space -= obj_len; + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0) - sizeof(obj); state.man_nobjs = 1; if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Set up second object to insert */ - obj_len = DBLOCK_SIZE(fh, 4) + 1; - obj = shared_wobj_g; - - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id2) < 0) + /* Insert second object into heap */ + if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id2) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5804,23 +5685,13 @@ test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param TEST_ERROR /* Check up on heap... */ - /* (Goes to 8 rows because of doubling) */ - for(u = 4; u < 8; u++) { - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size += DBLOCK_SIZE(fh, 5); - state.man_free_space -= obj_len; - state.man_nobjs = 2; + state.man_free_space -= sizeof(obj); + state.man_nobjs++; if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Set up third object to insert */ - obj_len = DBLOCK_SIZE(fh, 7) + 1; - obj = shared_wobj_g; - - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id3) < 0) + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id1) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5828,98 +5699,14 @@ test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param TEST_ERROR /* Check up on heap... */ - /* (Goes to 16 rows because of doubling) */ - for(u = 8; u < 16; u++) { - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size += DBLOCK_SIZE(fh, 8); - state.man_free_space -= obj_len; - state.man_nobjs = 3; + state.man_free_space += sizeof(obj); + state.man_nobjs--; if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Remove objects in different orders */ - if(tparam->del_dir == FHEAP_DEL_FORWARD) { - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.man_alloc_size -= DBLOCK_SIZE(fh, 3); - state.man_free_space += DBLOCK_SIZE(fh, 2) + 1; - state.man_nobjs = 2; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.man_alloc_size -= DBLOCK_SIZE(fh, 5); - state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; - state.man_nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove third object from heap */ - if(H5HF_remove(fh, dxpl, heap_id3) < 0) - FAIL_STACK_ERROR - } /* end if */ - else { - /* Remove third object from heap */ - if(H5HF_remove(fh, dxpl, heap_id3) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - /* (Goes to 8 rows because of halving) */ - for(u = 8; u < 16; u++) { - state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size -= DBLOCK_SIZE(fh, 8); - state.man_free_space += DBLOCK_SIZE(fh, 7) + 1; - state.man_nobjs = 2; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - /* (Goes to 4 rows because of halving) */ - for(u = 4; u < 8; u++) { - state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width; - } /* end for */ - state.man_alloc_size -= DBLOCK_SIZE(fh, 5); - state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; - state.man_nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) - FAIL_STACK_ERROR - } /* end else */ + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) @@ -5946,10 +5733,6 @@ test_man_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param TEST_ERROR /* Verify the file is correct size */ -#ifdef QAK -HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); -HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); -#endif /* QAK */ if(file_size != empty_size) TEST_ERROR @@ -5965,28 +5748,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_three_larger() */ -#endif /* QAK */ +} /* test_man_remove_two() */ -#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_remove_root_direct + * Function: test_man_remove_one_larger * - * Purpose: Test filling and removing all objects from root direct block in - * heap + * Purpose: Test removing single larger (but < standalone size) object + * from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 22, 2006 + * Tuesday, June 6, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_remove_one_larger(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 */ @@ -5994,126 +5775,125 @@ test_man_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ + unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ + unsigned char *obj; /* Buffer for object to insert */ + size_t obj_len; /* Length of object to insert */ + size_t id_len; /* Size of fractal heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from root direct block of absolute heap %s"; /* Test description */ + unsigned u; /* Local index variable */ - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + /* 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 - /* Fill the heap up */ - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, 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 + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Prepare for querying the size of a file with an empty heap */ + + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) TEST_ERROR - /* Free resources */ - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* All tests passed */ - PASSED() + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - return(0); + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR -error: - H5E_BEGIN_TRY { - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); - if(fh) - H5HF_close(fh, dxpl); - H5Fclose(file); - } H5E_END_TRY; - return(1); -} /* test_man_remove_root_direct() */ + /* + * Test removing one larger object from absolute heap + */ + TESTING("removing single larger object from absolute heap"); - -/*------------------------------------------------------------------------- - * Function: test_man_remove_two_direct - * - * Purpose: Test filling and removing all objects from (first) two direct - * blocks in heap - * - * Return: Success: 0 - * - * Failure: 1 - * - * Programmer: Quincey Koziol - * Monday, May 22, 2006 - * - *------------------------------------------------------------------------- - */ -static int -test_man_remove_two_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[FHEAP_FILENAME_LEN]; /* 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 */ - fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ - fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from two direct blocks of absolute heap %s"; /* Test description */ + /* Set up object to insert */ + obj_len = DBLOCK_SIZE(fh, 2) + 1; + obj = shared_wobj_g; - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* Insert object into heap */ + if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id) < 0) + FAIL_STACK_ERROR - /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Check up on heap... */ + for(u = 0; u < 4; u++) { + state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size = DBLOCK_SIZE(fh, 3); + state.man_free_space -= obj_len; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - /* Fill the first block in heap */ - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_alloc_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Remove object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Check up on heap... */ + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.man_nobjs = 0; if(check_stats(fh, &state)) - TEST_ERROR + FAIL_STACK_ERROR - /* Fill the second block in heap */ - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); - if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR - /* Free resources */ - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); + /* Verify the file is correct size */ + if(file_size != empty_size) + TEST_ERROR /* All tests passed */ PASSED() @@ -6122,34 +5902,31 @@ test_man_remove_two_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t error: H5E_BEGIN_TRY { - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_two_direct() */ +} /* test_man_remove_one_larger() */ /*------------------------------------------------------------------------- - * Function: test_man_remove_first_row + * Function: test_man_remove_two_larger * - * Purpose: Test filling and removing all objects from first row of direct - * blocks in heap + * Purpose: Test removing two larger (but < standalone size) objects + * from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, June 5, 2006 + * Saturday, June 10, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_remove_two_larger(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 */ @@ -6157,184 +5934,200 @@ test_man_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */ + unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ + unsigned char *obj; /* Buffer for object to insert */ + size_t obj_len; /* Length of object to insert */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ + off_t file_size; /* Size of file currently */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from first row of direct blocks of absolute heap %s"; /* Test description */ + unsigned u; /* Local index variable */ - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + /* 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 - /* Fill first row of direct blocks */ - if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, dxpl, 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 + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Prepare for querying the size of a file with an empty heap */ + + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) TEST_ERROR - /* Free resources */ - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* All tests passed */ - PASSED() + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - return(0); + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR -error: - H5E_BEGIN_TRY { - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); - if(fh) - H5HF_close(fh, dxpl); - H5Fclose(file); - } H5E_END_TRY; - return(1); -} /* test_man_remove_first_row() */ + /* + * Test removing two larger objects from absolute heap + */ + if(tparam->del_dir == FHEAP_DEL_FORWARD) + TESTING("removing two larger objects from absolute heap (forward)") + else + TESTING("removing two larger objects from absolute heap (reverse)") - -/*------------------------------------------------------------------------- - * Function: test_man_remove_first_two_rows - * - * Purpose: Test filling and removing all objects from first two rows of - * direct blocks in heap - * - * Return: Success: 0 - * - * Failure: 1 - * - * Programmer: Quincey Koziol - * Monday, June 12, 2006 - * - *------------------------------------------------------------------------- - */ -static int -test_man_remove_first_two_rows(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[FHEAP_FILENAME_LEN]; /* 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 */ - fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ - fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from first two rows of direct blocks of absolute heap %s"; /* Test description */ + /* Set up first object to insert */ + obj_len = DBLOCK_SIZE(fh, 2) + 1; + obj = shared_wobj_g; - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* Insert object into heap */ + if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id1) < 0) + FAIL_STACK_ERROR - /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Check up on heap... */ + for(u = 0; u < 4; u++) { + state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size = DBLOCK_SIZE(fh, 3); + state.man_free_space -= obj_len; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - /* Fill first two rows of direct blocks */ - if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_root_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Set up second object to insert */ + obj_len = DBLOCK_SIZE(fh, 4) + 1; + obj = shared_wobj_g; + /* Insert object into heap */ + if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id2) < 0) + FAIL_STACK_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Free resources */ - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); + /* Check up on heap... */ + /* (Goes to 8 rows because of doubling) */ + for(u = 4; u < 8; u++) { + state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size += DBLOCK_SIZE(fh, 5); + state.man_free_space -= obj_len; + state.man_nobjs = 2; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - /* All tests passed */ - PASSED() + /* Remove objects in different orders */ + if(tparam->del_dir == FHEAP_DEL_FORWARD) { + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id1) < 0) + FAIL_STACK_ERROR - return(0); + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR -error: - H5E_BEGIN_TRY { - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); - if(fh) - H5HF_close(fh, dxpl); - H5Fclose(file); - } H5E_END_TRY; - return(1); -} /* test_man_remove_first_two_rows() */ + /* Check up on heap... */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 3); + state.man_free_space += DBLOCK_SIZE(fh, 2) + 1; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - -/*------------------------------------------------------------------------- - * Function: test_man_remove_first_four_rows - * - * Purpose: Test filling and removing all objects from first four rows of - * direct blocks in heap - * - * Return: Success: 0 - * - * Failure: 1 - * - * Programmer: Quincey Koziol - * Tuesday, June 13, 2006 - * - *------------------------------------------------------------------------- - */ -static int -test_man_remove_first_four_rows(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[FHEAP_FILENAME_LEN]; /* 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 */ - fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - off_t empty_size; /* Size of a file with an empty heap */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ - fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from first four rows of direct blocks of absolute heap %s"; /* Test description */ + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + } /* end if */ + else { + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) - TEST_ERROR + /* Check up on heap... */ + /* (Goes to 4 rows because of halving) */ + for(u = 4; u < 8; u++) { + state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 5); + state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id1) < 0) + FAIL_STACK_ERROR + } /* end else */ - /* Fill first two rows of direct blocks */ - if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_root_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_root_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - if(fill_root_row(fh, dxpl, 3, fill_size, &state, &keep_ids)) + + /* Check up on heap... */ + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.man_nobjs = 0; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR - /* Free resources */ - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); + /* Verify the file is correct size */ +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +#endif /* QAK */ + if(file_size != empty_size) + TEST_ERROR /* All tests passed */ PASSED() @@ -6343,34 +6136,31 @@ test_man_remove_first_four_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa error: H5E_BEGIN_TRY { - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_remove_first_four_rows() */ +} /* test_man_remove_two_larger() */ /*------------------------------------------------------------------------- - * Function: test_man_remove_all_root_direct + * Function: test_man_remove_three_larger * - * Purpose: Test filling and removing all objects from all direct blocks - * in root indirect block of heap + * Purpose: Test removing three larger (but < standalone size) objects + * from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, June 13, 2006 + * Monday, June 12, 2006 * *------------------------------------------------------------------------- */ static int -test_man_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_remove_three_larger(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 */ @@ -6378,15 +6168,695 @@ test_man_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ - fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + unsigned char heap_id1[HEAP_ID_LEN]; /* Heap ID for first object */ + unsigned char heap_id2[HEAP_ID_LEN]; /* Heap ID for second object */ + unsigned char heap_id3[HEAP_ID_LEN]; /* Heap ID for third object */ + unsigned char *obj; /* Buffer for object to insert */ + size_t obj_len; /* Length of object to insert */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ + off_t file_size; /* Size of file currently */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from all direct blocks of root group in absolute heap %s"; /* Test description */ + unsigned u; /* Local index variable */ - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* 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, dxpl, 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 + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Prepare for querying the size of a file with an empty heap */ + + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; + + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + + /* + * Test removing three larger objects from absolute heap + */ + if(tparam->del_dir == FHEAP_DEL_FORWARD) + TESTING("removing three larger objects from absolute heap (forward)") + else + TESTING("removing three larger objects from absolute heap (reverse)") + + /* Set up first object to insert */ + obj_len = DBLOCK_SIZE(fh, 2) + 1; + obj = shared_wobj_g; + + /* Insert object into heap */ + if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id1) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + for(u = 0; u < 4; u++) { + state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size = DBLOCK_SIZE(fh, 3); + state.man_free_space -= obj_len; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Set up second object to insert */ + obj_len = DBLOCK_SIZE(fh, 4) + 1; + obj = shared_wobj_g; + + /* Insert object into heap */ + if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + /* (Goes to 8 rows because of doubling) */ + for(u = 4; u < 8; u++) { + state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size += DBLOCK_SIZE(fh, 5); + state.man_free_space -= obj_len; + state.man_nobjs = 2; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Set up third object to insert */ + obj_len = DBLOCK_SIZE(fh, 7) + 1; + obj = shared_wobj_g; + + /* Insert object into heap */ + if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id3) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + /* (Goes to 16 rows because of doubling) */ + for(u = 8; u < 16; u++) { + state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size += DBLOCK_SIZE(fh, 8); + state.man_free_space -= obj_len; + state.man_nobjs = 3; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Remove objects in different orders */ + if(tparam->del_dir == FHEAP_DEL_FORWARD) { + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id1) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 3); + state.man_free_space += DBLOCK_SIZE(fh, 2) + 1; + state.man_nobjs = 2; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 5); + state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Remove third object from heap */ + if(H5HF_remove(fh, dxpl, heap_id3) < 0) + FAIL_STACK_ERROR + } /* end if */ + else { + /* Remove third object from heap */ + if(H5HF_remove(fh, dxpl, heap_id3) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + /* (Goes to 8 rows because of halving) */ + for(u = 8; u < 16; u++) { + state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 8); + state.man_free_space += DBLOCK_SIZE(fh, 7) + 1; + state.man_nobjs = 2; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + /* (Goes to 4 rows because of halving) */ + for(u = 4; u < 8; u++) { + state.man_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; + state.man_free_space -= DBLOCK_FREE(fh, u) * cparam->managed.width; + } /* end for */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 5); + state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; + state.man_nobjs = 1; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id1) < 0) + FAIL_STACK_ERROR + } /* end else */ + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.man_nobjs = 0; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Close the file */ + if(H5Fclose(file) < 0) + TEST_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR + + /* Verify the file is correct size */ +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +#endif /* QAK */ + if(file_size != empty_size) + TEST_ERROR + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_remove_three_larger() */ +#endif /* QAK */ + +#ifndef QAK + +/*------------------------------------------------------------------------- + * Function: test_man_remove_root_direct + * + * Purpose: Test filling and removing all objects from root direct block in + * heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, May 22, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_remove_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "removing all objects from root direct block of absolute heap %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill the heap up */ + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_remove_root_direct() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_remove_two_direct + * + * Purpose: Test filling and removing all objects from (first) two direct + * blocks in heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, May 22, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_remove_two_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "removing all objects from two direct blocks of absolute heap %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill the first block in heap */ + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_alloc_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + if(check_stats(fh, &state)) + TEST_ERROR + + /* Fill the second block in heap */ + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + state.man_free_space = (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_remove_two_direct() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_remove_first_row + * + * Purpose: Test filling and removing all objects from first row of direct + * blocks in heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, June 5, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_remove_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "removing all objects from first row of direct blocks of absolute heap %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill first row of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_remove_first_row() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_remove_first_two_rows + * + * Purpose: Test filling and removing all objects from first two rows of + * direct blocks in heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, June 12, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_remove_first_two_rows(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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "removing all objects from first two rows of direct blocks of absolute heap %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill first two rows of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_root_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_remove_first_two_rows() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_remove_first_four_rows + * + * Purpose: Test filling and removing all objects from first four rows of + * direct blocks in heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, June 13, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_remove_first_four_rows(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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "removing all objects from first four rows of direct blocks of absolute heap %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill first two rows of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_root_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_root_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_root_row(fh, dxpl, 3, fill_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_remove_first_four_rows() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_remove_all_root_direct + * + * Purpose: Test filling and removing all objects from all direct blocks + * in root indirect block of heap + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, June 13, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_remove_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "removing all objects from all direct blocks of root group in absolute heap %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR /* Perform common test initialization operations */ if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) @@ -8375,24 +8845,290 @@ test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */ + /* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */ + + /* Finish blocks in partially used 2nd level indirect block */ + if(fill_partial_row(fh, dxpl, num_first_indirect_rows, cparam->managed.width - 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Direct block rows in skipped 2nd level indirect blocks */ + /* (less the one indirect block already used) */ + for(v = 0; v < cparam->managed.width - 1; v++) + if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Direct block row in used 3rd row 2nd level indirect block */ + if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_fill_2nd_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, the insert object + * that is too large to hold in first row of direct blocks of + * 3rd level indirect block, then backfill & extend all skipped + * 3rd level indirect block's direct blocks. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 11, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t obj_size; /* Size of object */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, and skip first rows of direct blocks of 3rd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_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 = DBLOCK_SIZE(fh, 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, 3) - obj_size; + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill rows skipped over in 3rd level indirect block's direct blocks */ + if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Add one more object, to create another "large" block */ + obj_size = SMALL_OBJ_SIZE1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_fill_2nd_direct_skip_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_fill_2nd_direct_skip_2nd_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 in 3rd level indirect block, then insert object + * that is too large to hold in first row of direct blocks of + * 3rd level indirect block's first 2nd level indirect block, then + * backfill & extend all skipped 2nd level indirect block's direct + * blocks. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 11, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t obj_size; /* Size of object */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct blocks, and skip first rows of direct blocks of 3rd level indirect block's 2nd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + TEST_ERROR + + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_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 = DBLOCK_SIZE(fh, 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR - /* Finish blocks in partially used 2nd level indirect block */ - if(fill_partial_row(fh, dxpl, num_first_indirect_rows, cparam->managed.width - 1, fill_size, &state, &keep_ids)) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Direct block rows in skipped 2nd level indirect blocks */ - /* (less the one indirect block already used) */ - for(v = 0; v < cparam->managed.width - 1; v++) - if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, 3) - obj_size; + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Direct block row in used 3rd row 2nd level indirect block */ - if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) + /* Fill rows skipped over in (3rd level indirect block's) 2nd level + * indirect block's direct blocks + */ + if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ @@ -8401,7 +9137,7 @@ test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1); + state.man_alloc_size += DBLOCK_SIZE(fh, 3); if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8430,17 +9166,18 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped() */ +} /* test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_2nd_direct_skip_start_block_add_skipped + * Function: test_man_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, the insert object - * that is too large to hold in first row of direct blocks of - * 3rd level indirect block, then backfill & extend all skipped - * 3rd level indirect block's direct blocks. + * 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 first row of 2nd level indirect + * blocks of 3rd level indirect block, then backfill & extend all + * skipped direct blocks. * * Return: Success: 0 * @@ -8452,7 +9189,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -8461,11 +9198,13 @@ test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ off_t empty_size; /* Size of a file with an empty heap */ size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, and skip first rows of direct blocks of 3rd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct blocks, and skip first row of indirect blocks of 3rd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -8476,6 +9215,9 @@ test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t TEST_ERROR + /* Retrieve info about heap */ + num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* Fill direct blocks in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -8492,13 +9234,24 @@ test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_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 = DBLOCK_SIZE(fh, 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + obj_size = DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ @@ -8506,7 +9259,7 @@ test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t TEST_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, 3) - obj_size; + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size; if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8514,13 +9267,20 @@ test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows skipped over in 3rd level indirect block's direct blocks */ - if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Fill rows skipped over in (first 3rd level indirect block's) 2nd level + * indirect block's direct blocks + * (and second 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, u, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) @@ -8528,7 +9288,7 @@ test_man_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8557,19 +9317,19 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_2nd_direct_skip_start_block_add_skipped() */ +} /* test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped + * Function: test_man_fill_2nd_direct_fill_direct_skip2_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 in 3rd level indirect block, then insert object - * that is too large to hold in first row of direct blocks of - * 3rd level indirect block's first 2nd level indirect block, then - * backfill & extend all skipped 2nd level indirect block's direct - * blocks. + * that is too large to hold in first & second rows of 2nd level + * indirect blocks (although this 3rd level indirect block only + * has one row of 2nd level indirect blocks) of 3rd level indirect + * block, then backfill & extend all skipped direct blocks. * * Return: Success: 0 * @@ -8581,7 +9341,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_fill_2nd_direct_fill_direct_skip2_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 */ @@ -8590,11 +9350,13 @@ test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ off_t empty_size; /* Size of a file with an empty heap */ size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct blocks, and skip first rows of direct blocks of 3rd level indirect block's 2nd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct blocks, and skip first two rows of indirect blocks of 3rd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -8605,6 +9367,12 @@ test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H TEST_ERROR + /* Retrieve info about heap */ + num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); +#ifdef QAK +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ + /* Fill direct blocks in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -8633,9 +9401,12 @@ test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H * range of skipped (indirect) blocks that are too small to hold the large * object */ - obj_size = DBLOCK_SIZE(fh, 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + obj_size = DBLOCK_SIZE(fh, num_first_indirect_rows) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows + 1); + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ @@ -8643,7 +9414,10 @@ test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H TEST_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, 3) - obj_size; + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows + 1) - obj_size; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8651,14 +9425,23 @@ test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows skipped over in (3rd level indirect block's) 2nd level + /* Fill rows skipped over in (first 3rd level indirect block's) 2nd level * indirect block's direct blocks + * (and second 3rd level indirect block's direct blocks) */ - if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR - if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + 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, u, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ + + /* Fill row of direct blocks in second 3rd level indirect block */ + if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ @@ -8667,7 +9450,7 @@ test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows + 1); if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8696,30 +9479,32 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped() */ +} /* test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped + * Function: test_man_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 in 3rd level indirect block, then insert object - * 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. + * direct blocks in 2nd level indirect blocks, all 3rd level + * indirect blocks in first row except the last one, fill direct + * blocks in last 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 - * Tuesday, April 11, 2006 + * Tues, April 18, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -8733,7 +9518,7 @@ test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(h size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct blocks, and skip first row of indirect blocks of 3rd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ @@ -8756,7 +9541,7 @@ test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(h if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ + /* Fill all rows of 2nd level indirect blocks in root indirect block */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -8764,7 +9549,17 @@ test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(h if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in third level indirect block */ + /* 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, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all direct block rows in last third level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -8797,9 +9592,8 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows skipped over in (first 3rd level indirect block's) 2nd level - * indirect block's direct blocks - * (and second 3rd 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 */ @@ -8807,7 +9601,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR - /* Direct block row in 3rd level indirect block */ + /* Direct block row in current 3rd level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -8847,31 +9641,33 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ +} /* test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped + * Function: test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_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 in 3rd level indirect block, then insert object - * that is too large to hold in first & second rows of 2nd level - * indirect blocks (although this 3rd level indirect block only - * has one row of 2nd level indirect blocks) of 3rd level indirect - * block, then backfill & extend all skipped direct blocks. + * 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: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 11, 2006 + * Tues, April 18, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -8885,8 +9681,8 @@ test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped( size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect block's direct blocks, and skip first two rows of indirect blocks of 3rd level indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ + unsigned u; /* Local index variables */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -8899,9 +9695,6 @@ test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped( /* Retrieve info about heap */ num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); -#ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); -#endif /* QAK */ /* Fill direct blocks in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) @@ -8911,7 +9704,7 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -8919,7 +9712,15 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in third level indirect block */ + /* Fill first row of 3rd level indirect blocks */ + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all direct block rows in 2nd row third level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -8927,15 +9728,24 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_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 = DBLOCK_SIZE(fh, num_first_indirect_rows) + 1; + obj_size = DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1; #ifdef QAK HDfprintf(stderr, "obj_size = %Zu\n", obj_size); #endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows + 1); + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8944,10 +9754,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); TEST_ERROR /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, num_first_indirect_rows + 1) - obj_size; -#ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); -#endif /* QAK */ + obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size; if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) TEST_ERROR @@ -8955,32 +9762,26 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows skipped over in (first 3rd level indirect block's) 2nd level - * indirect block's direct blocks - * (and second 3rd level indirect block's direct blocks) + /* 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 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Direct block rows in skipped 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + TEST_ERROR - /* Direct block row in 3rd level indirect block */ + /* Direct block row in current 2nd level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ - /* Fill row of direct blocks in second 3rd level indirect block */ - if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) - TEST_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Add one more object, to create another "large" block */ obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows + 1); + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR @@ -9009,32 +9810,31 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped() */ +} /* test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped + * Function: test_man_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, all 3rd level - * indirect blocks in first row except the last one, fill direct - * blocks in last 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. + * 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 - * Tues, April 18, 2006 + * Saturday, April 15, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -9048,7 +9848,7 @@ test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ @@ -9071,7 +9871,7 @@ test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks in root indirect block */ + /* Fill all rows of 2nd level indirect blocks */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9079,17 +9879,15 @@ test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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, 1, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in last third level indirect block */ + /* Fill all direct block rows in fourth level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9122,8 +9920,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows skipped over in 2nd level indirect block's direct blocks - * (and rows of next 3rd level indirect block's direct blocks) + /* 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 */ @@ -9131,7 +9930,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR - /* Direct block row in current 3rd level indirect block */ + /* Direct block row in 2nd level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -9171,33 +9970,33 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped() */ +} /* test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped + * Function: test_man_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, 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. + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, then + * fill all direct blocks and 2nd level indirect 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's first + * 3rd level indirect block, then + * backfill all skipped direct blocks & extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tues, April 18, 2006 + * Monday, April 17, 2006 * *------------------------------------------------------------------------- */ static int -test_man_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) +test_man_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 */ @@ -9211,8 +10010,8 @@ test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_s size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ - unsigned u; /* Local index variables */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ + unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -9234,7 +10033,7 @@ test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_s if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + /* Fill all rows of 2nd level indirect blocks */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9242,15 +10041,15 @@ test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_s if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill first row of 3rd level indirect blocks */ - if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in 2nd row third level indirect block */ + /* Fill all direct block rows in fourth level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9258,10 +10057,17 @@ test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_s if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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, 1, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Fill all rows of 2nd level indirect blocks in fourth level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all direct block rows in fourth level indirect block's 3rd level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) @@ -9292,15 +10098,17 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill rows skipped over in 2nd level indirect block's direct blocks - * (and rows of next 2nd level indirect block's direct blocks) + /* 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 skipped 2nd level indirect block */ - if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + TEST_ERROR - /* Direct block row in current 2nd level indirect block */ + /* Direct block row in 3rd level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -9340,18 +10148,22 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ +} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped + * Function: test_man_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, 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 + * 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 @@ -9359,12 +10171,12 @@ error: * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, April 15, 2006 + * Monday, April 17, 2006 * *------------------------------------------------------------------------- */ static int -test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_man_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 */ @@ -9378,7 +10190,7 @@ test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5 size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ @@ -9417,7 +10229,56 @@ test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5 if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in fourth level indirect block */ + /* Fill first row of 4th level indirect blocks */ + if(fill_4th_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Account for root indirect block doubling # of rows again */ + /* (From 16 rows to the max. # of rows: 22) */ + /* (Note: this is tied to the particular doubling table/heap creation parameters) */ + { + unsigned max_root_rows; /* Maximum # of rows in root indirect block */ + unsigned row; /* Row in heap */ + + /* Get some information for the heap */ + max_root_rows = HEAP_MAX_ROOT_ROWS(fh); + + /* Increase heap size & free space */ + for(row = 16; row < max_root_rows; row++) { + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + } /* end for */ + } /* end if */ + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all direct block rows in 2nd row 4th level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all rows of 2nd level indirect blocks in 2nd row 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill first row of 3rd level indirect blocks in 2nd row 4th level indirect block */ + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_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, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9450,9 +10311,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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 (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 */ @@ -9460,7 +10321,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR - /* Direct block row in 2nd level indirect block */ + /* Direct block row in 3rd level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -9500,21 +10361,25 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */ +} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped + * Function: test_man_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, then - * fill all direct blocks and 2nd level indirect 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's first - * 3rd level indirect block, then - * backfill all skipped direct blocks & extend. + * 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 * @@ -9526,7 +10391,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_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) +test_man_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 */ @@ -9540,7 +10405,7 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_blo size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ @@ -9579,7 +10444,7 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_blo if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in fourth level indirect block */ + /* Fill all direct block rows in 4th level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9587,7 +10452,7 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_blo if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks in fourth level indirect block */ + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9595,7 +10460,22 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_blo if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in fourth level indirect block's 3rd level indirect block */ + /* 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, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9628,9 +10508,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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) + /* 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 */ @@ -9638,7 +10518,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR - /* Direct block row in 3rd level indirect block */ + /* Direct block row in 4th level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -9678,23 +10558,25 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ +} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped + * Function: test_man_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, 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. + * 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 * @@ -9706,7 +10588,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_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) +test_man_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 */ @@ -9720,7 +10602,7 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_ size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ + const char *base_desc = "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, then remove all objects %s"; /* Test description */ unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ @@ -9759,32 +10641,26 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill first row of 4th level indirect blocks */ - if(fill_4th_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR - - /* Account for root indirect block doubling # of rows again */ - /* (From 16 rows to the max. # of rows: 22) */ - /* (Note: this is tied to the particular doubling table/heap creation parameters) */ - { - unsigned max_root_rows; /* Maximum # of rows in root indirect block */ - unsigned row; /* Row in heap */ + /* 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, fill_size, &state, &keep_ids)) + TEST_ERROR - /* Get some information for the heap */ - max_root_rows = HEAP_MAX_ROOT_ROWS(fh); + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + TEST_ERROR - /* Increase heap size & free space */ - for(row = 16; row < max_root_rows; row++) { - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); - } /* end for */ - } /* end if */ + /* Fill row of 3rd level indirect blocks in 4th level indirect block */ + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in 2nd row 4th level indirect block */ + /* Fill all direct block rows in 4th level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9792,7 +10668,7 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks in 2nd row 4th level indirect block */ + /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR @@ -9800,18 +10676,42 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill first row of 3rd level indirect blocks in 2nd row 4th level indirect block */ - if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_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, fill_size, &state, &keep_ids)) + TEST_ERROR + + /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in 4th level indirect block's 2nd row of 3rd level indirect block */ + /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR + /* Account for root indirect block doubling # of rows again */ + /* (From 16 rows to the max. # of rows: 22) */ + /* (Note: this is tied to the particular doubling table/heap creation parameters) */ + { + unsigned max_root_rows; /* Maximum # of rows in root indirect block */ + unsigned row; /* Row in heap */ + + /* Get some information for the heap */ + max_root_rows = HEAP_MAX_ROOT_ROWS(fh); + + /* Increase heap size & free space */ + for(row = 16; row < max_root_rows; row++) { + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + } /* end for */ + } /* end if */ + /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR @@ -9841,9 +10741,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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) + /* 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 */ @@ -9851,7 +10751,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR - /* Direct block row in 3rd level indirect block */ + /* Direct block row in 4th level indirect block */ if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -9891,37 +10791,32 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped() */ +} /* test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +#endif /* QAK */ +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped + * Function: test_man_frag_simple * - * 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. + * Purpose: Test inserting objects small enough to fit into first row of + * direct blocks, but not to share a block with another object, + * until start-block-size * 2 blocks are reached. Then, go back + * and fill in the space in the blocks skipped. + * + * Then, remove all the objects, in various ways * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 17, 2006 + * Monday, July 24, 2006 * *------------------------------------------------------------------------- */ static int -test_man_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) +test_man_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 */ @@ -9930,74 +10825,179 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_star H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ off_t empty_size; /* Size of a file with an empty heap */ size_t obj_size; /* Size of object */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "fragmenting small blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + unsigned u; /* Local index variables */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) TEST_ERROR /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR + /* 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 = DBLOCK_SIZE(fh, 0) / 2; + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + for(u = 0; u < cparam->managed.width; u++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + if(u == 0) { + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + } /* end if */ + } /* end for */ + state.man_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width; + for(u = 0; u < cparam->managed.width; u++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 1); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + /* (Account for doubling root indirect block for rows 3-4 */ + for(u = 0; u < 2; u++) { + state.man_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u + 2) * cparam->managed.width; + } /* end for */ + + /* Add one more object, to create a 2 * start_block_size block */ + state.man_alloc_size += DBLOCK_SIZE(fh, 2); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_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; + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in 4th level indirect block */ - if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + /* Fill in 2 * start_block_size block */ + obj_size = DBLOCK_FREE(fh, 2) - (DBLOCK_SIZE(fh, 0) / 2); + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR + + + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + TEST_ERROR + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_frag_simple() */ + + +/*------------------------------------------------------------------------- + * Function: test_man_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. + * + * Then, go back and remove all objects + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, July 25, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + unsigned root_direct_rows; /* Number of rows in root indirect block */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t obj_size; /* Size of object */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "fragmenting direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + unsigned u, v; /* Local index variables */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) TEST_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Retrieve # of direct rows in root indirect block */ + root_direct_rows = H5HF_get_dtable_max_drows_test(fh); - /* 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, fill_size, &state, &keep_ids)) + /* Insert objects small enough to fit into each direct block, but not to + * share them with other objects of the same size. + */ + obj_size = DBLOCK_SIZE(fh, 0) / 2; + state.man_size = DBLOCK_SIZE(fh, 0); + state.man_free_space = DBLOCK_FREE(fh, 0); + /* First row */ + for(u = 0; u < cparam->managed.width; u++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR - - /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ - if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + if(u == 0) { + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); + } /* end if */ + } /* end for */ + state.man_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width; + /* Second row */ + for(u = 0; u < cparam->managed.width; u++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 1); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -10005,51 +11005,57 @@ test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_star if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ - if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* (Account for doubling root indirect block for rows 3-4 */ + for(u = 0; u < 2; u++) { + state.man_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u + 2) * cparam->managed.width; + } /* 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 = DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1; -#ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); -#endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) - TEST_ERROR + /* Rows 3-4 */ + for(u = 0; u < 2; u++) { + obj_size = DBLOCK_SIZE(fh, u + 2) / 2; + for(v = 0; v < cparam->managed.width; v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, u + 2); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size; - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) - TEST_ERROR + /* (Account for doubling root indirect block for rows 5-8 */ + for(u = 0; u < 4; u++) { + state.man_size += DBLOCK_SIZE(fh, u + 4) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u + 4) * cparam->managed.width; + } /* end for */ + + /* Rows 5-8 */ + for(u = 0; u < 4; u++) { + obj_size = DBLOCK_SIZE(fh, u + 4) / 2; + for(v = 0; v < cparam->managed.width; v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, u + 4); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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, u, fill_size, &state, &keep_ids)) - TEST_ERROR + /* (Account for doubling root indirect block for rows 9-16 */ + for(u = 0; u < 8; u++) { + state.man_size += DBLOCK_SIZE(fh, u + 8) * cparam->managed.width; + state.man_free_space += DBLOCK_FREE(fh, u + 8) * cparam->managed.width; + } /* end for */ - /* Direct block row in 4th level indirect block */ - if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + /* Row 9 (last direct block row) */ + obj_size = DBLOCK_SIZE(fh, 8) / 2; + for(v = 0; v < cparam->managed.width; v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 8); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR } /* end for */ @@ -10057,11 +11063,13 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Add one more object, to create another "large" block */ - obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR + /* Go back and backfill all root block's direct blocks */ + for(u = 0; u < root_direct_rows; u++) { + obj_size = DBLOCK_FREE(fh, u) - (DBLOCK_SIZE(fh, u) / 2); + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ /* Perform common file & heap close operations */ @@ -10088,37 +11096,31 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +} /* test_man_frag_direct() */ /*------------------------------------------------------------------------- - * Function: test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped + * Function: test_man_frag_2nd_direct * - * 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. + * 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. + * + * Then, go back and remove all the objects * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 17, 2006 + * Tuesday, July 25, 2006 * *------------------------------------------------------------------------- */ static int -test_man_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) +test_man_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 */ @@ -10132,7 +11134,7 @@ test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_ size_t obj_size; /* Size of object */ size_t fill_size; /* Size of objects for "bulk" filled blocks */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "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, then remove all objects %s"; /* Test description */ + const char *base_desc = "fill root direct blocks, then fragment 2nd level indirect block's direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ unsigned u, v; /* Local index variables */ /* Perform common file & heap open operations */ @@ -10144,8 +11146,11 @@ test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_ TEST_ERROR - /* Retrieve info about heap */ + /* Compute # of bits used in first row */ num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); +#ifdef QAK +HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +#endif /* QAK */ /* Fill direct blocks in root indirect block */ if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) @@ -10155,146 +11160,148 @@ test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Insert objects small enough to fit into each direct block, but not to + * share them with other objects of the same size. + */ + for(u = 0; u < num_first_indirect_rows; u++) { + obj_size = DBLOCK_SIZE(fh, u) / 2; + for(v = 0; v < cparam->managed.width; v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, u); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ + } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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, fill_size, &state, &keep_ids)) - TEST_ERROR - - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR - - /* Fill row of 3rd level indirect blocks in 4th level indirect block */ - if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Go back and backfill all 2nd level indirect block's direct blocks */ + for(u = 0; u < num_first_indirect_rows; u++) { + obj_size = DBLOCK_FREE(fh, u) - (DBLOCK_SIZE(fh, u) / 2); + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR } /* end for */ - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - /* Fill all direct block rows in 4th level indirect block */ - if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + /* Perform common file & heap close operations */ + if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) TEST_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR + /* All tests passed */ + PASSED() - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + return(0); - /* 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, fill_size, &state, &keep_ids)) - TEST_ERROR +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_man_frag_2nd_direct() */ - /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ - if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) - TEST_ERROR - } /* end for */ + +/*------------------------------------------------------------------------- + * Function: test_man_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. + * + * Then, go back and remove all objects + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, July 25, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_man_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[FHEAP_FILENAME_LEN]; /* 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + unsigned root_direct_rows; /* Number of rows in root indirect block */ + off_t empty_size; /* Size of a file with an empty heap */ + size_t obj_size; /* Size of object */ + size_t fill_size; /* Size of objects for "bulk" filled blocks */ + fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "fill root direct blocks and 2nd level indirect blocks, then fragment 3rd level indirect block's direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + unsigned u, v; /* Local index variables */ - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) TEST_ERROR - /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ - if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) TEST_ERROR - /* Account for root indirect block doubling # of rows again */ - /* (From 16 rows to the max. # of rows: 22) */ - /* (Note: this is tied to the particular doubling table/heap creation parameters) */ - { - unsigned max_root_rows; /* Maximum # of rows in root indirect block */ - unsigned row; /* Row in heap */ - - /* Get some information for the heap */ - max_root_rows = HEAP_MAX_ROOT_ROWS(fh); - - /* Increase heap size & free space */ - for(row = 16; row < max_root_rows; row++) { - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); - } /* end for */ - } /* end if */ - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Compute # of direct rows in root indirect block */ + root_direct_rows = DTABLE_MAX_DROWS(fh); - /* 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 = DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1; -#ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); -#endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, num_first_indirect_rows) - obj_size; - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + /* Fill all rows of 2nd level indirect blocks in root indirect block */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_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) + /* Insert objects small enough to fit into each direct block, but not to + * share them with other objects of the same 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(fh, dxpl, u, fill_size, &state, &keep_ids)) + for(u = 0; u < root_direct_rows; u++) { + obj_size = DBLOCK_SIZE(fh, u) / 2; + for(v = 0; v < cparam->managed.width; v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, u); + if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) TEST_ERROR - - /* Direct block row in 4th level indirect block */ - if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) - TEST_ERROR + } /* end for */ } /* end for */ /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Add one more object, to create another "large" block */ - obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR + /* Go back and backfill all 3rd level indirect block's direct blocks */ + for(u = 0; u < root_direct_rows; u++) { + obj_size = DBLOCK_FREE(fh, u) - (DBLOCK_SIZE(fh, u) / 2); + for(v = 0; v < cparam->managed.width; v++) + if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + TEST_ERROR + } /* end for */ /* Perform common file & heap close operations */ @@ -10321,32 +11328,28 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +} /* test_man_frag_3rd_direct() */ #endif /* QAK */ #ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_frag_simple + * Function: test_huge_insert_one * - * Purpose: Test inserting objects small enough to fit into first row of - * direct blocks, but not to share a block with another object, - * until start-block-size * 2 blocks are reached. Then, go back - * and fill in the space in the blocks skipped. + * Purpose: Test inserting one huge object in the heap * * Then, remove all the objects, in various ways * * Return: Success: 0 - * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, July 24, 2006 + * Monday, August 7, 2006 * *------------------------------------------------------------------------- */ static int -test_man_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_huge_insert_one(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 */ @@ -10355,11 +11358,15 @@ test_man_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ + unsigned char *heap_id = NULL; /* Heap ID for object */ size_t obj_size; /* Size of object */ + size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "fragmenting small blocks, then backfill and extend, then remove all objects %s"; /* Test description */ - unsigned u; /* Local index variables */ + const char *base_desc = "insert one huge object, then remove %s"; /* Test description */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -10369,74 +11376,93 @@ test_man_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR - /* 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 = DBLOCK_SIZE(fh, 0) / 2; - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - for(u = 0; u < cparam->managed.width; u++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - if(u == 0) { - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); - } /* end if */ - } /* end for */ - state.man_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width; - for(u = 0; u < cparam->managed.width; u++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 1); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - } /* end for */ + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR + + /* Insert object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* (Account for doubling root indirect block for rows 3-4 */ - for(u = 0; u < 2; u++) { - state.man_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u + 2) * cparam->managed.width; - } /* end for */ - - /* Add one more object, to create a 2 * start_block_size block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 2); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + /* Check up on heap... */ + state.huge_size = obj_size; + state.huge_nobjs = 1; + if(check_stats(fh, &state)) TEST_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + /* Read in huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_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; - for(u = 0; u < cparam->managed.width; u++) - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + /* Delete individual objects, if we won't be deleting the entire heap later */ + if(tparam->del_dir != FHEAP_DEL_HEAP) { + /* Remove object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - for(u = 0; u < cparam->managed.width; u++) - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + + /* Check up on heap... */ + state.huge_size = 0; + state.huge_nobjs = 0; + if(check_stats(fh, &state)) TEST_ERROR + } /* end if */ - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - /* Fill in 2 * start_block_size block */ - obj_size = DBLOCK_FREE(fh, 2) - (DBLOCK_SIZE(fh, 0) / 2); - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) - TEST_ERROR + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Check for deleting the entire heap */ + if(tparam->del_dir == FHEAP_DEL_HEAP) { + /* Delete heap */ + if(H5HF_delete(f, dxpl, fh_addr) < 0) + FAIL_STACK_ERROR + } /* end if */ + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +#endif /* QAK */ + + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10448,6 +11474,7 @@ test_man_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10456,29 +11483,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_frag_simple() */ +} /* test_huge_insert_one() */ /*------------------------------------------------------------------------- - * Function: test_man_frag_direct + * Function: test_huge_insert_two * - * 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. + * Purpose: Test inserting two huge objects in the heap * - * Then, go back and remove all objects + * Then, remove all the objects, in various ways * * Return: Success: 0 - * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, July 25, 2006 + * Friday, August 11, 2006 * *------------------------------------------------------------------------- */ static int -test_man_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_huge_insert_two(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 */ @@ -10487,12 +11511,16 @@ test_man_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - unsigned root_direct_rows; /* Number of rows in root indirect block */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ + unsigned char *heap_id = NULL; /* Heap ID for first object */ + unsigned char *heap_id2 = NULL; /* Heap ID for second object */ size_t obj_size; /* Size of object */ + size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "fragmenting direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "insert two huge objects, then remove %s"; /* Test description */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -10502,111 +11530,171 @@ test_man_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR - /* Retrieve # of direct rows in root indirect block */ - root_direct_rows = H5HF_get_dtable_max_drows_test(fh); + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR - /* Insert objects small enough to fit into each direct block, but not to - * share them with other objects of the same size. - */ - obj_size = DBLOCK_SIZE(fh, 0) / 2; - state.man_size = DBLOCK_SIZE(fh, 0); - state.man_free_space = DBLOCK_FREE(fh, 0); - /* First row */ - for(u = 0; u < cparam->managed.width; u++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - if(u == 0) { - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 0); - } /* end if */ - } /* end for */ - state.man_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, 1) * cparam->managed.width; - /* Second row */ - for(u = 0; u < cparam->managed.width; u++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 1); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - } /* end for */ + /* Insert object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* (Account for doubling root indirect block for rows 3-4 */ - for(u = 0; u < 2; u++) { - state.man_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u + 2) * cparam->managed.width; - } /* end for */ + /* Check up on heap... */ + state.huge_size = obj_size; + state.huge_nobjs = 1; + if(check_stats(fh, &state)) + TEST_ERROR - /* Rows 3-4 */ - for(u = 0; u < 2; u++) { - obj_size = DBLOCK_SIZE(fh, u + 2) / 2; - for(v = 0; v < cparam->managed.width; v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, u + 2); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - } /* end for */ - } /* end for */ + /* Read in huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert second object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id2, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* (Account for doubling root indirect block for rows 5-8 */ - for(u = 0; u < 4; u++) { - state.man_size += DBLOCK_SIZE(fh, u + 4) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u + 4) * cparam->managed.width; - } /* end for */ + /* Check up on heap... */ + state.huge_size += obj_size ; + state.huge_nobjs = 2; + if(check_stats(fh, &state)) + TEST_ERROR - /* Rows 5-8 */ - for(u = 0; u < 4; u++) { - obj_size = DBLOCK_SIZE(fh, u + 4) / 2; - for(v = 0; v < cparam->managed.width; v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, u + 4); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + /* Read in second huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Delete individual objects, if we won't be deleting the entire heap later */ + if(tparam->del_dir != FHEAP_DEL_HEAP) { + if(tparam->del_dir == FHEAP_DEL_FORWARD) { + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - } /* end for */ - } /* end for */ - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Check up on heap... */ + state.huge_size = obj_size; + state.huge_nobjs = 1; + if(check_stats(fh, &state)) + TEST_ERROR - /* (Account for doubling root indirect block for rows 9-16 */ - for(u = 0; u < 8; u++) { - state.man_size += DBLOCK_SIZE(fh, u + 8) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u + 8) * cparam->managed.width; - } /* end for */ + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR - /* Row 9 (last direct block row) */ - obj_size = DBLOCK_SIZE(fh, 8) / 2; - for(v = 0; v < cparam->managed.width; v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 8); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - } /* end for */ + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Check up on heap... */ + state.huge_size = 0; + state.huge_nobjs = 0; + if(check_stats(fh, &state)) + TEST_ERROR + } /* end if */ + else { + /* Remove second object from heap */ + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR - /* Go back and backfill all root block's direct blocks */ - for(u = 0; u < root_direct_rows; u++) { - obj_size = DBLOCK_FREE(fh, u) - (DBLOCK_SIZE(fh, u) / 2); - for(v = 0; v < cparam->managed.width; v++) - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size = obj_size; + state.huge_nobjs = 1; + if(check_stats(fh, &state)) TEST_ERROR - } /* end for */ + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size = 0; + state.huge_nobjs = 0; + if(check_stats(fh, &state)) + TEST_ERROR + } /* end else */ + } /* end if */ + + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Check for deleting the entire heap */ + if(tparam->del_dir == FHEAP_DEL_HEAP) { + /* Delete heap */ + if(H5HF_delete(f, dxpl, fh_addr) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +#endif /* QAK */ + + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10618,6 +11706,8 @@ test_man_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10626,31 +11716,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_frag_direct() */ +} /* test_huge_insert_two() */ /*------------------------------------------------------------------------- - * Function: test_man_frag_2nd_direct + * Function: test_huge_insert_three * - * 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. + * Purpose: Test inserting three huge objects in the heap * - * Then, go back and remove all the objects + * Then, remove all the objects, in various ways * * Return: Success: 0 - * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, July 25, 2006 + * Friday, August 11, 2006 * *------------------------------------------------------------------------- */ static int -test_man_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_huge_insert_three(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 */ @@ -10659,67 +11744,264 @@ test_man_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ + unsigned char *heap_id = NULL; /* Heap ID for first object */ + unsigned char *heap_id2 = NULL; /* Heap ID for second object */ + unsigned char *heap_id3 = NULL; /* Heap ID for third object */ size_t obj_size; /* Size of object */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ + size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "fill root direct blocks, then fragment 2nd level indirect block's direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "insert three huge objects, then remove %s"; /* Test description */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) TEST_ERROR /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) + if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id3 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR - /* Compute # of bits used in first row */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); -#ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); -#endif /* QAK */ + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + /* Insert first object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Insert objects small enough to fit into each direct block, but not to - * share them with other objects of the same size. - */ - for(u = 0; u < num_first_indirect_rows; u++) { - obj_size = DBLOCK_SIZE(fh, u) / 2; - for(v = 0; v < cparam->managed.width; v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, u); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) - TEST_ERROR - } /* end for */ - } /* end for */ + /* Check up on heap... */ + state.huge_size = obj_size; + state.huge_nobjs = 1; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in first huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert second object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 2; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id2, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - /* Go back and backfill all 2nd level indirect block's direct blocks */ - for(u = 0; u < num_first_indirect_rows; u++) { - obj_size = DBLOCK_FREE(fh, u) - (DBLOCK_SIZE(fh, u) / 2); - for(v = 0; v < cparam->managed.width; v++) - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + /* Check up on heap... */ + state.huge_size += obj_size; + state.huge_nobjs = 2; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in second huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert third object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 3; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id3) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id3, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size += obj_size; + state.huge_nobjs = 3; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in third huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id3, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Delete individual objects, if we won't be deleting the entire heap later */ + if(tparam->del_dir != FHEAP_DEL_HEAP) { + if(tparam->del_dir == FHEAP_DEL_FORWARD) { + /* Remove first object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - } /* end for */ + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Remove second object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove third object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id3) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + } /* end if */ + else { + /* Remove third object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id3) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove second object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove first object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + } /* end else */ + } /* end if */ + + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Check for deleting the entire heap */ + if(tparam->del_dir == FHEAP_DEL_HEAP) { + /* Delete heap */ + if(H5HF_delete(f, dxpl, fh_addr) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +#endif /* QAK */ + + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10731,6 +12013,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10739,32 +12024,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_frag_2nd_direct() */ +} /* test_huge_insert_three() */ /*------------------------------------------------------------------------- - * Function: test_man_frag_3rd_direct + * Function: test_huge_insert_mix * - * 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. + * Purpose: Test inserting a mix of 'normal' & 'huge' objects in the heap * - * Then, go back and remove all objects + * Then, remove all the objects, in various ways * * Return: Success: 0 - * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, July 25, 2006 + * Friday, August 11, 2006 * *------------------------------------------------------------------------- */ static int -test_man_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_huge_insert_mix(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 */ @@ -10773,72 +12052,382 @@ test_man_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ - unsigned root_direct_rows; /* Number of rows in root indirect block */ + size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ + unsigned char *heap_id = NULL; /* Heap ID for first object */ + unsigned char *heap_id2 = NULL; /* Heap ID for second object */ + unsigned char *heap_id3 = NULL; /* Heap ID for third object */ + unsigned char *heap_id4 = NULL; /* Heap ID for fourth object */ + unsigned char *heap_id5 = NULL; /* Heap ID for fifth object */ size_t obj_size; /* Size of object */ - size_t fill_size; /* Size of objects for "bulk" filled blocks */ + size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "fill root direct blocks and 2nd level indirect blocks, then fragment 3rd level indirect block's direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "insert mix of normal & huge objects, then remove %s"; /* Test description */ + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) + TEST_ERROR + + /* Allocate heap ID(s) */ + if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id3 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id4 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id5 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + + /* Make certain that 'huge' object's heap IDs are correct size */ + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len != tparam->actual_id_len) + TEST_ERROR + + /* Insert first object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size += obj_size; + state.huge_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in first huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert second object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 2; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id2, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size += obj_size; + state.huge_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in second huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert third object too large for managed heap blocks */ + obj_size = SMALL_STAND_SIZE + 3; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id3) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id3, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size += obj_size; + state.huge_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in third huge object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id3, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert fourth object small enough to fit into 'normal' heap blocks */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id4) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id4, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_MAN) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.man_alloc_size = DBLOCK_SIZE(fh, 2); + state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size; + state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 2); + state.man_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in fourth ('normal') object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id4, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id4, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert fifth object small enough to fit into 'normal' heap blocks */ + obj_size = DBLOCK_SIZE(fh, 3) + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id5) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id5, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_MAN) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + /* (account for doubling of root indirect block) */ + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 4); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 5); + state.man_alloc_size += DBLOCK_SIZE(fh, 4); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); + state.man_free_space += DBLOCK_FREE(fh, 4) - obj_size; + state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 4); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 5); + state.man_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in fifth ('normal') object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id5, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id5, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Delete individual objects, if we won't be deleting the entire heap later */ + if(tparam->del_dir != FHEAP_DEL_HEAP) { + if(tparam->del_dir == FHEAP_DEL_FORWARD) { + /* Remove first object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove second object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove third object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id3) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) - TEST_ERROR + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR - /* Perform common test initialization operations */ - if(begin_test(tparam, base_desc, &keep_ids, &fill_size) < 0) - TEST_ERROR + /* Remove fourth ('normal') object from heap */ + if(H5HF_remove(fh, dxpl, heap_id4) < 0) + FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Compute # of direct rows in root indirect block */ - root_direct_rows = DTABLE_MAX_DROWS(fh); + /* Remove fifth ('normal') object from heap */ + if(H5HF_remove(fh, dxpl, heap_id5) < 0) + FAIL_STACK_ERROR - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + } /* end if */ + else { + /* Remove fifth ('normal') object from heap */ + if(H5HF_remove(fh, dxpl, heap_id5) < 0) + FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Fill all rows of 2nd level indirect blocks in root indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) - TEST_ERROR + /* Remove fourth ('normal') object from heap */ + if(H5HF_remove(fh, dxpl, heap_id4) < 0) + FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Insert objects small enough to fit into each direct block, but not to - * share them with other objects of the same size. - */ - for(u = 0; u < root_direct_rows; u++) { - obj_size = DBLOCK_SIZE(fh, u) / 2; - for(v = 0; v < cparam->managed.width; v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, u); - if(add_obj(fh, dxpl, (size_t)10, obj_size, &state, &keep_ids)) + /* Reset 'managed' object statistics after they are all removed */ + state.man_nobjs = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + + /* Remove third object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id3) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - } /* end for */ - } /* end for */ - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR - /* Go back and backfill all 3rd level indirect block's direct blocks */ - for(u = 0; u < root_direct_rows; u++) { - obj_size = DBLOCK_FREE(fh, u) - (DBLOCK_SIZE(fh, u) / 2); - for(v = 0; v < cparam->managed.width; v++) - if(add_obj(fh, dxpl, (size_t)20, obj_size, &state, &keep_ids)) + /* Remove second object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id2) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) TEST_ERROR - } /* end for */ + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR - /* Perform common file & heap close operations */ - if(close_heap(filename, dxpl, tparam, file, f, &fh, fh_addr, &state, &keep_ids, empty_size) < 0) + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + } /* end else */ + + /* Check up on heap... */ + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + TEST_ERROR + } /* end if */ + + + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Check for deleting the entire heap */ + if(tparam->del_dir == FHEAP_DEL_HEAP) { + /* Delete heap */ + if(H5HF_delete(f, dxpl, fh_addr) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +#endif /* QAK */ + + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR /* Free resources */ + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); + H5MM_xfree(heap_id4); + H5MM_xfree(heap_id5); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10850,6 +12439,11 @@ test_man_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * error: H5E_BEGIN_TRY { + H5MM_xfree(heap_id); + H5MM_xfree(heap_id2); + H5MM_xfree(heap_id3); + H5MM_xfree(heap_id4); + H5MM_xfree(heap_id5); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -10858,28 +12452,24 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_frag_3rd_direct() */ -#endif /* QAK */ +} /* test_huge_insert_mix() */ -#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_huge_insert_one + * Function: test_filtered_huge * - * Purpose: Test inserting one huge object in the heap - * - * Then, remove all the objects, in various ways + * Purpose: Test storing 'huge' object in a heap with I/O filters * * Return: Success: 0 * Failure: 1 * * Programmer: Quincey Koziol - * Monday, August 7, 2006 + * Tuesday, August 15, 2006 * *------------------------------------------------------------------------- */ static int -test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_filtered_huge(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 */ @@ -10887,6 +12477,7 @@ test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ + H5HF_create_t tmp_cparam; /* Local heap creation parameters */ fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ @@ -10894,36 +12485,99 @@ test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar unsigned char *heap_id = NULL; /* Heap ID for object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "insert one huge object, then remove %s"; /* Test description */ + unsigned deflate_level; /* Deflation level */ + unsigned old_actual_id_len; /* Old actual ID length */ + hbool_t huge_ids_direct; /* Are 'huge' objects directly acccessed? */ + const char *base_desc = "insert 'huge' object into heap with I/O filters, then remove %s"; /* Test description */ + + /* Copy heap creation properties */ + HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t)); + + /* Set an I/O filter for heap data */ + deflate_level = 6; + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + FAIL_STACK_ERROR + + /* Adjust actual ID length, if asking for IDs that can directly access 'huge' objects */ + if(cparam->id_len == 1) { + old_actual_id_len = tparam->actual_id_len; + tparam->actual_id_len = 29; /* 1 + 8 (file address size) + 8 (file length size) + 4 (filter mask length) + 8 (object length size) */ + } /* end if */ /* Perform common file & heap open operations */ - if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + if(open_heap(filename, fapl, dxpl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) TEST_ERROR /* Perform common test initialization operations */ if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) TEST_ERROR + /* Allocate heap ID(s) */ if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) TEST_ERROR - /* Make certain that 'huge' object's heap IDs are correct size */ + /* Make certain that 'huge' object's heap IDs are correct form */ if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len != tparam->actual_id_len) TEST_ERROR + if(H5HF_get_huge_info_test(fh, NULL, &huge_ids_direct) < 0) + FAIL_STACK_ERROR + if(cparam->id_len == 1) { + if(huge_ids_direct != TRUE) + TEST_ERROR + } /* end if */ + else + if(tparam->actual_id_len >= 29) { + if(huge_ids_direct != TRUE) + TEST_ERROR + } /* end if */ + else { + if(huge_ids_direct != FALSE) + TEST_ERROR + } /* end else */ /* Insert object too large for managed heap blocks */ obj_size = SMALL_STAND_SIZE + 1; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR +/* QAK */ +#ifdef QAK + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Re-open the heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR +#endif /* QAK */ +/* QAK */ + /* Check up on heap... */ state.huge_size = obj_size; state.huge_nobjs = 1; @@ -10958,7 +12612,6 @@ test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar TEST_ERROR } /* end if */ - /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) FAIL_STACK_ERROR @@ -10979,18 +12632,20 @@ test_huge_insert_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if((file_size = h5_get_file_size(filename)) == 0) TEST_ERROR #ifdef QAK -HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); +HDfprintf(stderr, "empty_size = %lu, file_size = %lu\n", (unsigned long)empty_size, (unsigned long)file_size); #endif /* QAK */ /* Verify the file is correct size */ if(file_size != empty_size) TEST_ERROR + /* Reset actual ID length, if asking for IDs that can directly access 'huge' objects */ + if(cparam->id_len == 1) + tparam->actual_id_len = old_actual_id_len; + /* Free resources */ + H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */ H5MM_xfree(heap_id); - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); /* All tests passed */ PASSED() @@ -11000,21 +12655,20 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { H5MM_xfree(heap_id); - H5MM_xfree(keep_ids.ids); - H5MM_xfree(keep_ids.lens); - H5MM_xfree(keep_ids.offs); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_huge_insert_one() */ +} /* test_filtered_huge() */ +#endif /* QAK */ +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_huge_insert_two + * Function: test_tiny_insert_one * - * Purpose: Test inserting two huge objects in the heap + * Purpose: Test inserting one tiny object in the heap * * Then, remove all the objects, in various ways * @@ -11022,12 +12676,12 @@ error: * Failure: 1 * * Programmer: Quincey Koziol - * Friday, August 11, 2006 + * Monday, August 14, 2006 * *------------------------------------------------------------------------- */ static int -test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_tiny_insert_one(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 */ @@ -11039,12 +12693,12 @@ test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar size_t id_len; /* Size of fractal heap IDs */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ - unsigned char *heap_id = NULL; /* Heap ID for first object */ - unsigned char *heap_id2 = NULL; /* Heap ID for second object */ + unsigned char *heap_id = NULL; /* Heap ID for object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "insert two huge objects, then remove %s"; /* Test description */ + const char *base_desc = "insert one tiny object, then remove %s"; /* Test description */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -11057,127 +12711,58 @@ test_huge_insert_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Allocate heap ID(s) */ if(NULL == (heap_id = H5MM_malloc(tparam->actual_id_len))) TEST_ERROR - if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) - TEST_ERROR - /* Make certain that 'huge' object's heap IDs are correct size */ + /* Make certain that 'tiny' object's heap IDs are correct size */ if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len != tparam->actual_id_len) TEST_ERROR - /* Insert object too large for managed heap blocks */ - obj_size = SMALL_STAND_SIZE + 1; + /* Insert object small enough to encode in heap ID */ + obj_size = tparam->actual_id_len - 2; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size = obj_size; - state.huge_nobjs = 1; - if(check_stats(fh, &state)) - TEST_ERROR - - /* Read in huge object */ - if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) - FAIL_STACK_ERROR - if(obj_size != robj_size) - TEST_ERROR - HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) FAIL_STACK_ERROR - if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + if(obj_type != H5HF_ID_TYPE_TINY) TEST_ERROR - /* Insert second object too large for managed heap blocks */ - obj_size = SMALL_STAND_SIZE + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Check up on heap... */ - state.huge_size += obj_size ; - state.huge_nobjs = 2; + state.tiny_size = obj_size; + state.tiny_nobjs = 1; if(check_stats(fh, &state)) TEST_ERROR - /* Read in second huge object */ - if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + /* Read in tiny object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) FAIL_STACK_ERROR if(obj_size != robj_size) TEST_ERROR HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0) + if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) FAIL_STACK_ERROR if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_ERROR /* Delete individual objects, if we won't be deleting the entire heap later */ if(tparam->del_dir != FHEAP_DEL_HEAP) { - if(tparam->del_dir == FHEAP_DEL_FORWARD) { - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size = obj_size; - state.huge_nobjs = 1; - if(check_stats(fh, &state)) - TEST_ERROR - - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size = 0; - state.huge_nobjs = 0; - if(check_stats(fh, &state)) - TEST_ERROR - } /* end if */ - else { - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size = obj_size; - state.huge_nobjs = 1; - if(check_stats(fh, &state)) - TEST_ERROR - - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id) < 0) - FAIL_STACK_ERROR + /* Remove object from heap */ + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR - /* Check up on heap... */ - state.huge_size = 0; - state.huge_nobjs = 0; - if(check_stats(fh, &state)) - TEST_ERROR - } /* end else */ + /* Check up on heap... */ + state.tiny_size = 0; + state.tiny_nobjs = 0; + if(check_stats(fh, &state)) + TEST_ERROR } /* end if */ @@ -11210,7 +12795,6 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); /* Free resources */ H5MM_xfree(heap_id); - H5MM_xfree(heap_id2); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11223,7 +12807,6 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { H5MM_xfree(heap_id); - H5MM_xfree(heap_id2); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11232,13 +12815,13 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_huge_insert_two() */ +} /* test_tiny_insert_one() */ /*------------------------------------------------------------------------- - * Function: test_huge_insert_three + * Function: test_tiny_insert_two * - * Purpose: Test inserting three huge objects in the heap + * Purpose: Test inserting two tiny objects in the heap * * Then, remove all the objects, in various ways * @@ -11246,12 +12829,12 @@ error: * Failure: 1 * * Programmer: Quincey Koziol - * Friday, August 11, 2006 + * Monday, August 14, 2006 * *------------------------------------------------------------------------- */ static int -test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_tiny_insert_two(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 */ @@ -11265,11 +12848,11 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp off_t file_size; /* Size of file currently */ unsigned char *heap_id = NULL; /* Heap ID for first object */ unsigned char *heap_id2 = NULL; /* Heap ID for second object */ - unsigned char *heap_id3 = NULL; /* Heap ID for third object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "insert three huge objects, then remove %s"; /* Test description */ + const char *base_desc = "insert two tiny objects, then remove %s"; /* Test description */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -11284,31 +12867,33 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp TEST_ERROR if(NULL == (heap_id2 = H5MM_malloc(tparam->actual_id_len))) TEST_ERROR - if(NULL == (heap_id3 = H5MM_malloc(tparam->actual_id_len))) - TEST_ERROR - /* Make certain that 'huge' object's heap IDs are correct size */ + /* Make certain that 'tiny' object's heap IDs are correct size */ if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len != tparam->actual_id_len) TEST_ERROR - /* Insert first object too large for managed heap blocks */ - obj_size = SMALL_STAND_SIZE + 1; + /* Insert object small enough to encode in heap ID */ + obj_size = tparam->actual_id_len - 2; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_TINY) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Check up on heap... */ - state.huge_size = obj_size; - state.huge_nobjs = 1; + state.tiny_size = obj_size; + state.tiny_nobjs = 1; if(check_stats(fh, &state)) TEST_ERROR - /* Read in first huge object */ + /* Read in tiny object */ if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) FAIL_STACK_ERROR if(obj_size != robj_size) @@ -11319,54 +12904,32 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_ERROR - /* Insert second object too large for managed heap blocks */ - obj_size = SMALL_STAND_SIZE + 2; + /* Insert second object small enough to encode in heap ID */ + obj_size = tparam->actual_id_len - 2; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size += obj_size; - state.huge_nobjs = 2; - if(check_stats(fh, &state)) - TEST_ERROR - - /* Read in second huge object */ - if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) - FAIL_STACK_ERROR - if(obj_size != robj_size) - TEST_ERROR - HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0) + if(H5HF_get_id_type_test(fh, heap_id2, &obj_type) < 0) FAIL_STACK_ERROR - if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + if(obj_type != H5HF_ID_TYPE_TINY) TEST_ERROR - /* Insert third object too large for managed heap blocks */ - obj_size = SMALL_STAND_SIZE + 3; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id3) < 0) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Check up on heap... */ - state.huge_size += obj_size; - state.huge_nobjs = 3; + state.tiny_size += obj_size ; + state.tiny_nobjs = 2; if(check_stats(fh, &state)) TEST_ERROR - /* Read in third huge object */ - if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + /* Read in second tiny object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) FAIL_STACK_ERROR if(obj_size != robj_size) TEST_ERROR HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id3, shared_robj_g) < 0) + if(H5HF_read(fh, dxpl, heap_id2, shared_robj_g) < 0) FAIL_STACK_ERROR if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_ERROR @@ -11375,8 +12938,6 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp if(tparam->del_dir != FHEAP_DEL_HEAP) { if(tparam->del_dir == FHEAP_DEL_FORWARD) { /* Remove first object from heap */ - if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) - FAIL_STACK_ERROR if(H5HF_remove(fh, dxpl, heap_id) < 0) FAIL_STACK_ERROR @@ -11385,14 +12946,12 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp TEST_ERROR /* Check up on heap... */ - state.huge_size -= robj_size; - state.huge_nobjs--; + state.tiny_size = obj_size; + state.tiny_nobjs = 1; if(check_stats(fh, &state)) TEST_ERROR /* Remove second object from heap */ - if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) - FAIL_STACK_ERROR if(H5HF_remove(fh, dxpl, heap_id2) < 0) FAIL_STACK_ERROR @@ -11401,47 +12960,13 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp TEST_ERROR /* Check up on heap... */ - state.huge_size -= robj_size; - state.huge_nobjs--; - if(check_stats(fh, &state)) - TEST_ERROR - - /* Remove third object from heap */ - if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) - FAIL_STACK_ERROR - if(H5HF_remove(fh, dxpl, heap_id3) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size -= robj_size; - state.huge_nobjs--; + state.tiny_size = 0; + state.tiny_nobjs = 0; if(check_stats(fh, &state)) TEST_ERROR } /* end if */ else { - /* Remove third object from heap */ - if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) - FAIL_STACK_ERROR - if(H5HF_remove(fh, dxpl, heap_id3) < 0) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) - TEST_ERROR - - /* Check up on heap... */ - state.huge_size -= robj_size; - state.huge_nobjs--; - if(check_stats(fh, &state)) - TEST_ERROR - /* Remove second object from heap */ - if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) - FAIL_STACK_ERROR if(H5HF_remove(fh, dxpl, heap_id2) < 0) FAIL_STACK_ERROR @@ -11450,14 +12975,12 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp TEST_ERROR /* Check up on heap... */ - state.huge_size -= robj_size; - state.huge_nobjs--; + state.tiny_size = obj_size; + state.tiny_nobjs = 1; if(check_stats(fh, &state)) TEST_ERROR /* Remove first object from heap */ - if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) - FAIL_STACK_ERROR if(H5HF_remove(fh, dxpl, heap_id) < 0) FAIL_STACK_ERROR @@ -11466,8 +12989,8 @@ test_huge_insert_three(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tp TEST_ERROR /* Check up on heap... */ - state.huge_size -= robj_size; - state.huge_nobjs--; + state.tiny_size = 0; + state.tiny_nobjs = 0; if(check_stats(fh, &state)) TEST_ERROR } /* end else */ @@ -11504,7 +13027,6 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); /* Free resources */ H5MM_xfree(heap_id); H5MM_xfree(heap_id2); - H5MM_xfree(heap_id3); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11518,7 +13040,6 @@ error: H5E_BEGIN_TRY { H5MM_xfree(heap_id); H5MM_xfree(heap_id2); - H5MM_xfree(heap_id3); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11527,13 +13048,14 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_huge_insert_three() */ +} /* test_tiny_insert_two() */ /*------------------------------------------------------------------------- - * Function: test_huge_insert_mix + * Function: test_tiny_insert_mix * - * Purpose: Test inserting a mix of 'normal' & 'huge' objects in the heap + * Purpose: Test inserting a mix of 'normal', 'huge' & 'tiny' objects in + * the heap * * Then, remove all the objects, in various ways * @@ -11541,12 +13063,12 @@ error: * Failure: 1 * * Programmer: Quincey Koziol - * Friday, August 11, 2006 + * Monday, August 14, 2006 * *------------------------------------------------------------------------- */ static int -test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_tiny_insert_mix(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 */ @@ -11563,10 +13085,13 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar unsigned char *heap_id3 = NULL; /* Heap ID for third object */ unsigned char *heap_id4 = NULL; /* Heap ID for fourth object */ unsigned char *heap_id5 = NULL; /* Heap ID for fifth object */ + unsigned char *heap_id6 = NULL; /* Heap ID for sixth object */ + unsigned char *heap_id7 = NULL; /* Heap ID for seventh object */ size_t obj_size; /* Size of object */ size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "insert mix of normal & huge objects, then remove %s"; /* Test description */ + const char *base_desc = "insert mix of normal, huge & tiny objects, then remove %s"; /* Test description */ /* Perform common file & heap open operations */ if(open_heap(filename, fapl, dxpl, cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) @@ -11587,8 +13112,12 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar TEST_ERROR if(NULL == (heap_id5 = H5MM_malloc(tparam->actual_id_len))) TEST_ERROR + if(NULL == (heap_id6 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR + if(NULL == (heap_id7 = H5MM_malloc(tparam->actual_id_len))) + TEST_ERROR - /* Make certain that 'huge' object's heap IDs are correct size */ + /* Make certain that 'tiny' object's heap IDs are correct size */ if(H5HF_get_id_len(fh, &id_len) < 0) FAIL_STACK_ERROR if(id_len != tparam->actual_id_len) @@ -11598,6 +13127,10 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar obj_size = SMALL_STAND_SIZE + 1; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) @@ -11624,6 +13157,10 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar obj_size = SMALL_STAND_SIZE + 2; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id2) < 0) FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id2, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) @@ -11650,6 +13187,10 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar obj_size = SMALL_STAND_SIZE + 3; if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id3) < 0) FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id3, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_HUGE) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) @@ -11667,74 +13208,143 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(obj_size != robj_size) TEST_ERROR HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id3, shared_robj_g) < 0) + if(H5HF_read(fh, dxpl, heap_id3, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert fourth object small enough to fit into 'normal' heap blocks */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id4) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id4, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_MAN) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.man_alloc_size = DBLOCK_SIZE(fh, 2); + state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size; + state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 2); + state.man_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in fourth ('normal') object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id4, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id4, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Insert fifth object small enough to fit into 'normal' heap blocks */ + obj_size = DBLOCK_SIZE(fh, 3) + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id5) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id5, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_MAN) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + /* (account for doubling of root indirect block) */ + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 4); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 5); + state.man_alloc_size += DBLOCK_SIZE(fh, 4); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); + state.man_free_space += DBLOCK_FREE(fh, 4) - obj_size; + state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 4); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 5); + state.man_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in fifth ('normal') object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id5, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id5, shared_robj_g) < 0) FAIL_STACK_ERROR if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_ERROR - /* Insert fourth object small enough to fit into 'normal' heap blocks */ - obj_size = DBLOCK_SIZE(fh, 0) + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id4) < 0) + + /* Insert sixth object small enough to encode in heap ID */ + obj_size = tparam->actual_id_len - 2; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id6) < 0) FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id6, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_TINY) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Check up on heap... */ - state.man_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - state.man_alloc_size = DBLOCK_SIZE(fh, 2); - state.man_free_space = cparam->managed.width * DBLOCK_FREE(fh, 0); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); - state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size; - state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 2); - state.man_nobjs++; + state.tiny_size = obj_size; + state.tiny_nobjs = 1; if(check_stats(fh, &state)) TEST_ERROR - /* Read in fourth ('normal') object */ - if(H5HF_get_obj_len(fh, dxpl, heap_id4, &robj_size) < 0) + /* Read in tiny object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id6, &robj_size) < 0) FAIL_STACK_ERROR if(obj_size != robj_size) TEST_ERROR HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id4, shared_robj_g) < 0) + if(H5HF_read(fh, dxpl, heap_id6, shared_robj_g) < 0) FAIL_STACK_ERROR if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_ERROR - /* Insert fifth object small enough to fit into 'normal' heap blocks */ - obj_size = DBLOCK_SIZE(fh, 3) + 1; - if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id5) < 0) + /* Insert seventh object small enough to encode in heap ID */ + obj_size = tparam->actual_id_len - 2; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id7) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id7, &obj_type) < 0) FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_TINY) + TEST_ERROR /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR /* Check up on heap... */ - /* (account for doubling of root indirect block) */ - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 4); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 5); - state.man_alloc_size += DBLOCK_SIZE(fh, 4); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 3); - state.man_free_space += DBLOCK_FREE(fh, 4) - obj_size; - state.man_free_space += (cparam->managed.width - 1) * DBLOCK_FREE(fh, 4); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 5); - state.man_nobjs++; + state.tiny_size += obj_size; + state.tiny_nobjs++; if(check_stats(fh, &state)) TEST_ERROR - /* Read in fifth ('normal') object */ - if(H5HF_get_obj_len(fh, dxpl, heap_id5, &robj_size) < 0) + /* Read in tiny object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id7, &robj_size) < 0) FAIL_STACK_ERROR if(obj_size != robj_size) TEST_ERROR HDmemset(shared_robj_g, 0, obj_size); - if(H5HF_read(fh, dxpl, heap_id5, shared_robj_g) < 0) + if(H5HF_read(fh, dxpl, heap_id7, shared_robj_g) < 0) FAIL_STACK_ERROR if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) TEST_ERROR @@ -11805,8 +13415,70 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + + /* Reset 'managed' object statistics after they are all removed */ + state.man_nobjs = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + + /* Remove sixth object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id6, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id6) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.tiny_size -= robj_size; + state.tiny_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove seventh object from heap */ + if(H5HF_remove(fh, dxpl, heap_id7) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR } /* end if */ else { + /* Remove seventh object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id7, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id7) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.tiny_size -= robj_size; + state.tiny_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Remove sixth object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id6, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id6) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + state.tiny_size -= robj_size; + state.tiny_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + /* Remove fifth ('normal') object from heap */ if(H5HF_remove(fh, dxpl, heap_id5) < 0) FAIL_STACK_ERROR @@ -11823,7 +13495,15 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Reset 'managed' object statistics after they are all removed */ + state.man_nobjs = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + /* Remove third object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id3, &robj_size) < 0) + FAIL_STACK_ERROR if(H5HF_remove(fh, dxpl, heap_id3) < 0) FAIL_STACK_ERROR @@ -11831,7 +13511,15 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + /* Remove second object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id2, &robj_size) < 0) + FAIL_STACK_ERROR if(H5HF_remove(fh, dxpl, heap_id2) < 0) FAIL_STACK_ERROR @@ -11839,6 +13527,12 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR + /* Check up on heap... */ + state.huge_size -= robj_size; + state.huge_nobjs--; + if(check_stats(fh, &state)) + TEST_ERROR + /* Remove first object from heap */ if(H5HF_remove(fh, dxpl, heap_id) < 0) FAIL_STACK_ERROR @@ -11846,12 +13540,12 @@ test_huge_insert_mix(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar /* Check for closing & re-opening the heap */ if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) TEST_ERROR - - /* Check up on heap... */ - HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - if(check_stats(fh, &state)) - TEST_ERROR } /* end else */ + + /* Check up on heap... */ + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + TEST_ERROR } /* end if */ @@ -11888,6 +13582,8 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); H5MM_xfree(heap_id3); H5MM_xfree(heap_id4); H5MM_xfree(heap_id5); + H5MM_xfree(heap_id6); + H5MM_xfree(heap_id7); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11904,6 +13600,8 @@ error: H5MM_xfree(heap_id3); H5MM_xfree(heap_id4); H5MM_xfree(heap_id5); + H5MM_xfree(heap_id6); + H5MM_xfree(heap_id7); H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); @@ -11912,14 +13610,192 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_huge_insert_mix() */ +} /* test_tiny_insert_mix() */ #endif /* QAK */ #endif /* QAK2 */ +#ifdef NOT_YET + +/*------------------------------------------------------------------------- + * Function: test_filtered_man_one + * + * Purpose: Test storing one 'managed' object in a heap with I/O filters + * + * Return: Success: 0 + * Failure: 1 + * + * Programmer: Quincey Koziol + * Monday, August 14, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_filtered_man_one(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[FHEAP_FILENAME_LEN]; /* 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 */ + H5HF_create_t tmp_cparam; /* Local heap creation parameters */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ + unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object */ + size_t obj_size; /* Size of object */ + size_t robj_size; /* Size of object read */ + unsigned char obj_type; /* Type of storage for object */ + fheap_heap_state_t state; /* State of fractal heap */ + unsigned deflate_level; /* Deflation level */ + const char *base_desc = "insert one 'managed' object into heap with I/O filters, then remove %s"; /* Test description */ + + /* Copy heap creation properties */ + HDmemcpy(&tmp_cparam, cparam, sizeof(H5HF_create_t)); + + /* Set an I/O filter for heap data */ + deflate_level = 6; + if(H5Z_append(&tmp_cparam.pline, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, 1, &deflate_level) < 0) + FAIL_STACK_ERROR + + /* Perform common file & heap open operations */ + if(open_heap(filename, fapl, dxpl, &tmp_cparam, tparam, &file, &f, &fh, &fh_addr, &state, &empty_size) < 0) + TEST_ERROR + + /* Perform common test initialization operations */ + if(begin_test(tparam, base_desc, &keep_ids, NULL) < 0) + TEST_ERROR + + + /* Insert object small enough to fit into 'normal' heap blocks */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + if(H5HF_insert(fh, dxpl, obj_size, shared_wobj_g, heap_id) < 0) + FAIL_STACK_ERROR + if(H5HF_get_id_type_test(fh, heap_id, &obj_type) < 0) + FAIL_STACK_ERROR + if(obj_type != H5HF_ID_TYPE_MAN) + TEST_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + +/* QAK */ +#ifdef QAK + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0) + FAIL_STACK_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + FAIL_STACK_ERROR + + /* Re-open the heap */ + if(NULL == (fh = H5HF_open(f, H5P_DATASET_XFER_DEFAULT, fh_addr))) + FAIL_STACK_ERROR +#endif /* QAK */ +/* QAK */ + + /* Check up on heap... */ + state.man_size = tmp_cparam.managed.width * DBLOCK_SIZE(fh, 0); + state.man_size += tmp_cparam.managed.width * DBLOCK_SIZE(fh, 1); + state.man_size += tmp_cparam.managed.width * DBLOCK_SIZE(fh, 2); + state.man_alloc_size = DBLOCK_SIZE(fh, 2); + state.man_free_space = tmp_cparam.managed.width * DBLOCK_FREE(fh, 0); + state.man_free_space += tmp_cparam.managed.width * DBLOCK_FREE(fh, 1); + state.man_free_space += DBLOCK_FREE(fh, 2) - obj_size; + state.man_free_space += (tmp_cparam.managed.width - 1) * DBLOCK_FREE(fh, 2); + state.man_nobjs++; + if(check_stats(fh, &state)) + TEST_ERROR + + /* Read in ('normal') object */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(obj_size != robj_size) + TEST_ERROR + HDmemset(shared_robj_g, 0, obj_size); + if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) + FAIL_STACK_ERROR + if(HDmemcmp(shared_wobj_g, shared_robj_g, obj_size)) + TEST_ERROR + + /* Delete individual objects, if we won't be deleting the entire heap later */ + if(tparam->del_dir != FHEAP_DEL_HEAP) { + /* Remove object from heap */ + if(H5HF_get_obj_len(fh, dxpl, heap_id, &robj_size) < 0) + FAIL_STACK_ERROR + if(H5HF_remove(fh, dxpl, heap_id) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(reopen_heap(f, dxpl, &fh, fh_addr, tparam) < 0) + TEST_ERROR + + /* Check up on heap... */ + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + TEST_ERROR + } /* end if */ + + /* Close the fractal heap */ + if(H5HF_close(fh, H5P_DATASET_XFER_DEFAULT) < 0) + FAIL_STACK_ERROR + fh = NULL; + + /* Check for deleting the entire heap */ + if(tparam->del_dir == FHEAP_DEL_HEAP) { + /* Delete heap */ + if(H5HF_delete(f, dxpl, fh_addr) < 0) + FAIL_STACK_ERROR + } /* end if */ + + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR + + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu, file_size = %lu\n", (unsigned long)empty_size, (unsigned long)file_size); +#endif /* QAK */ + + /* Verify the file is correct size */ + if(file_size != empty_size) + TEST_ERROR + + /* Free resources */ + H5O_reset(H5O_PLINE_ID, &tmp_cparam.pline); /* Release the I/O pipeline filter information */ + + /* All tests passed */ + PASSED() + + return(0); + +error: + H5E_BEGIN_TRY { + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_filtered_man_one() */ +#endif /* NOT_YET */ + #ifndef QAK /*------------------------------------------------------------------------- - * Function: test_man_random + * Function: test_random * * Purpose: Test inserting random sized objects into a heap, and read * them back. @@ -11936,7 +13812,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_random(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_random(hsize_t size_limit, 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 */ @@ -12085,11 +13961,11 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_random() */ +} /* test_random() */ /*------------------------------------------------------------------------- - * Function: test_man_random_pow2 + * Function: test_random_pow2 * * Purpose: Test inserting random sized objects with a "power of 2 * distribution" (which favors small objects) into a heap, @@ -12107,7 +13983,7 @@ error: *------------------------------------------------------------------------- */ static int -test_man_random_pow2(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_random_pow2(hsize_t size_limit, 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 */ @@ -12268,7 +14144,7 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_man_random_pow2() */ +} /* test_random_pow2() */ #endif /* QAK */ @@ -12356,6 +14232,8 @@ curr_test = FHEAP_TEST_REOPEN; /* Test fractal heap creation */ nerrors += test_create(fapl, &cparam, &tparam); nerrors += test_reopen(fapl, &cparam, &tparam); + nerrors += test_id_limits(fapl, &cparam); + nerrors += test_filtered_create(fapl, &cparam); #ifndef QAK2 #ifndef QAK @@ -12562,15 +14440,15 @@ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ /* - * Test fractal heap huge object insertion & deletion + * Test fractal heap 'huge' & 'tiny' object insertion & deletion */ #ifndef QAK { fheap_test_del_dir_t del_dir; /* Deletion direction */ unsigned id_len; /* Length of heap IDs */ - /* Test "normal" & "direct" storage of 'huge' heap IDs */ - for(id_len = 0; id_len < 2; id_len++) { + /* Test "normal" & "direct" storage of 'huge' & 'tiny' heap IDs */ + for(id_len = 0; id_len < 3; id_len++) { /* Set the ID length for this test */ cparam.id_len = id_len; @@ -12586,7 +14464,14 @@ HDfprintf(stderr, "Uncomment tests!\n"); puts("Using 'direct' heap ID format for 'huge' objects"); /* Adjust actual length of heap IDs for directly storing 'huge' object's file offset & length in heap ID */ - tparam.actual_id_len = 17; /* 1 + 8 (address size) + 8 (length size) */ + tparam.actual_id_len = 17; /* 1 + 8 (file address size) + 8 (file length size) */ + break; + + /* Use "direct" storage for 'huge' objects and larger IDs for 'tiny' objects */ + case 2: + cparam.id_len = 37; + puts("Using 'direct' heap ID format for 'huge' objects and larger IDs for 'tiny' objects"); + tparam.actual_id_len = 37; break; /* An unknown test? */ @@ -12594,14 +14479,25 @@ HDfprintf(stderr, "Uncomment tests!\n"); goto error; } /* end switch */ - /* Try several different methods of deleting 'huge' objects */ + /* Try several different methods of deleting objects */ for(del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) { tparam.del_dir = del_dir; + /* Test 'huge' object insert & delete */ nerrors += test_huge_insert_one(fapl, &cparam, &tparam); nerrors += test_huge_insert_two(fapl, &cparam, &tparam); nerrors += test_huge_insert_three(fapl, &cparam, &tparam); nerrors += test_huge_insert_mix(fapl, &cparam, &tparam); + nerrors += test_filtered_huge(fapl, &cparam, &tparam); + +#ifndef QAK + /* Test 'tiny' object insert & delete */ + nerrors += test_tiny_insert_one(fapl, &cparam, &tparam); + nerrors += test_tiny_insert_two(fapl, &cparam, &tparam); + nerrors += test_tiny_insert_mix(fapl, &cparam, &tparam); +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ } /* end for */ } /* end for */ @@ -12616,6 +14512,12 @@ HDfprintf(stderr, "Uncomment tests!\n"); HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK2 */ + /* Test I/O filter support */ +#ifdef NOT_YET + /* This test isn't working properly yet */ + nerrors += test_filtered_man_one(fapl, &cparam, &tparam); +#endif /* NOT_YET */ + #ifndef QAK /* Random object insertion & deletion */ if (ExpressMode > 1) @@ -12624,12 +14526,12 @@ HDfprintf(stderr, "Uncomment tests!\n"); /* (reduce size of tests when re-opening each time) */ /* XXX: Try to speed things up enough that these tests don't have to be reduced */ tparam.del_dir = FHEAP_DEL_FORWARD; - nerrors += test_man_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &cparam, &tparam); - nerrors += test_man_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &cparam, &tparam); + nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &cparam, &tparam); + nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &cparam, &tparam); tparam.del_dir = FHEAP_DEL_HEAP; - nerrors += test_man_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &cparam, &tparam); - nerrors += test_man_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &cparam, &tparam); + nerrors += test_random((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &cparam, &tparam); + nerrors += test_random_pow2((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(4*1000*1000)), fapl, &cparam, &tparam); } /* end else */ #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c index 5cb47e2..bbeb1c2 100644 --- a/tools/misc/h5debug.c +++ b/tools/misc/h5debug.c @@ -214,6 +214,22 @@ main(int argc, char *argv[]) status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5B2_TEST); break; + case H5B2_FHEAP_HUGE_INDIR_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_INDIR); + break; + + case H5B2_FHEAP_HUGE_FILT_INDIR_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_INDIR); + break; + + case H5B2_FHEAP_HUGE_DIR_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_DIR); + break; + + case H5B2_FHEAP_HUGE_FILT_DIR_ID: + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_DIR); + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); @@ -240,6 +256,22 @@ main(int argc, char *argv[]) status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5B2_TEST, extra, (unsigned)extra2); break; + case H5B2_FHEAP_HUGE_INDIR_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_INDIR, extra, (unsigned)extra2); + break; + + case H5B2_FHEAP_HUGE_FILT_INDIR_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_INDIR, extra, (unsigned)extra2); + break; + + case H5B2_FHEAP_HUGE_DIR_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_DIR, extra, (unsigned)extra2); + break; + + case H5B2_FHEAP_HUGE_FILT_DIR_ID: + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_DIR, extra, (unsigned)extra2); + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); @@ -266,6 +298,22 @@ main(int argc, char *argv[]) status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5B2_TEST, extra, (unsigned)extra2); break; + case H5B2_FHEAP_HUGE_INDIR_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_INDIR, extra, (unsigned)extra2); + break; + + case H5B2_FHEAP_HUGE_FILT_INDIR_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_INDIR, extra, (unsigned)extra2); + break; + + case H5B2_FHEAP_HUGE_DIR_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_DIR, extra, (unsigned)extra2); + break; + + case H5B2_FHEAP_HUGE_FILT_DIR_ID: + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, H5HF_BT2_FILT_DIR, extra, (unsigned)extra2); + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); -- cgit v0.12