summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5FS.c231
-rw-r--r--src/H5FSprivate.h12
-rw-r--r--src/H5HFpkg.h7
-rw-r--r--src/H5HFsection.c994
-rw-r--r--src/H5HFspace.c83
-rw-r--r--src/H5SL.c2
-rw-r--r--test/fheap.c14
7 files changed, 772 insertions, 571 deletions
diff --git a/src/H5FS.c b/src/H5FS.c
index 7b8e222..e465e11 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -119,8 +119,6 @@ static herr_t H5FS_sect_unlink_size(H5FS_t *fspace, const H5FS_section_class_t *
H5FS_section_info_t *sect);
static herr_t H5FS_sect_unlink_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_unlink(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
- H5FS_section_info_t *sect);
static herr_t H5FS_sect_link_size_bin(H5FS_t *fspace, const H5FS_section_class_t *cls,
H5FS_section_info_t *sect);
static herr_t H5FS_sect_link_size(H5FS_t *fspace, const H5FS_section_class_t *cls,
@@ -727,6 +725,7 @@ H5FS_sect_decrease(H5FS_t *fspace, const H5FS_section_class_t *cls)
/* Make certain there's only one section of this size */
HDassert(H5SL_count(fspace_node->sect_list) == 1);
HDassert((fspace_node->serial_count + fspace_node->ghost_count) == 1);
+ HDassert((fspace->hdr->serial_sect_count + fspace->hdr->ghost_sect_count) == 1);
/* Remove the free space section from the section size list */
if(NULL == (sect = H5SL_remove_first(fspace_node->sect_list)))
@@ -938,7 +937,6 @@ static herr_t
H5FS_sect_unlink_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
const H5FS_section_class_t *cls, H5FS_section_info_t *sect)
{
- H5FS_section_info_t *tmp_sect_node; /* Temporary section node */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_unlink_rest)
@@ -949,10 +947,17 @@ H5FS_sect_unlink_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
HDassert(cls);
HDassert(sect);
- /* Remove node from merge list */
- tmp_sect_node = H5SL_remove(fspace->merge_list, &sect->addr);
- if(tmp_sect_node == NULL || tmp_sect_node != sect)
- HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section node on size list")
+ /* Remove node from merge list, if it was entered there */
+ if(!(cls->flags & H5FS_CLS_SEPAR_OBJ)) {
+ H5FS_section_info_t *tmp_sect_node; /* Temporary section node */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: removing object from merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
+#endif /* QAK */
+ tmp_sect_node = H5SL_remove(fspace->merge_list, &sect->addr);
+ if(tmp_sect_node == NULL || tmp_sect_node != sect)
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section node on size list")
+ } /* end if */
/* Decrement amount of space required to serialize all sections */
fspace->serial_size -= fspace->sect_cls[sect->type].serial_size;
@@ -978,12 +983,11 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5FS_sect_unlink
+ * Function: H5FS_remove
*
- * Purpose: Unlink a section from the internal data structures
+ * Purpose: Remove a section from the free space manager
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
@@ -991,13 +995,13 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5FS_sect_unlink(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect)
+herr_t
+H5FS_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *sect)
{
const H5FS_section_class_t *cls; /* Class of section */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_unlink)
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_remove)
/* Check arguments. */
HDassert(f);
@@ -1017,7 +1021,7 @@ H5FS_sect_unlink(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_section_info_t *s
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5FS_sect_unlink() */
+} /* H5FS_remove() */
/*-------------------------------------------------------------------------
@@ -1246,12 +1250,17 @@ H5FS_sect_link_rest(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, const H5FS_section_
HDassert(fspace);
HDassert(sect);
- /* Add section to the address-ordered list of sections */
- if(fspace->merge_list == NULL)
- if(NULL == (fspace->merge_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, H5FS_DEFAULT_SKIPLIST_HEIGHT)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
- if(H5SL_insert(fspace->merge_list, sect, &sect->addr) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
+ /* Add section to the address-ordered list of sections, if allowed */
+ if(!(cls->flags & H5FS_CLS_SEPAR_OBJ)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
+#endif /* QAK */
+ if(fspace->merge_list == NULL)
+ if(NULL == (fspace->merge_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, H5FS_DEFAULT_SKIPLIST_HEIGHT)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
+ if(H5SL_insert(fspace->merge_list, sect, &sect->addr) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
+ } /* end if */
/* Increment amount of space required to serialize all sections */
#ifdef QAK
@@ -1344,8 +1353,9 @@ static herr_t
H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
H5FS_section_info_t **sect, void *op_data)
{
- H5FS_section_class_t *sect_cls = NULL; /* Section's class */
- hbool_t merged; /* Flag to indicate merge occurred */
+ H5FS_section_class_t *sect_cls; /* Section's class */
+ H5FS_section_info_t *tmp_sect_node; /* Temporary free space section */
+ hbool_t modified; /* Flag to indicate merge or shrink occurred */
htri_t status; /* Status value */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1361,18 +1371,25 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
/* Loop until no more merging */
do {
H5FS_section_class_t *tmp_sect_cls; /* Temporary section's class */
- H5FS_section_info_t *tmp_sect_node; /* Temporary free space section */
- /* Reset 'merge occurred' flag */
- merged = FALSE;
+ /* 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) {
- tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type]; /* Use class for left-most section */
- if(tmp_sect_cls->can_merge) {
+ /* 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")
@@ -1381,12 +1398,10 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
HDassert(tmp_sect_cls->merge);
/* Remove 'less than' node from data structures */
- if(H5FS_sect_unlink(f, dxpl_id, fspace, tmp_sect_node) < 0)
+ 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 */
- /* (rescan the class of the node, the 'can merge' callback can change it) */
- tmp_sect_cls = &fspace->sect_cls[tmp_sect_node->type]; /* Use class for left-most section */
if((*tmp_sect_cls->merge)(tmp_sect_node, *sect, op_data) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't merge two sections")
@@ -1394,7 +1409,7 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
*sect = tmp_sect_node;
/* Indicate successful merge occurred */
- merged = TRUE;
+ modified = TRUE;
} /* end if */
} /* end if */
} /* end if */
@@ -1404,54 +1419,87 @@ H5FS_sect_merge(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
/* Check for node after new node able to merge with new node */
if(tmp_sect_node) {
- tmp_sect_cls = &fspace->sect_cls[(*sect)->type]; /* Use class for left-most section */
- if(tmp_sect_cls->can_merge) {
+ /* 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 = (*tmp_sect_cls->can_merge)(*sect, tmp_sect_node, op_data)) < 0)
+ 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(tmp_sect_cls->merge);
+ HDassert(sect_cls->merge);
/* Remove 'greater than' node from data structures */
- if(H5FS_sect_unlink(f, dxpl_id, fspace, tmp_sect_node) < 0)
+ 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 */
- /* (rescan the class of the node, the 'can merge' callback can change it) */
- tmp_sect_cls = &fspace->sect_cls[(*sect)->type]; /* Use class for left-most section */
- if((*tmp_sect_cls->merge)(*sect, tmp_sect_node, op_data) < 0)
+ 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 */
- merged = TRUE;
+ modified = TRUE;
} /* end if */
} /* end if */
} /* end if */
- } while(merged);
+ } while(modified);
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"));
#endif /* QAK */
- /* Check for (possibly merged) section able to shrink the size of the container */
- sect_cls = &fspace->sect_cls[(*sect)->type];
- if(sect_cls->can_shrink) {
- if((status = (*sect_cls->can_shrink)(*sect, op_data)) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTSHRINK, FAIL, "can't check for shrinking container")
- if(status > 0) {
+ /* Loop until no more shrinking */
+ do {
+ /* Reset 'modification occurred' flag */
+ modified = FALSE;
+
+ /* Check for (possibly merged) section able to shrink the size of the container */
+ sect_cls = &fspace->sect_cls[(*sect)->type];
+ if(sect_cls->can_shrink) {
+ if((status = (*sect_cls->can_shrink)(*sect, op_data)) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTSHRINK, FAIL, "can't check for shrinking container")
+ if(status > 0) {
#ifdef QAK
HDfprintf(stderr, "%s: Can shrink!\n", FUNC);
#endif /* QAK */
- /* Shrink the container */
- /* (callback can indicate that it has discarded the section by setting *sect to NULL) */
- /* (rescan the class of the node, the 'can shrink' callback can change it) */
- sect_cls = &fspace->sect_cls[(*sect)->type];
- HDassert(sect_cls->shrink);
- if((*sect_cls->shrink)(sect, op_data) < 0)
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't shrink free space container")
+ /* Look for neighboring section before new section */
+ tmp_sect_node = H5SL_less(fspace->merge_list, &(*sect)->addr);
+
+ /* Shrink the container */
+ /* (callback can indicate that it has discarded the section by setting *sect to NULL) */
+ HDassert(sect_cls->shrink);
+ if((*sect_cls->shrink)(sect, op_data) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't shrink free space container")
+
+ /* Check if the new section was removed */
+ if(*sect == NULL && tmp_sect_node) {
+ /* 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")
+
+ *sect = tmp_sect_node;
+ } /* end if */
+
+ /* Indicate successful merge occurred */
+ modified = TRUE;
+ } /* end if */
} /* end if */
- } /* end if */
+ } while(modified && *sect);
+#ifdef QAK
+HDfprintf(stderr, "%s: Done shrinking\n", FUNC);
+if(*sect)
+ 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"));
+else
+ HDfprintf(stderr, "%s: *sect = %p\n", FUNC, *sect);
+#endif /* QAK */
done:
#ifdef QAK
@@ -2568,11 +2616,12 @@ done:
herr_t
H5FS_sect_change_class(H5FS_t *fspace, H5FS_section_info_t *sect, unsigned new_class)
{
- const H5FS_section_class_t *old_cls; /* Old class of section */
- const H5FS_section_class_t *new_cls; /* New class of section */
- unsigned old_class; /* Old class ID of section */
+ const H5FS_section_class_t *old_cls; /* Old class of section */
+ const H5FS_section_class_t *new_cls; /* New class of section */
+ unsigned old_class; /* Old class ID of section */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sect_change_class)
+ FUNC_ENTER_NOAPI_NOINIT(H5FS_sect_change_class)
/* Check arguments. */
HDassert(fspace);
@@ -2580,14 +2629,15 @@ H5FS_sect_change_class(H5FS_t *fspace, H5FS_section_info_t *sect, unsigned new_c
HDassert(sect);
HDassert(sect->type < fspace->hdr->nclasses);
HDassert(new_class < fspace->hdr->nclasses);
-#ifdef QAK
-HDfprintf(stderr, "%s: Called\n", "H5FS_sect_change_class");
-#endif /* QAK */
/* Get class info */
old_class = sect->type;
old_cls = &fspace->sect_cls[sect->type];
new_cls = &fspace->sect_cls[new_class];
+#ifdef QAK
+HDfprintf(stderr, "%s: old_cls->flags = %x\n", FUNC, old_cls->flags);
+HDfprintf(stderr, "%s: new_cls->flags = %x\n", FUNC, new_cls->flags);
+#endif /* QAK */
/* Check if the section's class change will affect the # of serializable or ghost sections */
if((old_cls->flags & H5FS_CLS_GHOST_OBJ) != (new_cls->flags & H5FS_CLS_GHOST_OBJ)) {
@@ -2599,7 +2649,7 @@ HDfprintf(stderr, "%s: Called\n", "H5FS_sect_change_class");
else
to_ghost = TRUE;
#ifdef QAK
-HDfprintf(stderr, "%s: to_ghost = %u\n", "H5FS_sect_change_class", to_ghost);
+HDfprintf(stderr, "%s: to_ghost = %u\n", FUNC, to_ghost);
#endif /* QAK */
/* Check for single vs. multiple sections managed */
@@ -2676,6 +2726,42 @@ HDfprintf(stderr, "%s: to_ghost = %u\n", "H5FS_sect_change_class", to_ghost);
} /* end else */
} /* end if */
+ /* Check if the section's class change will affect the mergable list */
+ if((old_cls->flags & H5FS_CLS_SEPAR_OBJ) != (new_cls->flags & H5FS_CLS_SEPAR_OBJ)) {
+ hbool_t to_mergable; /* Flag if the section is changing to a mergable section */
+
+ /* Determine if this section is becoming mergable or is becoming separate */
+ if(old_cls->flags & H5FS_CLS_SEPAR_OBJ)
+ to_mergable = TRUE;
+ else
+ to_mergable = FALSE;
+#ifdef QAK
+HDfprintf(stderr, "%s: to_mergable = %u\n", FUNC, to_mergable);
+#endif /* QAK */
+
+ /* Add or remove section from merge list, as appropriate */
+ if(to_mergable) {
+#ifdef QAK
+HDfprintf(stderr, "%s: inserting object into merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
+#endif /* QAK */
+ if(fspace->merge_list == NULL)
+ if(NULL == (fspace->merge_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, H5FS_DEFAULT_SKIPLIST_HEIGHT)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTCREATE, FAIL, "can't create skip list for merging free space sections")
+ if(H5SL_insert(fspace->merge_list, sect, &sect->addr) < 0)
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, FAIL, "can't insert free space node into merging skip list")
+ } /* end if */
+ else {
+ H5FS_section_info_t *tmp_sect_node; /* Temporary section node */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: removing object from merge list, sect->type = %u\n", FUNC, (unsigned)sect->type);
+#endif /* QAK */
+ tmp_sect_node = H5SL_remove(fspace->merge_list, &sect->addr);
+ if(tmp_sect_node == NULL || tmp_sect_node != sect)
+ HGOTO_ERROR(H5E_FSPACE, H5E_NOTFOUND, FAIL, "can't find section node on size list")
+ } /* end else */
+ } /* end if */
+
/* Change the section's class */
sect->type = new_class;
@@ -2689,10 +2775,11 @@ HDfprintf(stderr, "%s: to_ghost = %u\n", "H5FS_sect_change_class", to_ghost);
/* Mark free space as dirty also */
fspace->dirty = TRUE;
+done:
#ifdef H5FS_DEBUG
H5FS_assert(fspace);
#endif /* H5FS_DEBUG */
- FUNC_LEAVE_NOAPI(SUCCEED)
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5FS_sect_change_class() */
@@ -2965,11 +3052,16 @@ H5FS_debug_test(const H5FS_t *fspace)
herr_t
H5FS_assert(const H5FS_t *fspace)
{
+ hsize_t separate_obj; /* The number of separate objects managed */
+
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_assert)
#ifdef QAK
HDfprintf(stderr, "%s: fspace->hdr->tot_sect_count = %Hu\n", "H5FS_assert", fspace->hdr->tot_sect_count);
#endif /* QAK */
+ /* Initialize state */
+ separate_obj = 0;
+
/* Check for single vs. multiple sections managed */
if(fspace->single) {
const H5FS_section_class_t *cls; /* Class of section */
@@ -2996,6 +3088,10 @@ HDfprintf(stderr, "%s: fspace->single->size = %Hu, fspace->single->addr = %a, fs
HDassert(fspace->hdr->serial_sect_count == 1);
HDassert(fspace->hdr->ghost_sect_count == 0);
} /* end else */
+
+ /* Count node, if separate */
+ if(cls->flags & H5FS_CLS_SEPAR_OBJ)
+ separate_obj++;
} /* end if */
else if(fspace->bins) {
hsize_t acc_tot_sect_count; /* Accumulated total section count from bins */
@@ -3064,6 +3160,10 @@ HDfprintf(stderr, "%s: sect->size = %Hu, sect->addr = %a, sect->type = %u\n", "H
else
size_serial_count++;
+ /* Count node, if separate */
+ if(cls->flags & H5FS_CLS_SEPAR_OBJ)
+ separate_obj++;
+
/* Get the next section node in the list */
curr_sect_node = H5SL_next(curr_sect_node);
} /* end while */
@@ -3116,10 +3216,11 @@ 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));
+ HDassert(fspace->hdr->serial_sect_count > 0 || fspace->hdr->ghost_sect_count == 0);
/* Make certain that the number of sections on the address list is correct */
if(fspace->merge_list)
- HDassert(fspace->hdr->tot_sect_count == H5SL_count(fspace->merge_list));
+ HDassert(fspace->hdr->tot_sect_count == (separate_obj + H5SL_count(fspace->merge_list)));
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5FS_assert() */
diff --git a/src/H5FSprivate.h b/src/H5FSprivate.h
index 25383cc..2b840bd 100644
--- a/src/H5FSprivate.h
+++ b/src/H5FSprivate.h
@@ -42,6 +42,12 @@
#define H5FS_CLS_GHOST_OBJ 0x01 /* Objects in this class shouldn't be
* serialized to the file.
*/
+#define H5FS_CLS_SEPAR_OBJ 0x02 /* Objects in this class shouldn't
+ * participate in merge operations
+ */
+#define H5FS_CLS_MERGE_SYM 0x04 /* Objects in this class only merge
+ * with other objects in this class
+ */
/* Flags for H5FS_add() */
#define H5FS_ADD_DESERIALIZING 0x01 /* Free space is being deserialized
@@ -86,9 +92,9 @@ typedef struct H5FS_section_class_t {
/* Object methods */
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)(H5FS_section_info_t *, H5FS_section_info_t *, void *); /* Routine to determine if two nodes are mergable */
+ htri_t (*can_merge)(const H5FS_section_info_t *, const H5FS_section_info_t *, void *); /* Routine to determine if two nodes are mergable */
herr_t (*merge)(H5FS_section_info_t *, H5FS_section_info_t *, void *); /* Routine to merge two nodes */
- htri_t (*can_shrink)(H5FS_section_info_t *, void *); /* Routine to determine if node can shrink container */
+ htri_t (*can_shrink)(const H5FS_section_info_t *, void *); /* Routine to determine if node can shrink container */
herr_t (*shrink)(H5FS_section_info_t **, void *); /* Routine to shrink container */
herr_t (*free)(H5FS_section_info_t *); /* Routine to free node */
herr_t (*valid)(const struct H5FS_section_class_t *, const H5FS_section_info_t *); /* Routine to check if a section is valid */
@@ -147,6 +153,8 @@ H5_DLL H5FS_t *H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr,
size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata);
H5_DLL herr_t H5FS_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
H5FS_section_info_t *node, unsigned flags, void *op_data);
+H5_DLL herr_t H5FS_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
+ H5FS_section_info_t *node);
H5_DLL htri_t H5FS_find(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
hsize_t request, H5FS_section_info_t **node);
H5_DLL herr_t H5FS_iterate(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_operator_t op, void *op_data);
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 15f0665..aa7c3bf 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -359,7 +359,6 @@ typedef struct H5HF_parent_t {
typedef struct {
H5HF_hdr_t *hdr; /* Fractal heap header */
hid_t dxpl_id; /* DXPL ID for operation */
- hbool_t adjoin; /* Whether two spans of blocks adjoin each other */
} H5HF_add_ud1_t;
/*****************************/
@@ -521,10 +520,12 @@ H5_DLL hbool_t H5HF_man_iter_ready(H5HF_block_iter_t *biter);
/* Free space manipulation routines */
H5_DLL herr_t H5HF_space_start(H5HF_hdr_t *hdr, hid_t dxpl_id);
-H5_DLL htri_t H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request,
- H5HF_free_section_t **node);
H5_DLL herr_t H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *node, unsigned flags);
+H5_DLL htri_t H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request,
+ H5HF_free_section_t **node);
+H5_DLL herr_t H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *node);
H5_DLL herr_t H5HF_space_close(H5HF_hdr_t *hdr, hid_t dxpl_id);
H5_DLL herr_t H5HF_space_delete(H5HF_hdr_t *hdr, hid_t dxpl_id);
H5_DLL herr_t H5HF_space_sect_change_class(H5HF_hdr_t *hdr, H5HF_free_section_t *sect,
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 623d547..8888d06 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -69,11 +69,11 @@ static herr_t H5HF_sect_node_free(H5HF_free_section_t *sect,
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);
-static htri_t H5HF_sect_single_can_merge(H5FS_section_info_t *sect1,
- H5FS_section_info_t *sect2, void *udata);
+static htri_t H5HF_sect_single_can_merge(const H5FS_section_info_t *sect1,
+ const H5FS_section_info_t *sect2, void *udata);
static herr_t H5HF_sect_single_merge(H5FS_section_info_t *sect1,
H5FS_section_info_t *sect2, void *udata);
-static htri_t H5HF_sect_single_can_shrink(H5FS_section_info_t *sect,
+static htri_t H5HF_sect_single_can_shrink(const H5FS_section_info_t *sect,
void *udata);
static herr_t H5HF_sect_single_shrink(H5FS_section_info_t **_sect,
void *udata);
@@ -88,8 +88,7 @@ static H5HF_free_section_t *H5HF_sect_row_create(haddr_t sect_off,
static herr_t H5HF_sect_row_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect);
static herr_t H5HF_sect_row_from_single(H5HF_hdr_t *hdr,
H5HF_free_section_t *sect, H5HF_direct_t *dblock);
-static herr_t H5HF_sect_row_iblock_same(const H5HF_free_section_t *sect1,
- const H5HF_free_section_t *sect2);
+static herr_t H5HF_sect_row_free_real(H5HF_free_section_t *sect);
/* 'row' section callbacks */
static herr_t H5HF_sect_row_init_cls(H5FS_section_class_t *cls, void *udata);
@@ -99,11 +98,11 @@ static herr_t H5HF_sect_row_serialize(const H5FS_section_class_t *cls,
static H5FS_section_info_t *H5HF_sect_row_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);
-static htri_t H5HF_sect_row_can_merge(H5FS_section_info_t *sect1,
- H5FS_section_info_t *sect2, void *udata);
+static htri_t H5HF_sect_row_can_merge(const H5FS_section_info_t *sect1,
+ const H5FS_section_info_t *sect2, void *udata);
static herr_t H5HF_sect_row_merge(H5FS_section_info_t *sect1,
H5FS_section_info_t *sect2, void *udata);
-static htri_t H5HF_sect_row_can_shrink(H5FS_section_info_t *sect,
+static htri_t H5HF_sect_row_can_shrink(const H5FS_section_info_t *sect,
void *udata);
static herr_t H5HF_sect_row_shrink(H5FS_section_info_t **sect,
void *udata);
@@ -112,8 +111,9 @@ static herr_t H5HF_sect_row_valid(const H5FS_section_class_t *cls,
const H5FS_section_info_t *sect);
/* 'indirect' section routines */
-static H5HF_free_section_t *H5HF_sect_indirect_new(haddr_t sect_off,
- hsize_t sect_size, H5HF_indirect_t *iblock, hsize_t iblock_off,
+static H5HF_free_section_t *H5HF_sect_indirect_new(H5HF_hdr_t *hdr,
+ haddr_t sect_off, hsize_t sect_size,
+ 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,
@@ -134,14 +134,13 @@ 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 herr_t H5HF_sect_indirect_iblock_entries(H5HF_hdr_t *hdr,
- H5HF_free_section_t *sect);
-static herr_t H5HF_sect_indirect_iblock_same(const H5HF_free_section_t *sect1,
- const H5HF_free_section_t *sect2);
-static hbool_t H5HF_sect_indirect_is_last_row(const H5HF_free_section_t *row_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,
H5HF_free_section_t *sect1, H5HF_free_section_t *sect2);
-static herr_t H5HF_sect_indirect_shrink_row(H5HF_free_section_t *row_sect);
+static herr_t H5HF_sect_indirect_build_parent(H5HF_hdr_t *hdr, H5HF_free_section_t *sect);
+static herr_t H5HF_sect_indirect_shrink(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *sect);
static herr_t H5HF_sect_indirect_serialize(H5HF_hdr_t *hdr,
const H5HF_free_section_t *sect, uint8_t *buf);
static H5FS_section_info_t *H5HF_sect_indirect_deserialize(H5HF_hdr_t *hdr,
@@ -167,7 +166,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_SINGLE[1] = {{
/* Class variables */
H5HF_FSPACE_SECT_SINGLE, /* Section type */
0, /* Extra serialized size */
- 0, /* Class flags */
+ H5FS_CLS_MERGE_SYM, /* Class flags */
NULL, /* Class private info */
/* Class methods */
@@ -194,7 +193,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_FIRST_ROW[1] = {{
/* Class variables */
H5HF_FSPACE_SECT_FIRST_ROW, /* Section type */
0, /* Extra serialized size */
- 0, /* Class flags */
+ H5FS_CLS_MERGE_SYM, /* Class flags */
NULL, /* Class private info */
/* Class methods */
@@ -218,7 +217,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1] = {{
/* Class variables */
H5HF_FSPACE_SECT_NORMAL_ROW, /* Section type */
0, /* Extra serialized size */
- H5FS_CLS_GHOST_OBJ, /* Class flags */
+ H5FS_CLS_MERGE_SYM|H5FS_CLS_SEPAR_OBJ|H5FS_CLS_GHOST_OBJ, /* Class flags */
NULL, /* Class private info */
/* Class methods */
@@ -228,10 +227,10 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1] = {{
/* Object methods */
NULL, /* Serialize section */
NULL, /* Deserialize section */
- H5HF_sect_row_can_merge, /* Can sections merge? */
- H5HF_sect_row_merge, /* Merge sections */
- H5HF_sect_row_can_shrink, /* Can section shrink container?*/
- H5HF_sect_row_shrink, /* Shrink container w/section */
+ NULL, /* Can sections merge? */
+ NULL, /* Merge sections */
+ NULL, /* Can section shrink container?*/
+ NULL, /* Shrink container w/section */
H5HF_sect_row_free, /* Free section */
H5HF_sect_row_valid, /* Check validity of section */
NULL, /* Dump debugging for section */
@@ -245,7 +244,7 @@ H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1] = {{
/* Class variables */
H5HF_FSPACE_SECT_INDIRECT, /* Section type */
0, /* Extra serialized size */
- H5FS_CLS_GHOST_OBJ, /* Class flags */
+ H5FS_CLS_MERGE_SYM|H5FS_CLS_GHOST_OBJ, /* Class flags */
NULL, /* Class private info */
/* Class methods */
@@ -607,11 +606,11 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5HF_sect_single_can_merge(H5FS_section_info_t *_sect1,
- H5FS_section_info_t *_sect2, void UNUSED *_udata)
+H5HF_sect_single_can_merge(const H5FS_section_info_t *_sect1,
+ const H5FS_section_info_t *_sect2, void UNUSED *_udata)
{
- H5HF_free_section_t *sect1 = (H5HF_free_section_t *)_sect1; /* Fractal heap free section */
- H5HF_free_section_t *sect2 = (H5HF_free_section_t *)_sect2; /* Fractal heap free section */
+ const H5HF_free_section_t *sect1 = (const H5HF_free_section_t *)_sect1; /* Fractal heap free section */
+ const H5HF_free_section_t *sect2 = (const H5HF_free_section_t *)_sect2; /* Fractal heap free section */
htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_single_can_merge)
@@ -619,6 +618,7 @@ H5HF_sect_single_can_merge(H5FS_section_info_t *_sect1,
/* Check arguments. */
HDassert(sect1);
HDassert(sect2);
+ HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
#ifdef QAK
@@ -626,10 +626,6 @@ HDfprintf(stderr, "%s: sect1->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_singl
HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_single_can_merge", 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 */
- /* Single section can only merge with other single sections */
- if(sect1->sect_info.type != sect2->sect_info.type)
- HGOTO_DONE(FALSE)
-
/* Check if second section adjoins first section */
/* (This can only occur within a direct block, due to the direct block
* overhead at the beginning of a block, so no need to check if sections
@@ -676,7 +672,9 @@ H5HF_sect_single_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
/* Check arguments. */
HDassert(sect1);
+ HDassert(sect1->sect_info.type == H5HF_FSPACE_SECT_SINGLE);
HDassert(sect2);
+ HDassert(sect2->sect_info.type == H5HF_FSPACE_SECT_SINGLE);
HDassert(H5F_addr_eq(sect1->sect_info.addr + sect1->sect_info.size, sect2->sect_info.addr));
#ifdef QAK
@@ -758,45 +756,46 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5HF_sect_single_can_shrink(H5FS_section_info_t *_sect, void *_udata)
+H5HF_sect_single_can_shrink(const H5FS_section_info_t *_sect, void *_udata)
{
- H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Fractal heap free section */
+ const H5HF_free_section_t *sect = (const 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 */
- size_t dblock_size; /* Section's direct block's size */
- size_t dblock_overhead; /* Direct block's overhead */
htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_single_can_shrink)
/* Check arguments. */
HDassert(sect);
- HDassert(sect->sect_info.state == H5FS_SECT_LIVE);
#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->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"));
#endif /* QAK */
- /* Check for section occupying entire direct block */
- dblock_size = sect->u.single.dblock_size;
- dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
+ /* Check for section occupying entire root direct block */
+ /* (We shouldn't ever have a single section that occupies an entire
+ * direct block, unless it's in the root direct block (because it
+ * would have been converted into a row section, if there was an
+ * indirect block that covered it)
+ */
+ if(hdr->man_dtable.curr_root_rows == 0) {
+ size_t dblock_size; /* Section's direct block's size */
+ size_t dblock_overhead; /* Direct block's overhead */
+
+ dblock_size = hdr->man_dtable.cparam.start_block_size;
+ dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
#ifdef QAK
-HDfprintf(stderr, "%s: dblock_size = %Zu\n", FUNC, dblock_size);
-HDfprintf(stderr, "%s: dblock_overhead = %Zu\n", FUNC, dblock_overhead);
+HDfprintf(stderr, "%s: dblock_size = %Zu\n", "H5HF_sect_single_can_shrink", dblock_size);
+HDfprintf(stderr, "%s: dblock_overhead = %Zu\n", "H5HF_sect_single_can_shrink", dblock_overhead);
#endif /* QAK */
- if((dblock_size - dblock_overhead) == sect->sect_info.size) {
- /* We shouldn't ever have a single section that occupies an entire
- * direct block, unless it's in the root direct block (and
- * therefore there's no parent indirect block to hook into)
- */
- HDassert(hdr->man_dtable.curr_root_rows == 0);
- HGOTO_DONE(TRUE)
+ if((dblock_size - dblock_overhead) == sect->sect_info.size)
+ HGOTO_DONE(TRUE)
} /* end if */
else {
/* We shouldn't have a situation where the 'next block' iterator
* is moved before a direct block that still has objects within it.
*/
- HDassert(hdr->man_dtable.curr_root_rows == 0 || hdr->man_iter_off > sect->sect_info.addr);
+ HDassert(hdr->man_iter_off > sect->sect_info.addr);
HGOTO_DONE(FALSE)
} /* end else */
@@ -841,12 +840,13 @@ H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
HDfprintf(stderr, "%s: (*sect).sect_info = {%a, %Hu, %u}\n", FUNC, (*sect)->sect_info.addr, (*sect)->sect_info.size, (*sect)->sect_info.type);
#endif /* QAK */
- /* Check to see if we should revive either section */
+ /* Check to see if we should revive section */
if((*sect)->sect_info.state != H5FS_SECT_LIVE)
if(H5HF_sect_single_revive(hdr, dxpl_id, (*sect)) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't revive single free section")
/* Protect the direct block for the section */
+ /* (should be a root direct block) */
dblock_addr = (*sect)->u.single.dblock_addr;
HDassert(dblock_addr == hdr->man_dtable.table_addr);
#ifdef QAK
@@ -946,7 +946,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 */
- H5HF_direct_t *dblock; /* Direct block for section */
+ unsigned dblock_status = 0; /* Direct block's status in the metadata cache */
herr_t status; /* Generic status value */
#ifdef QAK
@@ -958,21 +958,33 @@ 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));
- /* Protect the direct block for the section */
- dblock = H5HF_man_dblock_protect(iblock->hdr, H5AC_dxpl_id, sect->u.single.dblock_addr, sect->u.single.dblock_size, iblock, sect->u.single.par_entry, H5AC_READ);
- HDassert(dblock);
-
- /* Sanity check settings for section */
- HDassert(sect->u.single.dblock_size > 0);
- HDassert(sect->u.single.dblock_size == dblock->size);
- HDassert(dblock->size > sect->sect_info.size);
- HDassert(H5F_addr_lt(dblock->block_off, sect->sect_info.addr));
- HDassert(H5F_addr_ge((dblock->block_off + dblock->size),
- (sect->sect_info.addr + sect->sect_info.size)));
-
- /* Release direct block */
- status = H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_DBLOCK, sect->u.single.dblock_addr, dblock, H5AC__NO_FLAGS_SET);
+ /* 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);
+
+ /* If the direct block for the section isn't already protected,
+ * protect it here in order to check single section's sanity
+ * against it.
+ */
+ if(!(dblock_status & H5AC_ES__IS_PROTECTED)) {
+ H5HF_direct_t *dblock; /* Direct block for section */
+
+ /* Protect the direct block for the section */
+ dblock = H5HF_man_dblock_protect(iblock->hdr, H5AC_dxpl_id, sect->u.single.dblock_addr, sect->u.single.dblock_size, iblock, sect->u.single.par_entry, H5AC_READ);
+ HDassert(dblock);
+
+ /* Sanity check settings for section */
+ HDassert(sect->u.single.dblock_size > 0);
+ HDassert(sect->u.single.dblock_size == dblock->size);
+ HDassert(dblock->size > sect->sect_info.size);
+ HDassert(H5F_addr_lt(dblock->block_off, sect->sect_info.addr));
+ HDassert(H5F_addr_ge((dblock->block_off + dblock->size),
+ (sect->sect_info.addr + sect->sect_info.size)));
+
+ /* Release direct block */
+ status = H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_DBLOCK, sect->u.single.dblock_addr, dblock, H5AC__NO_FLAGS_SET);
+ HDassert(status >= 0);
+ } /* end if */
} /* end if */
} /* end if */
@@ -1083,40 +1095,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_sect_row_iblock_same
- *
- * Purpose: Check if two row sections are located in the same indirect block
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * July 6 2006
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5HF_sect_row_iblock_same(const H5HF_free_section_t *row_sect1,
- const H5HF_free_section_t *row_sect2)
-{
- htri_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_row_iblock_same)
-
- /*
- * Check arguments.
- */
- HDassert(row_sect1);
- HDassert(row_sect2);
-
- /* Compare the underlying indirect sections */
- ret_value = H5HF_sect_indirect_iblock_same(row_sect1->u.row.under, row_sect2->u.row.under);
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_sect_row_iblock_same() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5HF_sect_row_revive
*
* Purpose: Update the memory information for a 'row' free section
@@ -1490,20 +1468,21 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5HF_sect_row_can_merge(H5FS_section_info_t *_sect1,
- H5FS_section_info_t *_sect2, void *_udata)
+H5HF_sect_row_can_merge(const H5FS_section_info_t *_sect1,
+ const H5FS_section_info_t *_sect2, void UNUSED *_udata)
{
- H5HF_free_section_t *sect1 = (H5HF_free_section_t *)_sect1; /* Fractal heap free section */
- 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 */
+ const H5HF_free_section_t *sect1 = (const H5HF_free_section_t *)_sect1; /* Fractal heap free section */
+ const H5HF_free_section_t *sect2 = (const H5HF_free_section_t *)_sect2; /* Fractal heap free section */
+ H5HF_free_section_t *top_indir_sect1, *top_indir_sect2; /* Top indirect section for each row */
htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_row_can_merge)
/* Check arguments. */
HDassert(sect1);
+ HDassert(sect1->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW);
HDassert(sect2);
+ HDassert(sect1->sect_info.type == sect2->sect_info.type); /* Checks "MERGE_SYM" flag */
HDassert(H5F_addr_lt(sect1->sect_info.addr, sect2->sect_info.addr));
#ifdef QAK
@@ -1513,46 +1492,29 @@ HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_row_c
#ifdef QAK
HDfprintf(stderr, "%s: sect1->u.row = {%p, %u, %u, %u, %t}\n", "H5HF_sect_row_can_merge", sect1->u.row.under, sect1->u.row.row, sect1->u.row.col, sect1->u.row.num_entries, sect1->u.row.checked_out);
-if(sect2->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- sect2->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW)
- HDfprintf(stderr, "%s: sect2->u.row = {%p, %u, %u, %u, %t}\n", "H5HF_sect_row_can_merge", sect2->u.row.under, sect2->u.row.row, sect2->u.row.col, sect2->u.row.num_entries, sect2->u.row.checked_out);
+HDfprintf(stderr, "%s: sect2->u.row = {%p, %u, %u, %u, %t}\n", "H5HF_sect_row_can_merge", sect2->u.row.under, sect2->u.row.row, sect2->u.row.col, sect2->u.row.num_entries, sect2->u.row.checked_out);
#endif /* QAK */
- /* Row section can only merge with other row sections */
- if(!((sect1->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- sect1->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW)
- && (sect2->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- sect2->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW)))
- HGOTO_DONE(FALSE)
-
-#ifdef QAK
-HDfprintf(stderr, "%s: hdr->man_iter_off = %Hu\n", "H5HF_sect_row_can_merge", hdr->man_iter_off);
-#endif /* QAK */
- /* If second section is after current 'next block' iterator and it's the
- * last row in the underlying indirect section, it should go away
- */
- if(sect2->sect_info.addr >= hdr->man_iter_off && H5HF_sect_indirect_is_last_row(sect2))
- HGOTO_DONE(TRUE)
+ /* Get the top indirect section underlying each row */
+ top_indir_sect1 = H5HF_sect_indirect_top(sect1->u.row.under);
+ HDassert(top_indir_sect1);
+ top_indir_sect2 = H5HF_sect_indirect_top(sect2->u.row.under);
+ HDassert(top_indir_sect2);
/* Check if second section shares the same underlying indirect block as
* the first section, but doesn't already have same underlying indirect
* section.
*/
- if(H5HF_sect_row_iblock_same(sect1, sect2)) {
- HDassert((sect1->u.row.row != sect2->u.row.row) ||
- (((sect1->u.row.col + sect1->u.row.num_entries) - 1)
- < sect2->u.row.col));
- if(sect1->u.row.under != sect2->u.row.under) {
- size_t dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr); /* Direct block's overhead */
-
+ if(top_indir_sect1 != top_indir_sect2) {
+ if(H5HF_sect_indirect_iblock_off(top_indir_sect1) == H5HF_sect_indirect_iblock_off(top_indir_sect2)) {
#ifdef QAK
-HDfprintf(stderr, "%s: dblock_overhead = %Zu\n", "H5HF_sect_row_can_merge", dblock_overhead);
+HDfprintf(stderr, "%s: top_indir_sect1->sect_info.addr = %a\n", "H5HF_sect_row_can_merge", top_indir_sect1->sect_info.addr);
+HDfprintf(stderr, "%s: top_indir_sect1->u.indirect.span_size = %Hu\n", "H5HF_sect_row_can_merge", top_indir_sect1->u.indirect.span_size);
+HDfprintf(stderr, "%s: top_indir_sect2->sect_info.addr = %a\n", "H5HF_sect_row_can_merge", top_indir_sect2->sect_info.addr);
#endif /* QAK */
/* Check if second section adjoins first section */
- if(H5F_addr_eq(sect1->sect_info.addr + (sect1->u.row.num_entries * (sect1->sect_info.size + dblock_overhead)), sect2->sect_info.addr)) {
- udata->adjoin = TRUE;
+ if(H5F_addr_eq((top_indir_sect1->sect_info.addr + top_indir_sect1->u.indirect.span_size), top_indir_sect2->sect_info.addr))
HGOTO_DONE(TRUE)
- } /* end if */
} /* end if */
} /* end if */
@@ -1595,58 +1557,32 @@ H5HF_sect_row_merge(H5FS_section_info_t *_sect1, H5FS_section_info_t *_sect2,
/* Check arguments. */
HDassert(sect1);
- HDassert(sect1->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- sect1->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW);
+ HDassert(sect1->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW);
HDassert(sect2);
- HDassert(sect2->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- sect2->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW);
+ HDassert(sect2->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW);
#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: 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 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: sect2->u.row = {%p, %u, %u, %u}\n", FUNC, sect2->u.row.under, sect2->u.row.row, sect2->u.row.col, sect2->u.row.num_entries);
-#endif /* QAK */
-
- /* Check if rows adjoin each other */
- /* (as opposed to second row just being after the end of the heap and
- * needed to be pruned away)
- */
- if(udata->adjoin) {
-#ifdef QAK
-HDfprintf(stderr, "%s: Merging underlying indirect blocks\n", FUNC);
-#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")
-#ifdef QAK
-HDfprintf(stderr, "%s: sect1->u.row = {%p, %u, %u, %u}\n", FUNC, sect1->u.row.under, sect1->u.row.row, sect1->u.row.col, sect1->u.row.num_entries);
+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")
- } /* end if */
- else {
-#ifdef QAK
-HDfprintf(stderr, "%s: Shrinking away second section\n", FUNC);
-#endif /* QAK */
- /* Shrink size of underlying indirect section */
- if(H5HF_sect_indirect_shrink_row(sect2) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't shrink underlying indirect section")
-
- /* Get rid of second section */
- if(H5HF_sect_row_free((H5FS_section_info_t *)sect2) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
- sect2 = NULL;
- } /* end else */
+ /* 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")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1672,7 +1608,7 @@ done:
*-------------------------------------------------------------------------
*/
static htri_t
-H5HF_sect_row_can_shrink(H5FS_section_info_t *_sect, void UNUSED *_udata)
+H5HF_sect_row_can_shrink(const H5FS_section_info_t *_sect, void UNUSED *_udata)
{
const H5HF_free_section_t *sect = (const H5HF_free_section_t *)_sect; /* Fractal heap free section */
H5HF_add_ud1_t *udata = (H5HF_add_ud1_t *)_udata; /* User callback data */
@@ -1683,19 +1619,18 @@ H5HF_sect_row_can_shrink(H5FS_section_info_t *_sect, void UNUSED *_udata)
/* Check arguments. */
HDassert(sect);
- HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- sect->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW);
+ HDassert(sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW);
#ifdef QAK
HDfprintf(stderr, "%s: sect->sect_info = {%a, %Hu, %u, %s}\n", "H5HF_sect_row_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: sect->u.row = {%p, %u, %u, %u}\n", "H5HF_sect_row_can_shrink", sect->u.row.under, sect->u.row.row, sect->u.row.col, sect->u.row.num_entries);
+HDfprintf(stderr, "%s: sect->u.row = {%p, %u, %u, %u, %t}\n", "H5HF_sect_row_can_shrink", sect->u.row.under, sect->u.row.row, sect->u.row.col, sect->u.row.num_entries, sect->u.row.checked_out);
#endif /* QAK */
/* Check if 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(sect->sect_info.addr >= hdr->man_iter_off && H5HF_sect_indirect_is_last_row(sect))
+ if(sect->sect_info.addr >= hdr->man_iter_off)
HGOTO_DONE(TRUE)
done:
@@ -1718,9 +1653,13 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_sect_row_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
+H5HF_sect_row_shrink(H5FS_section_info_t **_sect, void *_udata)
{
H5HF_free_section_t **sect = (H5HF_free_section_t **)_sect; /* Fractal heap free section */
+ H5HF_free_section_t *top_indir_sect; /* Top indirect section for row */
+ 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 */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_row_shrink)
@@ -1728,22 +1667,20 @@ H5HF_sect_row_shrink(H5FS_section_info_t **_sect, void UNUSED *_udata)
/* Check arguments. */
HDassert(sect);
HDassert(*sect);
- HDassert((*sect)->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW ||
- (*sect)->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW);
+ HDassert((*sect)->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW);
#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}\n", FUNC, (*sect)->u.row.under, (*sect)->u.row.row, (*sect)->u.row.col, (*sect)->u.row.num_entries);
#endif /* QAK */
+ /* 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 */
- if(H5HF_sect_indirect_shrink_row(*sect) < 0)
+ 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")
- /* Get rid of section */
- if(H5HF_sect_row_free((H5FS_section_info_t *)*sect) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
-
/* Indicate that the section has been released */
*sect = NULL;
@@ -1753,6 +1690,38 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_row_free_real
+ *
+ * Purpose: Free a 'row' section node
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, July 6, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_sect_row_free_real(H5HF_free_section_t *sect)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_row_free_real)
+
+ HDassert(sect);
+
+ /* Release the section */
+ if(H5HF_sect_node_free(sect, NULL) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_row_free_real() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_sect_row_free
*
* Purpose: Free a 'row' section node
@@ -1782,7 +1751,7 @@ H5HF_sect_row_free(H5FS_section_info_t *_sect)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't detach section node")
/* Release the section */
- if(H5HF_sect_node_free(sect, NULL) < 0)
+ if(H5HF_sect_row_free_real(sect) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
done:
@@ -1932,83 +1901,45 @@ HDfprintf(stderr, "%s: acc_span_size = %Hu\n", "H5HF_sect_indirect_span_size", a
/*-------------------------------------------------------------------------
- * Function: H5HF_sect_indirect_iblock_entries
+ * Function: H5HF_sect_indirect_iblock_off
*
- * Purpose: Compute the number of entries for the iblock that an
- * indirect section is located in
+ * Purpose: Get the offset of the indirect block for the section
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Offset of indirect block in "heap space" (can't fail)
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * July 3 2006
+ * July 6 2006
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5HF_sect_indirect_iblock_entries(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
+static hsize_t
+H5HF_sect_indirect_iblock_off(const H5HF_free_section_t *sect)
{
- unsigned nrows; /* Number of rows in target indirect block */
- herr_t ret_value = SUCCEED; /* Return value */
+ hsize_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_iblock_entries)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_iblock_off)
/*
* Check arguments.
*/
- HDassert(hdr);
HDassert(sect);
- /* If the section is 'live', just use it's indirect block */
- if(sect->sect_info.state == H5FS_SECT_LIVE) {
- HDassert(sect->u.indirect.u.iblock);
- nrows = sect->u.indirect.u.iblock->nrows;
- } /* end if */
- else {
- hsize_t curr_off; /* Current search offset */
- hsize_t iblock_off; /* Temporary copy of indirect block's offset */
- unsigned curr_row, curr_col; /* Current search row & column */
-
- /* Set starting offset for search */
- iblock_off = sect->u.indirect.u.iblock_off;
-
- curr_off = 0;
- do {
- /* Compute block's new offset */
- iblock_off -= curr_off;
+ ret_value = sect->sect_info.state == H5FS_SECT_LIVE ? sect->u.indirect.u.iblock->block_off : sect->u.indirect.u.iblock_off;
- /* Look up row & column in new indirect block for object */
- if(H5HF_dtable_lookup(&hdr->man_dtable, iblock_off, &curr_row, &curr_col) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of object")
- HDassert(curr_row >= hdr->man_dtable.max_direct_rows);
-
- /* Compute offset of block indicated */
- curr_off = hdr->man_dtable.row_block_off[curr_row] +
- hdr->man_dtable.row_block_size[curr_row] * curr_col;
- } while(curr_off != iblock_off);
-
- /* Compute # of rows in indirect block */
- nrows = (H5V_log2_gen(hdr->man_dtable.row_block_size[curr_row]) - hdr->man_dtable.first_row_bits) + 1;
#ifdef QAK
-HDfprintf(stderr, "%s: nrows = %u\n", FUNC, nrows);
+HDfprintf(stderr, "%s: Leaving, ret_value = %Hu\n", "H5HF_sect_indirect_iblock_off", ret_value);
#endif /* QAK */
- } /* end else */
- HDassert(nrows);
-
- /* Compute number of entries in indirect block */
- sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width * nrows;
-
-done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_sect_indirect_iblock_entries() */
+} /* end H5HF_sect_indirect_iblock_off() */
/*-------------------------------------------------------------------------
- * Function: H5HF_sect_indirect_iblock_same
+ * Function: H5HF_sect_indirect_top
*
- * Purpose: Check if two indirect sections are located in the same indirect block
+ * Purpose: Get the "top" indirect section
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Pointer to the top indirect sectin (can't fail)
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
@@ -2016,77 +1947,31 @@ done:
*
*-------------------------------------------------------------------------
*/
-static htri_t
-H5HF_sect_indirect_iblock_same(const H5HF_free_section_t *sect1,
- const H5HF_free_section_t *sect2)
-{
- htri_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_iblock_same)
-
- /*
- * Check arguments.
- */
- HDassert(sect1);
- HDassert(sect2);
-
- ret_value = ((sect1->sect_info.state == H5FS_SECT_LIVE ? sect1->u.indirect.u.iblock->block_off : sect1->u.indirect.u.iblock_off)
- == (sect2->sect_info.state == H5FS_SECT_LIVE ? sect2->u.indirect.u.iblock->block_off : sect2->u.indirect.u.iblock_off));
-
-#ifdef QAK
-HDfprintf(stderr, "%s: Leaving, ret_value = %t\n", "H5HF_sect_indirect_iblock_same", ret_value);
-#endif /* QAK */
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_sect_indirect_iblock_same() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5HF_sect_indirect_is_last_row
- *
- * Purpose: Check if a row is the last row in an indirect section
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * July 18 2006
- *
- *-------------------------------------------------------------------------
- */
-static hbool_t
-H5HF_sect_indirect_is_last_row(const H5HF_free_section_t *row_sect)
+static H5HF_free_section_t *
+H5HF_sect_indirect_top(H5HF_free_section_t *sect)
{
- const H5HF_free_section_t *sect; /* Underlying indirect section */
- hbool_t ret_value; /* Return value */
+ H5HF_free_section_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_is_last_row)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_top)
/*
* Check arguments.
*/
- HDassert(row_sect);
+ HDassert(sect);
- /* Check for any child indirect sections or if this row is not the last row */
- sect = row_sect->u.row.under;
#ifdef QAK
-HDfprintf(stderr, "%s: sect->u.indirect.indir_nents = %u\n", "H5HF_sect_indirect_is_last_row", sect->u.indirect.indir_nents);
-HDfprintf(stderr, "%s: sect->u.indirect.row = %u\n", "H5HF_sect_indirect_is_last_row", sect->u.indirect.row);
-HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", "H5HF_sect_indirect_is_last_row", sect->u.indirect.dir_nrows);
-HDfprintf(stderr, "%s: row_sect->u.row.row = %u\n", "H5HF_sect_indirect_is_last_row", row_sect->u.row.row);
+HDfprintf(stderr, "%s: sect1->u.indirect.parent = %p\n", "H5HF_sect_indirect_top", sect->u.indirect.parent);
#endif /* QAK */
- if(sect->u.indirect.indir_nents > 0)
- ret_value = FALSE;
- else if(((sect->u.indirect.row + sect->u.indirect.dir_nrows) - 1) ==
- row_sect->u.row.row)
- ret_value = TRUE;
+ if(sect->u.indirect.parent)
+ ret_value = H5HF_sect_indirect_top(sect->u.indirect.parent);
else
- ret_value = FALSE;
+ ret_value = sect;
#ifdef QAK
-HDfprintf(stderr, "%s: ret_value = %t\n", "H5HF_sect_indirect_is_last_row", ret_value);
+HDfprintf(stderr, "%s: Leaving, ret_value = %p\n", "H5HF_sect_indirect_top", ret_value);
#endif /* QAK */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_sect_indirect_is_last_row() */
+} /* end H5HF_sect_indirect_top() */
/*-------------------------------------------------------------------------
@@ -2179,7 +2064,7 @@ H5HF_sect_indirect_term_cls(H5FS_section_class_t *cls)
*-------------------------------------------------------------------------
*/
static H5HF_free_section_t *
-H5HF_sect_indirect_new(haddr_t sect_off, hsize_t sect_size,
+H5HF_sect_indirect_new(H5HF_hdr_t *hdr, haddr_t sect_off, hsize_t sect_size,
H5HF_indirect_t *iblock, hsize_t iblock_off, unsigned row, unsigned col,
unsigned nentries)
{
@@ -2192,6 +2077,7 @@ H5HF_sect_indirect_new(haddr_t sect_off, hsize_t sect_size,
/*
* Check arguments.
*/
+ HDassert(hdr);
HDassert(nentries);
/* Create free space section node */
@@ -2202,19 +2088,23 @@ H5HF_sect_indirect_new(haddr_t sect_off, hsize_t sect_size,
/* Set the 'indirect' specific fields */
if(iblock) {
sect->u.indirect.u.iblock = iblock;
+ sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
+ sect->u.indirect.u.iblock->max_rows;
if(H5HF_iblock_incr(sect->u.indirect.u.iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared indirect block")
iblock_incr = TRUE;
} /* end if */
- else
+ else {
sect->u.indirect.u.iblock_off = iblock_off;
+ sect->u.indirect.iblock_entries = 0;
+ } /* end else */
sect->u.indirect.row = row;
sect->u.indirect.col = col;
sect->u.indirect.num_entries = nentries;
- /* Reset the non-stored fields, they are computed later, on demand */
- sect->u.indirect.span_size = 0;
- sect->u.indirect.iblock_entries = 0;
+ /* 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")
/* This indirect section doesn't (currently) have a parent */
sect->u.indirect.parent = NULL;
@@ -2272,7 +2162,7 @@ HDfprintf(stderr, "%s: Entering\n", FUNC);
#endif /* QAK */
/* Create free space section node */
- if(NULL == (sect = H5HF_sect_indirect_new(row_sect->sect_info.addr,
+ if(NULL == (sect = H5HF_sect_indirect_new(hdr, row_sect->sect_info.addr,
row_sect->sect_info.size, iblock, iblock->block_off,
row_sect->u.row.row, row_sect->u.row.col, row_sect->u.row.num_entries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't create indirect section")
@@ -2349,6 +2239,7 @@ HDfprintf(stderr, "%s: end_row = %u, end_col = %u\n", FUNC, end_row, end_col);
* Check arguments.
*/
HDassert(sect);
+ HDassert(sect->u.indirect.span_size > 0);
/* Reset reference count for indirect section */
sect->u.indirect.rc = 0;
@@ -2495,7 +2386,7 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr);
child_iblock = NULL;
/* Create free space section node */
- if(NULL == (child_sect = H5HF_sect_indirect_new(curr_off, (hsize_t)0,
+ if(NULL == (child_sect = H5HF_sect_indirect_new(hdr, curr_off, (hsize_t)0,
child_iblock, curr_off, 0, 0, child_nentries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section")
@@ -2606,7 +2497,7 @@ HDfprintf(stderr, "%s: sect_off = %Hu\n", FUNC, sect_off);
#endif /* QAK */
/* Create free space section node */
- if(NULL == (sect = H5HF_sect_indirect_new(sect_off, (hsize_t)0, iblock,
+ if(NULL == (sect = H5HF_sect_indirect_new(hdr, sect_off, (hsize_t)0, iblock,
iblock->block_off, start_row, start_col, nentries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section")
@@ -2617,10 +2508,6 @@ HDfprintf(stderr, "%s: sect_off = %Hu\n", FUNC, sect_off);
/* Get end of section offset to return, if requested */
if(end_off) {
- /* Set the span size of the new section */
- if(H5HF_sect_indirect_span_size(hdr, sect) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute span size of section")
-
/* Compute the end of the section */
*end_off = sect_off + sect->u.indirect.span_size;
#ifdef QAK
@@ -2730,6 +2617,10 @@ HDfprintf(stderr, "%s: sect->u.indirect.u.iblock_off = %Hu\n", FUNC, sect->u.ind
/* Set the pointer to the section's indirect block */
sect->u.indirect.u.iblock = sec_iblock;
+ /* Set the number of entries in the indirect block */
+ sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
+ sect->u.indirect.u.iblock->max_rows;
+
/* Unlock indirect block */
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, sec_iblock->addr, sec_iblock, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
@@ -2793,6 +2684,10 @@ HDfprintf(stderr, "%s: sect->u.indirect.u.iblock_off = %Hu\n", FUNC, sect->u.ind
/* Set the pointer to the section's indirect block */
sect->u.indirect.u.iblock = sect_iblock;
+ /* Set the number of entries in the indirect block */
+ sect->u.indirect.iblock_entries = hdr->man_dtable.cparam.width *
+ sect->u.indirect.u.iblock->max_rows;
+
/* Section is "live" now */
sect->sect_info.state = H5FS_SECT_LIVE;
@@ -2868,6 +2763,8 @@ HDfprintf(stderr, "%s: row_start_entry = %u, row_end_entry = %u\n", FUNC, row_st
end_col = end_entry % hdr->man_dtable.cparam.width;
/* Additional sanity check */
+ HDassert(sect->u.indirect.span_size > 0);
+ HDassert(sect->u.indirect.iblock_entries > 0);
HDassert(sect->u.indirect.dir_rows);
HDassert(sect->u.indirect.dir_rows[(row_sect->u.row.row - start_row)] == row_sect);
#ifdef QAK
@@ -2915,9 +2812,8 @@ HDfprintf(stderr, "%s: row_entry = %u\n", FUNC, row_entry);
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for indirect section")
} /* end if */
- /* Adjust indirect section's span size, if it's set */
- if(sect->u.indirect.span_size > 0)
- sect->u.indirect.span_size -= row_sect->sect_info.size;
+ /* Adjust indirect section's span size */
+ sect->u.indirect.span_size -= row_sect->sect_info.size;
/* Check how to adjust section for allocated entry */
if(sect->u.indirect.num_entries > 1) {
@@ -3033,7 +2929,7 @@ HDfprintf(stderr, "%s: iblock = %p, iblock_off = %Hu\n", FUNC, iblock, iblock_of
#endif /* QAK */
/* Create peer indirect section */
- if(NULL == (peer_sect = H5HF_sect_indirect_new(sect->sect_info.addr,
+ if(NULL == (peer_sect = H5HF_sect_indirect_new(hdr, sect->sect_info.addr,
sect->sect_info.size, iblock, iblock_off, start_row, start_col,
peer_nentries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section")
@@ -3073,12 +2969,10 @@ HDfprintf(stderr, "%s: iblock = %p, iblock_off = %Hu\n", FUNC, iblock, iblock_of
/* Transfer/update cached information about indirect block */
peer_sect->u.indirect.iblock_entries = sect->u.indirect.iblock_entries;
peer_sect->u.indirect.span_size = row_sect->sect_info.addr - peer_sect->sect_info.addr;
- if(sect->u.indirect.span_size > 0)
- /* (span for row section has already been removed) */
- sect->u.indirect.span_size -= peer_sect->u.indirect.span_size;
/* Update information for current section */
sect->sect_info.addr = row_sect->sect_info.addr + hdr->man_dtable.row_block_size[new_start_row];
+ sect->u.indirect.span_size -= peer_sect->u.indirect.span_size; /* (span for row section has already been removed) */
sect->u.indirect.row = new_start_row;
sect->u.indirect.col = row_sect->u.row.col + 1;
sect->u.indirect.num_entries -= (peer_nentries + 1); /* Transferred entries, plus the entry allocated out of the row */
@@ -3134,6 +3028,8 @@ H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, H5HF_free_section_t *sect,
*/
HDassert(hdr);
HDassert(sect);
+ HDassert(sect->u.indirect.span_size > 0);
+ HDassert(sect->u.indirect.iblock_entries > 0);
#ifdef QAK
HDfprintf(stderr, "%s: child_entry = %u\n", FUNC, child_entry);
#endif /* QAK */
@@ -3192,8 +3088,7 @@ HDfprintf(stderr, "%s: Child is at start of indirect section\n", FUNC);
sect->u.indirect.col = 0;
} /* end if */
sect->u.indirect.num_entries--;
- if(sect->u.indirect.span_size > 0)
- sect->u.indirect.span_size -= hdr->man_dtable.row_block_size[start_row];
+ sect->u.indirect.span_size -= hdr->man_dtable.row_block_size[start_row];
/* Adjust indirect entry information */
sect->u.indirect.indir_nents--;
@@ -3215,8 +3110,7 @@ HDfprintf(stderr, "%s: Child is at end of indirect section\n", FUNC);
/* Adjust span of blocks covered */
sect->u.indirect.num_entries--;
- if(sect->u.indirect.span_size > 0)
- sect->u.indirect.span_size -= hdr->man_dtable.row_block_size[end_row];
+ sect->u.indirect.span_size -= hdr->man_dtable.row_block_size[end_row];
/* Adjust indirect entry information */
sect->u.indirect.indir_nents--;
@@ -3233,7 +3127,6 @@ HDfprintf(stderr, "%s: Child is at end of indirect section\n", FUNC);
unsigned peer_start_col; /* Starting column for new peer indirect section */
unsigned child_row; /* Row where child entry is located */
unsigned new_nentries; /* New number of entries for current indirect section */
- unsigned old_nentries; /* Old number of entries for current indirect section */
unsigned u; /* Local index variable */
#ifdef QAK
@@ -3248,11 +3141,11 @@ HDfprintf(stderr, "%s: Child is in middle of indirect section\n", FUNC);
peer_start_col = (child_entry + 1) % hdr->man_dtable.cparam.width;
child_row = child_entry / hdr->man_dtable.cparam.width;
new_nentries = sect->u.indirect.num_entries - (peer_nentries + 1);
- old_nentries = sect->u.indirect.num_entries;
#ifdef QAK
HDfprintf(stderr, "%s: peer_nentries = %u, peer_start_row = %u, peer_start_col = %u\n", FUNC, peer_nentries, peer_start_row, peer_start_col);
HDfprintf(stderr, "%s: new_nentries = %u\n", FUNC, new_nentries);
#endif /* QAK */
+ HDassert(child_row >= hdr->man_dtable.max_direct_rows);
/* Get indirect block information for peer */
if(sect->sect_info.state == H5FS_SECT_LIVE) {
@@ -3268,7 +3161,7 @@ HDfprintf(stderr, "%s: iblock = %p, iblock_off = %Hu\n", FUNC, iblock, iblock_of
#endif /* QAK */
/* Update the number of entries in current section & calculate it's span size */
- /* (Will use this to compute the section address for th peer section */
+ /* (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")
@@ -3285,7 +3178,7 @@ HDfprintf(stderr, "%s: peer_sect_addr = %a\n", FUNC, peer_sect_addr);
#endif /* QAK */
/* Create peer indirect section */
- if(NULL == (peer_sect = H5HF_sect_indirect_new(peer_sect_addr,
+ if(NULL == (peer_sect = H5HF_sect_indirect_new(hdr, peer_sect_addr,
sect->sect_info.size, iblock, iblock_off, peer_start_row,
peer_start_col, peer_nentries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section")
@@ -3299,11 +3192,11 @@ HDfprintf(stderr, "%s: peer_sect_addr = %a\n", FUNC, peer_sect_addr);
/* Transfer child indirect sections between current & peer sections */
HDmemcpy(&peer_sect->u.indirect.indir_ents[0],
- &sect->u.indirect.indir_ents[old_nentries - peer_nentries],
+ &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 */
#ifdef QAK
-HDfprintf(stderr, "%s: sect->u.indirect.indir_nents = %u, old_nentries = %u\n", FUNC, sect->u.indirect.indir_nents, old_nentries);
+HDfprintf(stderr, "%s: sect->u.indirect.indir_nents = %u\n", FUNC, sect->u.indirect.indir_nents);
#endif /* QAK */
/* Re-target transferred row sections to point to new underlying indirect section */
@@ -3485,7 +3378,6 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
H5HF_free_section_t *row_sect1, H5HF_free_section_t *row_sect2)
{
H5HF_free_section_t *sect1, *sect2; /* Indirect sections underlying row sections */
- hsize_t iblock_off1, iblock_off2; /* The offset of the indirect blocks for the indirect sections (in "heap space") */
unsigned start_entry1; /* Start entry for section #1 */
unsigned start_row1, start_col1; /* Starting row & column for section #1 */
unsigned end_entry1; /* End entry for section #1 */
@@ -3494,6 +3386,8 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
unsigned start_row2, start_col2; /* Starting row & column for section #2 */
unsigned end_row2, end_col2; /* Ending row & column for section #2 */
unsigned end_entry2; /* End entry for section #2 */
+ hbool_t merged_rows; /* Flag to indicate that rows was merged together */
+ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_merge_row)
@@ -3509,20 +3403,23 @@ H5HF_sect_indirect_merge_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
HDassert(row_sect2->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW);
/* Set up indirect section information */
- sect1 = row_sect1->u.row.under;
- sect2 = row_sect2->u.row.under;
+ sect1 = H5HF_sect_indirect_top(row_sect1->u.row.under);
+ HDassert(sect1);
+ sect2 = H5HF_sect_indirect_top(row_sect2->u.row.under);
+ HDassert(sect2);
#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: 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 */
/* Sanity check some assumptions about the indirect sections */
- HDassert(sect1->u.indirect.dir_nrows > 0);
- HDassert(sect1->u.indirect.dir_rows);
- HDassert(sect1->u.indirect.indir_nents == 0);
- HDassert(sect1->u.indirect.indir_ents == NULL);
- HDassert(sect2->u.indirect.dir_nrows > 0);
- HDassert(sect2->u.indirect.dir_rows);
+ HDassert(sect1->sect_info.state == H5FS_SECT_LIVE);
+ HDassert(sect1->u.indirect.span_size > 0);
+ HDassert(sect1->u.indirect.iblock_entries > 0);
+ HDassert(sect2->sect_info.state == H5FS_SECT_LIVE);
+ HDassert(sect2->u.indirect.span_size > 0);
+ HDassert(sect2->u.indirect.iblock_entries > 0);
+ HDassert(sect1->u.indirect.iblock_entries == sect2->u.indirect.iblock_entries);
/* Set up span information */
start_row1 = sect1->u.indirect.row;
@@ -3531,8 +3428,8 @@ HDfprintf(stderr, "%s: sect2->sect_info = {%a, %Hu, %u, %s}\n", FUNC, sect2->sec
end_entry1 = (start_entry1 + sect1->u.indirect.num_entries) - 1;
end_row1 = end_entry1 / hdr->man_dtable.cparam.width;
end_col1 = end_entry1 % hdr->man_dtable.cparam.width;
- HDassert(end_row1 == row_sect1->u.row.row);
#ifdef QAK
+HDfprintf(stderr, "%s: sect1->u.indirect.dir_nrows = %u\n", FUNC, sect1->u.indirect.dir_nrows);
HDfprintf(stderr, "%s: start_row1 = %u, start_col1 = %u, start_entry1 = %u\n", FUNC, start_row1, start_col1, start_entry1);
HDfprintf(stderr, "%s: sect1->u.indirect.num_entries = %u\n", FUNC, sect1->u.indirect.num_entries);
HDfprintf(stderr, "%s: end_row1 = %u, end_col1 = %u, end_entry1 = %u\n", FUNC, end_row1, end_col1, end_entry1);
@@ -3543,51 +3440,58 @@ HDfprintf(stderr, "%s: end_row1 = %u, end_col1 = %u, end_entry1 = %u\n", FUNC, e
end_entry2 = (start_entry2 + sect2->u.indirect.num_entries) - 1;
end_row2 = end_entry2 / hdr->man_dtable.cparam.width;
end_col2 = end_entry2 % hdr->man_dtable.cparam.width;
- HDassert(start_row2 == row_sect2->u.row.row);
#ifdef QAK
+HDfprintf(stderr, "%s: sect2->u.indirect.dir_nrows = %u\n", FUNC, sect2->u.indirect.dir_nrows);
HDfprintf(stderr, "%s: start_row2 = %u, start_col2 = %u, start_entry2 = %u\n", FUNC, start_row2, start_col2, start_entry2);
HDfprintf(stderr, "%s: sect2->u.indirect.num_entries = %u\n", FUNC, sect2->u.indirect.num_entries);
HDfprintf(stderr, "%s: end_row2 = %u, end_col2 = %u, end_entry2 = %u\n", FUNC, end_row2, end_col2, end_entry2);
#endif /* QAK */
- if(sect1->sect_info.state == H5FS_SECT_LIVE)
- iblock_off1 = sect1->u.indirect.u.iblock->block_off;
- else
- iblock_off1 = sect1->u.indirect.u.iblock_off;
- if(sect2->sect_info.state == H5FS_SECT_LIVE)
- iblock_off2 = sect2->u.indirect.u.iblock->block_off;
- else
- iblock_off2 = sect2->u.indirect.u.iblock_off;
-#ifdef QAK
-HDfprintf(stderr, "%s: iblock_off1 = %Hu\n", FUNC, iblock_off1);
-HDfprintf(stderr, "%s: iblock_off2 = %Hu\n", FUNC, iblock_off2);
-#endif /* QAK */
-
- /* Determine if the two indirect sections are in the same indirect block */
- if(iblock_off1 == iblock_off2) {
- unsigned src_row2; /* Source row for copying from second section */
- unsigned new_dir_nrows; /* New value for number of direct rows in first section */
- unsigned nrows_moved; /* Number of rows to move from second section to first */
- unsigned u; /* Local index variable */
-#ifdef QAK
-HDfprintf(stderr, "%s: sect1->u.indirect.dir_nrows = %u\n", FUNC, sect1->u.indirect.dir_nrows);
-HDfprintf(stderr, "%s: sect2->u.indirect.dir_nrows = %u\n", FUNC, sect2->u.indirect.dir_nrows);
-#endif /* QAK */
+ /* Check for direct sections in second section */
+ /* (second indirect section can be parent of indirect section for second
+ * row, and thus have no row sections of it's own)
+ */
+ if(sect2->u.indirect.dir_nrows > 0) {
+ unsigned new_dir_nrows1; /* New value for number of direct rows in first section */
+ unsigned src_row2; /* Source row for copying from second section */
+ unsigned nrows_moved2; /* Number of rows to move from second section to first */
+
+ /* Sanity check child row assumptions */
+ /* (second indirect section should be at top of equal or deeper
+ * hier. of row/indirect sections, so if second indirect section
+ * has child row sections, first indirect section _must_ have
+ * them also)
+ */
+ HDassert(sect1->u.indirect.dir_nrows > 0);
+ HDassert(sect1->u.indirect.dir_rows);
- /* Check for sections sharing a row */
- if(end_row1 == start_row2) {
+ /* Check for sections sharing a row in the same underlying indirect block */
+ if(row_sect1->u.row.under->u.indirect.u.iblock->block_off == row_sect2->u.row.under->u.indirect.u.iblock->block_off
+ && end_row1 == start_row2) {
+ H5HF_free_section_t *last_row_sect1; /* Last row in first indirect section */
#ifdef QAK
HDfprintf(stderr, "%s: Sections share a row\n", FUNC);
#endif /* QAK */
+ /* Locate the last row section in first indirect section, if we don't already have it */
+ if(row_sect1->u.row.row != end_row1)
+ last_row_sect1 = sect1->u.indirect.dir_rows[sect1->u.indirect.dir_nrows - 1];
+ else
+ last_row_sect1 = row_sect1;
+ HDassert(last_row_sect1);
+ HDassert(last_row_sect1->u.row.row == end_row1);
+
/* Adjust info for first row section, to absorb second row section */
- HDassert((row_sect1->u.row.col + row_sect1->u.row.num_entries) == row_sect2->u.row.col);
- row_sect1->u.row.num_entries += row_sect2->u.row.num_entries;
+ HDassert((last_row_sect1->u.row.col + last_row_sect1->u.row.num_entries) == row_sect2->u.row.col);
+ last_row_sect1->u.row.num_entries += row_sect2->u.row.num_entries;
/* Set up parameters for transfer of rows */
src_row2 = 1;
- nrows_moved = sect2->u.indirect.dir_nrows - 1;
- new_dir_nrows = (sect1->u.indirect.dir_nrows + sect2->u.indirect.dir_nrows) - 1;
+ nrows_moved2 = sect2->u.indirect.dir_nrows - 1;
+ new_dir_nrows1 = (sect1->u.indirect.dir_nrows + sect2->u.indirect.dir_nrows) - 1;
+
+ /* Indicate that the rows were merged */
+ merged_rows = TRUE;
} /* end if */
else {
#ifdef QAK
@@ -3596,159 +3500,292 @@ HDfprintf(stderr, "%s: Sections don't share a row\n", FUNC);
/* Set up parameters for transfer of rows */
src_row2 = 0;
- nrows_moved = sect2->u.indirect.dir_nrows;
- new_dir_nrows = sect1->u.indirect.dir_nrows + sect2->u.indirect.dir_nrows;
+ nrows_moved2 = sect2->u.indirect.dir_nrows;
+ new_dir_nrows1 = sect1->u.indirect.dir_nrows + sect2->u.indirect.dir_nrows;
+
+ /* Indicate that the rows were _not_ merged */
+ merged_rows = FALSE;
} /* end else */
#ifdef QAK
+HDfprintf(stderr, "%s: new_dir_nrows1 = %u\n", FUNC, new_dir_nrows1);
HDfprintf(stderr, "%s: src_row2 = %u\n", FUNC, src_row2);
-HDfprintf(stderr, "%s: nrows_moved = %u\n", FUNC, nrows_moved);
-HDfprintf(stderr, "%s: new_dir_nrows = %u\n", FUNC, new_dir_nrows);
+HDfprintf(stderr, "%s: nrows_moved2 = %u\n", FUNC, nrows_moved2);
#endif /* QAK */
/* Check if we need to move additional rows */
- if(nrows_moved > 0) {
+ if(nrows_moved2 > 0) {
/* Extend the first section's row array */
- if(NULL == (sect1->u.indirect.dir_rows = H5MM_realloc(sect1->u.indirect.dir_rows, sizeof(H5HF_free_section_t *) * new_dir_nrows)))
+ if(NULL == (sect1->u.indirect.dir_rows = H5MM_realloc(sect1->u.indirect.dir_rows, sizeof(H5HF_free_section_t *) * new_dir_nrows1)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array")
/* Transfer the second section's rows to first section */
HDmemcpy(&sect1->u.indirect.dir_rows[sect1->u.indirect.dir_nrows],
&sect2->u.indirect.dir_rows[src_row2],
- (sizeof(H5HF_free_section_t *) * nrows_moved));
+ (sizeof(H5HF_free_section_t *) * nrows_moved2));
/* Re-target the row sections moved from second section */
- for(u = sect1->u.indirect.dir_nrows; u < new_dir_nrows; u++)
+ for(u = sect1->u.indirect.dir_nrows; u < new_dir_nrows1; u++)
sect1->u.indirect.dir_rows[u]->u.row.under = sect1;
/* Adjust reference counts to account for transferred rows */
- sect1->u.indirect.rc += nrows_moved;
- sect2->u.indirect.rc -= nrows_moved;
- } /* end if */
+ sect1->u.indirect.rc += nrows_moved2;
+ sect2->u.indirect.rc -= nrows_moved2;
- /* Check for indirect sections in second section */
- if(sect2->u.indirect.indir_nents > 0) {
- HDassert(sect2->u.indirect.rc > 0);
- HDassert(sect2->u.indirect.indir_ents);
+ /* Update information for first section */
+ sect1->u.indirect.dir_nrows = new_dir_nrows1;
+ } /* end if */
+ } /* end if */
+ else
+ /* Indicate that the rows were _not_ merged */
+ merged_rows = FALSE;
- /* Copy over any child indirect sections in second section */
+ /* Check for indirect sections in second section */
+ if(sect2->u.indirect.indir_nents > 0) {
+ unsigned new_indir_nents1; /* New value for number of indirect entries in first section */
- /* Re-target the child indirect sections moved from second section */
+ /* Some sanity checks on second indirect section */
+ HDassert(sect2->u.indirect.rc > 0);
+ HDassert(sect2->u.indirect.indir_ents);
- /* Adjust reference counts for transferred child indirect sections */
+ /* Set up parameters for transfer of entries */
+ new_indir_nents1 = sect1->u.indirect.indir_nents + sect2->u.indirect.indir_nents;
-HDfprintf(stderr, "%s: moving child indirect sections between indirect sections not supported yet!\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "moving child indirect sections between two indirect sections not supported yet")
+ /* Check if first section can just take over second section's memory buffer */
+ if(sect1->u.indirect.indir_ents == NULL) {
+ sect1->u.indirect.indir_ents = sect2->u.indirect.indir_ents;
+ sect2->u.indirect.indir_ents = NULL;
} /* end if */
+ else {
+ /* Extend the first section's entry array */
+ if(NULL == (sect1->u.indirect.indir_ents = H5MM_realloc(sect1->u.indirect.indir_ents, sizeof(H5HF_free_section_t *) * new_indir_nents1)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for row section pointer array")
+
+ /* Transfer the second section's entries to first section */
+ HDmemcpy(&sect1->u.indirect.indir_ents[sect1->u.indirect.indir_nents],
+ &sect2->u.indirect.indir_ents[0],
+ (sizeof(H5HF_free_section_t *) * sect2->u.indirect.indir_nents));
+ } /* end else */
+
+ /* Re-target the child indirect sections moved from second section */
+ for(u = sect1->u.indirect.indir_nents; u < new_indir_nents1; u++)
+ sect1->u.indirect.indir_ents[u]->u.indirect.parent = sect1;
+
+ /* Adjust reference counts for transferred child indirect sections */
+ sect1->u.indirect.rc += sect2->u.indirect.indir_nents;
+ sect2->u.indirect.rc -= sect2->u.indirect.indir_nents;
/* Update information for first section */
- sect1->u.indirect.dir_nrows = new_dir_nrows;
- sect1->u.indirect.num_entries += sect2->u.indirect.num_entries;
- if(sect1->u.indirect.span_size) {
- if(sect2->u.indirect.span_size)
- sect1->u.indirect.span_size += sect2->u.indirect.span_size;
- else
- sect1->u.indirect.span_size = 0;
- } /* end if */
- if(sect1->u.indirect.iblock_entries == 0)
- sect1->u.indirect.iblock_entries = sect2->u.indirect.iblock_entries;
+ sect1->u.indirect.indir_nents = new_indir_nents1;
+ } /* end if */
+
+ /* Update information for first section */
+ sect1->u.indirect.num_entries += sect2->u.indirect.num_entries;
+ sect1->u.indirect.span_size += sect2->u.indirect.span_size;
- /* Make certain we've tracked the first section's dependents correctly */
- HDassert(sect1->u.indirect.rc ==
- (sect1->u.indirect.indir_nents + sect1->u.indirect.dir_nrows));
+ /* Make certain we've tracked the first section's dependents correctly */
+ HDassert(sect1->u.indirect.rc ==
+ (sect1->u.indirect.indir_nents + sect1->u.indirect.dir_nrows));
- /* Wrap up, for indirect sections not sharing a row */
- /* (want this to be after the first indirection section is consistent again) */
- if(end_row1 == start_row2) {
+ /* Wrap up, freeing or re-inserting second row section */
+ /* (want this to be after the first indirection section is consistent again) */
+ if(merged_rows) {
#ifdef QAK
HDfprintf(stderr, "%s: Finishing sections share a row\n", FUNC);
#endif /* QAK */
- /* Release second row section */
- /* (also releases second indirect section, since all of it's other
- * dependents are gone)
- */
- HDassert(sect2->u.indirect.rc == 1);
- if(H5HF_sect_row_free((H5FS_section_info_t *)row_sect2) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free row section")
- } /* end if */
- else {
+ /* Release second row section */
+ /* (indirectly releases second indirect section, since all of it's
+ * other dependents are gone)
+ */
+ HDassert(sect2->u.indirect.rc == 1);
+ if(H5HF_sect_row_free((H5FS_section_info_t *)row_sect2) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free row section")
+ } /* end if */
+ else {
#ifdef QAK
HDfprintf(stderr, "%s: Finishing sections don't share a row\n", FUNC);
#endif /* QAK */
- /* Decrement ref. count on second indirect section's parent */
- HDassert(sect2->u.indirect.rc == 0);
- if(sect2->u.indirect.parent)
- if(H5HF_sect_indirect_decr(sect2->u.indirect.parent) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't decrement ref. count on parent indirect section")
-
- /* Free second indirect section */
- if(H5HF_sect_indirect_free(sect2) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free indirect section node")
-
- /* Re-add the second section's first row */
- /* (it's already been added to first section, but it's been removed
- * from the free space manager and needs to be re-added)
- */
+ /* Decrement ref. count on second indirect section's parent */
+ HDassert(sect2->u.indirect.rc == 0);
+ if(sect2->u.indirect.parent)
+ if(H5HF_sect_indirect_decr(sect2->u.indirect.parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't decrement ref. count on parent indirect section")
+
+ /* Free second indirect section */
+ if(H5HF_sect_indirect_free(sect2) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free indirect section node")
+
+ /* Re-add the second section's first row */
+ /* (it's already been added to first indirect section, but it's been removed
+ * from the free space manager and needs to be re-added)
+ */
#ifdef QAK
HDfprintf(stderr, "%s: Re-inserting second row section\n", FUNC);
#endif /* QAK */
- row_sect2->sect_info.type = H5HF_FSPACE_SECT_NORMAL_ROW;
- HDassert(row_sect2->u.row.under == sect1);
- if(H5HF_space_add(hdr, dxpl_id, row_sect2, H5FS_ADD_RETURNED_SPACE) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't re-add second row section to free space")
+ row_sect2->sect_info.type = H5HF_FSPACE_SECT_NORMAL_ROW;
+ if(H5HF_space_add(hdr, dxpl_id, row_sect2, 0) < 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);
#endif /* QAK */
- } /* end else */
- } /* end if */
- else {
-HDfprintf(stderr, "%s: merging two indirect sections in different indirect blocks not supported yet!\n", FUNC);
-HGOTO_ERROR(H5E_HEAP, H5E_UNSUPPORTED, FAIL, "merging two indirect sections in different indirect blocks not supported yet")
} /* end else */
+#ifdef QAK
+HDfprintf(stderr, "%s: sect1->u.indirect.iblock_entries = %u\n", FUNC, sect1->u.indirect.iblock_entries);
+HDfprintf(stderr, "%s: sect1->u.indirect.num_entries = %u\n", FUNC, sect1->u.indirect.num_entries);
+#endif /* QAK */
+ /* Check if we can create parent indirect section for first section */
+ /* (i.e. merged indirect sections cover an entire indirect block) */
+ if(sect1->u.indirect.iblock_entries == sect1->u.indirect.num_entries) {
+#ifdef QAK
+HDfprintf(stderr, "%s: creating parent indirect section\n", FUNC);
+#endif /* QAK */
+ /* Build parent section for fully populated indirect section */
+ HDassert(sect1->u.indirect.parent == NULL);
+ if(H5HF_sect_indirect_build_parent(hdr, sect1) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCREATE, FAIL, "can't create parent for full indirect section")
+ } /* end if */
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_sect_indirect_merge_row() */
/*-------------------------------------------------------------------------
- * Function: H5HF_sect_indirect_shrink_row
+ * Function: H5HF_sect_indirect_build_parent
*
- * Purpose: "Shrink" an indirect by eliminating it's last row
+ * Purpose: Build a parent indirect section for a full indirect section
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
- * Tuesday, July 18, 2006
+ * Friday, July 21, 2006
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_sect_indirect_shrink_row(H5HF_free_section_t *row_sect)
+H5HF_sect_indirect_build_parent(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
{
- H5HF_free_section_t *sect; /* Indirect section underlying row section */
+ H5HF_indirect_t *par_iblock; /* Indirect block for parent section */
+ H5HF_free_section_t *par_sect; /* Parent indirect section */
+ unsigned par_row, par_col; /* Row & column in parent indirect section */
+ unsigned par_entry; /* Entry within parent indirect section */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_shrink_row)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_build_parent)
+#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 */
/* Sanity check parameters */
- HDassert(row_sect);
- HDassert(row_sect->u.row.under);
+ HDassert(hdr);
+ HDassert(sect);
+ HDassert(sect->u.indirect.span_size > 0);
+ HDassert(sect->u.indirect.iblock_entries > 0);
+ HDassert(sect->u.indirect.iblock_entries == sect->u.indirect.num_entries);
+ HDassert(sect->u.indirect.u.iblock);
+ HDassert(sect->u.indirect.parent == NULL);
+#ifdef QAK
+HDfprintf(stderr, "%s: sect->u.indirect = {%p, %u, %u, %u}\n", FUNC, sect->u.indirect.u.iblock, sect->u.indirect.row, sect->u.indirect.col, sect->u.indirect.num_entries);
+#endif /* QAK */
- /* Set up indirect section information */
- sect = row_sect->u.row.under;
+ /* Get information for creating parent indirect section */
+ par_entry = sect->u.indirect.u.iblock->par_entry;
+ par_row = par_entry / hdr->man_dtable.cparam.width;
+ par_col = par_entry % hdr->man_dtable.cparam.width;
+ HDassert(par_row >= hdr->man_dtable.max_direct_rows);
+#ifdef QAK
+HDfprintf(stderr, "%s: par_entry = %u, par_row = %u, par_col = %u\n", FUNC, par_entry, par_row, par_col);
+#endif /* QAK */
+ par_iblock = sect->u.indirect.u.iblock->parent;
+ HDassert(par_iblock);
+
+ /* Create parent indirect section */
+ if(NULL == (par_sect = H5HF_sect_indirect_new(hdr, sect->sect_info.addr,
+ sect->sect_info.size, par_iblock, par_iblock->block_off,
+ par_row, par_col, 1)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't create indirect section")
+
+ /* No rows of direct blocks covered in parent, reset direct row information */
+ par_sect->u.indirect.dir_nrows = 0;
+ par_sect->u.indirect.dir_rows = NULL;
+
+ /* Allocate space for the child indirect sections */
+ par_sect->u.indirect.indir_nents = 1;
+ if(NULL == (par_sect->u.indirect.indir_ents = H5MM_malloc(sizeof(H5HF_free_section_t *))))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "allocation failed for indirect section pointer array")
+
+ /* Attach sections together */
+ sect->u.indirect.parent = par_sect;
+ sect->u.indirect.par_entry = par_entry;
+ par_sect->u.indirect.indir_ents[0] = sect;
+ par_sect->u.indirect.rc = 1;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_indirect_build_parent() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_indirect_shrink
+ *
+ * Purpose: "Shrink" container w/section
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, July 24, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_sect_indirect_shrink(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_shrink)
+
+ /* Sanity check parameters */
+ HDassert(hdr);
+ HDassert(sect);
/* Sanity check some assumptions about the indirect section */
- HDassert(sect->u.indirect.dir_nrows > 0);
- HDassert(sect->u.indirect.dir_rows);
- HDassert(sect->u.indirect.indir_nents == 0);
- HDassert(sect->u.indirect.indir_ents == NULL);
+ HDassert(sect->u.indirect.dir_nrows > 0 || sect->u.indirect.indir_nents > 0);
+#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.indirect = {%p, %u, %u, %u}\n", FUNC, sect->u.indirect.u.iblock, sect->u.indirect.row, sect->u.indirect.col, sect->u.indirect.num_entries);
+HDfprintf(stderr, "%s: sect->u.indirect.span_size = %Hu\n", FUNC, sect->u.indirect.span_size);
+HDfprintf(stderr, "%s: sect->u.indirect.parent = %p\n", FUNC, sect->u.indirect.parent);
+#endif /* QAK */
- /* Decrement the number of rows */
- /* (other cleanup will be taken care of when the section is freed) */
- sect->u.indirect.dir_nrows--;
+ /* Walk through direct rows, freeing them */
+ for(u = 0; u < sect->u.indirect.dir_nrows; u++) {
+ /* Remove the normal rows from free space manager */
+ if(sect->u.indirect.dir_rows[u]->sect_info.type != H5HF_FSPACE_SECT_FIRST_ROW) {
+ HDassert(sect->u.indirect.dir_rows[u]->sect_info.type == H5HF_FSPACE_SECT_NORMAL_ROW);
+ if(H5HF_space_remove(hdr, dxpl_id, sect->u.indirect.dir_rows[u]) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove section from heap free space")
+ } /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5HF_sect_indirect_shrink_row() */
+ /* Release the row section */
+ if(H5HF_sect_row_free_real(sect->u.indirect.dir_rows[u]) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free child section node")
+ } /* end for */
+
+ /* Walk through indirect entries, freeing them (recursively) */
+ for(u = 0; u < sect->u.indirect.indir_nents; u++)
+ if(H5HF_sect_indirect_shrink(hdr, dxpl_id, sect->u.indirect.indir_ents[u]) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free child section node")
+
+ /* Free the indirect section itself */
+ if(H5HF_sect_indirect_free(sect) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free indirect section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_indirect_shrink() */
/*-------------------------------------------------------------------------
@@ -3894,8 +3931,8 @@ HDfprintf(stderr, "%s: nentries = %u\n", FUNC, nentries);
#endif /* QAK */
/* Create free space section node */
- if(NULL == (new_sect = H5HF_sect_indirect_new(sect_addr, sect_size, NULL,
- iblock_off, start_row, start_col, nentries)))
+ if(NULL == (new_sect = H5HF_sect_indirect_new(hdr, sect_addr, sect_size,
+ NULL, iblock_off, start_row, start_col, nentries)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, NULL, "can't create indirect section")
/* Compute start entry */
@@ -3994,7 +4031,6 @@ H5HF_sect_indirect_valid(const H5FS_section_class_t *row_cls, const H5HF_free_se
unsigned end_row; /* Row for last block covered */
unsigned end_col; /* Column for last block covered */
unsigned end_entry; /* Entry for last block covered */
- unsigned dir_nrows; /* Number of direct rows in section */
unsigned u; /* Local index variable */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_valid)
@@ -4042,22 +4078,38 @@ HDfprintf(stderr, "%s: start_row = %u, start_col = %u, start_entry = %u\n", "H5H
HDfprintf(stderr, "%s: end_row = %u, end_col = %u, end_entry = %u\n", "H5HF_sect_indirect_valid", end_row, end_col, end_entry);
#endif /* QAK */
- /* Iterate over direct rows, checking pointer references */
- dir_nrows = (end_row - start_row) + 1;
- HDassert(dir_nrows == sect->u.indirect.dir_nrows);
- for(u = 0; u < dir_nrows; u++) {
- const H5HF_free_section_t *tmp_row_sect; /* Pointer to row section */
-
- tmp_row_sect = sect->u.indirect.dir_rows[u];
- HDassert(tmp_row_sect->u.row.under == sect);
- HDassert(tmp_row_sect->u.row.row == (start_row + u));
- if(u < (dir_nrows - 1)) {
- const H5HF_free_section_t *tmp2_row_sect; /* Pointer to row section */
+ /* Sanity check any direct rows */
+ if(sect->u.indirect.dir_nrows > 0) {
+ unsigned dir_nrows; /* Number of direct rows in section */
+ unsigned max_dir_row; /* Maximum direct row in section */
- tmp2_row_sect = sect->u.indirect.dir_rows[u + 1];
- HDassert(tmp_row_sect->u.row.row != tmp2_row_sect->u.row.row);
- } /* end if */
- } /* end for */
+ /* Check for indirect rows in section */
+ if(end_row >= hdr->man_dtable.max_direct_rows)
+ max_dir_row = hdr->man_dtable.max_direct_rows - 1;
+ else
+ max_dir_row = end_row;
+
+ /* Iterate over direct rows, checking pointer references */
+ dir_nrows = (max_dir_row - start_row) + 1;
+ HDassert(dir_nrows == sect->u.indirect.dir_nrows);
+ for(u = 0; u < dir_nrows; u++) {
+ const H5HF_free_section_t *tmp_row_sect; /* Pointer to row section */
+
+ tmp_row_sect = sect->u.indirect.dir_rows[u];
+ HDassert(tmp_row_sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW
+ || 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)) {
+ 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);
+ } /* end if */
+ } /* end for */
+ } /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HF_sect_indirect_valid() */
diff --git a/src/H5HFspace.c b/src/H5HFspace.c
index 4634e49..646f07e 100644
--- a/src/H5HFspace.c
+++ b/src/H5HFspace.c
@@ -138,6 +138,54 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_space_add
+ *
+ * Purpose: Add a section to the free space for the heap
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * May 15 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
+ unsigned flags)
+{
+ H5HF_add_ud1_t udata; /* User data for free space manager 'add' */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_space_add)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(node);
+
+ /* Check if the free space for the heap has been initialized */
+ if(!hdr->fspace)
+ if(H5HF_space_start(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
+
+ /* Construct user data */
+ udata.hdr = hdr;
+ udata.dxpl_id = dxpl_id;
+
+ /* Add to the free space for the heap */
+ if(H5FS_add(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't add section to heap free space")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_space_add() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_space_find
*
* Purpose: Attempt to find space in a fractal heap
@@ -185,52 +233,40 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_space_add
+ * Function: H5HF_space_remove
*
- * Purpose: Add a section to the free space for the heap
+ * Purpose: Remove a section from the free space for the heap
*
* Return: Success: non-negative
- *
* Failure: negative
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * May 15 2006
+ * July 24 2006
*
*-------------------------------------------------------------------------
*/
herr_t
-H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
- unsigned flags)
+H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node)
{
- H5HF_add_ud1_t udata; /* User data for free space manager 'add' */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5HF_space_add)
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_space_remove)
/*
* Check arguments.
*/
HDassert(hdr);
+ HDassert(hdr->fspace);
HDassert(node);
- /* Check if the free space for the heap has been initialized */
- if(!hdr->fspace)
- if(H5HF_space_start(hdr, dxpl_id) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
-
- /* Construct user data */
- udata.hdr = hdr;
- udata.dxpl_id = dxpl_id;
- udata.adjoin = 0;
-
- /* Add to the free space for the heap */
- if(H5FS_add(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't add section to heap free space")
+ /* Remove from the free space for the heap */
+ if(H5FS_remove(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove section from heap free space")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5HF_space_add() */
+} /* end H5HF_space_remove() */
/*-------------------------------------------------------------------------
@@ -310,6 +346,9 @@ H5HF_space_sect_change_class(H5HF_hdr_t *hdr, H5HF_free_section_t *sect, unsigne
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_space_sect_change_class)
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
/*
* Check arguments.
diff --git a/src/H5SL.c b/src/H5SL.c
index a6e1d0b..a35c8a6 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -1324,7 +1324,7 @@ H5SL_prev(H5SL_node_t *slist_node)
NAME
H5SL_last
PURPOSE
- Gets a pointer to the lsat node in a skip list
+ Gets a pointer to the last node in a skip list
USAGE
H5SL_node_t *H5SL_last(slist)
H5SL_t *slist; IN: Pointer to skip list
diff --git a/test/fheap.c b/test/fheap.c
index 5fef553..be72650 100644
--- a/test/fheap.c
+++ b/test/fheap.c
@@ -13535,7 +13535,7 @@ HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
#ifndef QAK
-#ifndef QAK
+#ifndef QAK2
{
fheap_test_del_dir_t del_dir; /* Deletion direction */
fheap_test_del_drain_t drain_half; /* Deletion draining */
@@ -13545,13 +13545,13 @@ HDfprintf(stderr, "Uncomment tests!\n");
tparam.drain_half = drain_half;
for(del_dir = HEAP_DEL_FORWARD; del_dir < HEAP_DEL_NDIRS; del_dir++) {
tparam.del_dir = del_dir;
-#else /* QAK */
+#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 /* QAK */
+/* tparam.del_dir = HEAP_DEL_FORWARD; */
+tparam.del_dir = HEAP_DEL_REVERSE;
+#endif /* QAK2 */
#ifndef QAK
#ifndef QAK2
@@ -13568,11 +13568,11 @@ HDfprintf(stderr, "Uncomment tests!\n");
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */
-#ifndef QAK
+#ifndef QAK2
} /* end for */
} /* end for */
} /* end block */
-#endif /* QAK */
+#endif /* QAK2 */
#else /* QAK */
HDfprintf(stderr, "Uncomment tests!\n");
#endif /* QAK */