summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2006-07-31 09:54:09 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2006-07-31 09:54:09 (GMT)
commit87449d081d1c99312034d917502f2b6aca2ee60c (patch)
treed21839e74c6602b9a60ce383207001675b4b5ebd /src
parentce859f41bb12e07ecb8dff6a783ca21e782ad6fe (diff)
downloadhdf5-87449d081d1c99312034d917502f2b6aca2ee60c.zip
hdf5-87449d081d1c99312034d917502f2b6aca2ee60c.tar.gz
hdf5-87449d081d1c99312034d917502f2b6aca2ee60c.tar.bz2
[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)
Diffstat (limited to 'src')
-rw-r--r--src/H5FS.c187
-rw-r--r--src/H5FSprivate.h5
-rw-r--r--src/H5HF.c17
-rw-r--r--src/H5HFdbg.c12
-rw-r--r--src/H5HFdblock.c4
-rw-r--r--src/H5HFdtable.c85
-rw-r--r--src/H5HFhdr.c58
-rw-r--r--src/H5HFiblock.c4
-rw-r--r--src/H5HFint.c5
-rw-r--r--src/H5HFpkg.h9
-rw-r--r--src/H5HFsection.c725
11 files changed, 760 insertions, 351 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, &sect_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(&sect->u.indirect.dir_rows[0],
&sect->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);
&sect->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. */