From 87449d081d1c99312034d917502f2b6aca2ee60c Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Mon, 31 Jul 2006 04:54:09 -0500 Subject: [svn-r12517] Description: Fix the last scattered bunch of problems with the object deletion code, which appears to be completely working now (for objects that are stored within heap blocks - standalone objects aren't implemented yet). Also, re-work the regression test to speed up some of the existing tests and add in 100-200 more combinations of tests - overall, its probably even slower than it was... :-/ Tested: FreeBSD 4.11 (sleipnir) Linux 2.4 (chicago) Mac OS X (amazon) --- src/H5FS.c | 187 +- src/H5FSprivate.h | 5 + src/H5HF.c | 17 +- src/H5HFdbg.c | 12 +- src/H5HFdblock.c | 4 +- src/H5HFdtable.c | 85 +- src/H5HFhdr.c | 58 +- src/H5HFiblock.c | 4 + src/H5HFint.c | 5 +- src/H5HFpkg.h | 9 +- src/H5HFsection.c | 725 ++-- test/fheap.c | 10570 ++++++++++++++++++++++++++++++++++------------------ 12 files changed, 7602 insertions(+), 4079 deletions(-) diff --git a/src/H5FS.c b/src/H5FS.c index e465e11..ca9e321 100644 --- a/src/H5FS.c +++ b/src/H5FS.c @@ -127,6 +127,8 @@ static herr_t H5FS_sect_link_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, const H5FS_section_class_t *cls, H5FS_section_info_t *sect); static herr_t H5FS_sect_link(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect); +static herr_t H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, + H5FS_section_info_t **sect, void *op_data); static htri_t H5FS_find_bin_node(H5FS_t *fspace, hsize_t request, H5FS_section_info_t **node); static herr_t H5FS_serialize_sect_cb(void *_item, void UNUSED *key, void *_udata); static herr_t H5FS_serialize_node_cb(void *_item, void UNUSED *key, void *_udata); @@ -1363,94 +1365,95 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, /* Check arguments. */ HDassert(fspace); - HDassert(fspace->merge_list); HDassert(*sect); HDassert(H5F_addr_defined((*sect)->addr)); HDassert((*sect)->size); /* Loop until no more merging */ - do { - H5FS_section_class_t *tmp_sect_cls; /* Temporary section's class */ - - /* Reset 'modification occurred' flag */ - modified = FALSE; - - /* Look for neighboring section before new section */ - tmp_sect_node = H5SL_less(fspace->merge_list, &(*sect)->addr); - - /* Check for node before new node able to merge with new node */ - if(tmp_sect_node) { - /* Get classes for right & left sections */ - tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type]; - sect_cls = &fspace->sect_cls[(*sect)->type]; - - /* Check if sections of the left most class can merge with sections - * of another class & whether the sections are the same type, - * then check for 'can merge' callback - */ - if((!(tmp_sect_cls->flags & H5FS_CLS_MERGE_SYM) || (tmp_sect_node->type == (*sect)->type)) - && tmp_sect_cls->can_merge) { - /* Determine if the sections can merge */ - if((status = (*tmp_sect_cls->can_merge)(tmp_sect_node, *sect, op_data)) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for merging sections") - if(status > 0) { - /* Sanity check */ - HDassert(tmp_sect_cls->merge); - - /* Remove 'less than' node from data structures */ - if(H5FS_remove(f, dxpl_id, fspace, tmp_sect_node) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures") - - /* Merge the two sections together */ - if((*tmp_sect_cls->merge)(tmp_sect_node, *sect, op_data) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections") - - /* Retarget section pointer to 'less than' node that was merged into */ - *sect = tmp_sect_node; - - /* Indicate successful merge occurred */ - modified = TRUE; + if(fspace->merge_list) { + do { + H5FS_section_class_t *tmp_sect_cls; /* Temporary section's class */ + + /* Reset 'modification occurred' flag */ + modified = FALSE; + + /* Look for neighboring section before new section */ + tmp_sect_node = H5SL_less(fspace->merge_list, &(*sect)->addr); + + /* Check for node before new node able to merge with new node */ + if(tmp_sect_node) { + /* Get classes for right & left sections */ + tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type]; + sect_cls = &fspace->sect_cls[(*sect)->type]; + + /* Check if sections of the left most class can merge with sections + * of another class & whether the sections are the same type, + * then check for 'can merge' callback + */ + if((!(tmp_sect_cls->flags & H5FS_CLS_MERGE_SYM) || (tmp_sect_node->type == (*sect)->type)) + && tmp_sect_cls->can_merge) { + /* Determine if the sections can merge */ + if((status = (*tmp_sect_cls->can_merge)(tmp_sect_node, *sect, op_data)) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for merging sections") + if(status > 0) { + /* Sanity check */ + HDassert(tmp_sect_cls->merge); + + /* Remove 'less than' node from data structures */ + if(H5FS_remove(f, dxpl_id, fspace, tmp_sect_node) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures") + + /* Merge the two sections together */ + if((*tmp_sect_cls->merge)(tmp_sect_node, *sect, op_data) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections") + + /* Retarget section pointer to 'less than' node that was merged into */ + *sect = tmp_sect_node; + + /* Indicate successful merge occurred */ + modified = TRUE; + } /* end if */ } /* end if */ } /* end if */ - } /* end if */ - /* Look for section after new (or merged) section */ - tmp_sect_node = H5SL_greater(fspace->merge_list, &(*sect)->addr); - - /* Check for node after new node able to merge with new node */ - if(tmp_sect_node) { - /* Get classes for right & left sections */ - sect_cls = &fspace->sect_cls[(*sect)->type]; - tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type]; - - /* Check if sections of the left most class can merge with sections - * of another class & whether the sections are the same type, - * then check for 'can merge' callback - */ - if((!(sect_cls->flags & H5FS_CLS_MERGE_SYM) || ((*sect)->type == tmp_sect_node->type)) - && sect_cls->can_merge) { - - /* Determine if the sections can merge */ - if((status = (*sect_cls->can_merge)(*sect, tmp_sect_node, op_data)) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for merging sections") - if(status > 0) { - /* Sanity check */ - HDassert(sect_cls->merge); - - /* Remove 'greater than' node from data structures */ - if(H5FS_remove(f, dxpl_id, fspace, tmp_sect_node) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures") - - /* Merge the two sections together */ - if((*sect_cls->merge)(*sect, tmp_sect_node, op_data) < 0) - HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections") - - /* Indicate successful merge occurred */ - modified = TRUE; + /* Look for section after new (or merged) section */ + tmp_sect_node = H5SL_greater(fspace->merge_list, &(*sect)->addr); + + /* Check for node after new node able to merge with new node */ + if(tmp_sect_node) { + /* Get classes for right & left sections */ + sect_cls = &fspace->sect_cls[(*sect)->type]; + tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type]; + + /* Check if sections of the left most class can merge with sections + * of another class & whether the sections are the same type, + * then check for 'can merge' callback + */ + if((!(sect_cls->flags & H5FS_CLS_MERGE_SYM) || ((*sect)->type == tmp_sect_node->type)) + && sect_cls->can_merge) { + + /* Determine if the sections can merge */ + if((status = (*sect_cls->can_merge)(*sect, tmp_sect_node, op_data)) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTMERGE, FAIL, "can't check for merging sections") + if(status > 0) { + /* Sanity check */ + HDassert(sect_cls->merge); + + /* Remove 'greater than' node from data structures */ + if(H5FS_remove(f, dxpl_id, fspace, tmp_sect_node) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTRELEASE, FAIL, "can't remove section from internal data structures") + + /* Merge the two sections together */ + if((*sect_cls->merge)(*sect, tmp_sect_node, op_data) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections") + + /* Indicate successful merge occurred */ + modified = TRUE; + } /* end if */ } /* end if */ } /* end if */ - } /* end if */ - } while(modified); + } while(modified); + } /* end if */ HDassert(*sect); #ifdef QAK HDfprintf(stderr, "%s: Done merging, (*sect) = {%a, %Hu, %u, %s}\n", FUNC, (*sect)->addr, (*sect)->size, (*sect)->type, ((*sect)->state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); @@ -1471,7 +1474,14 @@ HDfprintf(stderr, "%s: Done merging, (*sect) = {%a, %Hu, %u, %s}\n", FUNC, (*sec HDfprintf(stderr, "%s: Can shrink!\n", FUNC); #endif /* QAK */ /* Look for neighboring section before new section */ - tmp_sect_node = H5SL_less(fspace->merge_list, &(*sect)->addr); + if(fspace->merge_list) { + tmp_sect_node = H5SL_less(fspace->merge_list, &(*sect)->addr); + + /* Make certain there isn't a section after the new section */ + HDassert(H5SL_greater(fspace->merge_list, &(*sect)->addr) == NULL); + } /* end if */ + else + tmp_sect_node = NULL; /* Shrink the container */ /* (callback can indicate that it has discarded the section by setting *sect to NULL) */ @@ -1527,12 +1537,13 @@ herr_t H5FS_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect, unsigned flags, void *op_data) { + H5FS_section_class_t *cls; /* Section's class */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5FS_add, FAIL) #ifdef QAK -HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", FUNC, sect->size, sect->addr, sect->type); +HDfprintf(stderr, "%s: *sect = {%a, %Hu, %u, %s}\n", FUNC, sect->addr, sect->size, sect->type, (sect->state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); #endif /* QAK */ /* Check arguments. */ @@ -1548,8 +1559,15 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", FU HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't deserialize sections") } /* end if */ + /* Call "add" section class callback, if there is one */ + cls = &fspace->sect_cls[sect->type]; + if(cls->add) { + if((*cls->add)(sect, &flags, op_data) < 0) + HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "'add' section class callback failed") + } /* end if */ + /* Check for merging returned space with existing section node */ - if((flags & H5FS_ADD_RETURNED_SPACE) && fspace->hdr->tot_sect_count > 0) { + if(flags & H5FS_ADD_RETURNED_SPACE) { #ifdef QAK HDfprintf(stderr, "%s: Returning space\n", FUNC); #endif /* QAK */ @@ -1577,7 +1595,7 @@ HDfprintf(stderr, "%s: fspace->hdr->tot_space = %Hu\n", FUNC, fspace->hdr->tot_s done: #ifdef H5FS_DEBUG -if(!(flags & H5FS_ADD_DESERIALIZING)) +if(!(flags & (H5FS_ADD_DESERIALIZING | H5FS_ADD_SKIP_VALID))) H5FS_assert(fspace); #endif /* H5FS_DEBUG */ FUNC_LEAVE_NOAPI(ret_value) @@ -2776,9 +2794,6 @@ HDfprintf(stderr, "%s: removing object from merge list, sect->type = %u\n", FUNC fspace->dirty = TRUE; done: -#ifdef H5FS_DEBUG - H5FS_assert(fspace); -#endif /* H5FS_DEBUG */ FUNC_LEAVE_NOAPI(ret_value) } /* H5FS_sect_change_class() */ @@ -3216,7 +3231,9 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", "H HDassert(fspace->hdr->tot_sect_count >= fspace->hdr->serial_sect_count); HDassert(fspace->hdr->tot_sect_count >= fspace->hdr->ghost_sect_count); HDassert(fspace->hdr->tot_sect_count == (fspace->hdr->serial_sect_count + fspace->hdr->ghost_sect_count)); +#ifdef QAK HDassert(fspace->hdr->serial_sect_count > 0 || fspace->hdr->ghost_sect_count == 0); +#endif /* QAK */ /* Make certain that the number of sections on the address list is correct */ if(fspace->merge_list) diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h index 2b840bd..dfbefa7 100644 --- a/src/H5FSprivate.h +++ b/src/H5FSprivate.h @@ -58,6 +58,10 @@ * as a result of freeing an * object) */ +#define H5FS_ADD_SKIP_VALID 0x04 /* Don't check validity after adding + * this section. (state of the + * managed sections is in flux) + */ /* Flags for deserialize callback */ #define H5FS_DESERIALIZE_NO_ADD 0x01 /* Don't add section to free space @@ -90,6 +94,7 @@ typedef struct H5FS_section_class_t { herr_t (*term_cls)(struct H5FS_section_class_t *); /* Routine to terminate class-specific settings */ /* Object methods */ + herr_t (*add)(H5FS_section_info_t *, unsigned *, void *); /* Routine called when section is about to be added to manager */ herr_t (*serialize)(const struct H5FS_section_class_t *, const H5FS_section_info_t *, uint8_t *); /* Routine to serialize a "live" section into a buffer */ H5FS_section_info_t *(*deserialize)(const struct H5FS_section_class_t *, hid_t dxpl_id, const uint8_t *, haddr_t, hsize_t, unsigned *); /* Routine to deserialize a buffer into a "live" section */ htri_t (*can_merge)(const H5FS_section_info_t *, const H5FS_section_info_t *, void *); /* Routine to determine if two nodes are mergable */ diff --git a/src/H5HF.c b/src/H5HF.c index 58da8a4..733df6c 100644 --- a/src/H5HF.c +++ b/src/H5HF.c @@ -354,7 +354,7 @@ HDfprintf(stderr, "%s: size = %Zu\n", FUNC, size); hdr = fh->hdr; /* Check if object is large enough to be standalone */ - if(size >= hdr->standalone_size) { + if(size > hdr->standalone_size) { HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "standalone blocks not supported yet") } /* end if */ else { @@ -582,8 +582,19 @@ H5HF_close(H5HF_t *fh, hid_t dxpl_id) * a reference loop and the objects couldn't be removed from * the metadata cache - QAK) */ - if(H5HF_man_iter_reset(&fh->hdr->next_block) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator") +#ifdef QAK +HDfprintf(stderr, "%s; fh->hdr->man_iter_off = %Hu\n", FUNC, fh->hdr->man_iter_off); +HDfprintf(stderr, "%s; fh->hdr->man_size = %Hu\n", FUNC, fh->hdr->man_size); +HDfprintf(stderr, "%s; fh->hdr->rc = %Zu\n", FUNC, fh->hdr->rc); +#endif /* QAK */ + /* Reset block iterator, if necessary */ + if(H5HF_man_iter_ready(&fh->hdr->next_block)) { + if(H5HF_man_iter_reset(&fh->hdr->next_block) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator") + } /* end if */ +#ifdef QAK +HDfprintf(stderr, "%s; After iterator reset fh->hdr->rc = %Zu\n", FUNC, fh->hdr->rc); +#endif /* QAK */ /* Decrement the reference count on the heap header */ if(H5HF_hdr_decr(fh->hdr) < 0) diff --git a/src/H5HFdbg.c b/src/H5HFdbg.c index 2d878f9..52227a6 100644 --- a/src/H5HFdbg.c +++ b/src/H5HFdbg.c @@ -622,20 +622,22 @@ H5HF_sects_debug_cb(const H5FS_section_info_t *_sect, void *_udata) HDassert(udata); /* Print generic section information */ + HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth, + "Section type:", + (sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE ? "single" : + (sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ? "first row" : + (sect->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW ? "normal row" : "unknown")))); HDfprintf(udata->stream, "%*s%-*s %a\n", udata->indent, "", udata->fwidth, "Section address:", sect->sect_info.addr); HDfprintf(udata->stream, "%*s%-*s %Hu\n", udata->indent, "", udata->fwidth, "Section size:", sect->sect_info.size); - HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth, - "Section type:", - (sect->sect_info.type == H5HF_FSPACE_SECT_SINGLE ? "single" : - (sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ? "first row" : - (sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ? "normal row" : "unknown")))); +#ifdef QAK HDfprintf(udata->stream, "%*s%-*s %s\n", udata->indent, "", udata->fwidth, "Section state:", (sect->sect_info.state == H5FS_SECT_LIVE ? "live" : "serialized")); +#endif /* QAK */ /* Dump section-specific debugging information */ if(H5FS_sect_debug(udata->fspace, _sect, udata->stream, udata->indent + 3, MAX(0, udata->fwidth - 3)) < 0) diff --git a/src/H5HFdblock.c b/src/H5HFdblock.c index 590d8f3..00821e9 100644 --- a/src/H5HFdblock.c +++ b/src/H5HFdblock.c @@ -394,14 +394,14 @@ HDfprintf(stderr, "%s: root direct block, dblock_addr = %a\n", FUNC, dblock_addr size_t next_size; /* Size of next direct block to create */ #ifdef QAK -HDfprintf(stderr, "%s: before updating iterator\n", FUNC); +HDfprintf(stderr, "%s: before updating iterator, hdr->man_iter_off = %Hu, hdr->man_size = %Hu\n", FUNC, hdr->man_iter_off, hdr->man_size); #endif /* QAK */ /* Update iterator to reflect any previous increments as well as allow for requested direct block size */ if(H5HF_hdr_update_iter(hdr, dxpl_id, min_dblock_size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTUPDATE, FAIL, "unable to update block iterator") #ifdef QAK -HDfprintf(stderr, "%s: after updating iterator\n", FUNC); +HDfprintf(stderr, "%s: after updating iterator, hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off); #endif /* QAK */ /* Retrieve information about current iterator position */ if(H5HF_man_iter_curr(&hdr->next_block, &next_row, NULL, &next_entry, &iblock) < 0) diff --git a/src/H5HFdtable.c b/src/H5HFdtable.c index 4c41805..e0e2ff9 100644 --- a/src/H5HFdtable.c +++ b/src/H5HFdtable.c @@ -231,7 +231,7 @@ H5HF_dtable_dest(H5HF_dtable_t *dtable) *------------------------------------------------------------------------- */ unsigned -H5HF_dtable_size_to_row(H5HF_dtable_t *dtable, size_t block_size) +H5HF_dtable_size_to_row(const H5HF_dtable_t *dtable, size_t block_size) { unsigned row; /* Row where block will fit */ @@ -265,7 +265,7 @@ H5HF_dtable_size_to_row(H5HF_dtable_t *dtable, size_t block_size) *------------------------------------------------------------------------- */ unsigned -H5HF_dtable_size_to_rows(H5HF_dtable_t *dtable, hsize_t size) +H5HF_dtable_size_to_rows(const H5HF_dtable_t *dtable, hsize_t size) { unsigned rows; /* # of rows required for indirect block */ @@ -281,3 +281,84 @@ H5HF_dtable_size_to_rows(H5HF_dtable_t *dtable, hsize_t size) FUNC_LEAVE_NOAPI(rows) } /* end H5HF_dtable_size_to_rows() */ + +/*------------------------------------------------------------------------- + * Function: H5HF_dtable_span_size + * + * Purpose: Compute the size covered by a span of entries + * + * Return: Non-zero span size on success/zero on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * July 25 2006 + * + *------------------------------------------------------------------------- + */ +hsize_t +H5HF_dtable_span_size(const H5HF_dtable_t *dtable, unsigned start_row, + unsigned start_col, unsigned num_entries) +{ + unsigned start_entry; /* Entry for first block covered */ + unsigned end_row; /* Row for last block covered */ + unsigned end_col; /* Column for last block covered */ + unsigned end_entry; /* Entry for last block covered */ + hsize_t acc_span_size; /* Accumulated span size */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_dtable_span_size) + + /* + * Check arguments. + */ + HDassert(dtable); + HDassert(num_entries > 0); + + /* Compute starting entry */ + start_entry = (start_row * dtable->cparam.width) + start_col; + + /* Compute ending entry, column & row */ + end_entry = (start_entry + num_entries) - 1; + end_row = end_entry / dtable->cparam.width; + end_col = end_entry % dtable->cparam.width; +#ifdef QAK +HDfprintf(stderr, "%s: start_row = %u, start_col = %u, start_entry = %u\n", "H5HF_sect_indirect_span_size", start_row, start_col, start_entry); +HDfprintf(stderr, "%s: end_row = %u, end_col = %u, end_entry = %u\n", "H5HF_sect_indirect_span_size", end_row, end_col, end_entry); +#endif /* QAK */ + + /* Initialize accumulated span size */ + acc_span_size = 0; + + /* Compute span size covered */ + + /* Check for multi-row span */ + if(start_row != end_row) { + /* Accomodate partial starting row */ + if(start_col > 0) { + acc_span_size = dtable->row_block_size[start_row] * + (dtable->cparam.width - start_col); + start_row++; + } /* end if */ + + /* Accumulate full rows */ + while(start_row < end_row) { + acc_span_size += dtable->row_block_size[start_row] * + dtable->cparam.width; + start_row++; + } /* end while */ + + /* Accomodate partial ending row */ + acc_span_size += dtable->row_block_size[start_row] * + (end_col + 1); + } /* end if */ + else { + /* Span is in same row */ + acc_span_size = dtable->row_block_size[start_row] * + ((end_col - start_col) + 1); + } /* end else */ + +#ifdef QAK +HDfprintf(stderr, "%s: acc_span_size = %Hu\n", "H5HF_dtable_span_size", acc_span_size); +#endif /* QAK */ + FUNC_LEAVE_NOAPI(acc_span_size) +} /* end H5HF_sect_indirect_span_size() */ + diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index fc67aed..69efdbc 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -270,6 +270,7 @@ done: herr_t H5HF_hdr_init(H5HF_hdr_t *hdr, haddr_t fh_addr, H5HF_create_t *cparam) { + size_t dblock_overhead; /* Direct block's overhead */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_init) @@ -325,6 +326,12 @@ H5HF_hdr_init(H5HF_hdr_t *hdr, haddr_t fh_addr, H5HF_create_t *cparam) if(H5HF_hdr_finish_init(hdr) < 0) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared fractal heap header") + /* Extra checking for possible gap between max. direct block size minus + * overhead and standalone object size */ + dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); + if((cparam->managed.max_direct_size - dblock_overhead) < cparam->standalone_size) + HGOTO_ERROR(H5E_HEAP, H5E_BADVALUE, FAIL, "max. direct block size not large enough to hold all managed blocks") + done: if(ret_value < 0) if(hdr) @@ -516,6 +523,12 @@ H5HF_hdr_adjust_heap(H5HF_hdr_t *hdr, hsize_t new_size, hssize_t extra_free) * Check arguments. */ HDassert(hdr); +#ifdef QAK +HDfprintf(stderr, "%s; new_size = %Hu, extra_free = %Hd\n", FUNC, new_size, extra_free); +HDfprintf(stderr, "%s; hdr->total_size = %Hu\n", FUNC, hdr->total_size); +HDfprintf(stderr, "%s; hdr->man_size = %Hu\n", FUNC, hdr->man_size); +HDfprintf(stderr, "%s; hdr->total_man_free = %Hu\n", FUNC, hdr->total_man_free); +#endif /* QAK */ /* Set the total space in heap */ hdr->total_size = new_size; @@ -635,6 +648,9 @@ H5HF_hdr_reset_iter(H5HF_hdr_t *hdr, hsize_t curr_off) HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator") /* Set the offset of the iterator in the heap */ +#ifdef QAK +HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu, curr_off = %Hu\n", FUNC, hdr->man_iter_off, curr_off); +#endif /* QAK */ hdr->man_iter_off = curr_off; done: @@ -659,7 +675,8 @@ herr_t H5HF_hdr_skip_blocks(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries) { - hsize_t sect_off; /* Offset of section in heap space */ + unsigned row, col; /* Row & column of entry */ + hsize_t sect_size; /* Size of section in heap space */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_skip_blocks) @@ -674,16 +691,25 @@ HDfprintf(stderr, "%s: start_entry = %u, nentries = %u\n", FUNC, start_entry, ne HDassert(iblock); HDassert(nentries); - /* Add 'indirect' section for blocks skipped in this row */ - if(H5HF_sect_indirect_add(hdr, dxpl_id, iblock, start_entry, nentries, §_off) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section for indirect block's free space") + /* Compute the span within the heap to skip */ + row = start_entry / hdr->man_dtable.cparam.width; + col = start_entry % hdr->man_dtable.cparam.width; + sect_size = H5HF_dtable_span_size(&hdr->man_dtable, row, col, nentries); #ifdef QAK -HDfprintf(stderr, "%s: sect_off = %Hu\n", FUNC, sect_off); +HDfprintf(stderr, "%s: Check 1.0 - hdr->man_iter_off = %Hu, sect_size = %Hu\n", FUNC, hdr->man_iter_off, sect_size); #endif /* QAK */ + HDassert(sect_size > 0); /* Advance the new block iterator */ - if(H5HF_hdr_inc_iter(hdr, (sect_off - hdr->man_iter_off), nentries) < 0) + if(H5HF_hdr_inc_iter(hdr, sect_size, nentries) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't increase allocated heap size") +#ifdef QAK +HDfprintf(stderr, "%s: Check 2.0 - hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off); +#endif /* QAK */ + + /* Add 'indirect' section for blocks skipped in this row */ + if(H5HF_sect_indirect_add(hdr, dxpl_id, iblock, start_entry, nentries) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section for indirect block's free space") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1092,9 +1118,12 @@ HDfprintf(stderr, "%s: curr_entry = %u\n", FUNC, curr_entry); #ifdef QAK HDfprintf(stderr, "%s: Heap empty\n", FUNC); #endif /* QAK */ - /* Reset header information back to "empty heap" state */ - if(H5HF_hdr_empty(hdr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty") + /* Reset iterator offset */ + hdr->man_iter_off = 0; + + /* Reset 'next block' iterator */ + if(H5HF_man_iter_reset(&hdr->next_block) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator") } /* end else */ } /* end if */ else { @@ -1194,12 +1223,21 @@ H5HF_hdr_empty(H5HF_hdr_t *hdr) FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_empty) #ifdef QAK -HDfprintf(stderr, "%s: Reseting heap header to empty\n", FUNC); +HDfprintf(stderr, "%s: Resetting heap header to empty\n", FUNC); #endif /* QAK */ /* Sanity check */ HDassert(hdr); + /* Reset block iterator, if necessary */ + if(H5HF_man_iter_ready(&hdr->next_block)) { +#ifdef QAK +HDfprintf(stderr, "%s: 'next block' iterator is ready\n", FUNC); +#endif /* QAK */ + if(H5HF_man_iter_reset(&hdr->next_block) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't reset block iterator") + } /* end if */ + /* Shrink heap size */ hdr->total_size = hdr->std_size; hdr->man_size = 0; diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index f48b4c2..3970a7e 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -181,6 +181,10 @@ HDfprintf(stderr, "%s: Removing indirect block from cache, iblock->addr = %a\n", /* Reset root pointer information */ iblock->hdr->man_dtable.curr_root_rows = 0; iblock->hdr->man_dtable.table_addr = HADDR_UNDEF; + + /* Reset header information back to "empty heap" state */ + if(H5HF_hdr_empty(iblock->hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't make heap empty") } /* end if */ /* Detach from parent indirect block */ diff --git a/src/H5HFint.c b/src/H5HFint.c index e9fe631..8964c29 100644 --- a/src/H5HFint.c +++ b/src/H5HFint.c @@ -281,7 +281,7 @@ H5HF_man_insert(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sec_node, size_t obj_size, const void *obj, void *id) { H5HF_direct_t *dblock = NULL; /* Pointer to direct block to modify */ - haddr_t dblock_addr; /* Direct block address */ + haddr_t dblock_addr = HADDR_UNDEF; /* Direct block address */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_man_insert) @@ -386,6 +386,9 @@ HDfprintf(stderr, "%s: blk_off = %Zu\n", FUNC, blk_off); HDfprintf(stderr, "%s: dblock->block_off = %Hu\n", FUNC, dblock->block_off); #endif /* QAK */ H5HF_ID_ENCODE(id, hdr, (dblock->block_off + blk_off), obj_size); +#ifdef QAK +HDfprintf(stderr, "%s: obj_off = %Hu, obj_len = %Zu\n", FUNC, (dblock->block_off + blk_off), obj_size); +#endif /* QAK */ } /* end if */ else { HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "inserting within mapped managed blocks not supported yet") diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h index aa7c3bf..725e5bb 100644 --- a/src/H5HFpkg.h +++ b/src/H5HFpkg.h @@ -416,8 +416,10 @@ H5_DLL herr_t H5HF_dtable_init(H5HF_dtable_t *dtable); H5_DLL herr_t H5HF_dtable_dest(H5HF_dtable_t *dtable); H5_DLL herr_t H5HF_dtable_lookup(const H5HF_dtable_t *dtable, hsize_t off, unsigned *row, unsigned *col); -H5_DLL unsigned H5HF_dtable_size_to_row(H5HF_dtable_t *dtable, size_t block_size); -H5_DLL unsigned H5HF_dtable_size_to_rows(H5HF_dtable_t *dtable, hsize_t size); +H5_DLL unsigned H5HF_dtable_size_to_row(const H5HF_dtable_t *dtable, size_t block_size); +H5_DLL unsigned H5HF_dtable_size_to_rows(const H5HF_dtable_t *dtable, hsize_t size); +H5_DLL hsize_t H5HF_dtable_span_size(const H5HF_dtable_t *dtable, unsigned start_row, + unsigned start_col, unsigned num_entries); /* Heap header routines */ H5_DLL herr_t H5HF_hdr_incr(H5HF_hdr_t *hdr); @@ -545,8 +547,7 @@ H5_DLL herr_t H5HF_sect_row_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect, unsigned *entry_p); H5_DLL H5HF_indirect_t *H5HF_sect_row_get_iblock(H5HF_free_section_t *sect); H5_DLL herr_t H5HF_sect_indirect_add(H5HF_hdr_t *hdr, hid_t dxpl_id, - H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries, - hsize_t *sect_off); + H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries); /* Testing routines */ #ifdef H5HF_TESTING diff --git a/src/H5HFsection.c b/src/H5HFsection.c index 8888d06..fbc514b 100644 --- a/src/H5HFsection.c +++ b/src/H5HFsection.c @@ -39,15 +39,23 @@ /* Local Macros */ /****************/ +/* Size of serialized indirect section information */ +#define H5HF_SECT_INDIRECT_SERIAL_SIZE(h) ( \ + (h)->heap_off_size /* Indirect block's offset in "heap space" */ \ + + 2 /* Row */ \ + + 2 /* Column */ \ + + 2 /* # of entries */ \ + ) + /******************/ /* Local Typedefs */ /******************/ -/* Typedef for "class private" information for indirect sections */ +/* Typedef for "class private" information for sections */ typedef struct { H5HF_hdr_t *hdr; /* Pointer to fractal heap header */ -} H5HF_sect_indirect_private_t; +} H5HF_sect_private_t; /********************/ @@ -60,12 +68,21 @@ typedef struct { /********************/ /* Shared routines */ +static herr_t H5HF_sect_init_cls(H5FS_section_class_t *cls, + H5HF_hdr_t *hdr); +static herr_t H5HF_sect_term_cls(H5FS_section_class_t *cls); static H5HF_free_section_t *H5HF_sect_node_new(unsigned sect_type, haddr_t sect_addr, hsize_t sect_size, H5FS_section_state_t state); static herr_t H5HF_sect_node_free(H5HF_free_section_t *sect, H5HF_indirect_t *parent); +/* 'single' section routines */ +static herr_t H5HF_sect_single_full_dblock(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t *sect); + /* 'single' section callbacks */ +static herr_t H5HF_sect_single_add(H5FS_section_info_t *sect, unsigned *flags, + void *udata); static H5FS_section_info_t *H5HF_sect_single_deserialize(const H5FS_section_class_t *cls, hid_t dxpl_id, const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, unsigned *des_flags); @@ -109,6 +126,8 @@ static herr_t H5HF_sect_row_shrink(H5FS_section_info_t **sect, static herr_t H5HF_sect_row_free(H5FS_section_info_t *sect); static herr_t H5HF_sect_row_valid(const H5FS_section_class_t *cls, const H5FS_section_info_t *sect); +static herr_t H5HF_sect_row_debug(const H5FS_section_info_t *sect, + FILE *stream, int indent, int fwidth); /* 'indirect' section routines */ static H5HF_free_section_t *H5HF_sect_indirect_new(H5HF_hdr_t *hdr, @@ -116,8 +135,9 @@ static H5HF_free_section_t *H5HF_sect_indirect_new(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock, hsize_t iblock_off, unsigned row, unsigned col, unsigned nentries); static herr_t H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, - H5HF_free_section_t *sect, hbool_t first_child, unsigned space_flags, - unsigned start_row, unsigned start_col, unsigned end_row, unsigned end_col); + H5HF_free_section_t *sect, hbool_t first_child, H5HF_free_section_t **first_row_sect, + unsigned space_flags, unsigned start_row, unsigned start_col, + unsigned end_row, unsigned end_col); static H5HF_free_section_t *H5HF_sect_indirect_for_row(H5HF_hdr_t *hdr, H5HF_indirect_t *iblock, H5HF_free_section_t *row_sect); static herr_t H5HF_sect_indirect_decr(H5HF_free_section_t *sect); @@ -132,8 +152,6 @@ static herr_t H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, static herr_t H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect); static hbool_t H5HF_sect_indirect_is_first(H5HF_free_section_t *sect); static H5HF_indirect_t * H5HF_sect_indirect_get_iblock(H5HF_free_section_t *sect); -static herr_t H5HF_sect_indirect_span_size(H5HF_hdr_t *hdr, - H5HF_free_section_t *sect); static hsize_t H5HF_sect_indirect_iblock_off(const H5HF_free_section_t *sect); static H5HF_free_section_t * H5HF_sect_indirect_top(H5HF_free_section_t *sect); static herr_t H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id, @@ -147,14 +165,14 @@ static H5FS_section_info_t *H5HF_sect_indirect_deserialize(H5HF_hdr_t *hdr, hid_t dxpl_id, const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size, unsigned *des_flags); static herr_t H5HF_sect_indirect_free(H5HF_free_section_t *sect); -static herr_t H5HF_sect_indirect_valid(const H5FS_section_class_t *row_cls, - const H5HF_free_section_t *row_sect); +static herr_t H5HF_sect_indirect_valid(const H5HF_hdr_t *hdr, + const H5HF_free_section_t *sect); +static herr_t H5HF_sect_indirect_debug(const H5HF_free_section_t *sect, + FILE *stream, int indent, int fwidth); /* 'indirect' section callbacks */ static herr_t H5HF_sect_indirect_init_cls(H5FS_section_class_t *cls, void *udata); static herr_t H5HF_sect_indirect_term_cls(H5FS_section_class_t *cls); -static herr_t H5HF_sect_indirect_debug(const H5FS_section_info_t *sect, - FILE *stream, int indent, int fwidth); /*********************/ @@ -174,6 +192,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_SINGLE[1] = {{ NULL, /* Terminate section class */ /* Object methods */ + H5HF_sect_single_add, /* Add section */ NULL, /* Serialize section */ H5HF_sect_single_deserialize, /* Deserialize section */ H5HF_sect_single_can_merge, /* Can sections merge? */ @@ -201,6 +220,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_FIRST_ROW[1] = {{ H5HF_sect_row_term_cls, /* Terminate section class */ /* Object methods */ + NULL, /* Add section */ H5HF_sect_row_serialize, /* Serialize section */ H5HF_sect_row_deserialize, /* Deserialize section */ H5HF_sect_row_can_merge, /* Can sections merge? */ @@ -209,7 +229,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_FIRST_ROW[1] = {{ H5HF_sect_row_shrink, /* Shrink container w/section */ H5HF_sect_row_free, /* Free section */ H5HF_sect_row_valid, /* Check validity of section */ - NULL, /* Dump debugging for section */ + H5HF_sect_row_debug, /* Dump debugging for section */ }}; /* Class info for "normal row" free space sections */ @@ -221,10 +241,11 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1] = {{ NULL, /* Class private info */ /* Class methods */ - NULL, /* Initialize section class */ - NULL, /* Terminate section class */ + H5HF_sect_row_init_cls, /* Initialize section class */ + H5HF_sect_row_term_cls, /* Terminate section class */ /* Object methods */ + NULL, /* Add section */ NULL, /* Serialize section */ NULL, /* Deserialize section */ NULL, /* Can sections merge? */ @@ -233,7 +254,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1] = {{ NULL, /* Shrink container w/section */ H5HF_sect_row_free, /* Free section */ H5HF_sect_row_valid, /* Check validity of section */ - NULL, /* Dump debugging for section */ + H5HF_sect_row_debug, /* Dump debugging for section */ }}; /* Class info for "indirect" free space sections */ @@ -252,6 +273,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1] = {{ H5HF_sect_indirect_term_cls, /* Terminate section class */ /* Object methods */ + NULL, /* Add section */ NULL, /* Serialize section */ NULL, /* Deserialize section */ NULL, /* Can sections merge? */ @@ -260,7 +282,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1] = {{ NULL, /* Shrink container w/section */ NULL, /* Free section */ NULL, /* Check validity of section */ - H5HF_sect_indirect_debug, /* Dump debugging for section */ + NULL, /* Dump debugging for section */ }}; /* Declare a free list to manage the H5HF_free_section_t struct */ @@ -279,6 +301,72 @@ H5FL_DEFINE(H5HF_free_section_t); /*------------------------------------------------------------------------- + * Function: H5HF_sect_init_cls + * + * Purpose: Initialize the common class structure + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, July 25, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_init_cls(H5FS_section_class_t *cls, H5HF_hdr_t *hdr) +{ + H5HF_sect_private_t *cls_prvt; /* Pointer to class private info */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_init_cls) + + /* Check arguments. */ + HDassert(cls); + HDassert(!cls->cls_private); + + /* Allocate & initialize the class-private (i.e. private shared) information + * for this type of section + */ + if(NULL == (cls_prvt = H5MM_malloc(sizeof(H5HF_sect_private_t)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + cls_prvt->hdr = hdr; + cls->cls_private = cls_prvt; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_init_cls() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_term_cls + * + * Purpose: Terminate the common class structure + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, July 25, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_term_cls(H5FS_section_class_t *cls) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_term_cls) + + /* Check arguments. */ + HDassert(cls); + + /* Free the class private information */ + cls->cls_private = H5MM_xfree(cls->cls_private); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5HF_sect_term_cls() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_sect_node_new * * Purpose: Allocate a free space section node of a particular type @@ -365,7 +453,7 @@ done: * * Purpose: Create a new 'single' section and return it to the caller * - * Return: Non-negative on success/Negative on failure + * Return: Pointer to new section on success/NULL on failure * * Programmer: Quincey Koziol * koziol@ncsa.uiuc.edu @@ -549,12 +637,146 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_sect_single_full_dblock + * + * Purpose: Checks if a single section covers the entire direct block + * that it resides in, and converts it to a row section if so + * + * Note: Does not convert a single section to a row section if the + * single section is for a root direct block + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Thursday, July 27, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_single_full_dblock(H5HF_hdr_t *hdr, hid_t dxpl_id, + H5HF_free_section_t *sect) +{ + size_t dblock_size; /* Section's direct block's size */ + size_t dblock_overhead; /* Direct block's overhead */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_full_dblock) + + /* Check arguments. */ + HDassert(sect); + HDassert(sect->sect_info.state == H5FS_SECT_LIVE); + HDassert(hdr); + +#ifdef QAK +HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); +#endif /* QAK */ + + /* Check for section occupying entire direct block */ + /* (and not the root direct block) */ + dblock_size = sect->u.single.dblock_size; + dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); +#ifdef QAK +HDfprintf(stderr, "%s: dblock_size = %u\n", FUNC, dblock_size); +HDfprintf(stderr, "%s: dblock_overhead = %Zu\n", FUNC, dblock_overhead); +HDfprintf(stderr, "%s: hdr->man_dtable.curr_root_rows = %u\n", FUNC, hdr->man_dtable.curr_root_rows); +#endif /* QAK */ + if((dblock_size - dblock_overhead) == sect->sect_info.size && + hdr->man_dtable.curr_root_rows > 0) { + H5HF_direct_t *dblock; /* Pointer to direct block for section */ + haddr_t dblock_addr; /* Section's direct block's address */ + + /* Protect the direct block for the section */ + dblock_addr = sect->u.single.dblock_addr; +#ifdef QAK +HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); +#endif /* QAK */ + if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, sect->u.single.parent, sect->u.single.par_entry, H5AC_READ))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block") + HDassert(H5F_addr_eq(dblock->block_off + dblock_overhead, sect->sect_info.addr)); + + /* Convert 'single' section into 'row' section */ + if(H5HF_sect_row_from_single(hdr, sect, dblock) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCONVERT, FAIL, "can't convert single section into row section") + +#ifdef QAK +HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); +HDfprintf(stderr, "%s: sect->u.row = {%p, %u, %u, %u, %t}\n", FUNC, sect->u.row.under, sect->u.row.row, sect->u.row.col, sect->u.row.num_entries, sect->u.row.checked_out); +#endif /* QAK */ + + /* Destroy direct block */ + if(H5HF_man_dblock_destroy(hdr, dxpl_id, dblock, dblock_addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release direct block") + dblock = NULL; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_single_full_dblock() */ + + +/*------------------------------------------------------------------------- + * Function: H5HF_sect_single_add + * + * Purpose: Perform any actions on section as it is added to free space + * manager + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Thursday, July 27, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5HF_sect_single_add(H5FS_section_info_t *_sect, unsigned *flags, void *_udata) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_add) + + /* Don't need to check section if we are deserializing, because it should + * have already been checked when it was first added + */ + if(!(*flags & H5FS_ADD_DESERIALIZING)) { + H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Fractal heap free section */ + H5HF_add_ud1_t *udata = (H5HF_add_ud1_t *)_udata; /* User callback data */ + H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */ + hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */ + + /* Sanity check */ + HDassert(sect); + HDassert(hdr); + +#ifdef QAK +HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_single_add", sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); +#endif /* QAK */ + + /* Check if single section covers entire direct block it's in */ + /* (converts to row section possibly) */ + if(H5HF_sect_single_full_dblock(hdr, dxpl_id, sect) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCONVERT, FAIL, "can't check/convert single section") + + /* Set the "returned space" flag if the single section was changed + * into a row section, so the "merging & shrinking" algorithm + * gets executed in the free space manager + */ + if(sect->sect_info.type != H5HF_FSPACE_SECT_SINGLE) + *flags |= H5FS_ADD_RETURNED_SPACE; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5HF_sect_single_add() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_sect_single_deserialize * * Purpose: Deserialize a buffer into a "live" single section * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol @@ -663,8 +885,6 @@ H5HF_sect_single_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2, H5HF_free_section_t *sect2 = (H5HF_free_section_t *)_sect2; /* Fractal heap free section */ H5HF_add_ud1_t *udata = (H5HF_add_ud1_t *)_udata; /* User callback data */ H5HF_hdr_t *hdr = udata->hdr; /* Fractal heap header */ - size_t dblock_size; /* Section's direct block's size */ - size_t dblock_overhead; /* Direct block's overhead */ hid_t dxpl_id = udata->dxpl_id; /* DXPL ID for operation */ herr_t ret_value = SUCCEED; /* Return value */ @@ -694,43 +914,10 @@ HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect2->sec if(H5HF_sect_single_revive(hdr, dxpl_id, sect1) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section") - /* Check for section occupying entire direct block */ - /* (and not the root direct block) */ - dblock_size = sect1->u.single.dblock_size; - dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); -#ifdef QAK -HDfprintf(stderr, "%s: dblock_size = %u\n", FUNC, dblock_size); -HDfprintf(stderr, "%s: dblock_overhead = %Zu\n", FUNC, dblock_overhead); -HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", FUNC, hdr->man_iter_off); -#endif /* QAK */ - if((dblock_size - dblock_overhead) == sect1->sect_info.size && - hdr->man_dtable.curr_root_rows > 0) { - H5HF_direct_t *dblock; /* Pointer to direct block for section */ - haddr_t dblock_addr; /* Section's direct block's address */ - - /* Protect the direct block for the section */ - dblock_addr = sect1->u.single.dblock_addr; -#ifdef QAK -HDfprintf(stderr, "%s: dblock_addr = %a\n", FUNC, dblock_addr); -#endif /* QAK */ - if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, sect1->u.single.parent, sect1->u.single.par_entry, H5AC_READ))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block") - HDassert(H5F_addr_eq(dblock->block_off + dblock_overhead, sect1->sect_info.addr)); - - /* Convert 'single' section into 'row' section */ - if(H5HF_sect_row_from_single(hdr, sect1, dblock) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTCONVERT, FAIL, "can't convert single section into row section") - -#ifdef QAK -HDfprintf(stderr, "%s: sect1->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect1->sect_info.addr, sect1->sect_info.size, sect1->sect_info.type, (sect1->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); -HDfprintf(stderr, "%s: sect1->u.row = {%p, %u, %u, %u, %t}\n", FUNC, sect1->u.row.under, sect1->u.row.row, sect1->u.row.col, sect1->u.row.num_entries, sect1->u.row.checked_out); -#endif /* QAK */ - - /* Destroy direct block */ - if(H5HF_man_dblock_destroy(hdr, dxpl_id, dblock, dblock_addr) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release direct block") - dblock = NULL; - } /* end if */ + /* Check if single section covers entire direct block it's in */ + /* (converts to row section possibly) */ + if(H5HF_sect_single_full_dblock(hdr, dxpl_id, sect1) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTCONVERT, FAIL, "can't check/convert single section") done: FUNC_LEAVE_NOAPI(ret_value) @@ -770,6 +957,7 @@ H5HF_sect_single_can_shrink(const H5FS_section_info_t *_sect, void *_udata) #ifdef QAK HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_single_can_shrink", sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); +HDfprintf(stderr, "%s: hdr->man_dtable.curr_root_rows = %u\n", "H5HF_sect_single_can_shrink", hdr->man_dtable.curr_root_rows); #endif /* QAK */ /* Check for section occupying entire root direct block */ @@ -946,6 +1134,7 @@ HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_single /* (not enough information to check on a single section in a root direct block) */ if(sect->u.single.parent != NULL) { H5HF_indirect_t *iblock; /* Indirect block that section's direct block resides in */ + size_t dblock_overhead; /* Direct block's overhead */ unsigned dblock_status = 0; /* Direct block's status in the metadata cache */ herr_t status; /* Generic status value */ @@ -958,6 +1147,13 @@ HDfprintf(stderr, "%s: sect->u.single = {%p, %u, %a, %Zu}\n", "H5HF_sect_single_ HDassert(H5F_addr_eq(iblock->ents[sect->u.single.par_entry].addr, sect->u.single.dblock_addr)); + /* Check if the section is actually within the heap */ + HDassert(sect->sect_info.addr < iblock->hdr->man_iter_off); + + /* Check that the direct block has been merged correctly */ + dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(iblock->hdr); + HDassert((sect->sect_info.size + dblock_overhead) < sect->u.single.dblock_size); + /* Check the direct block's status in the metadata cache */ status = H5AC_get_entry_status(iblock->hdr->f, sect->u.single.dblock_addr, &dblock_status); HDassert(status >= 0); @@ -1313,17 +1509,24 @@ H5HF_sect_row_get_iblock(H5HF_free_section_t *sect) static herr_t H5HF_sect_row_init_cls(H5FS_section_class_t *cls, void *_udata) { + H5HF_hdr_t *hdr = (H5HF_hdr_t *)_udata; /* Fractal heap header */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_row_init_cls) /* Check arguments. */ HDassert(cls); - HDassert(!cls->cls_private); + HDassert(hdr); - /* Forward call to indirect class initialization */ - if(H5HF_sect_indirect_init_cls(cls, _udata) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize row section class") + /* Call common class initialization */ + if(H5HF_sect_init_cls(cls, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize common section class") + + /* First row sections actually are proxies for indirection sections on disk */ + if(cls->type == H5HF_FSPACE_SECT_FIRST_ROW) + cls->serial_size = H5HF_SECT_INDIRECT_SERIAL_SIZE(hdr); + else + cls->serial_size = 0; done: FUNC_LEAVE_NOAPI(ret_value) @@ -1357,9 +1560,9 @@ H5HF_sect_row_term_cls(H5FS_section_class_t *cls) /* Check arguments. */ HDassert(cls); - /* Forward call to indirect class termination */ - if(H5HF_sect_indirect_term_cls(cls) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't terminate row section class") + /* Call common class termination */ + if(H5HF_sect_term_cls(cls) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't terminate common section class") done: FUNC_LEAVE_NOAPI(ret_value) @@ -1398,7 +1601,7 @@ H5HF_sect_row_serialize(const H5FS_section_class_t *cls, HDassert(sect->sect_info.addr == sect->u.row.under->sect_info.addr); /* Forward to indirect routine to serialize underlying section */ - hdr = ((H5HF_sect_indirect_private_t *)(cls->cls_private))->hdr; + hdr = ((H5HF_sect_private_t *)(cls->cls_private))->hdr; if(H5HF_sect_indirect_serialize(hdr, sect->u.row.under, buf) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSERIALIZE, FAIL, "can't serialize row section's underlying indirect section") @@ -1441,7 +1644,7 @@ H5HF_sect_row_deserialize(const H5FS_section_class_t *cls, hid_t dxpl_id, HDassert(sect_size); /* Forward to indirect routine to deserialize underlying section */ - hdr = ((H5HF_sect_indirect_private_t *)(cls->cls_private))->hdr; + hdr = ((H5HF_sect_private_t *)(cls->cls_private))->hdr; if(NULL == (ret_value = H5HF_sect_indirect_deserialize(hdr, dxpl_id, buf, sect_addr, sect_size, des_flags))) HGOTO_ERROR(H5E_HEAP, H5E_CANTDECODE, NULL, "can't deserialize row section's underlying indirect section") @@ -1566,23 +1769,39 @@ HDfprintf(stderr, "%s: sect1->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect1->sec HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect2->sect_info.addr, sect2->sect_info.size, sect2->sect_info.type, (sect2->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); #endif /* QAK */ - /* Check to see if we should revive first section */ - if(sect1->sect_info.state != H5FS_SECT_LIVE) - if(H5HF_sect_row_revive(hdr, dxpl_id, sect1) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section") + /* Check if second section is past end of "next block" iterator */ +#ifdef QAK +HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", "H5HF_sect_row_can_shrink", hdr->man_iter_off); +#endif /* QAK */ + if(sect2->sect_info.addr >= hdr->man_iter_off) { + H5HF_free_section_t *top_indir_sect; /* Top indirect section for row */ - /* Check to see if we should revive second section */ - if(sect2->sect_info.state != H5FS_SECT_LIVE) - if(H5HF_sect_row_revive(hdr, dxpl_id, sect2) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section") + /* Get the top indirect section underlying second row section */ + top_indir_sect = H5HF_sect_indirect_top(sect2->u.row.under); + + /* Shrink away underlying indirect section */ + if(H5HF_sect_indirect_shrink(hdr, dxpl_id, top_indir_sect) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't shrink underlying indirect section") + } /* end if */ + else { + /* Check to see if we should revive first section */ + if(sect1->sect_info.state != H5FS_SECT_LIVE) + if(H5HF_sect_row_revive(hdr, dxpl_id, sect1) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section") + + /* Check to see if we should revive second section */ + if(sect2->sect_info.state != H5FS_SECT_LIVE) + if(H5HF_sect_row_revive(hdr, dxpl_id, sect2) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section") #ifdef QAK HDfprintf(stderr, "%s: sect1->u.row = {%p, %u, %u, %u, %t}\n", FUNC, sect1->u.row.under, sect1->u.row.row, sect1->u.row.col, sect1->u.row.num_entries, sect1->u.row.checked_out); HDfprintf(stderr, "%s: sect2->u.row = {%p, %u, %u, %u, %t}\n", FUNC, sect2->u.row.under, sect2->u.row.row, sect2->u.row.col, sect2->u.row.num_entries, sect2->u.row.checked_out); #endif /* QAK */ - /* Merge rows' underlying indirect sections together */ - if(H5HF_sect_indirect_merge_row(hdr, dxpl_id, sect1, sect2) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTMERGE, FAIL, "can't merge underlying indirect sections") + /* Merge rows' underlying indirect sections together */ + if(H5HF_sect_indirect_merge_row(hdr, dxpl_id, sect1, sect2) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTMERGE, FAIL, "can't merge underlying indirect sections") + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -1677,7 +1896,7 @@ HDfprintf(stderr, "%s: (*sect)->u.row = {%p, %u, %u, %u}\n", FUNC, (*sect)->u.ro /* Get the top indirect section underlying each row */ top_indir_sect = H5HF_sect_indirect_top((*sect)->u.row.under); - /* Shrink size of underlying indirect section */ + /* Shrink away underlying indirect section */ if(H5HF_sect_indirect_shrink(hdr, dxpl_id, top_indir_sect) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't shrink underlying indirect section") @@ -1775,15 +1994,22 @@ done: static herr_t H5HF_sect_row_valid(const H5FS_section_class_t *cls, const H5FS_section_info_t *_sect) { + H5HF_sect_private_t *cls_prvt; /* Pointer to class private info */ + const H5HF_hdr_t *hdr; /* Fractal heap header */ const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Pointer to section to check */ const H5HF_free_section_t *indir_sect; /* Pointer to underlying indirect section */ unsigned indir_idx; /* Index of row in underlying indirect section's row array */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_row_valid) + /* Basic sanity check */ HDassert(cls); HDassert(sect); + /* Retrieve class private information */ + cls_prvt = cls->cls_private; + hdr = cls_prvt->hdr; + #ifdef QAK HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_row_valid", sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); HDfprintf(stderr, "%s: sect->u.row = {%p, %u, %u, %u, %t}\n", "H5HF_sect_row_valid", sect->u.row.under, sect->u.row.row, sect->u.row.col, sect->u.row.num_entries, sect->u.row.checked_out); @@ -1799,13 +2025,21 @@ HDfprintf(stderr, "%s: indir_idx = %u\n", "H5HF_sect_row_valid", indir_idx); #endif /* QAK */ HDassert(indir_sect->u.indirect.dir_rows[indir_idx] == sect); + /* Check if the section is actually within the heap */ + HDassert(sect->sect_info.addr < hdr->man_iter_off); + /* Different checking for different kinds of rows */ if(sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW) { + H5HF_free_section_t *top_indir_sect; /* Top indirect section for row */ + /* Some extra sanity checks on the row */ HDassert(sect->u.row.row == indir_sect->u.indirect.row); + /* Get the top indirect section underlying row */ + top_indir_sect = H5HF_sect_indirect_top(sect->u.row.under); + /* Check that the row's underlying indirect section is valid */ - H5HF_sect_indirect_valid(cls, sect); + H5HF_sect_indirect_valid(hdr, top_indir_sect); } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -1813,91 +2047,51 @@ HDfprintf(stderr, "%s: indir_idx = %u\n", "H5HF_sect_row_valid", indir_idx); /*------------------------------------------------------------------------- - * Function: H5HF_sect_indirect_span_size + * Function: H5HF_sect_row_debug * - * Purpose: Compute the span size covered by an indirect section + * Purpose: Dump debugging information about an row free space section * - * Return: Non-negative on success/Negative on failure + * Return: Success: non-negative + * Failure: negative * * Programmer: Quincey Koziol - * koziol@ncsa.uiuc.edu - * July 3 2006 + * Tuesday, July 25, 2006 * *------------------------------------------------------------------------- */ static herr_t -H5HF_sect_indirect_span_size(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) +H5HF_sect_row_debug(const H5FS_section_info_t *_sect, + FILE *stream, int indent, int fwidth) { - unsigned start_row; /* Row for first block covered */ - unsigned start_col; /* Column for first block covered */ - unsigned start_entry; /* Entry for first block covered */ - unsigned end_row; /* Row for last block covered */ - unsigned end_col; /* Column for last block covered */ - unsigned end_entry; /* Entry for last block covered */ - hsize_t acc_span_size; /* Accumulated span size */ + const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_span_size) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_row_debug) - /* - * Check arguments. - */ - HDassert(hdr); + /* Check arguments. */ HDassert(sect); - HDassert(sect->u.indirect.num_entries > 0); - /* Compute starting entry, column & row */ - start_row = sect->u.indirect.row; - start_col = sect->u.indirect.col; - start_entry = (start_row * hdr->man_dtable.cparam.width) + start_col; - - /* Compute ending entry, column & row */ - end_entry = (start_entry + sect->u.indirect.num_entries) - 1; - end_row = end_entry / hdr->man_dtable.cparam.width; - end_col = end_entry % hdr->man_dtable.cparam.width; -#ifdef QAK -HDfprintf(stderr, "%s: start_row = %u, start_col = %u, start_entry = %u\n", "H5HF_sect_indirect_span_size", start_row, start_col, start_entry); -HDfprintf(stderr, "%s: end_row = %u, end_col = %u, end_entry = %u\n", "H5HF_sect_indirect_span_size", end_row, end_col, end_entry); -#endif /* QAK */ - - /* Initialize accumulated span size */ - acc_span_size = 0; - - /* Compute span size covered */ - - /* Check for multi-row span */ - if(start_row != end_row) { - /* Accomodate partial starting row */ - if(start_col > 0) { - acc_span_size = hdr->man_dtable.row_block_size[start_row] * - (hdr->man_dtable.cparam.width - start_col); - start_row++; - } /* end if */ + /* Print indirect section information */ + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Row:", + sect->u.row.row); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Column:", + sect->u.row.col); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Number of entries:", + sect->u.row.num_entries); - /* Accumulate full rows */ - while(start_row < end_row) { - acc_span_size += hdr->man_dtable.row_block_size[start_row] * - hdr->man_dtable.cparam.width; - start_row++; - } /* end while */ + /* If this is a first row section display information about underlying indirect section */ + if(sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW) { + /* Print indirect section header */ + HDfprintf(stream, "%*s%-*s\n", indent, "", fwidth, + "Underlying indirect section:"); - /* Accomodate partial ending row */ - acc_span_size += hdr->man_dtable.row_block_size[start_row] * - (end_col + 1); + H5HF_sect_indirect_debug(sect->u.row.under, stream, indent + 3, MAX(0, fwidth - 3)); } /* end if */ - else { - /* Span is in same row */ - acc_span_size = hdr->man_dtable.row_block_size[start_row] * - ((end_col - start_col) + 1); - } /* end else */ - - /* Set the span size for the indirect section */ -#ifdef QAK -HDfprintf(stderr, "%s: acc_span_size = %Hu\n", "H5HF_sect_indirect_span_size", acc_span_size); -#endif /* QAK */ - sect->u.indirect.span_size = acc_span_size; FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5HF_sect_indirect_span_size() */ +} /* H5HF_sect_row_debug() */ /*------------------------------------------------------------------------- @@ -1992,28 +2186,20 @@ static herr_t H5HF_sect_indirect_init_cls(H5FS_section_class_t *cls, void *_udata) { H5HF_hdr_t *hdr = (H5HF_hdr_t *)_udata; /* Fractal heap header */ - H5HF_sect_indirect_private_t *cls_prvt; /* Pointer to class private info */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_init_cls) /* Check arguments. */ HDassert(cls); - HDassert(!cls->cls_private); + HDassert(hdr); - /* Allocate & initialize the class-private (i.e. private shared) information - * for this type of section - */ - if(NULL == (cls_prvt = H5MM_malloc(sizeof(H5HF_sect_indirect_private_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - cls_prvt->hdr = hdr; - cls->cls_private = cls_prvt; + /* Call to common class initialization */ + if(H5HF_sect_init_cls(cls, hdr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize common section class") /* Set the size of all serialized objects of this class of sections */ - cls->serial_size = hdr->heap_off_size /* Indirect block's offset in "heap space" */ - + 2 /* Row */ - + 2 /* Column */ - + 2; /* # of entries */ + cls->serial_size = H5HF_SECT_INDIRECT_SERIAL_SIZE(hdr); done: FUNC_LEAVE_NOAPI(ret_value) @@ -2037,15 +2223,19 @@ done: static herr_t H5HF_sect_indirect_term_cls(H5FS_section_class_t *cls) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_term_cls) + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_term_cls) /* Check arguments. */ HDassert(cls); - /* Free the class private information */ - cls->cls_private = H5MM_xfree(cls->cls_private); + /* Call common class termination */ + if(H5HF_sect_term_cls(cls) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't terminate common section class") - FUNC_LEAVE_NOAPI(SUCCEED) +done: + FUNC_LEAVE_NOAPI(ret_value) } /* H5HF_sect_indirect_term_cls() */ @@ -2103,8 +2293,9 @@ H5HF_sect_indirect_new(H5HF_hdr_t *hdr, haddr_t sect_off, hsize_t sect_size, sect->u.indirect.num_entries = nentries; /* Compute span size of indirect section */ - if(H5HF_sect_indirect_span_size(hdr, sect) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, NULL, "can't compute span size of section") + sect->u.indirect.span_size = H5HF_dtable_span_size(&hdr->man_dtable, + row, col, nentries); + HDassert(sect->u.indirect.span_size > 0); /* This indirect section doesn't (currently) have a parent */ sect->u.indirect.parent = NULL; @@ -2213,8 +2404,8 @@ HDfprintf(stderr, "%s: Leaving\n", FUNC); */ static herr_t H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, - H5HF_free_section_t *sect, hbool_t first_child, unsigned space_flags, - unsigned start_row, unsigned start_col, + H5HF_free_section_t *sect, hbool_t first_child, H5HF_free_section_t **first_row_sect, + unsigned space_flags, unsigned start_row, unsigned start_col, unsigned end_row, unsigned end_col) { hsize_t curr_off; /* Offset of new section in "heap space" */ @@ -2224,6 +2415,7 @@ H5HF_sect_indirect_init_rows(H5HF_hdr_t *hdr, hid_t dxpl_id, unsigned curr_entry; /* Current entry within indirect section */ unsigned curr_indir_entry; /* Current indirect entry within indirect section */ unsigned curr_row; /* Current row within indirect section */ + unsigned dir_nrows; /* # of direct rows in indirect section */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -2252,14 +2444,21 @@ HDfprintf(stderr, "%s: end_row = %u, end_col = %u\n", FUNC, end_row, end_col); max_direct_row = MIN(end_row, (hdr->man_dtable.max_direct_rows - 1)); /* Compute # of direct rows covered */ - sect->u.indirect.dir_nrows = (max_direct_row - start_row) + 1; + dir_nrows = (max_direct_row - start_row) + 1; + + /* Don't set the of direct rows in section yet, so sanity + * checking works (enabled in free section manager, with H5FS_DEBUG + * macro) correctly. + */ + sect->u.indirect.dir_nrows = 0; /* Allocate space for the derived row sections */ - if(NULL == (sect->u.indirect.dir_rows = H5MM_malloc(sizeof(H5HF_free_section_t *) * sect->u.indirect.dir_nrows))) + if(NULL == (sect->u.indirect.dir_rows = H5MM_malloc(sizeof(H5HF_free_section_t *) * dir_nrows))) HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array") } /* end if */ else { /* No rows of direct blocks covered, reset direct row information */ + dir_nrows = 0; sect->u.indirect.dir_nrows = 0; sect->u.indirect.dir_rows = NULL; } /* end else */ @@ -2329,11 +2528,16 @@ HDfprintf(stderr, "%s: Creating direct row, row_col = %u, row_entries = %u\n", F /* Add new row section to array for indirect section */ sect->u.indirect.dir_rows[curr_row] = row_sect; - /* Add new row section to free space manager for the heap */ - if(H5HF_space_add(hdr, dxpl_id, row_sect, space_flags) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add row section to free space") + /* Check to see if we should grab the first row section instead of adding it immediately */ + if(first_row_sect) + *first_row_sect = row_sect; + else { + /* Add new row section to free space manager for the heap */ + if(H5HF_space_add(hdr, dxpl_id, row_sect, space_flags) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add row section to free space") + } /* end else */ - /* Add new row section to array for indirect section */ + /* Increment reference count for underlying indirect section */ sect->u.indirect.rc++; /* Advance the offset to the next section */ @@ -2342,8 +2546,9 @@ HDfprintf(stderr, "%s: Creating direct row, row_col = %u, row_entries = %u\n", F /* Advance the current entry to the next row*/ curr_entry += row_entries; - /* Reset the 'first child' flag */ + /* Reset the 'first child' parameters */ first_child = FALSE; + first_row_sect = NULL; } /* end if */ else { H5HF_indirect_t *child_iblock; /* Child indirect block */ @@ -2392,8 +2597,8 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr); /* Initialize rows for new indirect section */ if(H5HF_sect_indirect_init_rows(hdr, dxpl_id, child_sect, - first_child, space_flags, 0, 0, (child_nrows - 1), - (hdr->man_dtable.cparam.width - 1)) < 0) + first_child, first_row_sect, space_flags, 0, 0, + (child_nrows - 1), (hdr->man_dtable.cparam.width - 1)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize indirect section") /* If we have a valid child indirect block, release it now */ @@ -2414,8 +2619,9 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr); curr_entry++; curr_indir_entry++; - /* Reset the 'first child' flag */ + /* Reset the 'first child' parameters */ first_child = FALSE; + first_row_sect = NULL; } /* end for */ } /* end else */ @@ -2428,6 +2634,10 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr); /* Reset column for all other rows */ row_col = 0; } /* end for */ + + /* Set the final # of direct rows in section */ + sect->u.indirect.dir_nrows = dir_nrows; + /* Make certain we've tracked the section's dependents correctly */ HDassert(sect->u.indirect.rc == (sect->u.indirect.indir_nents + sect->u.indirect.dir_nrows)); @@ -2453,10 +2663,10 @@ done: */ herr_t H5HF_sect_indirect_add(H5HF_hdr_t *hdr, hid_t dxpl_id, - H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries, - hsize_t *end_off /*out*/) + H5HF_indirect_t *iblock, unsigned start_entry, unsigned nentries) { - H5HF_free_section_t *sect = NULL; /* 'Indirect3' free space section to add */ + H5HF_free_section_t *sect = NULL; /* 'Indirect' free space section to add */ + H5HF_free_section_t *first_row_sect = NULL; /* First row section in new indirect section */ hsize_t sect_off; /* Offset of section in heap space */ unsigned start_row; /* Start row in indirect block */ unsigned start_col; /* Start column in indirect block */ @@ -2502,18 +2712,16 @@ HDfprintf(stderr, "%s: sect_off = %Hu\n", FUNC, sect_off); HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section") /* Initialize rows for new indirect section */ - if(H5HF_sect_indirect_init_rows(hdr, dxpl_id, sect, TRUE, 0, start_row, - start_col, end_row, end_col) < 0) + if(H5HF_sect_indirect_init_rows(hdr, dxpl_id, sect, TRUE, &first_row_sect, + H5FS_ADD_SKIP_VALID, start_row, start_col, end_row, end_col) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize indirect section") + HDassert(first_row_sect); - /* Get end of section offset to return, if requested */ - if(end_off) { - /* Compute the end of the section */ - *end_off = sect_off + sect->u.indirect.span_size; -#ifdef QAK -HDfprintf(stderr, "%s: *end_off = %Hu\n", FUNC, *end_off); -#endif /* QAK */ - } /* end if */ + /* Now that underlying indirect section is consistent, add first row + * section to free space manager for the heap + */ + if(H5HF_space_add(hdr, dxpl_id, first_row_sect, H5FS_ADD_RETURNED_SPACE) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't add row section to free space") done: if(ret_value < 0 && sect) @@ -2558,14 +2766,19 @@ HDfprintf(stderr, "%s: sect->u.indirect.rc = %u\n", FUNC, sect->u.indirect.rc); /* If the indirect section's ref. count drops to zero, free the section */ if(sect->u.indirect.rc == 0) { - /* Decrement ref. count on indirect section's parent */ - if(sect->u.indirect.parent) - if(H5HF_sect_indirect_decr(sect->u.indirect.parent) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't decrement ref. count on parent indirect section") + H5HF_free_section_t *par_sect; /* Parent indirect section */ + + /* Preserve pointer to parent indirect section when freeing this section */ + par_sect = sect->u.indirect.parent; /* Free indirect section */ if(H5HF_sect_indirect_free(sect) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free indirect section node") + + /* Decrement ref. count on indirect section's parent */ + if(par_sect) + if(H5HF_sect_indirect_decr(par_sect) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't decrement ref. count on parent indirect section") } /* end if */ done: @@ -2724,7 +2937,7 @@ static herr_t H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect, hbool_t *alloc_from_start) { - H5HF_free_section_t *sect; /* Indirect3 section underlying row section */ + H5HF_free_section_t *sect; /* Indirect section underlying row section */ unsigned row_start_entry; /* Entry for first block covered in row section */ unsigned row_end_entry; /* Entry for last block covered in row section */ unsigned row_entry; /* Entry to allocate in row section */ @@ -2765,6 +2978,7 @@ HDfprintf(stderr, "%s: row_start_entry = %u, row_end_entry = %u\n", FUNC, row_st /* Additional sanity check */ HDassert(sect->u.indirect.span_size > 0); HDassert(sect->u.indirect.iblock_entries > 0); + HDassert(sect->u.indirect.dir_nrows > 0); HDassert(sect->u.indirect.dir_rows); HDassert(sect->u.indirect.dir_rows[(row_sect->u.row.row - start_row)] == row_sect); #ifdef QAK @@ -2829,6 +3043,10 @@ HDfprintf(stderr, "%s: Entry is at start of indirect section\n", FUNC); if(sect->u.indirect.col == hdr->man_dtable.cparam.width) { HDassert(row_sect->u.row.num_entries == 1); + /* Adjust section's span information */ + sect->u.indirect.row++; + sect->u.indirect.col = 0; + /* Adjust direct row information */ sect->u.indirect.dir_nrows--; #ifdef QAK @@ -2837,6 +3055,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", FUNC, sect->u.indirec /* Adjust direct row sections for indirect section */ if(sect->u.indirect.dir_nrows > 0) { + HDassert(sect->u.indirect.dir_rows); HDmemmove(§->u.indirect.dir_rows[0], §->u.indirect.dir_rows[1], sect->u.indirect.dir_nrows * sizeof(H5HF_free_section_t *)); @@ -2849,6 +3068,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", FUNC, sect->u.indirec } /* end if */ else { /* Sanity check */ + HDassert(sect->u.indirect.indir_nents > 0); HDassert(sect->u.indirect.indir_ents); /* Eliminate direct rows for this section */ @@ -2859,9 +3079,6 @@ HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", FUNC, sect->u.indirec if(H5HF_sect_indirect_first(hdr, sect->u.indirect.indir_ents[0]) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for child indirect section") } /* end else */ - - sect->u.indirect.row++; - sect->u.indirect.col = 0; } /* end if */ /* Adjust number of entries covered */ @@ -2874,6 +3091,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", FUNC, sect->u.indirec HDfprintf(stderr, "%s: Entry is at end of indirect section\n", FUNC); #endif /* QAK */ /* Sanity check */ + HDassert(sect->u.indirect.indir_nents == 0); HDassert(sect->u.indirect.indir_ents == NULL); /* Adjust number of entries covered */ @@ -2985,8 +3203,13 @@ HDfprintf(stderr, "%s: iblock = %p, iblock_off = %Hu\n", FUNC, iblock, iblock_of } /* end else */ } /* end if */ else { + /* Decrement count of entries & rows */ sect->u.indirect.num_entries--; sect->u.indirect.dir_nrows--; + HDassert(sect->u.indirect.dir_nrows == 0); + + /* Eliminate direct rows for this section */ + sect->u.indirect.dir_rows = H5MM_xfree(sect->u.indirect.dir_rows); } /* end else */ done: @@ -3075,7 +3298,9 @@ HDfprintf(stderr, "%s: end_entry = %u, end_row = %u, end_col = %u\n", FUNC, end_ HDfprintf(stderr, "%s: Child is at start of indirect section\n", FUNC); #endif /* QAK */ /* Sanity check */ + HDassert(sect->u.indirect.dir_nrows == 0); HDassert(sect->u.indirect.dir_rows == NULL); + HDassert(sect->u.indirect.indir_nents > 0); HDassert(sect->u.indirect.indir_ents); /* Adjust section start */ @@ -3106,6 +3331,7 @@ HDfprintf(stderr, "%s: Child is at start of indirect section\n", FUNC); HDfprintf(stderr, "%s: Child is at end of indirect section\n", FUNC); #endif /* QAK */ /* Sanity check */ + HDassert(sect->u.indirect.indir_nents > 0); HDassert(sect->u.indirect.indir_ents); /* Adjust span of blocks covered */ @@ -3133,6 +3359,7 @@ HDfprintf(stderr, "%s: Child is at end of indirect section\n", FUNC); HDfprintf(stderr, "%s: Child is in middle of indirect section\n", FUNC); #endif /* QAK */ /* Sanity check */ + HDassert(sect->u.indirect.indir_nents > 0); HDassert(sect->u.indirect.indir_ents); /* Compute basic information about peer & current indirect sections */ @@ -3163,11 +3390,12 @@ HDfprintf(stderr, "%s: iblock = %p, iblock_off = %Hu\n", FUNC, iblock, iblock_of /* Update the number of entries in current section & calculate it's span size */ /* (Will use this to compute the section address for the peer section */ sect->u.indirect.num_entries = new_nentries; - if(H5HF_sect_indirect_span_size(hdr, sect) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute span size of section") + sect->u.indirect.span_size = H5HF_dtable_span_size(&hdr->man_dtable, + sect->u.indirect.row, sect->u.indirect.col, new_nentries); #ifdef QAK HDfprintf(stderr, "%s: sect->u.indirect.span_size = %Hu\n", FUNC, sect->u.indirect.span_size); #endif /* QAK */ + HDassert(sect->u.indirect.span_size > 0); /* Compute address of peer indirect section */ peer_sect_addr = sect->sect_info.addr; @@ -3195,6 +3423,10 @@ HDfprintf(stderr, "%s: peer_sect_addr = %a\n", FUNC, peer_sect_addr); §->u.indirect.indir_ents[sect->u.indirect.indir_nents - peer_nentries], (sizeof(H5HF_free_section_t *) * peer_nentries)); sect->u.indirect.indir_nents -= (peer_nentries + 1); /* Transferred blocks, plus child entry */ + + /* Eliminate indirect entries for this section, if appropriate */ + if(sect->u.indirect.indir_nents == 0) + sect->u.indirect.indir_ents = H5MM_xfree(sect->u.indirect.indir_ents); #ifdef QAK HDfprintf(stderr, "%s: sect->u.indirect.indir_nents = %u\n", FUNC, sect->u.indirect.indir_nents); #endif /* QAK */ @@ -3229,8 +3461,13 @@ HDfprintf(stderr, "%s: peer_sect->u.indirect.rc = %u\n", FUNC, peer_sect->u.indi } /* end else */ } /* end if */ else { + /* Decrement count of entries & indirect entries */ sect->u.indirect.num_entries--; sect->u.indirect.indir_nents--; + HDassert(sect->u.indirect.indir_nents == 0); + + /* Eliminate indirect entries for this section */ + sect->u.indirect.indir_ents = H5MM_xfree(sect->u.indirect.indir_ents); } /* end else */ /* Decrement # of sections which depend on this row */ @@ -3307,6 +3544,7 @@ H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) /* Sanity checks */ HDassert(sect->u.indirect.row == 0); HDassert(sect->u.indirect.col == 0); + HDassert(sect->u.indirect.dir_rows); HDassert(sect->u.indirect.dir_rows[0]); /* Change first row section in indirect section to be the "first row" */ @@ -3316,6 +3554,7 @@ H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect) else { /* Sanity checks */ HDassert(sect->u.indirect.indir_nents > 0); + HDassert(sect->u.indirect.indir_ents); HDassert(sect->u.indirect.indir_ents[0]); /* Forward to first child indirect section */ @@ -3545,6 +3784,7 @@ HDfprintf(stderr, "%s: nrows_moved2 = %u\n", FUNC, nrows_moved2); /* Some sanity checks on second indirect section */ HDassert(sect2->u.indirect.rc > 0); + HDassert(sect2->u.indirect.indir_nents > 0); HDassert(sect2->u.indirect.indir_ents); /* Set up parameters for transfer of entries */ @@ -3622,7 +3862,7 @@ HDfprintf(stderr, "%s: Finishing sections don't share a row\n", FUNC); HDfprintf(stderr, "%s: Re-inserting second row section\n", FUNC); #endif /* QAK */ row_sect2->sect_info.type = H5HF_FSPACE_SECT_NORMAL_ROW; - if(H5HF_space_add(hdr, dxpl_id, row_sect2, 0) < 0) + if(H5HF_space_add(hdr, dxpl_id, row_sect2, H5FS_ADD_SKIP_VALID) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't re-add second row section to free space") #ifdef QAK HDfprintf(stderr, "%s: Done re-inserting second row section\n", FUNC); @@ -3886,9 +4126,9 @@ H5HF_sect_indirect_deserialize(H5HF_hdr_t *hdr, hid_t dxpl_id, { H5HF_free_section_t *new_sect; /* New indirect section */ hsize_t iblock_off; /* Indirect block's offset */ - unsigned start_row; /* Indirect3 section's start row */ - unsigned start_col; /* Indirect3 section's start column */ - unsigned nentries; /* Indirect3 section's number of entries */ + unsigned start_row; /* Indirect section's start row */ + unsigned start_col; /* Indirect section's start column */ + unsigned nentries; /* Indirect section's number of entries */ unsigned start_entry; /* Start entry in indirect block */ unsigned end_entry; /* End entry in indirect block */ unsigned end_row; /* End row in indirect block */ @@ -3912,19 +4152,19 @@ HDfprintf(stderr, "%s: sect_addr = %a, sect_size = %Hu\n", FUNC, sect_addr, sect HDfprintf(stderr, "%s: iblock_off = %Hu\n", FUNC, iblock_off); #endif /* QAK */ - /* Indirect3 section's row */ + /* Indirect section's row */ UINT16DECODE(buf, start_row); #ifdef QAK HDfprintf(stderr, "%s: start_row = %u\n", FUNC, start_row); #endif /* QAK */ - /* Indirect3 section's column */ + /* Indirect section's column */ UINT16DECODE(buf, start_col); #ifdef QAK HDfprintf(stderr, "%s: start_col = %u\n", FUNC, start_col); #endif /* QAK */ - /* Indirect3 section's # of entries */ + /* Indirect section's # of entries */ UINT16DECODE(buf, nentries); #ifdef QAK HDfprintf(stderr, "%s: nentries = %u\n", FUNC, nentries); @@ -3944,8 +4184,9 @@ HDfprintf(stderr, "%s: nentries = %u\n", FUNC, nentries); end_col = end_entry % hdr->man_dtable.cparam.width; /* Initialize rows for new indirect section */ - if(H5HF_sect_indirect_init_rows(hdr, dxpl_id, new_sect, TRUE, H5FS_ADD_DESERIALIZING, - new_sect->u.indirect.row, new_sect->u.indirect.col, end_row, end_col) < 0) + if(H5HF_sect_indirect_init_rows(hdr, dxpl_id, new_sect, TRUE, NULL, + H5FS_ADD_DESERIALIZING, new_sect->u.indirect.row, new_sect->u.indirect.col, + end_row, end_col) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't initialize indirect section") /* Indicate that this section shouldn't be added to free space manager's list */ @@ -4019,12 +4260,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5HF_sect_indirect_valid(const H5FS_section_class_t *row_cls, const H5HF_free_section_t *row_sect) +H5HF_sect_indirect_valid(const H5HF_hdr_t *hdr, const H5HF_free_section_t *sect) { - const H5HF_free_section_t *sect; /* Pointer to underlying indirect section */ - H5HF_sect_indirect_private_t *cls_prvt; /* Pointer to class private info */ - const H5HF_hdr_t *hdr; /* Fractal heap header */ - hsize_t iblock_off; /* Indirect block's offset in "heap space" */ unsigned start_row; /* Row for first block covered */ unsigned start_col; /* Column for first block covered */ unsigned start_entry; /* Entry for first block covered */ @@ -4036,15 +4273,9 @@ H5HF_sect_indirect_valid(const H5FS_section_class_t *row_cls, const H5HF_free_se FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_valid) /* Sanity check arguments */ - HDassert(row_cls); - HDassert(row_sect); - - /* Set up indirect section */ - sect = row_sect->u.row.under; - cls_prvt = row_cls->cls_private; - hdr = cls_prvt->hdr; - HDassert(sect); HDassert(hdr); + HDassert(sect); + #ifdef QAK HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_indirect_valid", sect->sect_info.addr, sect->sect_info.size, sect->sect_info.type, (sect->sect_info.state == H5FS_SECT_LIVE ? "H5FS_SECT_LIVE" : "H5FS_SECT_SERIALIZED")); if(sect->sect_info.state == H5FS_SECT_LIVE) @@ -4054,16 +4285,6 @@ else HDfprintf(stderr, "%u, %u, %u}\n", sect->u.indirect.row, sect->u.indirect.col, sect->u.indirect.num_entries); #endif /* QAK */ - /* Retrieve the indirect block's offset */ - if(sect->sect_info.state == H5FS_SECT_LIVE) - iblock_off = sect->u.indirect.u.iblock->block_off; - else - iblock_off = sect->u.indirect.u.iblock_off; - -#ifdef QAK -HDfprintf(stderr, "%s: iblock_off = %Hu\n", "H5HF_sect_indirect_valid", iblock_off); -#endif /* QAK */ - /* Compute starting entry, column & row */ start_row = sect->u.indirect.row; start_col = sect->u.indirect.col; @@ -4100,14 +4321,42 @@ HDfprintf(stderr, "%s: end_row = %u, end_col = %u, end_entry = %u\n", "H5HF_sect || tmp_row_sect->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW); HDassert(tmp_row_sect->u.row.under == sect); HDassert(tmp_row_sect->u.row.row == (start_row + u)); - if(u < (dir_nrows - 1)) { + if(u > 0) { const H5HF_free_section_t *tmp_row_sect2; /* Pointer to row section */ - tmp_row_sect2 = sect->u.indirect.dir_rows[u + 1]; - HDassert(tmp_row_sect->u.row.row < tmp_row_sect2->u.row.row); - HDassert(H5F_addr_lt(tmp_row_sect->sect_info.addr, tmp_row_sect2->sect_info.addr)); - HDassert(tmp_row_sect->sect_info.size <= tmp_row_sect2->sect_info.size); + tmp_row_sect2 = sect->u.indirect.dir_rows[u - 1]; + HDassert(tmp_row_sect2->u.row.row < tmp_row_sect->u.row.row); + HDassert(H5F_addr_lt(tmp_row_sect2->sect_info.addr, tmp_row_sect->sect_info.addr)); + HDassert(tmp_row_sect2->sect_info.size <= tmp_row_sect->sect_info.size); + } /* end if */ + } /* end for */ + } /* end if */ + + /* Sanity check any indirect entries */ + if(sect->u.indirect.indir_nents > 0) { + /* Basic sanity checks */ + if(sect->sect_info.state == H5FS_SECT_LIVE) { + HDassert(sect->u.indirect.iblock_entries); + HDassert(sect->u.indirect.indir_nents <= sect->u.indirect.iblock_entries); + } /* end if */ + HDassert(sect->u.indirect.indir_ents); + + /* Sanity check each child indirect section */ + for(u = 0; u < sect->u.indirect.indir_nents; u++) { + const H5HF_free_section_t *tmp_child_sect; /* Pointer to child indirect section */ + + tmp_child_sect = sect->u.indirect.indir_ents[u]; + HDassert(tmp_child_sect->sect_info.type == H5HF_FSPACE_SECT_INDIRECT); + HDassert(tmp_child_sect->u.indirect.parent == sect); + if(u > 0) { + const H5HF_free_section_t *tmp_child_sect2; /* Pointer to child indirect section */ + + tmp_child_sect2 = sect->u.indirect.indir_ents[u - 1]; + HDassert(H5F_addr_lt(tmp_child_sect2->sect_info.addr, tmp_child_sect->sect_info.addr)); } /* end if */ + + /* Recursively check child indirect section */ + H5HF_sect_indirect_valid(hdr, tmp_child_sect); } /* end for */ } /* end if */ @@ -4130,11 +4379,9 @@ HDfprintf(stderr, "%s: end_row = %u, end_col = %u, end_entry = %u\n", "H5HF_sect *------------------------------------------------------------------------- */ static herr_t -H5HF_sect_indirect_debug(const H5FS_section_info_t *_sect, +H5HF_sect_indirect_debug(const H5HF_free_section_t *sect, FILE *stream, int indent, int fwidth) { - const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Section to dump info */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_debug) /* Check arguments. */ diff --git a/test/fheap.c b/test/fheap.c index be72650..c7ae68e 100644 --- a/test/fheap.c +++ b/test/fheap.c @@ -33,15 +33,17 @@ /* Object size macros */ #define SMALL_OBJ_SIZE1 10 #define SMALL_OBJ_SIZE2 20 +#define NUM_FILL_OBJS 11 /* "Small" heap creation parameters */ -#define SMALL_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */ -#define SMALL_STAND_SIZE (48 * 1024) /* Standalone obj. min. size */ -#define SMALL_MAN_WIDTH 4 /* Managed obj. table width */ -#define SMALL_MAN_START_BLOCK_SIZE 512 /* Managed obj. starting block size */ -#define SMALL_MAN_MAX_DIRECT_SIZE (64 * 1024) /* Managed obj. max. direct block size */ -#define SMALL_MAN_MAX_INDEX 32 /* Managed obj. # of bits for total heap size */ -#define SMALL_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */ +#define SMALL_ADDRMAP H5HF_ABSOLUTE /* Heap address mapping */ +#define SMALL_DBLOCK_OVERHEAD 22 /* Overhead for direct blocks */ +#define SMALL_MAN_WIDTH 4 /* Managed obj. table width */ +#define SMALL_MAN_START_BLOCK_SIZE 512 /* Managed obj. starting block size */ +#define SMALL_MAN_MAX_DIRECT_SIZE (64 * 1024) /* Managed obj. max. direct block size */ +#define SMALL_MAN_MAX_INDEX 32 /* Managed obj. # of bits for total heap size */ +#define SMALL_MAN_START_ROOT_ROWS 1 /* Managed obj. starting # of root indirect block rows */ +#define SMALL_STAND_SIZE (SMALL_MAN_MAX_DIRECT_SIZE - SMALL_DBLOCK_OVERHEAD) /* Standalone obj. min. size */ /* Define this macro to enable all insertion tests */ /* #define ALL_INSERT_TESTS */ @@ -69,23 +71,31 @@ typedef enum { /* Order to delete objects */ typedef enum { - HEAP_DEL_FORWARD, /* Delete objects from 0 -> nobjs */ - HEAP_DEL_REVERSE, /* Delete objects from nobjs -> 0 */ - HEAP_DEL_NDIRS /* The number of different deletion orders, must be last */ + FHEAP_DEL_FORWARD, /* Delete objects from 0 -> nobjs */ + FHEAP_DEL_REVERSE, /* Delete objects from nobjs -> 0 */ + FHEAP_DEL_NDIRS /* The number of different deletion orders, must be last */ } fheap_test_del_dir_t; /* Order to delete objects */ typedef enum { - HEAP_DEL_DRAIN_ALL, /* Don't drain half of objects first */ - HEAP_DEL_DRAIN_HALF, /* Don't drain half of objects first */ - HEAP_DEL_DRAIN_N /* The number of different ways to drain, must be last */ + FHEAP_DEL_DRAIN_ALL, /* Don't drain half of objects first */ + FHEAP_DEL_DRAIN_HALF, /* Don't drain half of objects first */ + FHEAP_DEL_DRAIN_N /* The number of different ways to drain, must be last */ } fheap_test_del_drain_t; +/* Size of objects for "bulk" filling heap blocks */ +typedef enum { + FHEAP_TEST_FILL_LARGE, /* Fill heap blocks with "large" objects */ + FHEAP_TEST_FILL_SINGLE, /* Fill heap blocks with single object */ + FHEAP_TEST_FILL_N /* The number of different ways to test filling heap blocks, must be last */ +} fheap_test_fill_t; + /* Testing parameters */ typedef struct fheap_test_param_t { fheap_test_type_t reopen_heap; /* Whether to re-open the heap during the test */ fheap_test_del_dir_t del_dir; /* Whether to delete objects forward or reverse */ fheap_test_del_drain_t drain_half; /* Whether to drain half of the objects & refill, when deleting objects */ + fheap_test_fill_t fill; /* How to "bulk" fill heap blocks */ } fheap_test_param_t; /* Heap state information */ @@ -233,15 +243,14 @@ error: *------------------------------------------------------------------------- */ static int -add_obj(H5HF_t *fh, hid_t dxpl, unsigned obj_off, size_t obj_size, - fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids) +add_obj(H5HF_t *fh, hid_t dxpl, unsigned obj_off, + size_t obj_size, fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids) { unsigned char heap_id[HEAP_ID_LEN]; /* Heap ID for object inserted */ unsigned char *obj; /* Buffer for object to insert */ /* Sanity check */ HDassert(fh); - HDassert(state); /* Initialize object buffer */ obj = &shared_wobj_g[obj_off]; @@ -251,13 +260,16 @@ add_obj(H5HF_t *fh, hid_t dxpl, unsigned obj_off, size_t obj_size, if(H5HF_insert(fh, dxpl, obj_size, obj, heap_id) < 0) FAIL_STACK_ERROR - /* Adjust state of heap */ - state->nobjs++; - state->man_free_space -= obj_size; + /* Check for tracking the heap's state */ + if(state) { + /* Adjust state of heap */ + state->nobjs++; + state->man_free_space -= obj_size; - /* Check free space left in heap */ - if(check_stats(fh, state)) - FAIL_STACK_ERROR + /* Check free space left in heap */ + if(check_stats(fh, state)) + FAIL_STACK_ERROR + } /* end if */ /* Read in object */ if(H5HF_read(fh, dxpl, heap_id, shared_robj_g) < 0) @@ -279,7 +291,7 @@ add_obj(H5HF_t *fh, hid_t dxpl, unsigned obj_off, size_t obj_size, } /* end if */ /* Append the object info onto the array */ - HDmemcpy(&keep_ids->ids[keep_ids->num_ids * HEAP_ID_LEN], obj, HEAP_ID_LEN); + HDmemcpy(&keep_ids->ids[keep_ids->num_ids * HEAP_ID_LEN], heap_id, HEAP_ID_LEN); keep_ids->lens[keep_ids->num_ids] = obj_size; keep_ids->offs[keep_ids->num_ids] = obj_off; @@ -310,18 +322,18 @@ error: *------------------------------------------------------------------------- */ static char * -get_del_string(fheap_test_param_t *tparam) +get_del_string(const fheap_test_param_t *tparam) { char *str; /* Remove half of total objects from heap */ - if(tparam->del_dir == HEAP_DEL_FORWARD) - if(tparam->drain_half == HEAP_DEL_DRAIN_ALL) + if(tparam->del_dir == FHEAP_DEL_FORWARD) + if(tparam->drain_half == FHEAP_DEL_DRAIN_ALL) str = HDstrdup("(all - forward)"); else str = HDstrdup("(half, refill, all - forward)"); else - if(tparam->drain_half == HEAP_DEL_DRAIN_ALL) + if(tparam->drain_half == FHEAP_DEL_DRAIN_ALL) str = HDstrdup("(all - reverse)"); else str = HDstrdup("(half, refill, all - reverse)"); @@ -331,6 +343,37 @@ get_del_string(fheap_test_param_t *tparam) /*------------------------------------------------------------------------- + * Function: get_fill_size + * + * Purpose: Retrieve the size of objects to "bulk" fill blocks with + * + * Return: Size of object to pass down to "fill_heap" routine on + * success/can't fail + * + * Programmer: Quincey Koziol + * Thursday, July 27, 2006 + * + *------------------------------------------------------------------------- + */ +static size_t +get_fill_size(const fheap_test_param_t *tparam) +{ + switch(tparam->fill) { + case FHEAP_TEST_FILL_LARGE: + return((size_t)(-1)); + + case FHEAP_TEST_FILL_SINGLE: + return((size_t)0); + + default: + HDassert(0 && "Unknown bulk fill type?!?"); + } /* end switch */ + + return(0); +} /* get_fill_size() */ + + +/*------------------------------------------------------------------------- * Function: del_objs_half_refill * * Purpose: Remove half of objects from heap and refill @@ -346,7 +389,7 @@ get_del_string(fheap_test_param_t *tparam) */ static int del_objs_half_refill(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tparam, - fheap_heap_state_t *state, fheap_heap_ids_t *keep_ids) + fheap_heap_ids_t *keep_ids) { unsigned char *wobj; /* Buffer for object to insert */ haddr_t fh_addr; /* Address of fractal heap */ @@ -357,7 +400,6 @@ del_objs_half_refill(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tpar /* Sanity check */ HDassert(fh); HDassert(*fh); - HDassert(state); HDassert(keep_ids); /* Check for closing & re-opening the heap */ @@ -369,11 +411,11 @@ del_objs_half_refill(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tpar } /* end if */ /* Remove half of total objects from heap */ - if(tparam->del_dir == HEAP_DEL_FORWARD) + if(tparam->del_dir == FHEAP_DEL_FORWARD) obj_idx = 0; else - obj_idx = state->nobjs - 1; - half_nobjs = state->nobjs / 2; + obj_idx = keep_ids->num_ids - 1; + half_nobjs = keep_ids->num_ids / 2; for(u = 0; u < half_nobjs; u++) { /* Remove object from heap */ if(H5HF_remove(*fh, dxpl, &keep_ids->ids[HEAP_ID_LEN * obj_idx]) < 0) @@ -391,17 +433,17 @@ del_objs_half_refill(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tpar } /* end if */ /* Adjust index of object to delete next */ - if(tparam->del_dir == HEAP_DEL_FORWARD) + if(tparam->del_dir == FHEAP_DEL_FORWARD) obj_idx++; else obj_idx--; } /* end for */ /* Re-insert half of total objects back into heap */ - if(tparam->del_dir == HEAP_DEL_FORWARD) + if(tparam->del_dir == FHEAP_DEL_FORWARD) obj_idx = 0; else - obj_idx = state->nobjs - 1; + obj_idx = keep_ids->num_ids - 1; for(u = 0; u < half_nobjs; u++) { /* Re-insert object */ wobj = &shared_wobj_g[keep_ids->offs[obj_idx]]; @@ -420,7 +462,7 @@ del_objs_half_refill(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tpar } /* end if */ /* Adjust index of object to delete next */ - if(tparam->del_dir == HEAP_DEL_FORWARD) + if(tparam->del_dir == FHEAP_DEL_FORWARD) obj_idx++; else obj_idx--; @@ -463,8 +505,8 @@ del_objs(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tparam, HDassert(keep_ids); /* Check for first deleting half of objects & then re-inserting them */ - if(tparam->drain_half == HEAP_DEL_DRAIN_HALF) - if(del_objs_half_refill(f, dxpl, fh, tparam, state, keep_ids)) + if(tparam->drain_half == FHEAP_DEL_DRAIN_HALF) + if(del_objs_half_refill(f, dxpl, fh, tparam, keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -476,11 +518,11 @@ del_objs(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tparam, } /* end if */ /* Remove all objects from heap */ - if(tparam->del_dir == HEAP_DEL_FORWARD) + if(tparam->del_dir == FHEAP_DEL_FORWARD) obj_idx = 0; else - obj_idx = state->nobjs - 1; - for(u = 0; u < state->nobjs; u++) { + obj_idx = keep_ids->num_ids - 1; + for(u = 0; u < keep_ids->num_ids; u++) { /* Remove object from heap */ if(H5HF_remove(*fh, dxpl, &keep_ids->ids[HEAP_ID_LEN * obj_idx]) < 0) FAIL_STACK_ERROR @@ -497,18 +539,16 @@ del_objs(H5F_t *f, hid_t dxpl, H5HF_t **fh, fheap_test_param_t *tparam, } /* end if */ /* Adjust index of object to delete next */ - if(tparam->del_dir == HEAP_DEL_FORWARD) + if(tparam->del_dir == FHEAP_DEL_FORWARD) obj_idx++; else obj_idx--; } /* end for */ + /* Heap should be completely empty now, reset our state */ + HDmemset(state, 0, sizeof(fheap_heap_state_t)); + /* Check up on heap... */ - state->heap_size = 0; - state->man_size = 0; - state->man_alloc_size = 0; - state->man_free_space = 0; - state->nobjs = 0; if(check_stats(*fh, state)) FAIL_STACK_ERROR @@ -572,6 +612,12 @@ fill_heap(H5HF_t *fh, hid_t dxpl, unsigned block_row, size_t obj_size, curr_off_ptr = shared_offs_g; obj_off = 0; + /* Check for some "magic" object sizes */ + if(obj_size == 0) + obj_size = data_size; + else if(obj_size == (size_t)(-1)) + obj_size = (data_size / NUM_FILL_OBJS) + 1; + /* Loop over inserting objects into the root direct block, until there's no more space */ while(data_size >= obj_size) { /* Increment object count */ @@ -1732,6 +1778,7 @@ test_abs_insert_root_mult(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 */ 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) */ @@ -1763,12 +1810,15 @@ test_abs_insert_root_mult(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t */ TESTING("inserting objects to fill absolute heap's root direct block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill the heap up */ state.heap_size = DBLOCK_SIZE(fh, 0); 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -1831,6 +1881,7 @@ test_abs_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) */ @@ -1862,12 +1913,15 @@ test_abs_insert_force_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_par */ TESTING("inserting objects to create root indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill the heap up */ state.heap_size = DBLOCK_SIZE(fh, 0); 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -1938,6 +1992,7 @@ test_abs_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) */ @@ -1969,12 +2024,15 @@ test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ */ 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 */ state.heap_size = DBLOCK_SIZE(fh, 0); 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -1993,7 +2051,7 @@ test_abs_insert_fill_second(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -2046,6 +2104,7 @@ test_abs_insert_third_direct(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) */ @@ -2077,12 +2136,15 @@ test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param */ TESTING("inserting objects to create third direct block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill the first direct block up */ state.heap_size = DBLOCK_SIZE(fh, 0); 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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) */ @@ -2090,7 +2152,7 @@ test_abs_insert_third_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2158,6 +2220,7 @@ test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t 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) */ @@ -2189,8 +2252,11 @@ test_abs_fill_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t */ TESTING("inserting objects to fill first row of 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2253,6 +2319,7 @@ test_abs_start_second_row(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 */ 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) */ @@ -2284,8 +2351,11 @@ test_abs_start_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t */ TESTING("inserting objects to start second row of root indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill first root indirect row */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2356,6 +2426,7 @@ test_abs_fill_second_row(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 */ 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) */ @@ -2387,8 +2458,11 @@ test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * */ TESTING("inserting objects to fill second row of root indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill first root indirect row */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_row(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2403,7 +2477,7 @@ test_abs_fill_second_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * } /* end if */ /* Fill second root indirect row */ - if(fill_root_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -2456,6 +2530,7 @@ test_abs_start_third_row(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 */ 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) */ @@ -2487,12 +2562,15 @@ test_abs_start_third_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * */ TESTING("inserting objects to start third row of root indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill first root indirect row */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2567,6 +2645,7 @@ test_abs_fill_fourth_row(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 */ 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 */ @@ -2599,9 +2678,12 @@ test_abs_fill_fourth_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * */ TESTING("inserting objects to fill four rows 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_row(fh, dxpl, u, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2664,6 +2746,7 @@ test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_para 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) */ @@ -2695,8 +2778,11 @@ test_abs_fill_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_para */ TESTING("inserting objects to fill all direct rows 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2759,6 +2845,7 @@ test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_ 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) */ @@ -2790,8 +2877,11 @@ test_abs_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_ */ TESTING("inserting objects to create first recursive indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2860,6 +2950,7 @@ test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhe 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) */ @@ -2892,13 +2983,16 @@ test_abs_second_direct_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhe */ 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 */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_heap(fh, dxpl, 0, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -2969,6 +3063,7 @@ test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_ 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) */ @@ -3001,8 +3096,11 @@ test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_ */ 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 up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3017,7 +3115,7 @@ test_abs_fill_first_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_ } /* end if */ /* Fill first recursive indirect block */ - if(fill_2nd_indirect(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3071,6 +3169,7 @@ test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test 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) */ @@ -3103,12 +3202,15 @@ test_abs_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test */ TESTING("inserting objects to start second recursive indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3181,6 +3283,7 @@ test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap 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) */ @@ -3213,12 +3316,15 @@ test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap */ TESTING("inserting objects to fill all direct blocks in second recursive indirect block"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3233,7 +3339,7 @@ test_abs_fill_second_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap } /* end if */ /* Fill 2nd recursive indirect block */ - if(fill_2nd_indirect(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3288,6 +3394,7 @@ test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_te 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) */ @@ -3320,8 +3427,11 @@ test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_te */ 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 in root indirect block up */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3336,7 +3446,7 @@ test_abs_fill_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fheap_te } /* end if */ /* Fill row of recursive indirect blocks */ - if(fill_2nd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3389,6 +3499,7 @@ test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t 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) */ @@ -3421,12 +3532,15 @@ test_abs_start_2nd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t */ 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 in root indirect block up */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3497,6 +3611,7 @@ test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_te 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) */ @@ -3529,8 +3644,11 @@ test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_te */ TESTING("inserting objects to fill recursive indirect blocks two levels deep"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3545,7 +3663,7 @@ test_abs_recursive_indirect_two_deep(hid_t fapl, H5HF_create_t *cparam, fheap_te } /* end if */ /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3599,6 +3717,7 @@ test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t 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) */ @@ -3631,12 +3750,15 @@ test_abs_start_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t */ TESTING("inserting objects to start recursive indirect blocks three levels deep"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3708,6 +3830,7 @@ test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh 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) */ @@ -3740,16 +3863,19 @@ test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh */ 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); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3764,7 +3890,7 @@ test_abs_fill_first_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh } /* end if */ /* Fill row of recursive indirect blocks in third level indirect block */ - if(fill_2nd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_2nd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3818,6 +3944,7 @@ test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea 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) */ @@ -3850,12 +3977,15 @@ test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea */ 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); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3870,7 +4000,7 @@ test_abs_fill_3rd_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea } /* end if */ /* Fill 1st row of 3rd level indirect blocks */ - if(fill_3rd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -3924,6 +4054,7 @@ test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea 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) */ @@ -3956,12 +4087,15 @@ test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea */ 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); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -3976,7 +4110,7 @@ test_abs_fill_all_3rd_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea } /* end if */ /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4031,6 +4165,7 @@ test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t 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) */ @@ -4063,16 +4198,19 @@ test_abs_start_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t */ 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); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4145,6 +4283,7 @@ test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh 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) */ @@ -4177,24 +4316,27 @@ test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh */ 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); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4209,7 +4351,7 @@ test_abs_fill_first_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fh } /* end if */ /* Fill first row of 3rd level deep indirect blocks in fourth level indirect block */ - if(fill_3rd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4264,6 +4406,7 @@ test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea 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) */ @@ -4296,16 +4439,19 @@ test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea */ 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); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4320,7 +4466,7 @@ test_abs_fill_4th_recursive_indirect_row(hid_t fapl, H5HF_create_t *cparam, fhea } /* end if */ /* Fill 1st row of 4th level indirect blocks */ - if(fill_4th_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_4th_indirect_row(fh, dxpl, 1, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4375,6 +4521,7 @@ test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea 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) */ @@ -4407,16 +4554,19 @@ test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea */ TESTING("inserting objects to fill all rows of recursive indirect blocks four levels deep"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4431,7 +4581,7 @@ test_abs_fill_all_4th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fhea } /* end if */ /* Fill all rows of 4th level indirect blocks */ - if(fill_all_4th_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_4th_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4489,6 +4639,7 @@ test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t 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) */ @@ -4522,8 +4673,11 @@ test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t */ TESTING("inserting objects to create first direct block in recursive indirect blocks five levels deep"); + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + /* Fill direct blocks up in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4538,7 +4692,7 @@ test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t } /* end if */ /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4553,7 +4707,7 @@ test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t } /* end if */ /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4568,7 +4722,7 @@ test_abs_start_5th_recursive_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_t } /* end if */ /* Fill all rows of 4th level indirect blocks */ - if(fill_all_4th_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_all_4th_indirect_rows(fh, dxpl, fill_size, &state, NULL)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -4615,23 +4769,21 @@ error: #ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_skip_start_block + * Function: test_abs_remove_bogus * - * Purpose: Test inserting object into absolute heap which is too large - * for starting block size, which forces root indirect block - * creation + * Purpose: Test removing bogus heap IDs * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, March 27, 2006 + * Monday, May 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -4639,9 +4791,13 @@ test_abs_skip_start_block(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_id[HEAP_ID_LEN]; /* Heap ID for object */ size_t id_len; /* Size of fractal heap IDs */ - size_t obj_size; /* Size of object */ + 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)); @@ -4655,7 +4811,7 @@ test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 @@ -4669,29 +4825,9 @@ test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* - * Test inserting object into absolute heap which doesn't fit into starting - * block size - */ - TESTING("inserting object that is too large for starting block"); - - obj_size = DBLOCK_SIZE(fh, 0) + 1; - state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - 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 += cparam->managed.width * DBLOCK_FREE(fh, 2); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -4700,6 +4836,51 @@ test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t FAIL_STACK_ERROR } /* end if */ + /* + * Test removing bogus IDs from heap + */ + TESTING("removing bad heap IDs from absolute heap"); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Set heap ID to random (non-null) value */ + for(u = 0; 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 */ + 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) + FAIL_STACK_ERROR + + /* Make certain we can't accidentally use a valid heap ID */ + while(obj_off < state.heap_size) { + /* Set heap ID to random (non-null) value */ + for(u = 0; u < HEAP_ID_LEN; u++) + heap_id[u] = HDrandom() + 1; + + /* Get offset of random heap ID */ + if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) + FAIL_STACK_ERROR + } /* end while */ + + /* 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) TEST_ERROR @@ -4720,27 +4901,25 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_skip_start_block() */ +} /* test_abs_remove_bogus() */ /*------------------------------------------------------------------------- - * Function: test_abs_skip_start_block_add_back + * Function: test_abs_remove_one * - * Purpose: Test inserting object into absolute heap which is too large - * for starting block size, which forces root indirect block - * creation, then add object which fits in skipped direct block + * Purpose: Test removing single object from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 28, 2006 + * Monday, May 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -4748,9 +4927,13 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test 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 */ - size_t obj_size; /* Size of object */ + 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 */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -4764,7 +4947,7 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test 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 @@ -4778,30 +4961,47 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test 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 inserting object into absolute heap which doesn't fit into starting - * block size + * Test removing first (small) object from absolute heap */ - TESTING("skipping starting block, then adding object back to first block"); + TESTING("removing single object from absolute heap"); - /* Insert object too large for starting block size */ - obj_size = DBLOCK_SIZE(fh, 0) + 1; - state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - 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 += cparam->managed.width * DBLOCK_FREE(fh, 2); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* 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, sizeof(obj), obj, &heap_id) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -4810,14 +5010,22 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test FAIL_STACK_ERROR } /* end if */ - /* Insert an object to fill up the heap block just created */ - obj_size = DBLOCK_FREE(fh, 2) - obj_size; - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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.nobjs = 1; + if(check_stats(fh, &state)) + 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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -4826,9 +5034,13 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test FAIL_STACK_ERROR } /* end if */ - /* Insert second "real" object, which should go in earlier direct block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(add_obj(fh, dxpl, 20, SMALL_OBJ_SIZE2, &state, NULL)) + /* Check up on heap... */ + state.heap_size = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.nobjs = 0; + if(check_stats(fh, &state)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4839,6 +5051,14 @@ test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test 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() @@ -4851,28 +5071,25 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_skip_start_block_add_back() */ +} /* test_abs_remove_one() */ /*------------------------------------------------------------------------- - * Function: test_abs_skip_start_block_add_skipped + * Function: test_abs_remove_two * - * Purpose: Test inserting object into absolute heap which is too large - * for starting block size, which forces root indirect block - * creation, then add objects to fill skipped direct blocks - * and add another object to start on next "normal" block + * Purpose: Test removing two objects from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, March 28, 2006 + * Monday, May 22, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -4880,9 +5097,14 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_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[SMALL_OBJ_SIZE1]; /* Buffer for object to insert */ size_t id_len; /* Size of fractal heap IDs */ - size_t obj_size; /* Size of object */ + 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 */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -4896,7 +5118,7 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_t 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 @@ -4910,30 +5132,47 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_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 inserting object into absolute heap which doesn't fit into starting - * block size + * Test removing two (small) objects from absolute heap */ - TESTING("skipping starting block, then adding objects to backfill and extend"); + TESTING("removing two objects from absolute heap"); - /* Insert object too large for starting block size */ - obj_size = DBLOCK_SIZE(fh, 0) + 1; - state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - 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 += cparam->managed.width * DBLOCK_FREE(fh, 2); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Initialize the buffer for objects to insert */ + for(u = 0; u < sizeof(obj); u++) + obj[u] = u; + + /* 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 */ if(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -4942,14 +5181,22 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_t FAIL_STACK_ERROR } /* end if */ - /* Insert an object to fill up the heap block just created */ - obj_size = DBLOCK_FREE(fh, 2) - obj_size; - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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.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) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -4958,15 +5205,19 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_t FAIL_STACK_ERROR } /* end if */ - /* Add rows of blocks to "backfill" direct blocks that were skipped */ - if(fill_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + state.man_free_space -= sizeof(obj); + state.nobjs++; + if(check_stats(fh, &state)) FAIL_STACK_ERROR - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + + /* Remove first object from heap */ + if(H5HF_remove(fh, dxpl, heap_id1) < 0) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -4975,9 +5226,34 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_t FAIL_STACK_ERROR } /* end if */ - /* Insert another object, which should extend direct blocks, instead of backfill */ - state.man_alloc_size += DBLOCK_SIZE(fh, 2); - if(add_obj(fh, dxpl, 20, SMALL_OBJ_SIZE2, &state, NULL)) + /* Check up on heap... */ + state.man_free_space += sizeof(obj); + state.nobjs--; + 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(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + state.heap_size = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.nobjs = 0; + if(check_stats(fh, &state)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -4988,6 +5264,14 @@ test_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_t 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() @@ -5000,28 +5284,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_skip_start_block_add_skipped() */ +} /* test_abs_remove_two() */ /*------------------------------------------------------------------------- - * Function: test_abs_skip_2nd_block + * Function: test_abs_remove_one_larger * - * Purpose: Test inserting object into absolute heap which is small - * enough for starting block size, then add object too large - * for any blocks in first row of direct blocks, to force - * early creation of indirect block (and range of skipped blocks) + * Purpose: Test removing single larger (but < standalone size) object + * from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, April 1, 2006 + * Tuesday, June 6, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -5029,9 +5311,14 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *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_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 */ - size_t obj_size; /* Size of object */ + 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 */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5045,7 +5332,7 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t 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 @@ -5056,23 +5343,50 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t 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 inserting first (small) object into absolute heap + * Test removing one larger object from absolute heap */ - TESTING("insert object to initial block, then add object too large for starting direct blocks"); + TESTING("removing single larger object from absolute heap"); - /* Insert small object, to create root direct block */ - state.heap_size = DBLOCK_SIZE(fh, 0); - 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, 10, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5081,26 +5395,25 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t FAIL_STACK_ERROR } /* end if */ - /* Insert large object, to force creation of indirect block and - * range of skipped blocks that are too small to hold the second object - */ - obj_size = DBLOCK_SIZE(fh, 0) + 1; - state.heap_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - state.man_size += (cparam->managed.width - 1) * 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 - 1 )* DBLOCK_FREE(fh, 0); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Check up on heap... */ + for(u = 0; u < 4; u++) { + state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.nobjs = 1; + if(check_stats(fh, &state)) + 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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5109,12 +5422,29 @@ test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *t FAIL_STACK_ERROR } /* end if */ + /* Check up on heap... */ + state.heap_size = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.nobjs = 0; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_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 */ @@ -5129,31 +5459,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_skip_2nd_block() */ +} /* test_abs_remove_one_larger() */ /*------------------------------------------------------------------------- - * Function: test_abs_skip_2nd_block_add_skipped + * Function: test_abs_remove_two_larger * - * Purpose: Test inserting object into absolute heap which is small - * enough for starting block size, then add object too large - * for any blocks in first row of direct blocks, to force - * early creation of indirect block (and range of skipped blocks). - * Then add more objects to fill up remainder of initial direct - * block and all the skipped blocks, and one more object (to - * start next "normal" block). + * Purpose: Test removing two larger (but < standalone size) objects + * from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, April 1, 2006 + * Saturday, June 10, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -5161,10 +5486,15 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes 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 */ size_t id_len; /* Size of fractal heap IDs */ - size_t obj_size; /* Size of object */ + 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 */ - unsigned v; /* Local index variables */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5178,7 +5508,7 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes 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 @@ -5189,23 +5519,53 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes 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 inserting first (small) object into absolute heap + * Test removing two larger objects from absolute heap */ - TESTING("insert object to initial block, then add object too large for starting direct blocks, then backfill and extend"); + 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)") - /* Insert small object, to create root direct block */ - state.heap_size = DBLOCK_SIZE(fh, 0); - 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, 10, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5214,42 +5574,29 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes FAIL_STACK_ERROR } /* end if */ - /* Insert large object, to force creation of indirect block and - * range of skipped blocks that are too small to hold the second object - */ - obj_size = DBLOCK_SIZE(fh, 0) + 1; - state.heap_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - state.man_size += (cparam->managed.width - 1) * 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 - 1 )* DBLOCK_FREE(fh, 0); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Check up on heap... */ + for(u = 0; u < 4; u++) { + state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.nobjs = 1; + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Set up second object to insert */ + obj_len = DBLOCK_SIZE(fh, 4) + 1; + obj = shared_wobj_g; - /* Insert an object to fill up the (smaller) heap block just created */ - obj_size = DBLOCK_FREE(fh, 0) - SMALL_OBJ_SIZE1; - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* 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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5258,38 +5605,84 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes FAIL_STACK_ERROR } /* end if */ - /* Fill remainder of 2 * start size block */ - obj_size = DBLOCK_FREE(fh, 2) - (DBLOCK_SIZE(fh, 0) + 1); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Check up on heap... */ + /* (Goes to 8 rows because of doubling) */ + for(u = 4; u < 8; u++) { + state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.nobjs = 2; + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_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 - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 3); + state.man_free_space += DBLOCK_SIZE(fh, 2) + 1; + state.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 - /* Insert objects to fill remaining rows of the starting block size */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Fill remainder of first row of direct heap blocks up */ - for(v = 0; v < (cparam->managed.width - 1); v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(fill_heap(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + /* (Goes to 4 rows because of halving) */ + for(u = 4; u < 8; u++) { + state.heap_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.nobjs = 1; + if(check_stats(fh, &state)) FAIL_STACK_ERROR - } /* end for */ - /* Fill second row of direct blocks */ - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - 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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5298,9 +5691,13 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes FAIL_STACK_ERROR } /* end if */ - /* Insert one more object, to create new 2 * start size direct block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 2); - if(add_obj(fh, dxpl, 10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + state.heap_size = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.nobjs = 0; + if(check_stats(fh, &state)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -5311,6 +5708,18 @@ test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_tes 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() @@ -5323,33 +5732,26 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_skip_2nd_block_add_skipped() */ +} /* test_abs_remove_two_larger() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_one_partial_skip_2nd_block_add_skipped - * - * Purpose: Test filling initial direct block, then add object small enough - * for initial block size (to create root indirect block), then - * add object too large for any blocks in first three rows of - * direct blocks, to force extension of indirect block (and range - * of skipped blocks). + * Function: test_abs_remove_three_larger * - * Then add more objects to fill up remainder of partial direct - * block and all the skipped blocks, and one more object (to - * start next "normal" block). + * Purpose: Test removing three larger (but < standalone size) objects + * from heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 3, 2006 + * Monday, June 12, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -5357,8 +5759,14 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_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 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 */ - size_t obj_size; /* Size of object */ + 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 */ unsigned u; /* Local index variable */ @@ -5374,7 +5782,7 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * 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 @@ -5385,70 +5793,53 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* - * Test absolute heap - */ - TESTING("skipping blocks with indirect root, then backfill and extend"); - - /* Fill initial direct block */ - state.heap_size = DBLOCK_SIZE(fh, 0); - 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Prepare for querying the size of a file with an empty heap */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Insert small object, to create root indirect block */ - state.heap_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0); - state.man_size += (cparam->managed.width - 1) * 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, 10, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 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 heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Insert large object, to force creation of indirect block and - * range of skipped blocks that are too small to hold the large object + /* 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 */ - obj_size = DBLOCK_SIZE(fh, 2) + 1; - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - 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, 3); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); - 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, 10, obj_size, &state, NULL)) + 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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5457,14 +5848,29 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * FAIL_STACK_ERROR } /* end if */ - /* Insert an object to fill up the (smaller) heap block just created */ - obj_size = DBLOCK_FREE(fh, 0) - SMALL_OBJ_SIZE1; - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + for(u = 0; u < 4; u++) { + state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5473,14 +5879,30 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * FAIL_STACK_ERROR } /* end if */ - /* Insert object to fill remainder of 4 * start size block */ - obj_size = DBLOCK_FREE(fh, 3) - (DBLOCK_SIZE(fh, 2) + 1); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + /* (Goes to 8 rows because of doubling) */ + for(u = 4; u < 8; u++) { + state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5489,47 +5911,134 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * FAIL_STACK_ERROR } /* end if */ - /* Insert objects to fill remaining heaps in first row */ - for(u = 0; u < (cparam->managed.width - 2); u++) { - /* Fill a direct heap block up */ - state.man_alloc_size += DBLOCK_SIZE(fh, 0); - if(fill_heap(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Check up on heap... */ + /* (Goes to 16 rows because of doubling) */ + for(u = 8; u < 16; u++) { + state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.nobjs = 3; + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_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 - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 3); + state.man_free_space += DBLOCK_SIZE(fh, 2) + 1; + state.nobjs = 2; + if(check_stats(fh, &state)) FAIL_STACK_ERROR - } /* end if */ - /* Insert objects to fill remaining heaps in second row */ - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - 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(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + state.man_alloc_size -= DBLOCK_SIZE(fh, 5); + state.man_free_space += DBLOCK_SIZE(fh, 4) + 1; + state.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 - /* Insert objects to fill remaining heaps in third row */ - if(fill_row(fh, dxpl, 2, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + /* (Goes to 8 rows because of halving) */ + for(u = 8; u < 16; u++) { + state.heap_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.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(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + /* (Goes to 4 rows because of halving) */ + for(u = 4; u < 8; u++) { + state.heap_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; + 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.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(tparam->reopen_heap) { - /* Close heap */ + /* Close (empty) heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -5538,9 +6047,13 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * FAIL_STACK_ERROR } /* end if */ - /* Insert one more object, to create new 4 * start size direct block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, 10, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + state.heap_size = 0; + state.man_size = 0; + state.man_alloc_size = 0; + state.man_free_space = 0; + state.nobjs = 0; + if(check_stats(fh, &state)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -5551,6 +6064,18 @@ test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t * 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() @@ -5563,32 +6088,28 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_one_partial_skip_2nd_block_add_skipped() */ - +} /* test_abs_remove_three_larger() */ +#endif /* QAK */ + +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_fill_row_skip_add_skipped - * - * Purpose: Test filling first row of direct blocks, then - * add object too large for any blocks in first three rows of - * direct blocks, to force extension of indirect block (and range - * of skipped blocks). + * Function: test_abs_remove_root_direct * - * Then add more objects to fill up remainder of partial direct - * block and all the skipped blocks, and one more object (to - * start next "normal" block). + * Purpose: Test filling and removing all objects from root direct block in + * heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 15, 2006 + * Monday, May 22, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -5596,9 +6117,15 @@ test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test 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 */ size_t id_len; /* Size of fractal heap IDs */ - size_t obj_size; /* Size of object */ + 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 */ + const char *base_desc = "removing all objects from root direct block of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5612,7 +6139,7 @@ test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test 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 @@ -5623,73 +6150,57 @@ test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* - * Test absolute heap - */ - TESTING("filling first row, then skipping rows, then backfill and extend"); - - /* Fill first row of direct blocks */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Prepare for querying the size of a file with an empty heap */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Insert large object, to force creation of indirect block and - * range of skipped blocks that are too small to hold the large object - */ - obj_size = DBLOCK_SIZE(fh, 2) + 1; - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); - 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, 3); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); - 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 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 heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Insert object to fill remainder of 4 * start size block */ - obj_size = DBLOCK_FREE(fh, 3) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* 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 - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Test filling & removing all (small) objects from root direct block of absolute heap + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Insert objects to fill remaining heaps in second row */ - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill the heap up */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5703,24 +6214,12 @@ test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test FAIL_STACK_ERROR } /* end if */ - /* Insert objects to fill remaining heaps in third row */ - if(fill_row(fh, dxpl, 2, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert one more object, to create new 4 * start size direct block */ - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR /* Close the fractal heap */ @@ -5731,6 +6230,19 @@ test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test 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 + + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -5738,33 +6250,36 @@ test_abs_fill_row_skip_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_row_skip_add_skipped() */ +} /* test_abs_remove_root_direct() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_direct_skip_indirect_start_block_add_skipped + * Function: test_abs_remove_two_direct * - * Purpose: Test filling all direct blocks in root indirect block, then - * add object too large for initial block in first row of direct - * blocks in indirect block, to force extension of non-root - * indirect block (and range of skipped blocks). + * Purpose: Test filling and removing all objects from (first) two direct + * blocks in heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 3, 2006 + * Monday, May 22, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -5772,9 +6287,15 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea 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 */ size_t id_len; /* Size of fractal heap IDs */ - size_t obj_size; /* Size of object */ + 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 */ + const char *base_desc = "removing all objects from two direct blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5788,7 +6309,7 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea 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 @@ -5799,33 +6320,60 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea 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 - /* - * Test absolute heap - */ - TESTING("filling direct blocks and skipping blocks in non-root indirect block, then backfill and extend"); + /* Prepare for querying the size of a file with an empty heap */ - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ - /* Insert large object, to force creation of indirect block and - * range of skipped blocks that are too small to hold the large object + /* 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 filling & removing all (small) objects from two direct blocks of absolute heap */ - obj_size = DBLOCK_SIZE(fh, 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill the first block in heap */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5839,10 +6387,16 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea FAIL_STACK_ERROR } /* end if */ - /* Add rows of blocks to "backfill" direct blocks that were skipped */ - if(fill_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + + /* Fill the second block in heap */ + state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -5856,51 +6410,39 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea FAIL_STACK_ERROR } /* end if */ - /* Insert an object to fill up the (biggest) heap block created */ - obj_size = DBLOCK_FREE(fh, 3) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill direct block heaps with 2 * initial block size in nested indirect block */ - if(fill_row(fh, dxpl, 2, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert one more object, to create new 4 * start size direct block */ - obj_size = SMALL_OBJ_SIZE1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + fh = NULL; /* 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 +#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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -5908,34 +6450,36 @@ test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_crea error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_direct_skip_indirect_start_block_add_skipped() */ +} /* test_abs_remove_two_direct() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped + * Function: test_abs_remove_first_row * - * Purpose: Test filling all direct blocks in root indirect block, then - * add object too large for all direct blocks in first row of - * indirect blocks, to force skipping a row of indirect blocks - * (and range of skipped blocks), then backfill all direct blocks - * skipped and extend to next "normal" direct block. + * Purpose: Test filling and removing all objects from first row of direct + * blocks in heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 3, 2006 + * Monday, June 5, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -5943,12 +6487,15 @@ test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_ 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - unsigned row; /* Current row in indirect block */ - size_t obj_size; /* Size of object */ + 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 */ + const char *base_desc = "removing all objects from first row of direct blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -5962,7 +6509,7 @@ test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_ 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 @@ -5973,83 +6520,58 @@ test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_ if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* 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 */ - - /* - * Test absolute heap - */ - TESTING("filling direct blocks and skipping row of non-root indirect blocks, then backfill and extend"); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Prepare for querying the size of a file with an empty heap */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 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) + 1; + /* 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 #ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_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, 20, obj_size, &state, NULL)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Test filling & removing all (small) objects from first row of direct blocks of absolute heap + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill all rows of direct blocks that are smaller than large object's block size */ - for(row = 0; row < num_first_indirect_rows; row++) { - /* Fill rows of direct blocks in skipped indirect blocks */ - for(u = 0; u < cparam->managed.width; u++) - if(fill_row(fh, dxpl, row, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill first row of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */ - if(fill_row(fh, dxpl, row, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -6062,19 +6584,38 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - FAIL_STACK_ERROR + TEST_ERROR + fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) - FAIL_STACK_ERROR + TEST_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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); /* All tests passed */ PASSED() @@ -6083,35 +6624,36 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped() */ +} /* test_abs_remove_first_row() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped + * Function: test_abs_remove_first_two_rows * - * Purpose: Test filling all direct blocks in root indirect block and all - * direct blocks in 2nd level indirect blocks, except the last - * one, then insert object insert object that is too large to - * hold in row of 2nd level indirect blocks (forcing the use of - * the next row of 2nd level blocks), then backfill all skipped - * direct blocks & extend. + * Purpose: Test filling and removing all objects from first two rows of + * direct blocks in heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 18, 2006 + * Monday, June 12, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -6119,11 +6661,15 @@ test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_ 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - size_t obj_size; /* Size of object */ + 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 variables */ + const char *base_desc = "removing all objects from first two rows of direct blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -6137,7 +6683,7 @@ test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_ 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 @@ -6148,76 +6694,58 @@ test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_ 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - /* - * Test absolute heap - */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, except last one, and insert object too large for 2nd level indirect blocks, then backfill and extend"); + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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 - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill first row (except one) of 2nd level indirect blocks */ - for(u = 0; u < cparam->managed.width - 1; u++) - /* Fill all rows of 2nd level indirect blocks in root block */ - if(fill_2nd_indirect(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object + /* + * Test filling & removing all (small) objects from first row of direct blocks of absolute heap */ - 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* 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, 20, obj_size, &state, NULL)) + /* Fill first two rows of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_root_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -6231,44 +6759,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* Fill rows skipped over in 2nd level indirect block's direct blocks - * (and rows of next 2nd level indirect block's direct blocks) - */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in skipped 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in current 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + fh = NULL; /* 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 +#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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -6276,38 +6799,36 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ +} /* test_abs_remove_first_two_rows() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped + * Function: test_abs_remove_first_four_rows * - * Purpose: Test filling all direct blocks in root indirect block, then - * add object too large for all direct blocks in first row of - * indirect blocks, to force skipping a row of indirect blocks - * (and range of skipped blocks), then add object that is too - * large for initial block size in skipped indirect blocks, then - * backfill all direct blocks and extend to next "normal" direct - * block (but insert first block of backfilling with object - * too large for initial block size in skipped indirect block - * row's direct blocks). + * 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, April 11, 2006 + * Tuesday, June 13, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -6315,12 +6836,15 @@ test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - unsigned row; /* Current row in indirect block */ - size_t obj_size; /* Size of object */ + 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 */ + const char *base_desc = "removing all objects from first four rows of direct blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -6334,7 +6858,7 @@ test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5 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 @@ -6345,59 +6869,62 @@ test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - /* - * Test absolute heap - */ - TESTING("filling direct blocks and skipping row of non-root indirect blocks, then skip row of direct blocks, then backfill and extend"); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 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 - } /* end if */ + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object + /* + * Test filling & removing all (small) objects from first row of direct blocks of absolute heap */ - 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* 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, 20, obj_size, &state, NULL)) + /* Fill first two rows of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_root_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_root_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_root_row(fh, dxpl, 3, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -6411,102 +6938,38 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* Insert object too large for initial block size in skipped indirect blocks */ - obj_size = DBLOCK_SIZE(fh, 3) + 1; -#ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); -#endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, 4); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + fh = NULL; - /* Insert object to fill space in (medium) block just created */ - obj_size = DBLOCK_FREE(fh, 4) - obj_size; + /* 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 #ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); #endif /* QAK */ - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Finish off blocks in row of medium block size (just to make row filling easier below) */ - obj_size = DBLOCK_FREE(fh, 4); - for(u = 1; u < cparam->managed.width; u++) { - state.man_alloc_size += DBLOCK_SIZE(fh, 4); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all rows of direct blocks that are smaller than large object's block size */ - for(row = 0; row < num_first_indirect_rows; row++) { - /* Fill rows of direct blocks in skipped indirect blocks */ - for(u = 0; u < cparam->managed.width; u++) - if(fill_row(fh, dxpl, row, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */ - /* (Skip the row of blocks filled above) */ - if(row != 4) - if(fill_row(fh, dxpl, row, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end while */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Close the fractal heap */ - if(H5HF_close(fh, dxpl) < 0) + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR - /* Close the file */ - if(H5Fclose(file) < 0) - TEST_ERROR + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); /* All tests passed */ PASSED() @@ -6515,33 +6978,36 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped() */ +} /* test_abs_remove_first_four_rows() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_direct_skip_indirect_two_rows_add_skipped + * Function: test_abs_remove_all_root_direct * - * Purpose: Test filling all direct blocks in root indirect block, then - * add object too large for initial block in first two rows of - * indirect blocks, to force extension of non-root - * indirect block (and range of skipped blocks). + * 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 - * Saturday, April 15, 2006 + * Tuesday, June 13, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -6549,12 +7015,15 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - unsigned max_dblock_rows; /* Max. # of rows (of direct blocks) in the root indirect block */ - size_t obj_size; /* Size of object */ + 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, v; /* Local index variables */ + const char *base_desc = "removing all objects from all direct blocks of root group in absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -6568,7 +7037,7 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ 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 @@ -6579,100 +7048,57 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); - max_dblock_rows = DTABLE_MAX_DROWS(fh); - - /* - * Test absolute heap - */ - TESTING("filling direct blocks and skipping two rows of root indirect block, then backfill and extend"); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert large object, to force creation of indirect block and - * range of skipped blocks that are too small to hold the large object - */ - obj_size = DBLOCK_SIZE(fh, max_dblock_rows - 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Prepare for querying the size of a file with an empty heap */ - /* Insert an object to fill up the (biggest) heap block created */ - obj_size = DBLOCK_FREE(fh, max_dblock_rows - 1) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ - /* Fill rows skipped over in indirect block's direct blocks */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in first row of skipped 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Direct block rows in second row of skipped 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - /* Direct block row in used 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Test filling & removing all (small) objects from first row of direct blocks of absolute heap + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */ + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* Direct block rows in skipped 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, num_first_indirect_rows, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -6685,35 +7111,39 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ FAIL_STACK_ERROR } /* end if */ - /* Direct block row in used 2nd level indirect block */ - if(fill_row(fh, dxpl, num_first_indirect_rows, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + fh = NULL; /* 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 +#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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -6721,35 +7151,36 @@ test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_direct_skip_indirect_two_rows_add_skipped() */ +} /* test_abs_remove_all_root_direct() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped + * Function: test_abs_remove_2nd_indirect * - * Purpose: Test filling all direct blocks in root indirect block, then - * add object too large for initial block in first two rows of - * indirect blocks, to force extension of non-root - * indirect block, then add object too large for first row of - * indirect blocks, (and ranges of skipped blocks), then backfill - * and extend. + * Purpose: Test filling and removing all objects up to 2nd level indirect + * blocks of heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, July 11, 2006 + * Tuesday, June 13, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_remove_2nd_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 */ @@ -6757,12 +7188,15 @@ test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ - unsigned max_dblock_rows; /* Max. # of rows (of direct blocks) in the root indirect block */ - size_t obj_size; /* Size of object */ + 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, v; /* Local index variables */ + const char *base_desc = "removing all objects from 2nd level indirect blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -6776,7 +7210,7 @@ test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t 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 @@ -6787,142 +7221,62 @@ test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); - max_dblock_rows = DTABLE_MAX_DROWS(fh); - - /* - * Test absolute heap - */ - TESTING("filling direct blocks and skipping two rows of root indirect block, skip one row of root indirect block, then backfill and extend"); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Prepare for querying the size of a file with an empty heap */ - /* Insert large object, to force creation of two rows of indirect blocks and - * range of skipped blocks that are too small to hold the large object - */ - obj_size = DBLOCK_SIZE(fh, max_dblock_rows - 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ - /* Insert an object to fill up the (biggest) heap block created */ - obj_size = DBLOCK_FREE(fh, max_dblock_rows - 1) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 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 - } /* end if */ + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR - /* Insert large object that can't fit in first row of indirect blocks - * previously skipped, but is small enough to fit into second row of - * skipped blocks. + /* + * Test filling & removing all (small) objects from first row of direct blocks of absolute heap */ - obj_size = DBLOCK_SIZE(fh, max_dblock_rows - 3) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 2); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* Insert an object to fill up the (2nd biggest) heap block created */ - obj_size = DBLOCK_FREE(fh, max_dblock_rows - 2) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill rows skipped over in indirect block's direct blocks */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in first row of skipped 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block rows in second row of skipped 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in used 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { /* Close heap */ @@ -6934,35 +7288,39 @@ test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t FAIL_STACK_ERROR } /* end if */ - /* Direct block row in used 3rd row 2nd level indirect block */ - if(fill_row(fh, dxpl, num_first_indirect_rows, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR + fh = NULL; /* 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 +#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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -6970,44 +7328,61 @@ test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(hid_t error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped() */ +} /* test_abs_remove_2nd_indirect() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_2nd_direct_skip_start_block_add_skipped + * Function: test_abs_remove_3rd_indirect * - * 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. + * Purpose: Test filling and removing all objects up to 3rd level indirect + * blocks of heap * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 11, 2006 + * Monday, July 24, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_remove_3rd_indirect(hid_t +#ifdef LATER + UNUSED +#endif /* LATER */ + fapl, H5HF_create_t +#ifdef LATER + UNUSED +#endif /* LATER */ + *cparam, fheap_test_param_t *tparam) { +#ifndef LATER hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ char filename[1024]; /* Filename to use */ H5F_t *f = NULL; /* Internal file object pointer */ H5HF_t *fh = NULL; /* Fractal heap wrapper */ haddr_t fh_addr; /* Address of fractal heap */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal heap IDs */ - size_t obj_size; /* Size of object */ + 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 */ + const char *base_desc = "removing all objects from 3rd level indirect blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7021,7 +7396,7 @@ test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t 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 @@ -7032,84 +7407,70 @@ test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* - * Test absolute heap - */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, and skip first rows of direct blocks of 3rd level indirect block, then backfill and extend"); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Prepare for querying the size of a file with an empty heap */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Close file */ + if(H5Fclose(file)<0) TEST_ERROR; - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = DBLOCK_SIZE(fh, 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, 3) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR +#else /* LATER */ + const char *base_desc = "removing all objects from 3rd level indirect blocks of absolute heap %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ +#endif /* LATER */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ +#ifndef LATER + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill rows skipped over in 3rd level indirect block's direct blocks */ - if(fill_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - if(fill_row(fh, dxpl, 2, SMALL_OBJ_SIZE1, &state, NULL)) + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7123,57 +7484,87 @@ test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t FAIL_STACK_ERROR } /* end if */ - /* 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, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() +#else /* LATER */ + SKIPPED(); + puts(" Takes too long right now"); +#endif /* LATER */ return(0); +#ifndef LATER error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_2nd_direct_skip_start_block_add_skipped() */ +#endif /* LATER */ +} /* test_abs_remove_3rd_indirect() */ +#endif /* QAK */ +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped + * Function: test_abs_skip_start_block * - * 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. + * Purpose: Test inserting object into absolute heap which is too large + * for starting block size, which forces root indirect block + * creation + * + * Then, remove all the objects, in various ways * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 11, 2006 + * Monday, March 27, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_skip_start_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -7181,9 +7572,15 @@ test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H 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 */ 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 obj_size; /* Size of object */ fheap_heap_state_t state; /* State of fractal heap */ + const char *base_desc = "inserting object that is too large for starting block, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7208,80 +7605,64 @@ test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR HDmemset(&state, 0, sizeof(fheap_heap_state_t)); - - /* - * Test absolute heap - */ - TESTING("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"); - - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Prepare for querying the size of a file with an empty heap */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close file */ + if(H5Fclose(file)<0) + TEST_ERROR - /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = DBLOCK_SIZE(fh, 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, 3); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Insert object to fill space in (large) block created */ - obj_size = DBLOCK_FREE(fh, 3) - obj_size; - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + obj_size = DBLOCK_SIZE(fh, 0) + 1; + state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + 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 += cparam->managed.width * DBLOCK_FREE(fh, 2); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7295,77 +7676,77 @@ test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H FAIL_STACK_ERROR } /* end if */ - /* Fill rows skipped over in (3rd level indirect block's) 2nd level - * indirect block's direct blocks - */ - if(fill_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - if(fill_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - if(fill_row(fh, dxpl, 2, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) - TEST_ERROR + FAIL_STACK_ERROR - /* All tests passed */ - PASSED() + /* 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 */ - return(0); + /* Verify the file is correct size */ + if(file_size != empty_size) + 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); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped() */ +} /* test_abs_skip_start_block() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped + * Function: test_abs_skip_start_block_add_back * - * 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. + * Purpose: Test inserting object into absolute heap which is too large + * for starting block size, which forces root indirect block + * creation, then add object which fits in skipped direct block * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 11, 2006 + * Tuesday, March 28, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_skip_start_block_add_back(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -7373,11 +7754,15 @@ test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(h 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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ size_t obj_size; /* Size of object */ fheap_heap_state_t state; /* State of fractal heap */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "skipping starting block, then adding object back to first block, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7402,50 +7787,65 @@ test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(h 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 - /* 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 */ + /* Prepare for querying the size of a file with an empty heap */ - /* - * Test absolute heap - */ - TESTING("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"); + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Close file */ + if(H5Fclose(file)<0) + TEST_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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 - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert object too large for starting block size */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + 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 += cparam->managed.width * DBLOCK_FREE(fh, 2); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7459,16 +7859,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = 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, 20, obj_size, &state, NULL)) + /* Insert an object to fill up the heap block just created */ + obj_size = DBLOCK_FREE(fh, 2) - obj_size; + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7482,9 +7875,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) + /* Insert second "real" object, which should go in earlier direct block */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, 20, SMALL_OBJ_SIZE2, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7498,46 +7891,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in 3rd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -7545,36 +7931,38 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ +} /* test_abs_skip_start_block_add_back() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped + * Function: test_abs_skip_start_block_add_skipped * - * Purpose: Test filling all direct blocks in root indirect block and all - * direct blocks in 2nd level indirect blocks, fill all direct - * blocks 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. + * Purpose: Test inserting object into absolute heap which is too large + * for starting block size, which forces root indirect block + * creation, then add objects to fill skipped direct blocks + * and add another object to start on next "normal" block * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 11, 2006 + * Tuesday, March 28, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_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_abs_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -7582,11 +7970,16 @@ test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped( 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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "skipping starting block, then adding objects to backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7611,35 +8004,68 @@ test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped( 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("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"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert object too large for starting block size */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + 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 += cparam->managed.width * DBLOCK_FREE(fh, 2); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7653,8 +8079,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in third level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert an object to fill up the heap block just created */ + obj_size = DBLOCK_FREE(fh, 2) - obj_size; + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7668,16 +8095,10 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = 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, 20, obj_size, &state, NULL)) + /* Add rows of blocks to "backfill" direct blocks that were skipped */ + if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7691,12 +8112,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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 */ - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Insert another object, which should extend direct blocks, instead of backfill */ + state.man_alloc_size += DBLOCK_SIZE(fh, 2); + if(add_obj(fh, dxpl, 20, SMALL_OBJ_SIZE2, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7710,50 +8128,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in 3rd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Fill row of direct blocks in second 3rd level indirect block */ - if(fill_row(fh, dxpl, num_first_indirect_rows, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -7761,37 +8168,38 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped() */ +} /* test_abs_skip_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped + * Function: test_abs_skip_2nd_block * - * 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. + * Purpose: Test inserting object into absolute heap which is small + * enough for starting block size, then add object too large + * for any blocks in first row of direct blocks, to force + * early creation of indirect block (and range of skipped blocks) * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tues, April 18, 2006 + * Saturday, April 1, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_skip_2nd_block(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -7799,11 +8207,15 @@ test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ size_t obj_size; /* Size of object */ fheap_heap_state_t state; /* State of fractal heap */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "insert object to initial block, then add object too large for starting direct blocks, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -7828,35 +8240,58 @@ test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - /* - * Test absolute heap - */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling first row of 3rd level indirect blocks, except last one, fill all direct blocks in last 3rd level indirect block, and insert object too large for it's 2nd level indirect blocks, then backfill and extend"); + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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 - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill all rows of 2nd level indirect blocks in root indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert small object, to create root direct block */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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, 10, SMALL_OBJ_SIZE1, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -7870,11 +8305,22 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Insert large object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the second object + */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + state.heap_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.man_size += (cparam->managed.width - 1) * 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 - 1 )* DBLOCK_FREE(fh, 0); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -7887,138 +8333,81 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in last third level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; - /* 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; + /* 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, "obj_size = %Zu\n", obj_size); +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); #endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Verify the file is correct size */ + if(file_size != empty_size) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); - /* 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill rows skipped over in 2nd level indirect block's direct blocks - * (and rows of next 3rd level indirect block's direct blocks) - */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in current 3rd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Close the fractal heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Close the file */ - if(H5Fclose(file) < 0) - TEST_ERROR - - /* All tests passed */ - PASSED() + /* 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); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped() */ +} /* test_abs_skip_2nd_block() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped + * Function: test_abs_skip_2nd_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. + * Purpose: Test inserting object into absolute heap which is small + * enough for starting block size, then add object too large + * for any blocks in first row of direct blocks, to force + * early creation of indirect block (and range of skipped blocks). + * Then add more objects to fill up remainder of initial direct + * block and all the skipped blocks, and one more object (to + * start next "normal" block). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tues, April 18, 2006 + * Saturday, April 1, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -8026,11 +8415,17 @@ test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_s 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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u; /* Local index variables */ + const char *base_desc = "insert object to initial block, then add object too large for starting direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -8055,20 +8450,61 @@ test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_s 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling first row of 3rd level indirect blocks, fill all direct blocks in next 3rd level indirect block, fill all 1st row of 2nd level indirect blocks, except last one, and insert object too large for 2nd level indirect block, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Insert small object, to create root direct block */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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, 10, SMALL_OBJ_SIZE1, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8082,8 +8518,21 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert large object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the second object + */ + obj_size = DBLOCK_SIZE(fh, 0) + 1; + state.heap_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.man_size += (cparam->managed.width - 1) * 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 - 1 )* DBLOCK_FREE(fh, 0); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 2); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8097,8 +8546,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill first row of 3rd level indirect blocks */ - if(fill_3rd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert an object to fill up the (smaller) heap block just created */ + obj_size = DBLOCK_FREE(fh, 0) - SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8112,8 +8562,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in 2nd row third level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill remainder of 2 * start size block */ + obj_size = DBLOCK_FREE(fh, 2) - (DBLOCK_SIZE(fh, 0) + 1); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8127,32 +8578,17 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Insert objects to fill remaining rows of the starting block size */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Fill remainder of first row of direct heap blocks up */ + for(v = 0; v < (cparam->managed.width - 1); v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - } /* end if */ + } /* 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, 20, obj_size, &state, NULL)) + /* Fill second row of direct blocks */ + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8166,9 +8602,9 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) + /* Insert one more object, to create new 2 * start size direct block */ + state.man_alloc_size += DBLOCK_SIZE(fh, 2); + if(add_obj(fh, dxpl, 10, SMALL_OBJ_SIZE1, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8182,44 +8618,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* Fill rows skipped over in 2nd level indirect block's direct blocks - * (and rows of next 2nd level indirect block's direct blocks) - */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in skipped 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in current 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -8227,36 +8658,43 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ +} /* test_abs_skip_2nd_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped + * Function: test_abs_fill_one_partial_skip_2nd_block_add_skipped * - * Purpose: Test filling all direct blocks in root indirect block and all - * direct blocks in 2nd level indirect blocks, fill all direct - * blocks and indirect blocks in 3rd level indirect block, then - * fill all direct blocks in 4th level indirect block, then - * insert object that is too large to hold in first row of 2nd - * level indirect blocks of 4th level indirect block, then - * backfill all skipped direct blocks & extend. + * Purpose: Test filling initial direct block, then add object small enough + * for initial block size (to create root indirect block), then + * add object too large for any blocks in first three rows of + * direct blocks, to force extension of indirect block (and range + * of skipped blocks). + * + * Then add more objects to fill up remainder of partial direct + * block and all the skipped blocks, and one more object (to + * start next "normal" block). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, April 15, 2006 + * Monday, April 3, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_one_partial_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -8264,11 +8702,17 @@ test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5 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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "skipping blocks with indirect root, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -8293,20 +8737,61 @@ test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill 4th level indirect block's direct blocks, and skip first row of 2nd indirect blocks of 4th level indirect block, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill initial direct block */ + state.heap_size = DBLOCK_SIZE(fh, 0); + 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8320,8 +8805,12 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert small object, to create root indirect block */ + state.heap_size += (cparam->managed.width - 1) * DBLOCK_SIZE(fh, 0); + state.man_size += (cparam->managed.width - 1) * 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, 10, SMALL_OBJ_SIZE1, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8335,8 +8824,21 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert large object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the large object + */ + obj_size = DBLOCK_SIZE(fh, 2) + 1; + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + 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, 3); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8350,8 +8852,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in fourth level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert an object to fill up the (smaller) heap block just created */ + obj_size = DBLOCK_FREE(fh, 0) - SMALL_OBJ_SIZE1; + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8365,16 +8868,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = 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, 20, obj_size, &state, NULL)) + /* Insert object to fill remainder of 4 * start size block */ + obj_size = DBLOCK_FREE(fh, 3) - (DBLOCK_SIZE(fh, 2) + 1); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8388,9 +8884,27 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) + /* Insert objects to fill remaining heaps in first row */ + for(u = 0; u < (cparam->managed.width - 2); u++) { + /* Fill a direct heap block up */ + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(fill_heap(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert objects to fill remaining heaps in second row */ + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8404,20 +8918,25 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* Fill rows skipped over in (first 4th level indirect block's) 2nd level - * indirect block's direct blocks - * (and second row of 2nd level indirect block's direct blocks) - */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Insert objects to fill remaining heaps in third row */ + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Direct block row in 2nd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - } /* end for */ + } /* end if */ + + /* Insert one more object, to create new 4 * start size direct block */ + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, 10, SMALL_OBJ_SIZE1, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -8430,20 +8949,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, 10, obj_size, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -8451,38 +8989,42 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */ +} /* test_abs_fill_one_partial_skip_2nd_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped + * Function: test_abs_fill_row_skip_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. + * Purpose: Test filling first row of direct blocks, then + * add object too large for any blocks in first three rows of + * direct blocks, to force extension of indirect block (and range + * of skipped blocks). + * + * Then add more objects to fill up remainder of partial direct + * block and all the skipped blocks, and one more object (to + * start next "normal" block). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 17, 2006 + * Monday, May 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_row_skip_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 */ @@ -8490,11 +9032,16 @@ test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_blo 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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "filling first row, then skipping rows, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -8519,20 +9066,57 @@ test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_blo 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill 4th level indirect block's direct, 2nd level indirect blocks and 3rd level direct block, and skip first row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill first row of direct blocks */ + if(fill_root_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8546,23 +9130,21 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert large object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the large object + */ + obj_size = DBLOCK_SIZE(fh, 2) + 1; + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 2); + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 3); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, 1); + 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, 3); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, 1); + 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, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8576,8 +9158,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in fourth level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert object to fill remainder of 4 * start size block */ + obj_size = DBLOCK_FREE(fh, 3) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8591,8 +9174,8 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks in fourth level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert objects to fill remaining heaps in second row */ + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8606,8 +9189,8 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in fourth level indirect block's 3rd level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert objects to fill remaining heaps in third row */ + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8621,16 +9204,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = 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, 20, obj_size, &state, NULL)) + /* Insert one more object, to create new 4 * start size direct block */ + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8644,62 +9220,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill rows skipped over in (first 4th level indirect block's first 3rd - * level block's) 2nd level indirect block's direct blocks - * (and rows of 2nd 3rd level indirect block's direct blocks) - */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in 3rd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -8707,40 +9260,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ +} /* test_abs_fill_row_skip_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped + * Function: test_abs_skip_direct_skip_indirect_two_rows_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. + * Purpose: Test adding object too large for all but the last row in the + * direct blocks in root indirect block, then + * add object too large for initial block in first two rows of + * indirect blocks, to force extension of non-root + * indirect block (and range of skipped blocks). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 17, 2006 + * Saturday, April 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -8748,11 +9300,18 @@ test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_ 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned num_direct_rows; /* Number of rows (of direct blocks) in root indirect block */ + unsigned row; /* Current row */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ size_t obj_size; /* Size of object */ fheap_heap_state_t state; /* State of fractal heap */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "skipping direct blocks to last row and skipping two rows of root indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -8777,37 +9336,90 @@ test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_ 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill first row of 4th level indirect blocks, fill 2nd row 4th level indirect block's direct, 2nd level indirect blocks, first row of 3rd level indirect blocks, 3rd level direct block in 2nd row, and skip first row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Compute # direct block rows in root indirect block */ + num_direct_rows = DTABLE_MAX_DROWS(fh); - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Compute heap size & free space when half direct blocks allocated */ + row = 0; + do { + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + row++; + } while(row < (num_direct_rows / 2)); - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert object to extend root block to middle of root direct blocks + */ + obj_size = DBLOCK_SIZE(fh, row - 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, row - 1); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR + /* Compute heap size & free space when all direct blocks allocated */ + do { + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + row++; + } while(row < num_direct_rows); + + /* Insert large objects into last row of direct blocks in root indirect + * block, to force extension of root indirect block that covers the first + * row of indirect blocks in root indirect block + */ + obj_size = DBLOCK_SIZE(fh, num_direct_rows - 2) + 1; + for(v = 0; v < cparam->managed.width; v++) { + state.man_alloc_size += DBLOCK_SIZE(fh, num_direct_rows - 1); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { /* Close heap */ @@ -8819,8 +9431,20 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Compute heap size & free space when root indirect block doubles again */ + do { + state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); + state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); + row++; + } while(row < (2 * num_direct_rows)); + + /* Insert large object, to force creation of indirect blocks with + * range of skipped blocks that are too small to hold the large object + */ + obj_size = DBLOCK_SIZE(fh, num_direct_rows - 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, num_direct_rows - 1); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -8834,177 +9458,38 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill first row of 4th level indirect blocks */ - if(fill_4th_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_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 */ + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Get some information for the heap */ - max_root_rows = HEAP_MAX_ROOT_ROWS(fh); + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; - /* Increase heap size & free space */ - for(row = 16; row < max_root_rows; row++) { - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 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(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all direct block rows in 2nd row 4th level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all rows of 2nd level indirect blocks in 2nd row 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill first row of 3rd level indirect blocks in 2nd row 4th level indirect block */ - if(fill_3rd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill all direct block rows in 4th level indirect block's 2nd row of 3rd level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Close the file */ + if(H5Fclose(file) < 0) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = DBLOCK_SIZE(fh, num_first_indirect_rows - 1) + 1; + /* Get the size of the file */ + if((file_size = h5_get_file_size(filename)) == 0) + TEST_ERROR #ifdef QAK -HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); #endif /* QAK */ - state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Fill rows skipped over in (first block in 2nd row 4th level indirect - * block's first 3rd level block's) 2nd level indirect block's direct - * blocks (and rows of 2nd 3rd level indirect block's direct blocks) - */ - for(u = 0; u < num_first_indirect_rows; u++) { - /* Direct block rows in 2nd level indirect blocks */ - for(v = 0; v < cparam->managed.width; v++) - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in 3rd level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - /* Close the fractal heap */ - if(H5HF_close(fh, dxpl) < 0) + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR - /* Close the file */ - if(H5Fclose(file) < 0) - TEST_ERROR + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); /* All tests passed */ PASSED() @@ -9013,42 +9498,38 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped() */ +} /* test_abs_skip_direct_skip_indirect_two_rows_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped + * Function: test_abs_fill_direct_skip_indirect_start_block_add_skipped * - * Purpose: Test filling all direct blocks in root indirect block and all - * direct blocks in 2nd level indirect blocks, fill all direct - * blocks and indirect blocks in 3rd level indirect block, 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 filling all direct blocks in root indirect block, then + * add object too large for initial block in first row of direct + * blocks in indirect block, to force extension of non-root + * indirect block (and range of skipped blocks). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 17, 2006 + * Monday, April 3, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_direct_skip_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -9056,11 +9537,16 @@ test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_star 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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "filling direct blocks and skipping blocks in non-root indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -9085,20 +9571,57 @@ test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_star 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill first row of 3rd level indirect blocks in 4th level indirect block except last 3rd level block, fill direct blocks in 3rd level block, and skip row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9112,8 +9635,12 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert large object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the large object + */ + obj_size = DBLOCK_SIZE(fh, 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9127,8 +9654,10 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Add rows of blocks to "backfill" direct blocks that were skipped */ + if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9142,8 +9671,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in 4th level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Insert an object to fill up the (biggest) heap block created */ + obj_size = DBLOCK_FREE(fh, 3) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9157,8 +9687,8 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill direct block heaps with 2 * initial block size in nested indirect block */ + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9172,16 +9702,11 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ - if(fill_2nd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ + /* Insert one more object, to create new 4 * start size direct block */ + obj_size = SMALL_OBJ_SIZE1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -9194,100 +9719,39 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* Insert large object, to force creation of indirect block and - * range of skipped (indirect) blocks that are too small to hold the large - * object - */ - obj_size = 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, 20, obj_size, &state, NULL)) + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 20, obj_size, &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(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Direct block row in 4th level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ - - /* 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, 10, obj_size, &state, NULL)) + /* Close the file */ + if(H5Fclose(file) < 0) FAIL_STACK_ERROR - /* Close the fractal heap */ - if(H5HF_close(fh, dxpl) < 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 */ - /* Close the file */ - if(H5Fclose(file) < 0) + /* Verify the file is correct size */ + if(file_size != empty_size) TEST_ERROR + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -9295,42 +9759,39 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +} /* test_abs_fill_direct_skip_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped + * Function: test_abs_fill_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 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 + * add object too large for all direct blocks in first row of + * indirect blocks, to force skipping a row of indirect blocks + * (and range of skipped blocks), then backfill all direct blocks + * skipped and extend to next "normal" direct block. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, April 17, 2006 + * Monday, April 3, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -9338,11 +9799,19 @@ test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_ 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 */ size_t id_len; /* Size of fractal heap IDs */ unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned row; /* Current row in indirect block */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + const char *base_desc = "filling direct blocks and skipping row of non-root indirect blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -9367,20 +9836,60 @@ test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_ 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 - /* Retrieve info about heap */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ + /* 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 absolute heap + * Display testing message */ - TESTING("filling direct blocks, filling 2nd level indirect blocks, filling 3rd level indirect blocks, fill first row of 4th level indirect blocks, except last one, fill first row of 3rd level indirect blocks in last 4th level indirect block except last 3rd level block, fill direct blocks in 3rd level block, and skip row of 2nd indirect blocks of 4th level indirect block's 3rd level indirect block, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9394,8 +9903,13 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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; + state.man_alloc_size += DBLOCK_SIZE(fh, num_first_indirect_rows); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9409,8 +9923,9 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 3rd level indirect blocks */ - if(fill_all_3rd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9424,18 +9939,15 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Fill all rows of direct blocks that are smaller than large object's block size */ + for(row = 0; row < num_first_indirect_rows; row++) { + /* Fill rows of direct blocks in skipped indirect blocks */ + for(u = 0; u < cparam->managed.width; u++) + if(fill_row(fh, dxpl, row, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Fill row of 3rd level indirect blocks in 4th level indirect block */ - if(fill_3rd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */ + if(fill_row(fh, dxpl, row, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR } /* end for */ @@ -9450,8 +9962,10 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all direct block rows in 4th level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9465,65 +9979,196 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks in 4th level indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Check up on heap... */ + if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Close the fractal heap */ + if(H5HF_close(fh, dxpl) < 0) + FAIL_STACK_ERROR + fh = NULL; - /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Close the file */ + if(H5Fclose(file) < 0) + FAIL_STACK_ERROR - /* Fill row of 2nd level indirect blocks in 3rd level indirect block */ - if(fill_2nd_indirect_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ + /* 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 */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Verify the file is correct size */ + if(file_size != empty_size) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Free resources */ + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); - /* Fill all direct block rows in 4th level indirect block's last 3rd level indirect block */ - if(fill_all_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* All tests passed */ + PASSED() - /* 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 */ + return(0); - /* Get some information for the heap */ - max_root_rows = HEAP_MAX_ROOT_ROWS(fh); +error: + H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped() */ - /* Increase heap size & free space */ - for(row = 16; row < max_root_rows; row++) { - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); - } /* end for */ + +/*------------------------------------------------------------------------- + * Function: test_abs_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, except the last + * one, then insert object insert object that is too large to + * hold in row of 2nd level indirect blocks (forcing the use of + * the next row of 2nd level blocks), then backfill all skipped + * direct blocks & extend. + * + * Return: Success: 0 + * + * Failure: 1 + * + * Programmer: Quincey Koziol + * Tuesday, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ + 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, except last one, and insert object too large for 2nd level indirect blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 + + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR } /* end if */ + /* Fill first row (except one) of 2nd level indirect blocks */ + for(u = 0; u < cparam->managed.width - 1; u++) + /* Fill all rows of 2nd level indirect blocks in root block */ + if(fill_2nd_indirect(fh, dxpl, 1, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { /* Close heap */ @@ -9544,7 +10189,7 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); 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, 20, obj_size, &state, NULL)) + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9560,7 +10205,7 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); /* 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, 20, obj_size, &state, NULL)) + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -9574,18 +10219,16 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); FAIL_STACK_ERROR } /* end if */ - /* 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) + /* 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, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Direct block rows in skipped 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Direct block row in 4th level indirect block */ - if(fill_row(fh, dxpl, u, SMALL_OBJ_SIZE1, &state, NULL)) + /* Direct block row in current 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR } /* end for */ @@ -9603,17 +10246,53 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); /* 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, 10, obj_size, &state, NULL)) + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -9621,34 +10300,43 @@ HDfprintf(stderr, "obj_size = %Zu\n", obj_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +} /* test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_skip_direct_skip_indirect_two_rows_add_skipped + * Function: test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped * - * Purpose: Test adding object too large for all but the last row in the - * direct blocks in root indirect block, then - * add object too large for initial block in first two rows of - * indirect blocks, to force extension of non-root - * indirect block (and range of skipped blocks). + * Purpose: Test filling all direct blocks in root indirect block, then + * add object too large for all direct blocks in first row of + * indirect blocks, to force skipping a row of indirect blocks + * (and range of skipped blocks), then add object that is too + * large for initial block size in skipped indirect blocks, then + * backfill all direct blocks and extend to next "normal" direct + * block (but insert first block of backfilling with object + * too large for initial block size in skipped indirect block + * row's direct blocks). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, April 15, 2006 + * Tuesday, April 11, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -9656,12 +10344,19 @@ test_abs_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned num_direct_rows; /* Number of rows (of direct blocks) in root indirect block */ - unsigned row; /* Current row */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned row; /* Current row in indirect block */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned v; /* Local index variables */ + const char *base_desc = "filling direct blocks and skipping row of non-root indirect blocks, then skip row of direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -9686,47 +10381,156 @@ test_abs_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ 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 - /* Compute # direct block rows in root indirect block */ - num_direct_rows = DTABLE_MAX_DROWS(fh); + /* Prepare for querying the size of a file with an empty heap */ - /* - * Test absolute heap - */ - TESTING("skipping direct blocks to last row and skipping two rows of root indirect block, then backfill and extend"); + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Compute heap size & free space when half direct blocks allocated */ - row = 0; - do{ - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); - row++; - } while(row < (num_direct_rows / 2)); + /* Close file */ + if(H5Fclose(file)<0) + TEST_ERROR - /* Insert object to extend root block to middle of root direct blocks + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 + + /* + * Display testing message */ - obj_size = DBLOCK_SIZE(fh, row - 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, row -1); - if(add_obj(fh, dxpl, 10, obj_size, &state, NULL)) + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) FAIL_STACK_ERROR - /* Compute heap size & free space when all direct blocks allocated */ - do{ - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); - row++; - } while(row < num_direct_rows); + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Insert large objects into last row of direct blocks in root indirect - * block, to force extension of root indirect block that covers the first - * row of indirect blocks in root indirect block + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object */ - obj_size = DBLOCK_SIZE(fh, num_direct_rows - 2) + 1; - for(v = 0; v < cparam->managed.width; v++) { - state.man_alloc_size += DBLOCK_SIZE(fh, num_direct_rows -1); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert object too large for initial block size in skipped indirect blocks */ + obj_size = DBLOCK_SIZE(fh, 3) + 1; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + state.man_alloc_size += DBLOCK_SIZE(fh, 4); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert object to fill space in (medium) block just created */ + obj_size = DBLOCK_FREE(fh, 4) - obj_size; +#ifdef QAK +HDfprintf(stderr, "obj_size = %Zu\n", obj_size); +#endif /* QAK */ + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Finish off blocks in row of medium block size (just to make row filling easier below) */ + obj_size = DBLOCK_FREE(fh, 4); + for(u = 1; u < cparam->managed.width; u++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 4); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR } /* end for */ @@ -9741,30 +10545,81 @@ test_abs_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ FAIL_STACK_ERROR } /* end if */ - /* Compute heap size & free space when root indirect block doubles again */ - do{ - state.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_size += cparam->managed.width * DBLOCK_SIZE(fh, row); - state.man_free_space += cparam->managed.width * DBLOCK_FREE(fh, row); - row++; - } while(row < (2 * num_direct_rows)); + /* Fill all rows of direct blocks that are smaller than large object's block size */ + for(row = 0; row < num_first_indirect_rows; row++) { + /* Fill rows of direct blocks in skipped indirect blocks */ + for(u = 0; u < cparam->managed.width; u++) + if(fill_row(fh, dxpl, row, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Insert large object, to force creation of indirect blocks with - * range of skipped blocks that are too small to hold the large object - */ - obj_size = DBLOCK_SIZE(fh, num_direct_rows - 2) + 1; - state.man_alloc_size += DBLOCK_SIZE(fh, num_direct_rows -1); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* Fill row of direct blocks in largest (i.e. non-skipped) indirect block */ + /* (Skip the row of blocks filled above) */ + if(row != 4) + if(fill_row(fh, dxpl, row, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end while */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -9772,35 +10627,38 @@ test_abs_skip_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_ error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_skip_direct_skip_indirect_two_rows_add_skipped() */ -#endif /* QAK */ +} /* test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped() */ -#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_frag_simple + * Function: test_abs_fill_direct_skip_indirect_two_rows_add_skipped * - * 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 filling all direct blocks in root indirect block, then + * add object too large for initial block in first two rows of + * indirect blocks, to force extension of non-root + * indirect block (and range of skipped blocks). * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 18, 2006 + * Saturday, April 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_direct_skip_indirect_two_rows_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -9808,10 +10666,19 @@ test_abs_frag_simple(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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal heap IDs */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned max_dblock_rows; /* Max. # of rows (of direct blocks) in the root indirect block */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u; /* Local index variables */ + const char *base_desc = "filling direct blocks and skipping two rows of root indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -9836,38 +10703,97 @@ test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar 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 - /* - * Test absolute heap - */ - TESTING("fragmenting small blocks, then backfill and extend"); + /* Prepare for querying the size of a file with an empty heap */ - /* 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. + /* 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 + + /* + * Display testing message */ - obj_size = DBLOCK_SIZE(fh, 0) / 2; - state.heap_size = DBLOCK_SIZE(fh, 0); - 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, 10, obj_size, &state, NULL)) + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Retrieve info about heap */ + num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + max_dblock_rows = DTABLE_MAX_DROWS(fh); + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - if(u == 0) { - state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 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.heap_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; - 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, 10, obj_size, &state, NULL)) + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped blocks that are too small to hold the large object + */ + obj_size = DBLOCK_SIZE(fh, max_dblock_rows - 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - } /* end for */ + } /* end if */ + + /* Insert an object to fill up the (biggest) heap block created */ + obj_size = DBLOCK_FREE(fh, max_dblock_rows - 1) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -9880,17 +10806,22 @@ test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* (Account for doubling root indirect block for rows 3-4 */ - for(u = 0; u < 2; u++) { - state.heap_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; - 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 */ + /* Fill rows skipped over in indirect block's direct blocks */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in first row of skipped 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* 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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR + /* Direct block rows in second row of skipped 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Direct block row in used 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -9903,14 +10834,27 @@ test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) + /* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */ + + /* Direct block rows in skipped 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - for(u = 0; u < cparam->managed.width; u++) - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ + + /* Direct block row in used 2nd level indirect block */ + if(fill_row(fh, dxpl, num_first_indirect_rows, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -9923,19 +10867,56 @@ test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* Fill in 2 * start_block_size block */ - obj_size = DBLOCK_FREE(fh, 2) - (DBLOCK_SIZE(fh, 0) / 2); - if(add_obj(fh, dxpl, 20, obj_size, &state, NULL)) + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -9943,32 +10924,40 @@ test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_frag_simple() */ +} /* test_abs_fill_direct_skip_indirect_two_rows_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_frag_direct + * Function: test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped * - * 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 filling all direct blocks in root indirect block, then + * add object too large for initial block in first two rows of + * indirect blocks, to force extension of non-root + * indirect block, then add object too large for first row of + * indirect blocks, (and ranges of skipped blocks), then backfill + * and extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, April 18, 2006 + * Tuesday, July 11, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_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 */ @@ -9976,10 +10965,18 @@ test_abs_frag_direct(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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal heap IDs */ - unsigned root_direct_rows; /* Number of rows in root indirect block */ + unsigned num_first_indirect_rows; /* Number of rows (of direct blocks) in each of the first indirect blocks */ + unsigned max_dblock_rows; /* Max. # of rows (of direct blocks) in the root indirect block */ + off_t empty_size; /* Size of a file with an empty heap */ + off_t file_size; /* Size of file currently */ 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 and skipping two rows of root indirect block, skip one row of root indirect block, then backfill and extend, then remove all objects %s"; /* Test description */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ @@ -10005,42 +11002,97 @@ test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar 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 - /* Retrieve # of direct rows in root indirect block */ - root_direct_rows = H5HF_get_dtable_max_drows_test(fh); + /* 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 absolute heap + * Display testing message */ - TESTING("fragmenting direct blocks, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* 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.heap_size = DBLOCK_SIZE(fh, 0); - 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, 10, obj_size, &state, NULL)) + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Retrieve info about heap */ + num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + max_dblock_rows = DTABLE_MAX_DROWS(fh); + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - if(u == 0) { - state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 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.heap_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; - 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, 10, obj_size, &state, NULL)) + } /* end if */ + + /* Insert large object, to force creation of two rows of indirect blocks and + * range of skipped blocks that are too small to hold the large object + */ + obj_size = DBLOCK_SIZE(fh, max_dblock_rows - 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 1); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - } /* end for */ + } /* end if */ + + /* Insert an object to fill up the (biggest) heap block created */ + obj_size = DBLOCK_FREE(fh, max_dblock_rows - 1) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -10053,22 +11105,30 @@ test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* (Account for doubling root indirect block for rows 3-4 */ - for(u = 0; u < 2; u++) { - state.heap_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; - 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 that can't fit in first row of indirect blocks + * previously skipped, but is small enough to fit into second row of + * skipped blocks. + */ + obj_size = DBLOCK_SIZE(fh, max_dblock_rows - 3) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, max_dblock_rows - 2); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - } /* end for */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert an object to fill up the (2nd biggest) heap block created */ + obj_size = DBLOCK_FREE(fh, max_dblock_rows - 2) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -10081,21 +11141,21 @@ test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* (Account for doubling root indirect block for rows 5-8 */ - for(u = 0; u < 4; u++) { - state.heap_size += DBLOCK_SIZE(fh, u + 4) * cparam->managed.width; - 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 */ + /* Fill rows skipped over in indirect block's direct blocks */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in first row of skipped 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_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, 10, obj_size, &state, NULL)) + /* Direct block rows in second row of skipped 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - } /* end for */ + + /* Direct block row in used 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR } /* end for */ /* Check for closing & re-opening the heap */ @@ -10109,20 +11169,17 @@ test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* (Account for doubling root indirect block for rows 9-16 */ - for(u = 0; u < 8; u++) { - state.heap_size += DBLOCK_SIZE(fh, u + 8) * cparam->managed.width; - 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 */ + /* Fill rows in second row of skipped 2nd level indirect blocks (and used 2nd level block) */ - /* 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, 10, obj_size, &state, NULL)) + /* 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)) + FAIL_STACK_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)) FAIL_STACK_ERROR - } /* end for */ /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -10135,22 +11192,71 @@ test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -10158,34 +11264,39 @@ test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpar error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_frag_direct() */ +} /* test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_frag_2nd_direct + * Function: test_abs_fill_2nd_direct_skip_start_block_add_skipped * - * 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 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 18, 2006 + * Tuesday, April 11, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_2nd_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -10193,11 +11304,16 @@ test_abs_frag_2nd_direct(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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -10222,24 +11338,61 @@ test_abs_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * 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 - /* Compute # of bits used in first row */ - num_first_indirect_rows = IBLOCK_MAX_DROWS(fh, 1); + /* 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 #ifdef QAK -HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - /* - * Test absolute heap - */ - TESTING("fill root direct blocks, then fragment 2nd level indirect block's direct blocks, then backfill and extend"); + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* 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 - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -10249,17 +11402,29 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* Insert objects small enough to fit into each direct block, but not to - * share them with other objects of the same size. + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object */ - 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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - } /* end for */ + obj_size = DBLOCK_SIZE(fh, 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -10272,22 +11437,91 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, 3) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill rows skipped over in 3rd level indirect block's direct blocks */ + if(fill_row(fh, dxpl, 0, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -10295,35 +11529,41 @@ HDfprintf(stderr, "num_first_indirect_rows = %u\n", num_first_indirect_rows); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_frag_2nd_direct() */ +} /* test_abs_fill_2nd_direct_skip_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_frag_3rd_direct + * Function: test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped * - * 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 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 18, 2006 + * Tuesday, April 11, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -10331,11 +11571,16 @@ test_abs_frag_3rd_direct(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 */ size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ 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 */ - unsigned u, v; /* Local index variables */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -10360,17 +11605,57 @@ test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * 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 - /* Compute # of direct rows in root indirect block */ - root_direct_rows = DTABLE_MAX_DROWS(fh); + /* 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 absolute heap + * Display testing message */ - TESTING("fill root direct blocks and 2nd level indirect blocks, then fragment 3rd level indirect block's direct blocks, then backfill and extend"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -10384,8 +11669,8 @@ test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * FAIL_STACK_ERROR } /* end if */ - /* Fill all rows of 2nd level indirect blocks in root indirect block */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -10399,17 +11684,9 @@ test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * FAIL_STACK_ERROR } /* end if */ - /* 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, 10, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ - } /* end for */ + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -10422,183 +11699,112 @@ test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t * FAIL_STACK_ERROR } /* end if */ - /* 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, 20, obj_size, &state, NULL)) - FAIL_STACK_ERROR - } /* end for */ + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = DBLOCK_SIZE(fh, 2) + 1; + state.man_alloc_size += DBLOCK_SIZE(fh, 3); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Close the fractal heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Close the file */ - if(H5Fclose(file) < 0) - TEST_ERROR + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* All tests passed */ - PASSED() + /* Insert object to fill space in (large) block created */ + obj_size = DBLOCK_FREE(fh, 3) - obj_size; + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - return(0); + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR -error: - H5E_BEGIN_TRY { - if(fh) - H5HF_close(fh, dxpl); - H5Fclose(file); - } H5E_END_TRY; - return(1); -} /* test_abs_frag_3rd_direct() */ -#endif /* QAK */ - -#ifndef QAK - -/*------------------------------------------------------------------------- - * Function: test_abs_random_managed - * - * Purpose: Test inserting random sized objects (that are smaller than - * the standalone size) into a heap, and read them back. - * - * Return: Success: 0 - * - * Failure: 1 - * - * Programmer: Quincey Koziol - * Tuesday, May 9, 2006 - * - *------------------------------------------------------------------------- - */ -static int -test_abs_random_managed(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 */ - char filename[1024]; /* Filename to use */ - H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_t *fh = NULL; /* Fractal heap wrapper */ - haddr_t fh_addr; /* Address of fractal heap */ - size_t id_len; /* Size of fractal heap IDs */ - unsigned long seed = 0; /* Random # seed */ - size_t num_ids = 0; /* # of heap IDs in array */ - size_t alloc_ids = 0; /* # of heap IDs allocated in array */ - hsize_t total_obj_added; /* Size of objects added */ - size_t obj_size; /* Size of object */ - size_t obj_loc; /* Location of object in buffer */ - unsigned char *ids = NULL; /* Array of heap IDs */ - unsigned u; /* Local index variables */ - - /* Set the filename to use for this test (dependent on fapl) */ - h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - - /* Create the file to work on */ - if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) - TEST_ERROR - - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* Create absolute heap */ - if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) - FAIL_STACK_ERROR - if(H5HF_get_id_len(fh, &id_len) < 0) - FAIL_STACK_ERROR - if(id_len > HEAP_ID_LEN) + /* 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)) FAIL_STACK_ERROR - if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + if(fill_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - if(!H5F_addr_defined(fh_addr)) + if(fill_row(fh, dxpl, 2, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address: %a\n", fh_addr); -#endif /* QAK */ - - /* - * Test absolute heap - */ - TESTING("inserting random-sized objects (smaller than standalone size)"); - - /* Choose random # seed */ - seed = (unsigned long)HDtime(NULL); -#ifdef QAK -/* seed = (unsigned long)1153176468; */ -HDfprintf(stderr, "Random # seed was: %lu\n", seed); -#endif /* QAK */ - HDsrandom(seed); - - /* Loop over adding objects to the heap, until the size limit is reached */ - total_obj_added = 0; - while(total_obj_added < size_limit) { - /* Choose a random size of object (from 1 up to stand alone block size) */ - obj_size = (HDrandom() % (cparam->standalone_size - 1)) + 1; - - /* Increment object count */ - num_ids++; -#ifdef QAK -HDfprintf(stderr, "num_ids = %Zu, total_obj_added = %Hu, obj_size = %Zu\n", num_ids, total_obj_added, obj_size); -#endif /* QAK */ - /* Check for needing to increase size of heap ID array */ - if(num_ids > alloc_ids) { - alloc_ids = MAX(1024, (alloc_ids * 2)); - if(NULL == (ids = H5MM_realloc(ids, HEAP_ID_LEN * alloc_ids))) - FAIL_STACK_ERROR - } /* end if */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Insert object */ - obj_loc = cparam->standalone_size - obj_size; - if(H5HF_insert(fh, dxpl, obj_size, &shared_wobj_g[obj_loc], &ids[(num_ids - 1) * HEAP_ID_LEN]) < 0) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Increment the amount of objects added */ - total_obj_added += obj_size; - } /* end while */ -#ifdef QAK -HDfprintf(stderr, "num_ids = %Zu, total_obj_added = %Hu, size_limit = %Hu\n", num_ids, total_obj_added, size_limit); -#endif /* QAK */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Verify reading the objects written out */ - for(u = 0; u < num_ids; u++) { - /* Get object length */ - if(H5HF_get_obj_len(fh, &ids[u * HEAP_ID_LEN], &obj_size) < 0) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Clear read buffer */ - HDmemset(shared_robj_g, 0, obj_size); - - /* Read in object */ - if(H5HF_read(fh, dxpl, &ids[u * HEAP_ID_LEN], shared_robj_g) < 0) - FAIL_STACK_ERROR + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - /* Check for correct object */ - obj_loc = cparam->standalone_size - obj_size; - if(HDmemcmp(&shared_wobj_g[obj_loc], shared_robj_g, obj_size)) - FAIL_STACK_ERROR - } /* end for */ + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) + 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(ids); + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); /* All tests passed */ PASSED() @@ -10606,35 +11812,41 @@ HDfprintf(stderr, "num_ids = %Zu, total_obj_added = %Hu, size_limit = %Hu\n", nu return(0); error: - HDfprintf(stderr, "Random # seed was: %lu\n", seed); H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); - H5MM_xfree(ids); } H5E_END_TRY; return(1); -} /* test_abs_random_managed() */ +} /* test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_random_pow2_managed + * Function: test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped * - * Purpose: Test inserting random sized objects (that are smaller than the - * standalone size) with a "power of 2 distribution" into a heap, - * and read them back. + * 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. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 15, 2006 + * Tuesday, April 11, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_random_pow2_managed(hsize_t size_limit, hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -10642,15 +11854,18 @@ test_abs_random_pow2_managed(hsize_t size_limit, hid_t fapl, H5HF_create_t *cpar 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 */ size_t id_len; /* Size of fractal heap IDs */ - unsigned long seed = 0; /* Random # seed */ - size_t num_ids = 0; /* # of heap IDs in array */ - size_t alloc_ids = 0; /* # of heap IDs allocated in array */ - hsize_t total_obj_added; /* Size of objects added */ + 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 */ + off_t file_size; /* Size of file currently */ size_t obj_size; /* Size of object */ - size_t obj_loc; /* Location of object in buffer */ - unsigned char *ids = NULL; /* Array of heap IDs */ - unsigned u; /* Local index variables */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -10674,103 +11889,218 @@ test_abs_random_pow2_managed(hsize_t size_limit, hid_t fapl, H5HF_create_t *cpar FAIL_STACK_ERROR if(!H5F_addr_defined(fh_addr)) FAIL_STACK_ERROR -#ifdef QAK -HDfprintf(stderr, "Fractal heap header address: %a\n", fh_addr); -#endif /* QAK */ - - /* - * Test absolute heap - */ - TESTING("inserting random-sized objects with power of 2 distribution (smaller than standalone size)"); - - /* Choose random # seed */ - seed = (unsigned long)HDtime(NULL); -#ifdef QAK -HDfprintf(stderr, "Random # seed was: %lu\n", seed); -#endif /* QAK */ - HDsrandom(seed); + HDmemset(&state, 0, sizeof(fheap_heap_state_t)); + if(check_stats(fh, &state)) + FAIL_STACK_ERROR - /* Loop over adding objects to the heap, until the size limit is reached */ - total_obj_added = 0; - while(total_obj_added < size_limit) { - unsigned size_range = 10; /* Object size range */ + /* Prepare for querying the size of a file with an empty heap */ - /* Determine the size of the range for this object */ - /* (50% of the objects inserted will use the initial size range, - * 25% of the objects will be twice as large, 12.5% will be - * four times larger, etc.) - */ - while(HDrandom() < (RAND_MAX / 2) && size_range < cparam->standalone_size) - size_range *= 2; - if(size_range > cparam->standalone_size) - size_range = cparam->standalone_size; + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Choose a random size of object (from 1 up to stand alone block size) */ - obj_size = (HDrandom() % (size_range - 1)) + 1; + /* Close file */ + if(H5Fclose(file)<0) + TEST_ERROR - /* Increment object count */ - num_ids++; + /* Get the size of a file w/empty heap*/ + if((empty_size = h5_get_file_size(filename)) == 0) + TEST_ERROR #ifdef QAK -if((num_ids % 100000) == 0) - HDfprintf(stderr, "num_ids = %Zu, total_obj_added = %Hu, obj_size = %Zu\n", num_ids, total_obj_added, obj_size); +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - /* Check for needing to increase size of heap ID array */ - if(num_ids > alloc_ids) { - alloc_ids = MAX(1024, (alloc_ids * 2)); - if(NULL == (ids = H5MM_realloc(ids, HEAP_ID_LEN * alloc_ids))) - FAIL_STACK_ERROR - } /* end if */ + /* Re-open the file */ + if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) + TEST_ERROR - /* Insert object */ - obj_loc = cparam->standalone_size - obj_size; - if(H5HF_insert(fh, dxpl, obj_size, &shared_wobj_g[obj_loc], &ids[(num_ids - 1) * HEAP_ID_LEN]) < 0) - FAIL_STACK_ERROR + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Increment the amount of objects added */ - total_obj_added += obj_size; - } /* end while */ + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Verify reading the objects written out */ - for(u = 0; u < num_ids; u++) { - /* Get object length */ - if(H5HF_get_obj_len(fh, &ids[u * HEAP_ID_LEN], &obj_size) < 0) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Clear read buffer */ - HDmemset(shared_robj_g, 0, obj_size); + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Read in object */ - if(H5HF_read(fh, dxpl, &ids[u * HEAP_ID_LEN], shared_robj_g) < 0) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Check for correct object */ - obj_loc = cparam->standalone_size - obj_size; - if(HDmemcmp(&shared_wobj_g[obj_loc], shared_robj_g, obj_size)) + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR } /* end for */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) + 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(ids); + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); /* All tests passed */ PASSED() @@ -10778,35 +12108,42 @@ if((num_ids % 100000) == 0) return(0); error: - HDfprintf(stderr, "Random # seed was: %lu\n", seed); H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); - H5MM_xfree(ids); } H5E_END_TRY; return(1); -} /* test_abs_random_pow2_managed() */ -#endif /* QAK */ +} /* test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ -#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_remove_bogus + * Function: test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped * - * Purpose: Test removing bogus heap IDs + * 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. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 15, 2006 + * Tuesday, April 11, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_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 */ @@ -10814,12 +12151,18 @@ test_abs_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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal heap IDs */ - hsize_t obj_off; /* Offset of object in heap */ + 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 */ + off_t file_size; /* Size of file currently */ + 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 */ - unsigned u; /* Local index variable */ - herr_t ret; /* Generic return value */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -10832,24 +12175,800 @@ test_abs_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa 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)) + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 + + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all direct block rows in third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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 */ + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* 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 + + /* 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(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); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped + * + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, 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 + * Tues, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + 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 */ + 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 */ + off_t file_size; /* Size of file currently */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 + + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all direct block rows in last third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill rows skipped over in 2nd level indirect block's direct blocks + * (and rows of next 3rd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Direct block row in current 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* 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 + + /* 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(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); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); + if(fh) + H5HF_close(fh, dxpl); + H5Fclose(file); + } H5E_END_TRY; + return(1); +} /* test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped() */ + + +/*------------------------------------------------------------------------- + * Function: test_abs_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, 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 + * Tues, April 18, 2006 + * + *------------------------------------------------------------------------- + */ +static int +test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +{ + hid_t file = -1; /* File ID */ + hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ + char filename[1024]; /* Filename to use */ + H5F_t *f = NULL; /* Internal file object pointer */ + H5HF_t *fh = NULL; /* Fractal heap wrapper */ + haddr_t fh_addr; /* Address of fractal heap */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ + size_t id_len; /* Size of fractal 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 */ + off_t file_size; /* Size of file currently */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u; /* Local index variables */ + + /* Set the filename to use for this test (dependent on fapl) */ + h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); + + /* Create the file to work on */ + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) + TEST_ERROR + + /* Get a pointer to the internal file object */ + if(NULL == (f = H5I_object(file))) + STACK_ERROR + + /* Create absolute heap */ + if(NULL == (fh = H5HF_create(f, H5P_DATASET_XFER_DEFAULT, cparam))) + FAIL_STACK_ERROR + if(H5HF_get_id_len(fh, &id_len) < 0) + FAIL_STACK_ERROR + if(id_len > HEAP_ID_LEN) + FAIL_STACK_ERROR + if(H5HF_get_heap_addr(fh, &fh_addr) < 0) + FAIL_STACK_ERROR + if(!H5F_addr_defined(fh_addr)) + FAIL_STACK_ERROR + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ + + /* 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 + + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill first row of 3rd level indirect blocks */ + if(fill_3rd_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all direct block rows in 2nd row third level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -10858,56 +12977,80 @@ test_abs_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa FAIL_STACK_ERROR } /* end if */ - /* - * Test removing bogus IDs from heap + /* Fill rows skipped over in 2nd level indirect block's direct blocks + * (and rows of next 2nd level indirect block's direct blocks) */ - TESTING("removing bad heap IDs from absolute heap"); + 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)) + FAIL_STACK_ERROR - /* Set heap ID to random (non-null) value */ - for(u = 0; u < HEAP_ID_LEN; u++) - heap_id[u] = HDrandom() + 1; + /* Direct block row in current 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ - /* 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 + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Fill root direct blocks */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, NULL)) - FAIL_STACK_ERROR + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* Get offset of random heap ID */ - if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) + /* 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR - /* Make certain we can't accidentally use a valid heap ID */ - while(obj_off < state.heap_size) { - /* Set heap ID to random (non-null) value */ - for(u = 0; u < HEAP_ID_LEN; u++) - heap_id[u] = HDrandom() + 1; + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Get offset of random heap ID */ - if(H5HF_get_id_off_test(fh, heap_id, &obj_off) < 0) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - } /* end while */ + } /* end if */ - /* 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) + /* Check up on heap... */ + if(check_stats(fh, &state)) + FAIL_STACK_ERROR + + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) FAIL_STACK_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) + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -10915,30 +13058,41 @@ test_abs_remove_bogus(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpa error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_bogus() */ +} /* test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_one + * Function: test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped * - * Purpose: Test removing single object from heap + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, then + * fill all direct blocks in 4th level indirect block, then + * insert object that is too large to hold in first row of 2nd + * level indirect blocks of 4th level indirect block, then + * backfill all skipped direct blocks & extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 15, 2006 + * Saturday, April 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -10946,13 +13100,18 @@ test_abs_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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal 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 */ off_t file_size; /* Size of file currently */ + 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 */ - unsigned u; /* Local index variable */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -10966,7 +13125,7 @@ test_abs_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 @@ -10987,11 +13146,15 @@ test_abs_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ /* Re-open the file */ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) @@ -11006,21 +13169,142 @@ test_abs_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR /* - * Test removing first (small) object from absolute heap + * Display testing message */ - TESTING("removing single object from absolute heap"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Initialize the buffer for objects to insert */ - for(u = 0; u < sizeof(obj); u++) - obj[u] = u; + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all direct block rows in fourth level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill rows skipped over in (first 4th level indirect block's) 2nd level + * indirect block's direct blocks + * (and second row of 2nd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id) < 0) - FAIL_STACK_ERROR + /* Direct block row in 2nd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11029,22 +13313,15 @@ test_abs_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - state.heap_size = DBLOCK_SIZE(fh, 0); - 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.nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove object from heap */ - if(H5HF_remove(fh, dxpl, heap_id) < 0) + /* 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11054,30 +13331,38 @@ test_abs_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara } /* end if */ /* Check up on heap... */ - state.heap_size = 0; - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.nobjs = 0; if(check_stats(fh, &state)) FAIL_STACK_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) - TEST_ERROR + 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -11085,30 +13370,43 @@ test_abs_remove_one(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_one() */ +} /* test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_two + * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped * - * Purpose: Test removing two objects from heap + * 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. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 22, 2006 + * Monday, April 17, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -11116,14 +13414,18 @@ test_abs_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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal 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 */ off_t file_size; /* Size of file currently */ + 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 */ - unsigned u; /* Local index variable */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -11137,7 +13439,7 @@ test_abs_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 @@ -11158,11 +13460,15 @@ test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ /* Re-open the file */ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) @@ -11177,21 +13483,32 @@ test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR /* - * Test removing two (small) objects from absolute heap + * Display testing message */ - TESTING("removing two objects from absolute heap"); + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Initialize the buffer for objects to insert */ - for(u = 0; u < sizeof(obj); u++) - obj[u] = u; + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Insert first object into heap */ - if(H5HF_insert(fh, dxpl, sizeof(obj), obj, &heap_id1) < 0) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11200,22 +13517,13 @@ test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - state.heap_size = DBLOCK_SIZE(fh, 0); - 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.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, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11224,19 +13532,13 @@ test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - state.man_free_space -= sizeof(obj); - state.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, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11245,19 +13547,13 @@ test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - state.man_free_space += sizeof(obj); - state.nobjs--; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) + /* Fill all direct block rows in fourth level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11266,146 +13562,67 @@ test_abs_remove_two(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tpara FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - state.heap_size = 0; - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.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 */ - 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_abs_remove_two() */ - - -/*------------------------------------------------------------------------- - * Function: test_abs_remove_one_larger - * - * Purpose: Test removing single larger (but < standalone size) object - * from heap - * - * Return: Success: 0 - * - * Failure: 1 - * - * Programmer: Quincey Koziol - * Tuesday, June 6, 2006 - * - *------------------------------------------------------------------------- - */ -static int -test_abs_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 */ - char filename[1024]; /* Filename to use */ - H5F_t *f = NULL; /* Internal file object pointer */ - H5HF_t *fh = NULL; /* Fractal heap wrapper */ - haddr_t fh_addr; /* Address of fractal heap */ - 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 */ - unsigned u; /* Local index variable */ - - /* Set the filename to use for this test (dependent on fapl) */ - h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); - - /* Create the file to work on */ - if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) - TEST_ERROR - - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR - - /* Create absolute heap */ - if(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)) + /* 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)) 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; + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 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 heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* Re-open the file */ - if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 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)) + FAIL_STACK_ERROR - /* Get a pointer to the internal file object */ - if(NULL == (f = H5I_object(file))) - STACK_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* - * Test removing one larger object from absolute heap + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object */ - TESTING("removing single larger object from absolute heap"); + 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Set up object to insert */ - obj_len = DBLOCK_SIZE(fh, 2) + 1; - obj = shared_wobj_g; + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id) < 0) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11414,25 +13631,41 @@ test_abs_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - for(u = 0; u < 4; u++) { - state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - state.man_free_space += DBLOCK_FREE(fh, u) * cparam->managed.width; + /* Fill rows skipped over in (first 4th level indirect block's first 3rd + * level block's) 2nd level indirect block's direct blocks + * (and rows of 2nd 3rd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR } /* end for */ - state.man_alloc_size = DBLOCK_SIZE(fh, 3); - state.man_free_space -= obj_len; - state.nobjs = 1; - if(check_stats(fh, &state)) - FAIL_STACK_ERROR - /* Remove object from heap */ - if(H5HF_remove(fh, dxpl, heap_id) < 0) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11442,17 +13675,17 @@ test_abs_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t } /* end if */ /* Check up on heap... */ - state.heap_size = 0; - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.nobjs = 0; if(check_stats(fh, &state)) FAIL_STACK_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_ERROR + /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) FAIL_STACK_ERROR + fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) @@ -11461,11 +13694,19 @@ test_abs_remove_one_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t /* 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -11473,31 +13714,45 @@ test_abs_remove_one_larger(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); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_one_larger() */ +} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_two_larger + * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped * - * Purpose: Test removing two larger (but < standalone size) objects - * from heap + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, fill all + * direct & indirect blocks in first row of 4th level indirect + * blocks, then fill all direct blocks in first row of 3rd level + * indirect blocks in 4th level indirect block, fill direct blocks + * in first block of 2nd row of 3rd level indirect blocks in 4th + * level indirect block, then insert object insert object that is + * too large to hold in first row of 2nd level indirect blocks of + * 3rd level indirect block (in 4th level indirect block), then + * backfill all skipped direct blocks & extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Saturday, June 10, 2006 + * Monday, April 17, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -11505,15 +13760,18 @@ test_abs_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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal 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 */ off_t file_size; /* Size of file currently */ + 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 */ - unsigned u; /* Local index variable */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -11527,7 +13785,7 @@ test_abs_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 @@ -11548,11 +13806,15 @@ test_abs_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ /* Re-open the file */ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) @@ -11567,24 +13829,110 @@ test_abs_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 + * Display testing message */ - if(tparam->del_dir == HEAP_DEL_FORWARD) - TESTING("removing two larger objects from absolute heap (forward)") - else - TESTING("removing two larger objects from absolute heap (reverse)") + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Set up first object to insert */ - obj_len = DBLOCK_SIZE(fh, 2) + 1; - obj = shared_wobj_g; + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id1) < 0) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill first row of 4th level indirect blocks */ + if(fill_4th_indirect_row(fh, dxpl, 1, fill_size, &state, &keep_ids)) + FAIL_STACK_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.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 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(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all direct block rows in 2nd row 4th level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11593,29 +13941,28 @@ test_abs_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - for(u = 0; u < 4; u++) { - state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.nobjs = 1; - if(check_stats(fh, &state)) + /* 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)) FAIL_STACK_ERROR - /* Set up second object to insert */ - obj_len = DBLOCK_SIZE(fh, 4) + 1; - obj = shared_wobj_g; + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id2) < 0) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11624,84 +13971,95 @@ test_abs_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - /* (Goes to 8 rows because of doubling) */ - for(u = 4; u < 8; u++) { - state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.nobjs = 2; - if(check_stats(fh, &state)) + /* 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)) FAIL_STACK_ERROR - /* Remove objects in different orders */ - if(tparam->del_dir == HEAP_DEL_FORWARD) { - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 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) + 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 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.nobjs = 1; - if(check_stats(fh, &state)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) 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(tparam->reopen_heap) { - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Fill rows skipped over in (first block in 2nd row 4th level indirect + * block's first 3rd level block's) 2nd level indirect block's direct + * blocks (and rows of 2nd 3rd level indirect block's direct blocks) + */ + for(u = 0; u < num_first_indirect_rows; u++) { + /* Direct block rows in 2nd level indirect blocks */ + for(v = 0; v < cparam->managed.width; v++) + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - } /* end if */ - /* Check up on heap... */ - /* (Goes to 4 rows because of halving) */ - for(u = 4; u < 8; u++) { - state.heap_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.nobjs = 1; - if(check_stats(fh, &state)) + /* Direct block row in 3rd level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR + } /* end for */ - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - } /* end else */ + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11711,34 +14069,38 @@ test_abs_remove_two_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t } /* end if */ /* Check up on heap... */ - state.heap_size = 0; - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.nobjs = 0; if(check_stats(fh, &state)) FAIL_STACK_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) - TEST_ERROR + 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 */ #ifdef QAK -HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -11746,31 +14108,47 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_two_larger() */ +} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_three_larger + * Function: test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped * - * Purpose: Test removing three larger (but < standalone size) objects - * from heap + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, fill all + * direct & indirect blocks in 4th level indirect + * block, then fill all direct blocks in first row of 3rd + * level indirect blocks in 4th level indirect block except + * the last (3rd level indirect block) in 4th level indirect block, + * fill direct blocks in last 3rd level indirect block, then + * insert object insert object that is too large to hold in first + * row of 2nd level indirect blocks of 3rd level indirect block + * (in 4th level indirect block) (forcing the use of the next + * 4th level block), then backfill all skipped direct blocks & + * extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, June 12, 2006 + * Monday, April 17, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -11778,16 +14156,18 @@ test_abs_remove_three_larger(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 */ - 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 */ + fheap_heap_ids_t keep_ids; /* Structure to retain heap IDs */ size_t id_len; /* Size of fractal 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 */ off_t file_size; /* Size of file currently */ + 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 */ - unsigned u; /* Local index variable */ + 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 */ + char *del_str = NULL; /* Deletion order description */ + char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -11801,7 +14181,7 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param 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 @@ -11822,11 +14202,15 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ /* Re-open the file */ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) @@ -11841,24 +14225,47 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param FAIL_STACK_ERROR /* - * Test removing three larger objects from absolute heap + * Display testing message */ - if(tparam->del_dir == HEAP_DEL_FORWARD) - TESTING("removing three larger objects from absolute heap (forward)") - else - TESTING("removing three larger objects from absolute heap (reverse)") + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); - /* Set up first object to insert */ - obj_len = DBLOCK_SIZE(fh, 2) + 1; - obj = shared_wobj_g; + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* Insert object into heap */ - if(H5HF_insert(fh, dxpl, obj_len, obj, &heap_id1) < 0) + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11867,29 +14274,13 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - for(u = 0; u < 4; u++) { - state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.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) + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11898,30 +14289,13 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - /* (Goes to 8 rows because of doubling) */ - for(u = 4; u < 8; u++) { - state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.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) + /* Fill all direct block rows in 4th level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -11930,134 +14304,132 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - /* (Goes to 16 rows because of doubling) */ - for(u = 8; u < 16; u++) { - state.heap_size += DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.nobjs = 3; - if(check_stats(fh, &state)) + /* 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)) FAIL_STACK_ERROR - /* Remove objects in different orders */ - if(tparam->del_dir == HEAP_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(tparam->reopen_heap) { - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR - - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 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.nobjs = 2; - if(check_stats(fh, &state)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) + /* 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)) FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) - 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)) + FAIL_STACK_ERROR + } /* end for */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 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.nobjs = 1; - if(check_stats(fh, &state)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Remove third object from heap */ - if(H5HF_remove(fh, dxpl, heap_id3) < 0) + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) 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(tparam->reopen_heap) { - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 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) + 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR - } /* end if */ + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Check up on heap... */ - /* (Goes to 8 rows because of halving) */ - for(u = 8; u < 16; u++) { - state.heap_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.nobjs = 2; - if(check_stats(fh, &state)) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR + } /* end if */ - /* Remove second object from heap */ - if(H5HF_remove(fh, dxpl, heap_id2) < 0) - FAIL_STACK_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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close (empty) heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) FAIL_STACK_ERROR - } /* end if */ - /* Check up on heap... */ - /* (Goes to 4 rows because of halving) */ - for(u = 4; u < 8; u++) { - state.heap_size -= DBLOCK_SIZE(fh, u) * cparam->managed.width; - 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.nobjs = 1; - if(check_stats(fh, &state)) + /* Direct block row in 4th level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR + } /* end for */ - /* Remove first object from heap */ - if(H5HF_remove(fh, dxpl, heap_id1) < 0) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) FAIL_STACK_ERROR - } /* end else */ + } /* end if */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { - /* Close (empty) heap */ + /* Close heap */ if(H5HF_close(fh, dxpl) < 0) TEST_ERROR @@ -12067,34 +14439,38 @@ test_abs_remove_three_larger(hid_t fapl, H5HF_create_t *cparam, fheap_test_param } /* end if */ /* Check up on heap... */ - state.heap_size = 0; - state.man_size = 0; - state.man_alloc_size = 0; - state.man_free_space = 0; - state.nobjs = 0; if(check_stats(fh, &state)) FAIL_STACK_ERROR + /* Delete objects inserted (either forward or reverse order) */ + if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) + FAIL_STACK_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) - TEST_ERROR + 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 */ #ifdef QAK -HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); 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(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + /* All tests passed */ PASSED() @@ -12102,34 +14478,47 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); error: H5E_BEGIN_TRY { + H5MM_xfree(keep_ids.ids); + H5MM_xfree(keep_ids.lens); + H5MM_xfree(keep_ids.offs); + H5MM_xfree(del_str); + H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_three_larger() */ -#endif /* QAK */ +} /* test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ -#ifndef QAK -#ifndef QAK2 /*------------------------------------------------------------------------- - * Function: test_abs_remove_root_direct + * Function: test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped * - * Purpose: Test filling and removing all objects from root direct block in - * heap + * Purpose: Test filling all direct blocks in root indirect block and all + * direct blocks in 2nd level indirect blocks, fill all direct + * blocks and indirect blocks in 3rd level indirect block, fill all + * direct & indirect blocks in first row of 4th level indirect + * blocks, except last one, then fill all direct blocks in first + * row of 3rd level indirect blocks in 4th level indirect block + * except the last (3rd level indirect block) in 4th level + * indirect block, fill direct blocks in last 3rd level indirect + * block, then insert object insert object that is too large to + * hold in row of 2nd level indirect blocks in 3rd level indirect + * block (in 4th level indirect block) (forcing the use of the + * next row of 4th level blocks), then backfill all skipped direct + * blocks & extend. * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Monday, May 22, 2006 + * Monday, April 17, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -12139,12 +14528,16 @@ test_abs_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ 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 */ + 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 */ off_t file_size; /* Size of file currently */ + 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 = "removing all objects from root direct block of absolute heap %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 */ char *del_str = NULL; /* Deletion order description */ char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -12158,7 +14551,7 @@ test_abs_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ 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 @@ -12179,11 +14572,15 @@ test_abs_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + 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 +#ifdef QAK +HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); +#endif /* QAK */ /* Re-open the file */ if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) @@ -12198,25 +14595,250 @@ test_abs_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ FAIL_STACK_ERROR /* - * Test filling & removing all (small) objects from root direct block of absolute heap + * Display testing message */ del_str = get_del_string(tparam); HDassert(del_str); test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); sprintf(test_desc, base_desc, del_str); TESTING(test_desc); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 2nd level indirect blocks */ + if(fill_all_2nd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all rows of 3rd level indirect blocks */ + if(fill_all_3rd_indirect_rows(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_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)) + FAIL_STACK_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)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill all direct block rows in 4th level indirect block */ + if(fill_all_direct(fh, dxpl, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_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)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_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.heap_size += cparam->managed.width * DBLOCK_SIZE(fh, 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(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Insert large object, to force creation of indirect block and + * range of skipped (indirect) blocks that are too small to hold the large + * object + */ + obj_size = 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) + FAIL_STACK_ERROR + + /* Direct block row in 4th level indirect block */ + if(fill_row(fh, dxpl, u, fill_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Initialize the heap ID structure */ - HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ - /* Fill the heap up */ - state.heap_size = DBLOCK_SIZE(fh, 0); - 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, SMALL_OBJ_SIZE1, &state, &keep_ids)) + /* 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -12240,15 +14862,19 @@ test_abs_remove_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_ /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_ERROR + fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + 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) @@ -12276,26 +14902,32 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_root_direct() */ +} /* test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped() */ +#endif /* QAK */ +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_remove_two_direct + * Function: test_abs_frag_simple * - * Purpose: Test filling and removing all objects from (first) two direct - * blocks in heap + * 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, May 22, 2006 + * Monday, July 24, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_two_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_frag_simple(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -12307,10 +14939,12 @@ test_abs_remove_two_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 obj_size; /* Size of object */ 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 */ + const char *base_desc = "fragmenting small blocks, then backfill and extend, then remove all objects %s"; /* Test description */ char *del_str = NULL; /* Deletion order description */ char *test_desc = NULL; /* Test description */ + unsigned u; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -12324,7 +14958,7 @@ test_abs_remove_two_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 @@ -12345,7 +14979,8 @@ test_abs_remove_two_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR /* Get the size of a file w/empty heap*/ if((empty_size = h5_get_file_size(filename)) == 0) @@ -12367,26 +15002,45 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR /* - * Test filling & removing all (small) objects from two direct blocks of absolute heap + * Display testing message */ del_str = get_del_string(tparam); HDassert(del_str); test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); sprintf(test_desc, base_desc, del_str); TESTING(test_desc); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); /* Initialize the heap ID structure */ HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill the first block in heap */ + /* 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.heap_size = DBLOCK_SIZE(fh, 0); 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, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR + for(u = 0; u < cparam->managed.width; u++) { + state.man_alloc_size += DBLOCK_SIZE(fh, 0); + if(add_obj(fh, dxpl, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(u == 0) { + state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 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.heap_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; + 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -12399,16 +15053,52 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR } /* end if */ - /* Check up on heap... */ - if(check_stats(fh, &state)) + /* (Account for doubling root indirect block for rows 3-4 */ + for(u = 0; u < 2; u++) { + state.heap_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; + 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, 10, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR - /* Fill the second block in heap */ - state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 0); - 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, SMALL_OBJ_SIZE1, &state, &keep_ids)) + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + for(u = 0; u < cparam->managed.width; u++) + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Fill in 2 * start_block_size block */ + obj_size = DBLOCK_FREE(fh, 2) - (DBLOCK_SIZE(fh, 0) / 2); + if(add_obj(fh, dxpl, 20, obj_size, &state, &keep_ids)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -12432,12 +15122,12 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_ERROR fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + FAIL_STACK_ERROR /* Get the size of the file */ if((file_size = h5_get_file_size(filename)) == 0) @@ -12472,26 +15162,29 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_two_direct() */ +} /* test_abs_frag_simple() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_first_row + * Function: test_abs_frag_direct * - * Purpose: Test filling and removing all objects from first row of direct - * blocks in heap + * 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 - * Monday, June 5, 2006 + * Tuesday, July 25, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_frag_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -12501,12 +15194,15 @@ test_abs_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 */ + unsigned root_direct_rows; /* Number of rows in root indirect block */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ + size_t obj_size; /* Size of object */ 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 */ + const char *base_desc = "fragmenting direct blocks, then backfill and extend, then remove all objects %s"; /* Test description */ char *del_str = NULL; /* Deletion order description */ char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -12520,7 +15216,7 @@ test_abs_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t 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 @@ -12541,7 +15237,8 @@ test_abs_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR /* Get the size of a file w/empty heap*/ if((empty_size = h5_get_file_size(filename)) == 0) @@ -12550,36 +15247,163 @@ test_abs_remove_first_row(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); #endif /* QAK */ - /* Re-open the file */ - if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 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 + + /* + * Display testing message + */ + del_str = get_del_string(tparam); + HDassert(del_str); + test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); + sprintf(test_desc, base_desc, del_str); + TESTING(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); + + /* Initialize the heap ID structure */ + HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + + /* Retrieve # of direct rows in root indirect block */ + root_direct_rows = H5HF_get_dtable_max_drows_test(fh); + + /* 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.heap_size = DBLOCK_SIZE(fh, 0); + 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + if(u == 0) { + state.heap_size = cparam->managed.width * DBLOCK_SIZE(fh, 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.heap_size += DBLOCK_SIZE(fh, 1) * cparam->managed.width; + 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* (Account for doubling root indirect block for rows 3-4 */ + for(u = 0; u < 2; u++) { + state.heap_size += DBLOCK_SIZE(fh, u + 2) * cparam->managed.width; + 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 */ + + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* (Account for doubling root indirect block for rows 5-8 */ + for(u = 0; u < 4; u++) { + state.heap_size += DBLOCK_SIZE(fh, u + 4) * cparam->managed.width; + 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 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 + } /* end if */ - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) - FAIL_STACK_ERROR + /* (Account for doubling root indirect block for rows 9-16 */ + for(u = 0; u < 8; u++) { + state.heap_size += DBLOCK_SIZE(fh, u + 8) * cparam->managed.width; + 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 */ - /* - * Test filling & removing all (small) objects from first row of direct blocks of absolute heap - */ - del_str = get_del_string(tparam); - HDassert(del_str); - test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); - sprintf(test_desc, base_desc, del_str); - TESTING(test_desc); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ - /* Initialize the heap ID structure */ - HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR - /* Fill first row of direct blocks */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ /* Check for closing & re-opening the heap */ if(tparam->reopen_heap) { @@ -12602,12 +15426,12 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_ERROR fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + FAIL_STACK_ERROR /* Get the size of the file */ if((file_size = h5_get_file_size(filename)) == 0) @@ -12642,26 +15466,31 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_first_row() */ +} /* test_abs_frag_direct() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_first_two_rows + * Function: test_abs_frag_2nd_direct * - * Purpose: Test filling and removing all objects from first two rows of - * direct blocks in heap + * 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, June 12, 2006 + * Tuesday, July 25, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_first_two_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_frag_2nd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -12671,12 +15500,16 @@ test_abs_remove_first_two_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_par 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 */ + 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 */ off_t file_size; /* Size of file currently */ + 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 = "removing all objects from first two rows of direct blocks of absolute heap %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 */ char *del_str = NULL; /* Deletion order description */ char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -12690,7 +15523,7 @@ test_abs_remove_first_two_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_par 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 @@ -12711,7 +15544,8 @@ test_abs_remove_first_two_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_par TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR /* Get the size of a file w/empty heap*/ if((empty_size = h5_get_file_size(filename)) == 0) @@ -12733,23 +15567,30 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR /* - * Test filling & removing all (small) objects from first row of direct blocks of absolute heap + * Display testing message */ del_str = get_del_string(tparam); HDassert(del_str); test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); sprintf(test_desc, base_desc, del_str); TESTING(test_desc); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); /* Initialize the heap ID structure */ HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill first two rows of direct blocks */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR - if(fill_root_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, &keep_ids)) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -12763,6 +15604,48 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR } /* end if */ + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Check up on heap... */ if(check_stats(fh, &state)) FAIL_STACK_ERROR @@ -12773,12 +15656,12 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_ERROR fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + FAIL_STACK_ERROR /* Get the size of the file */ if((file_size = h5_get_file_size(filename)) == 0) @@ -12813,26 +15696,32 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_first_two_rows() */ +} /* test_abs_frag_2nd_direct() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_first_four_rows + * Function: test_abs_frag_3rd_direct * - * Purpose: Test filling and removing all objects from first four rows of - * direct blocks in heap + * 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, June 13, 2006 + * Tuesday, July 25, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_first_four_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_frag_3rd_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) { hid_t file = -1; /* File ID */ hid_t dxpl = H5P_DATASET_XFER_DEFAULT; /* DXPL to use */ @@ -12842,12 +15731,16 @@ test_abs_remove_first_four_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa 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 */ + unsigned root_direct_rows; /* Number of rows in root indirect block */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ + 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 = "removing all objects from first four rows of direct blocks of absolute heap %s"; /* Test description */ + 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 */ char *del_str = NULL; /* Deletion order description */ char *test_desc = NULL; /* Test description */ + unsigned u, v; /* Local index variables */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -12861,7 +15754,7 @@ test_abs_remove_first_four_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa 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 @@ -12882,7 +15775,8 @@ test_abs_remove_first_four_rows(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR /* Get the size of a file w/empty heap*/ if((empty_size = h5_get_file_size(filename)) == 0) @@ -12904,27 +15798,42 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR /* - * Test filling & removing all (small) objects from first row of direct blocks of absolute heap + * Display testing message */ del_str = get_del_string(tparam); HDassert(del_str); test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); sprintf(test_desc, base_desc, del_str); TESTING(test_desc); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); + del_str = H5MM_xfree(del_str); + test_desc = H5MM_xfree(test_desc); /* Initialize the heap ID structure */ HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill first two rows of direct blocks */ - if(fill_root_row(fh, dxpl, 0, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR - if(fill_root_row(fh, dxpl, 1, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR - if(fill_root_row(fh, dxpl, 2, SMALL_OBJ_SIZE1, &state, &keep_ids)) + /* Retrieve "bulk" filling object size */ + fill_size = get_fill_size(tparam); + + /* Compute # of direct rows in root indirect block */ + root_direct_rows = DTABLE_MAX_DROWS(fh); + + /* Fill direct blocks in root indirect block */ + if(fill_root_direct(fh, dxpl, fill_size, &state, &keep_ids)) FAIL_STACK_ERROR - if(fill_root_row(fh, dxpl, 3, SMALL_OBJ_SIZE1, &state, &keep_ids)) + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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)) FAIL_STACK_ERROR /* Check for closing & re-opening the heap */ @@ -12938,6 +15847,48 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR } /* end if */ + /* 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, 10, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* 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, 20, obj_size, &state, &keep_ids)) + FAIL_STACK_ERROR + } /* end for */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + /* Check up on heap... */ if(check_stats(fh, &state)) FAIL_STACK_ERROR @@ -12948,12 +15899,12 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); /* Close the fractal heap */ if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + FAIL_STACK_ERROR fh = NULL; /* Close the file */ if(H5Fclose(file) < 0) - TEST_ERROR + FAIL_STACK_ERROR /* Get the size of the file */ if((file_size = h5_get_file_size(filename)) == 0) @@ -12988,26 +15939,30 @@ error: H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_first_four_rows() */ +} /* test_abs_frag_3rd_direct() */ +#endif /* QAK */ +#ifndef QAK /*------------------------------------------------------------------------- - * Function: test_abs_remove_all_root_direct + * Function: test_abs_random_managed * - * Purpose: Test filling and removing all objects from all direct blocks - * in root indirect block of heap + * Purpose: Test inserting random sized objects (that are smaller than + * the standalone size) into a heap, and read them back. + * + * Then, go back and remove all objects * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, June 13, 2006 + * Tuesday, May 9, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_random_managed(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 */ @@ -13017,12 +15972,14 @@ test_abs_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa 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 */ + unsigned long seed = 0; /* Random # seed */ + hsize_t total_obj_added; /* Size of objects added */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ + size_t obj_size; /* Size of object */ + size_t obj_loc; /* Location of object in buffer */ 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 */ - char *del_str = NULL; /* Deletion order description */ - char *test_desc = NULL; /* Test description */ + size_t u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -13036,7 +15993,7 @@ test_abs_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa 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 @@ -13057,7 +16014,8 @@ test_abs_remove_all_root_direct(hid_t fapl, H5HF_create_t *cparam, fheap_test_pa TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR /* Get the size of a file w/empty heap*/ if((empty_size = h5_get_file_size(filename)) == 0) @@ -13079,50 +16037,100 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR /* - * Test filling & removing all (small) objects from first row of direct blocks of absolute heap + * Display testing message */ - del_str = get_del_string(tparam); - HDassert(del_str); - test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); - sprintf(test_desc, base_desc, del_str); - TESTING(test_desc); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); + TESTING("inserting random-sized objects (smaller than standalone size), then remove all objects (all - random)"); /* Initialize the heap ID structure */ HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR + /* Choose random # seed */ + seed = (unsigned long)HDtime(NULL); +#ifdef QAK +/* seed = (unsigned long)1153176468; */ +HDfprintf(stderr, "Random # seed was: %lu\n", seed); +#endif /* QAK */ + HDsrandom(seed); - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Loop over adding objects to the heap, until the size limit is reached */ + total_obj_added = 0; + while(total_obj_added < size_limit) { + /* Choose a random size of object (from 1 up to stand alone block size) */ + obj_size = (HDrandom() % (cparam->standalone_size - 1)) + 1; + obj_loc = cparam->standalone_size - obj_size; - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Insert object */ + if(add_obj(fh, dxpl, obj_loc, obj_size, NULL, &keep_ids)) FAIL_STACK_ERROR - } /* end if */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Increment the amount of objects added */ + total_obj_added += obj_size; + } /* end while */ +#ifdef QAK +HDfprintf(stderr, "keep_ids.num_ids = %Zu, total_obj_added = %Hu, size_limit = %Hu\n", keep_ids.num_ids, total_obj_added, size_limit); +#endif /* QAK */ + + /* Randomize the order of the IDs kept */ + for(u = 0; u < keep_ids.num_ids; u++) { + size_t pos; /* Position to swap with */ + + /* Choose a position to swap with */ + /* (0 is current position) */ + pos = HDrandom() % (keep_ids.num_ids - u); + + /* If we chose a different position, swap with it */ + if(pos > 0) { + unsigned char temp_id[HEAP_ID_LEN]; /* Temp. heap ID holder */ + + /* Swap current position with future position */ + /* (just swap the heap ID, the len & offset isn't used */ + HDmemcpy(temp_id, &keep_ids.ids[u * HEAP_ID_LEN], HEAP_ID_LEN); + HDmemcpy(&keep_ids.ids[u * HEAP_ID_LEN], &keep_ids.ids[(u + pos) * HEAP_ID_LEN], HEAP_ID_LEN); + HDmemcpy(&keep_ids.ids[(u + pos) * HEAP_ID_LEN], temp_id, HEAP_ID_LEN); + } /* end if */ + } /* end for */ + + /* Delete objects inserted */ + for(u = 0; u < keep_ids.num_ids; u++) { + /* Remove object from heap */ + if(H5HF_remove(fh, dxpl, &keep_ids.ids[HEAP_ID_LEN * u]) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + } /* end for */ /* Check up on heap... */ if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Delete objects inserted (either forward or reverse order) */ - if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) - FAIL_STACK_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) - TEST_ERROR + FAIL_STACK_ERROR /* Get the size of the file */ if((file_size = h5_get_file_size(filename)) == 0) @@ -13146,38 +16154,39 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); return(0); error: + HDfprintf(stderr, "Random # seed was: %lu\n", seed); H5E_BEGIN_TRY { H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_all_root_direct() */ -#endif /* QAK2 */ +} /* test_abs_random_managed() */ /*------------------------------------------------------------------------- - * Function: test_abs_remove_2nd_indirect + * Function: test_abs_random_pow2_managed * - * Purpose: Test filling and removing all objects up to 2nd level indirect - * blocks of heap + * Purpose: Test inserting random sized objects (that are smaller than the + * standalone size) with a "power of 2 distribution" into a heap, + * and read them back. + * + * Then, go back and remove all objects * * Return: Success: 0 * * Failure: 1 * * Programmer: Quincey Koziol - * Tuesday, June 13, 2006 + * Monday, May 15, 2006 * *------------------------------------------------------------------------- */ static int -test_abs_remove_2nd_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param_t *tparam) +test_abs_random_pow2_managed(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 */ @@ -13187,12 +16196,14 @@ test_abs_remove_2nd_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param 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 */ + unsigned long seed = 0; /* Random # seed */ + hsize_t total_obj_added; /* Size of objects added */ off_t empty_size; /* Size of a file with an empty heap */ off_t file_size; /* Size of file currently */ + size_t obj_size; /* Size of object */ + size_t obj_loc; /* Location of object in buffer */ fheap_heap_state_t state; /* State of fractal heap */ - const char *base_desc = "removing all objects from 2nd level indirect blocks of absolute heap %s"; /* Test description */ - char *del_str = NULL; /* Deletion order description */ - char *test_desc = NULL; /* Test description */ + size_t u; /* Local index variable */ /* Set the filename to use for this test (dependent on fapl) */ h5_fixname(FILENAME[0], fapl, filename, sizeof(filename)); @@ -13206,7 +16217,7 @@ test_abs_remove_2nd_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param 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 @@ -13227,7 +16238,8 @@ test_abs_remove_2nd_indirect(hid_t fapl, H5HF_create_t *cparam, fheap_test_param TEST_ERROR /* Close file */ - if(H5Fclose(file)<0) TEST_ERROR; + if(H5Fclose(file)<0) + TEST_ERROR /* Get the size of a file w/empty heap*/ if((empty_size = h5_get_file_size(filename)) == 0) @@ -13249,54 +16261,112 @@ HDfprintf(stderr, "empty_size = %lu\n", (unsigned long)empty_size); FAIL_STACK_ERROR /* - * Test filling & removing all (small) objects from first row of direct blocks of absolute heap + * Display testing message */ - del_str = get_del_string(tparam); - HDassert(del_str); - test_desc = H5MM_malloc(HDstrlen(del_str) + HDstrlen(base_desc)); - sprintf(test_desc, base_desc, del_str); - TESTING(test_desc); - del_str = H5MM_xfree(del_str); - test_desc = H5MM_xfree(test_desc); + TESTING("inserting random-sized objects with power of 2 distribution (smaller than standalone size), then remove all objects (all - random)"); /* Initialize the heap ID structure */ HDmemset(&keep_ids, 0, sizeof(fheap_heap_ids_t)); - /* Fill direct blocks in root indirect block */ - if(fill_root_direct(fh, dxpl, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR + /* Choose random # seed */ + seed = (unsigned long)HDtime(NULL); +#ifdef QAK +/* seed = (unsigned long)1153176468; */ +HDfprintf(stderr, "Random # seed was: %lu\n", seed); +#endif /* QAK */ + HDsrandom(seed); - /* Fill all rows of 2nd level indirect blocks */ - if(fill_all_2nd_indirect_rows(fh, dxpl, SMALL_OBJ_SIZE1, &state, &keep_ids)) - FAIL_STACK_ERROR + /* Loop over adding objects to the heap, until the size limit is reached */ + total_obj_added = 0; + while(total_obj_added < size_limit) { + unsigned size_range = 64; /* Object size range */ - /* Check for closing & re-opening the heap */ - if(tparam->reopen_heap) { - /* Close heap */ - if(H5HF_close(fh, dxpl) < 0) - TEST_ERROR + /* Determine the size of the range for this object */ + /* (50% of the objects inserted will use the initial size range, + * 25% of the objects will be twice as large, 12.5% will be + * four times larger, etc.) + */ + while(HDrandom() < (RAND_MAX / 2) && size_range < cparam->standalone_size) + size_range *= 2; + if(size_range > cparam->standalone_size) + size_range = cparam->standalone_size; - /* Re-open heap */ - if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + /* Choose a random size of object (from 1 up to stand alone block size) */ + obj_size = (HDrandom() % (size_range - 1)) + 1; + obj_loc = cparam->standalone_size - obj_size; + + /* Insert object */ + if(add_obj(fh, dxpl, obj_loc, obj_size, NULL, &keep_ids)) FAIL_STACK_ERROR - } /* end if */ + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + + /* Increment the amount of objects added */ + total_obj_added += obj_size; + } /* end while */ +#ifdef QAK +HDfprintf(stderr, "keep_ids.num_ids = %Zu, total_obj_added = %Hu, size_limit = %Hu\n", keep_ids.num_ids, total_obj_added, size_limit); +#endif /* QAK */ + + /* Randomize the order of the IDs kept */ + for(u = 0; u < keep_ids.num_ids; u++) { + size_t pos; /* Position to swap with */ + + /* Choose a position to swap with */ + /* (0 is current position) */ + pos = HDrandom() % (keep_ids.num_ids - u); + + /* If we chose a different position, swap with it */ + if(pos > 0) { + unsigned char temp_id[HEAP_ID_LEN]; /* Temp. heap ID holder */ + + /* Swap current position with future position */ + /* (just swap the heap ID, the len & offset isn't used */ + HDmemcpy(temp_id, &keep_ids.ids[u * HEAP_ID_LEN], HEAP_ID_LEN); + HDmemcpy(&keep_ids.ids[u * HEAP_ID_LEN], &keep_ids.ids[(u + pos) * HEAP_ID_LEN], HEAP_ID_LEN); + HDmemcpy(&keep_ids.ids[(u + pos) * HEAP_ID_LEN], temp_id, HEAP_ID_LEN); + } /* end if */ + } /* end for */ + + /* Delete objects inserted */ + for(u = 0; u < keep_ids.num_ids; u++) { + /* Remove object from heap */ + if(H5HF_remove(fh, dxpl, &keep_ids.ids[HEAP_ID_LEN * u]) < 0) + FAIL_STACK_ERROR + + /* Check for closing & re-opening the heap */ + if(tparam->reopen_heap) { + /* Close (empty) heap */ + if(H5HF_close(fh, dxpl) < 0) + TEST_ERROR + + /* Re-open heap */ + if(NULL == (fh = H5HF_open(f, dxpl, fh_addr))) + FAIL_STACK_ERROR + } /* end if */ + } /* end for */ /* Check up on heap... */ if(check_stats(fh, &state)) FAIL_STACK_ERROR - /* Delete objects inserted (either forward or reverse order) */ - if(del_objs(f, dxpl, &fh, tparam, &state, &keep_ids)) - FAIL_STACK_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) - TEST_ERROR + FAIL_STACK_ERROR /* Get the size of the file */ if((file_size = h5_get_file_size(filename)) == 0) @@ -13320,18 +16390,17 @@ HDfprintf(stderr, "file_size = %lu\n", (unsigned long)file_size); return(0); error: + HDfprintf(stderr, "Random # seed was: %lu\n", seed); H5E_BEGIN_TRY { H5MM_xfree(keep_ids.ids); H5MM_xfree(keep_ids.lens); H5MM_xfree(keep_ids.offs); - H5MM_xfree(del_str); - H5MM_xfree(test_desc); if(fh) H5HF_close(fh, dxpl); H5Fclose(file); } H5E_END_TRY; return(1); -} /* test_abs_remove_2nd_indirect() */ +} /* test_abs_random_pow2_managed() */ #endif /* QAK */ @@ -13412,170 +16481,215 @@ curr_test = FHEAP_TEST_NORMAL; nerrors += test_create(fapl, &cparam, &tparam); nerrors += test_reopen(fapl, &cparam, &tparam); - /* - * Test fractal heap object insertion - */ +#ifndef QAK + { + fheap_test_fill_t fill; /* Size of objects to fill heap blocks with */ + +#ifndef QAK2 + /* Filling with different sized objects */ + for(fill = FHEAP_TEST_FILL_LARGE; fill < FHEAP_TEST_FILL_N; fill++) { +#else /* QAK2 */ +HDfprintf(stderr, "Uncomment test loop!\n"); +fill = FHEAP_TEST_FILL_LARGE; +/* fill = FHEAP_TEST_FILL_SINGLE; */ +#endif /* QAK2 */ + tparam.fill = fill; + + /* Set appropriate testing parameters for each test */ + switch(fill) { + /* "Bulk fill" heap blocks with 'large' objects */ + case FHEAP_TEST_FILL_LARGE: + puts("Bulk-filling blocks w/large objects"); + break; + + /* "Bulk fill" heap blocks with 'single' objects */ + case FHEAP_TEST_FILL_SINGLE: + puts("Bulk-filling blocks w/single object"); + break; + + /* An unknown test? */ + default: + goto error; + } /* end switch */ + + /* + * Test fractal heap object insertion + */ #ifdef ALL_INSERT_TESTS - /* Simple insertion */ - nerrors += test_abs_insert_first(fapl, &cparam, &tparam); - nerrors += test_abs_insert_second(fapl, &cparam, &tparam); - nerrors += test_abs_insert_root_mult(fapl, &cparam, &tparam); - nerrors += test_abs_insert_force_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_insert_fill_second(fapl, &cparam, &tparam); - nerrors += test_abs_insert_third_direct(fapl, &cparam, &tparam); - nerrors += test_abs_fill_first_row(fapl, &cparam, &tparam); - nerrors += test_abs_start_second_row(fapl, &cparam, &tparam); - nerrors += test_abs_fill_second_row(fapl, &cparam, &tparam); - nerrors += test_abs_start_third_row(fapl, &cparam, &tparam); - nerrors += test_abs_fill_fourth_row(fapl, &cparam, &tparam); - nerrors += test_abs_fill_all_root_direct(fapl, &cparam, &tparam); - nerrors += test_abs_first_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_second_direct_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_first_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_second_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_second_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_recursive_indirect_row(fapl, &cparam, &tparam); - nerrors += test_abs_start_2nd_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_recursive_indirect_two_deep(fapl, &cparam, &tparam); - nerrors += test_abs_start_3rd_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_first_3rd_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_3rd_recursive_indirect_row(fapl, &cparam, &tparam); - nerrors += test_abs_fill_all_3rd_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_start_4th_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_first_4th_recursive_indirect(fapl, &cparam, &tparam); - nerrors += test_abs_fill_4th_recursive_indirect_row(fapl, &cparam, &tparam); - nerrors += test_abs_fill_all_4th_recursive_indirect(fapl, &cparam, &tparam); + /* Simple insertion */ + nerrors += test_abs_insert_first(fapl, &cparam, &tparam); + nerrors += test_abs_insert_second(fapl, &cparam, &tparam); + nerrors += test_abs_insert_root_mult(fapl, &cparam, &tparam); + nerrors += test_abs_insert_force_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_insert_fill_second(fapl, &cparam, &tparam); + nerrors += test_abs_insert_third_direct(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_row(fapl, &cparam, &tparam); + nerrors += test_abs_start_second_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_second_row(fapl, &cparam, &tparam); + nerrors += test_abs_start_third_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_fourth_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_all_root_direct(fapl, &cparam, &tparam); + nerrors += test_abs_first_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_second_direct_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_second_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_second_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_recursive_indirect_row(fapl, &cparam, &tparam); + nerrors += test_abs_start_2nd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_recursive_indirect_two_deep(fapl, &cparam, &tparam); + nerrors += test_abs_start_3rd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_3rd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_recursive_indirect_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_all_3rd_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_start_4th_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_first_4th_recursive_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_fill_4th_recursive_indirect_row(fapl, &cparam, &tparam); + nerrors += test_abs_fill_all_4th_recursive_indirect(fapl, &cparam, &tparam); #endif /* ALL_INSERT_TESTS */ - /* If this test fails, uncomment the tests above, which build up to this - * level of complexity gradually. -QAK - */ + /* If this test fails, uncomment the tests above, which build up to this + * level of complexity gradually. -QAK + */ #ifndef QAK - if (ExpressMode > 1) - printf("***Express test mode on. test_abs_start_5th_recursive_indirect is skipped\n"); - else - nerrors += test_abs_start_5th_recursive_indirect(fapl, &cparam, &tparam); + if (ExpressMode > 1) + printf("***Express test mode on. test_abs_start_5th_recursive_indirect is skipped\n"); + else + nerrors += test_abs_start_5th_recursive_indirect(fapl, &cparam, &tparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ + /* + * Test fractal heap object deletion + */ + /* Simple removal */ #ifndef QAK - /* Skip blocks insertion */ - nerrors += test_abs_skip_start_block(fapl, &cparam, &tparam); - nerrors += test_abs_skip_start_block_add_back(fapl, &cparam, &tparam); - nerrors += test_abs_skip_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_skip_2nd_block(fapl, &cparam, &tparam); - nerrors += test_abs_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_one_partial_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_row_skip_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_direct_skip_indirect_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_direct_skip_indirect_two_rows_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_2nd_direct_skip_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(fapl, &cparam, &tparam); - nerrors += test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(fapl, &cparam, &tparam); - - /* Additional skipped block insertion tests */ - nerrors += test_abs_skip_direct_skip_indirect_two_rows_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_remove_bogus(fapl, &cparam, &tparam); + nerrors += test_abs_remove_one(fapl, &cparam, &tparam); + nerrors += test_abs_remove_two(fapl, &cparam, &tparam); + nerrors += test_abs_remove_one_larger(fapl, &cparam, &tparam); + tparam.del_dir = FHEAP_DEL_FORWARD; + nerrors += test_abs_remove_two_larger(fapl, &cparam, &tparam); + tparam.del_dir = FHEAP_DEL_REVERSE; + nerrors += test_abs_remove_two_larger(fapl, &cparam, &tparam); + tparam.del_dir = FHEAP_DEL_FORWARD; + nerrors += test_abs_remove_three_larger(fapl, &cparam, &tparam); + tparam.del_dir = FHEAP_DEL_REVERSE; + nerrors += test_abs_remove_three_larger(fapl, &cparam, &tparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ - /* Fragmented block insertion */ #ifndef QAK - nerrors += test_abs_frag_simple(fapl, &cparam, &tparam); - nerrors += test_abs_frag_direct(fapl, &cparam, &tparam); - nerrors += test_abs_frag_2nd_direct(fapl, &cparam, &tparam); - nerrors += test_abs_frag_3rd_direct(fapl, &cparam, &tparam); -#else /* QAK */ -HDfprintf(stderr, "Uncomment tests!\n"); -#endif /* QAK */ +#ifndef QAK2 + { + fheap_test_del_dir_t del_dir; /* Deletion direction */ + fheap_test_del_drain_t drain_half; /* Deletion draining */ + + /* More complex removal patterns */ + for(drain_half = FHEAP_DEL_DRAIN_ALL; drain_half < FHEAP_DEL_DRAIN_N; drain_half++) { + tparam.drain_half = drain_half; + for(del_dir = FHEAP_DEL_FORWARD; del_dir < FHEAP_DEL_NDIRS; del_dir++) { + tparam.del_dir = del_dir; +#else /* QAK2 */ +HDfprintf(stderr, "Uncomment test loops!\n"); +tparam.drain_half = FHEAP_DEL_DRAIN_ALL; +/* tparam.drain_half = FHEAP_DEL_DRAIN_HALF; */ +tparam.del_dir = FHEAP_DEL_FORWARD; +/* tparam.del_dir = FHEAP_DEL_REVERSE; */ +#endif /* QAK2 */ - /* Random object insertion */ #ifndef QAK - if (ExpressMode > 1) - printf("***Express test mode on. Some tests skipped\n"); - else { - nerrors += test_abs_random_managed((hsize_t)(100*1000*1000), fapl, &cparam, &tparam); - nerrors += test_abs_random_pow2_managed((hsize_t)(100*1000*1000), fapl, &cparam, &tparam); - } /* end else */ -#else /* QAK */ -HDfprintf(stderr, "Uncomment tests!\n"); + /* Simple insertion patterns */ + nerrors += test_abs_remove_root_direct(fapl, &cparam, &tparam); + nerrors += test_abs_remove_two_direct(fapl, &cparam, &tparam); + nerrors += test_abs_remove_first_row(fapl, &cparam, &tparam); + nerrors += test_abs_remove_first_two_rows(fapl, &cparam, &tparam); + nerrors += test_abs_remove_first_four_rows(fapl, &cparam, &tparam); + if (ExpressMode > 1) + printf("***Express test mode on. Some tests skipped\n"); + else { + nerrors += test_abs_remove_all_root_direct(fapl, &cparam, &tparam); + nerrors += test_abs_remove_2nd_indirect(fapl, &cparam, &tparam); + nerrors += test_abs_remove_3rd_indirect(fapl, &cparam, &tparam); + } /* end else */ #endif /* QAK */ - /* - * Test fractal heap object deletion - */ - /* Simple removal */ #ifndef QAK - nerrors += test_abs_remove_bogus(fapl, &cparam, &tparam); - nerrors += test_abs_remove_one(fapl, &cparam, &tparam); - nerrors += test_abs_remove_two(fapl, &cparam, &tparam); - nerrors += test_abs_remove_one_larger(fapl, &cparam, &tparam); - tparam.del_dir = HEAP_DEL_FORWARD; - nerrors += test_abs_remove_two_larger(fapl, &cparam, &tparam); - tparam.del_dir = HEAP_DEL_REVERSE; - nerrors += test_abs_remove_two_larger(fapl, &cparam, &tparam); - tparam.del_dir = HEAP_DEL_FORWARD; - nerrors += test_abs_remove_three_larger(fapl, &cparam, &tparam); - tparam.del_dir = HEAP_DEL_REVERSE; - nerrors += test_abs_remove_three_larger(fapl, &cparam, &tparam); + /* Skip blocks insertion */ + /* (covers insertion & deletion of skipped blocks) */ + nerrors += test_abs_skip_start_block(fapl, &cparam, &tparam); + nerrors += test_abs_skip_start_block_add_back(fapl, &cparam, &tparam); + nerrors += test_abs_skip_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_skip_2nd_block(fapl, &cparam, &tparam); + nerrors += test_abs_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_one_partial_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_row_skip_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_skip_direct_skip_indirect_two_rows_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_less_one_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_2nd_indirect_skip_2nd_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_indirect_two_rows_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_direct_skip_indirect_two_rows_skip_indirect_row_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_skip_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_skip_2nd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_2nd_direct_fill_direct_skip2_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_less_one_fill_direct_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_1st_row_3rd_direct_fill_2nd_direct_less_one_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + if (ExpressMode > 1) + printf("***Express test mode on. Some tests skipped\n"); + else { + nerrors += test_abs_fill_3rd_direct_fill_direct_skip_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_two_rows_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_3rd_direct_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + nerrors += test_abs_fill_4th_direct_less_one_fill_2nd_direct_fill_direct_skip_3rd_indirect_wrap_start_block_add_skipped(fapl, &cparam, &tparam); + } /* end else */ #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ #ifndef QAK + /* Fragmented insertion patterns */ + /* (covers insertion & deletion of fragmented blocks) */ + nerrors += test_abs_frag_simple(fapl, &cparam, &tparam); + nerrors += test_abs_frag_direct(fapl, &cparam, &tparam); + nerrors += test_abs_frag_2nd_direct(fapl, &cparam, &tparam); + nerrors += test_abs_frag_3rd_direct(fapl, &cparam, &tparam); +#else /* QAK */ + HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ #ifndef QAK2 - { - fheap_test_del_dir_t del_dir; /* Deletion direction */ - fheap_test_del_drain_t drain_half; /* Deletion draining */ - - /* More complex removals */ - for(drain_half = HEAP_DEL_DRAIN_ALL; drain_half < HEAP_DEL_DRAIN_N; drain_half++) { - tparam.drain_half = drain_half; - for(del_dir = HEAP_DEL_FORWARD; del_dir < HEAP_DEL_NDIRS; del_dir++) { - tparam.del_dir = del_dir; -#else /* QAK2 */ -HDfprintf(stderr, "Uncomment test loops!\n"); -/* tparam.drain_half = HEAP_DEL_DRAIN_ALL; */ -tparam.drain_half = HEAP_DEL_DRAIN_HALF; -/* tparam.del_dir = HEAP_DEL_FORWARD; */ -tparam.del_dir = HEAP_DEL_REVERSE; -#endif /* QAK2 */ - -#ifndef QAK -#ifndef QAK2 - nerrors += test_abs_remove_root_direct(fapl, &cparam, &tparam); - nerrors += test_abs_remove_two_direct(fapl, &cparam, &tparam); - nerrors += test_abs_remove_first_row(fapl, &cparam, &tparam); - nerrors += test_abs_remove_first_two_rows(fapl, &cparam, &tparam); - nerrors += test_abs_remove_first_four_rows(fapl, &cparam, &tparam); - nerrors += test_abs_remove_all_root_direct(fapl, &cparam, &tparam); -#else /* QAK2 */ -HDfprintf(stderr, "Uncomment tests!\n"); + } /* end for */ + } /* end for */ + } /* end block */ #endif /* QAK2 */ - nerrors += test_abs_remove_2nd_indirect(fapl, &cparam, &tparam); #else /* QAK */ HDfprintf(stderr, "Uncomment tests!\n"); #endif /* QAK */ #ifndef QAK2 } /* end for */ - } /* end for */ - } /* end block */ #endif /* QAK2 */ + } /* end block */ +#else /* QAK */ +HDfprintf(stderr, "Uncomment tests!\n"); +#endif /* QAK */ + +#ifndef QAK + /* Random object insertion & deletion */ + if (ExpressMode > 1) + printf("***Express test mode on. Some tests skipped\n"); + else { + /* (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 */ + nerrors += test_abs_random_managed((curr_test == FHEAP_TEST_NORMAL ? (hsize_t)(100*1000*1000) : (hsize_t)(50*1000*1000)), fapl, &cparam, &tparam); + nerrors += test_abs_random_pow2_managed((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"); #endif /* QAK */ + #ifndef QAK } /* end for */ #endif /* QAK */ -- cgit v0.12