summaryrefslogtreecommitdiffstats
path: root/src/H5HFsection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5HFsection.c')
-rw-r--r--src/H5HFsection.c717
1 files changed, 632 insertions, 85 deletions
diff --git a/src/H5HFsection.c b/src/H5HFsection.c
index 6cbe4cb..f164cdb 100644
--- a/src/H5HFsection.c
+++ b/src/H5HFsection.c
@@ -50,21 +50,43 @@
/********************/
/* Local Prototypes */
/********************/
+
+/* Shared routines */
+static herr_t H5HF_sect_node_alloc(H5FS_section_class_t *sect_cls,
+ unsigned sect_type, haddr_t sect_addr, hsize_t sect_size,
+ H5FS_section_info_t **sect);
+static herr_t H5HF_sect_node_free(H5HF_free_section_t *sect,
+ H5HF_indirect_t *parent);
+
+/* 'single' section callbacks */
static herr_t H5HF_sect_single_deserialize(H5FS_section_class_t *sect_cls,
const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size,
H5FS_section_info_t **sect);
-static herr_t H5HF_sect_range_init(H5FS_section_class_t *cls, const 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, void *udata);
+static herr_t H5HF_sect_single_shrink(H5FS_section_info_t **sect, void *udata);
+static herr_t H5HF_sect_single_free(H5FS_section_info_t *sect);
+
+/* 'range' section callbacks */
+static herr_t H5HF_sect_range_init_cls(H5FS_section_class_t *cls, const void *udata);
static herr_t H5HF_sect_range_serialize(const H5FS_section_info_t *sect, uint8_t *buf);
static herr_t H5HF_sect_range_deserialize(H5FS_section_class_t *sect_cls,
const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size,
H5FS_section_info_t **sect);
+static herr_t H5HF_sect_range_free(H5FS_section_info_t *sect);
static herr_t H5HF_sect_range_debug(const H5FS_section_info_t *sect,
FILE *stream, int indent, int fwidth);
-static herr_t H5HF_sect_indirect_init(H5FS_section_class_t *cls, const void *udata);
+
+/* 'indirect' section callbacks */
+static herr_t H5HF_sect_indirect_init_cls(H5FS_section_class_t *cls, const void *udata);
static herr_t H5HF_sect_indirect_serialize(const H5FS_section_info_t *sect, uint8_t *buf);
static herr_t H5HF_sect_indirect_deserialize(H5FS_section_class_t *sect_cls,
const uint8_t *buf, haddr_t sect_addr, hsize_t sect_size,
H5FS_section_info_t **sect);
+static herr_t H5HF_sect_indirect_free(H5FS_section_info_t *sect);
static herr_t H5HF_sect_indirect_debug(const H5FS_section_info_t *sect,
FILE *stream, int indent, int fwidth);
@@ -76,32 +98,47 @@ static herr_t H5HF_sect_indirect_debug(const H5FS_section_info_t *sect,
/* Class info for "single" free space sections */
/* (No callbacks necessary) */
H5FS_section_class_t H5FS_SECT_CLS_FHEAP_SINGLE[1] = {{
- H5FS_SECT_FHEAP_SINGLE,
- 0,
- NULL,
- NULL,
- H5HF_sect_single_deserialize,
- NULL,
+ H5FS_SECT_FHEAP_SINGLE, /* Section type */
+ 0, /* Extra serialized size */
+ NULL, /* Initialize section class */
+ NULL, /* Serialize section */
+ H5HF_sect_single_deserialize, /* Deserialize section */
+ H5HF_sect_single_can_merge, /* Can sections merge? */
+ H5HF_sect_single_merge, /* Merge sections */
+ H5HF_sect_single_can_shrink, /* Can section shrink container?*/
+ H5HF_sect_single_shrink, /* Shrink container w/section */
+ H5HF_sect_single_free, /* Free section */
+ NULL, /* Dump debugging for section */
}};
/* Class info for "range" free space sections */
H5FS_section_class_t H5FS_SECT_CLS_FHEAP_RANGE[1] = {{
- H5FS_SECT_FHEAP_RANGE,
- 0,
- H5HF_sect_range_init,
- H5HF_sect_range_serialize,
- H5HF_sect_range_deserialize,
- H5HF_sect_range_debug,
+ H5FS_SECT_FHEAP_RANGE, /* Section type */
+ 0, /* Extra serialized size */
+ H5HF_sect_range_init_cls, /* Initialize section class */
+ H5HF_sect_range_serialize, /* Serialize section */
+ H5HF_sect_range_deserialize, /* Deserialize section */
+ NULL, /* Can sections merge? */
+ NULL, /* Merge sections */
+ NULL, /* Can section shrink container?*/
+ NULL, /* Shrink container w/section */
+ H5HF_sect_range_free, /* Free section */
+ H5HF_sect_range_debug, /* Dump debugging for section */
}};
/* Class info for "indirect" free space sections */
H5FS_section_class_t H5FS_SECT_CLS_FHEAP_INDIRECT[1] = {{
- H5FS_SECT_FHEAP_INDIRECT,
- 0,
- H5HF_sect_indirect_init,
- H5HF_sect_indirect_serialize,
- H5HF_sect_indirect_deserialize,
- H5HF_sect_indirect_debug,
+ H5FS_SECT_FHEAP_INDIRECT, /* Section type */
+ 0, /* Extra serialized size */
+ H5HF_sect_indirect_init_cls, /* Initialize section class */
+ H5HF_sect_indirect_serialize, /* Serialize section */
+ H5HF_sect_indirect_deserialize, /* Deserialize section */
+ NULL, /* Can sections merge? */
+ NULL, /* Merge sections */
+ NULL, /* Can section shrink container?*/
+ NULL, /* Shrink container w/section */
+ H5HF_sect_indirect_free, /* Free section */
+ H5HF_sect_indirect_debug, /* Dump debugging for section */
}};
/* Declare a free list to manage the H5HF_free_section_t struct */
@@ -120,63 +157,6 @@ H5FL_DEFINE(H5HF_free_section_t);
/*-------------------------------------------------------------------------
- * Function: H5HF_free_section_free_cb
- *
- * Purpose: Free a free section node
- *
- * Return: Success: non-negative
- *
- * Failure: negative
- *
- * Programmer: Quincey Koziol
- * Monday, March 13, 2006
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5HF_free_section_free_cb(void *_sect, void UNUSED *key, void UNUSED *op_data)
-{
- H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect;
- herr_t ret_value = 0; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5HF_free_section_free_cb)
-
- HDassert(sect);
-
- /* Check for live reference to an indirect block */
- if(sect->sect_info.state == H5FS_SECT_LIVE) {
- H5HF_indirect_t *iblock; /* Indirect block referenced */
-
- /* Find indirect block that free section references */
- switch(sect->sect_info.cls->type) {
- case H5FS_SECT_FHEAP_SINGLE:
- iblock = sect->u.single.parent;
- break;
-
- case H5FS_SECT_FHEAP_RANGE:
- iblock = sect->u.range.iblock;
- break;
-
- case H5FS_SECT_FHEAP_INDIRECT:
- iblock = sect->u.indirect.iblock;
- break;
- } /* end switch */
-
- /* Release indirect block, if there was one */
- if(iblock)
- if(H5HF_iblock_decr(iblock) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
- } /* end if */
-
- /* Release the sections */
- H5FL_FREE(H5HF_free_section_t, sect);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5HF_free_section_free_cb() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5HF_sect_node_alloc
*
* Purpose: Allocate a free space section node of a particular type
@@ -225,6 +205,114 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_node_free
+ *
+ * Purpose: Free a section node
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_node_free(H5HF_free_section_t *sect, H5HF_indirect_t *parent)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_node_free)
+
+ HDassert(sect);
+
+ /* Release indirect block, if there was one */
+ if(parent)
+ if(H5HF_iblock_decr(parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on parent indirect block")
+
+ /* Release the section */
+ H5FL_FREE(H5HF_free_section_t, sect);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_node_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_revive
+ *
+ * Purpose: Update the memory information for a 'single' free section
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * May 8 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_single_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *sect)
+{
+ H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
+ unsigned sec_entry; /* Entry within section indirect block */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_revive)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(sect);
+ HDassert(sect->sect_info.state == H5FS_SECT_SERIALIZED);
+
+ /* Check for root direct block */
+ if(hdr->man_dtable.curr_root_rows == 0) {
+ /* Set the information for the section */
+ sect->u.single.parent = NULL;
+ sect->u.single.par_entry = 0;
+
+ /* Set direct block info */
+ HDassert(H5F_addr_defined(hdr->man_dtable.table_addr));
+ sect->u.single.dblock_addr = hdr->man_dtable.table_addr;
+ sect->u.single.dblock_size = hdr->man_dtable.cparam.start_block_size;
+ } /* end if */
+ else {
+ /* Look up indirect block containing direct blocks for range */
+ if(H5HF_man_locate_block(hdr, dxpl_id, sect->sect_info.addr, FALSE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
+
+ /* Increment reference count on indirect block that free section is in */
+ if(H5HF_iblock_incr(sec_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
+
+ /* Set the information for the section */
+ sect->u.single.parent = sec_iblock;
+ sect->u.single.par_entry = sec_entry;
+
+ /* Set direct block info */
+ sect->u.single.dblock_addr = sec_iblock->ents[sec_entry].addr;
+ sect->u.single.dblock_size = hdr->man_dtable.row_block_size[sec_entry / hdr->man_dtable.cparam.width];
+
+ /* 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")
+ sec_iblock = NULL;
+ } /* end else */
+
+ /* Section is "live" now */
+ sect->sect_info.state = H5FS_SECT_LIVE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_single_revive() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_sect_single_deserialize
*
* Purpose: Deserialize a buffer into a "live" single section
@@ -263,7 +351,276 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5HF_sect_range_init
+ * Function: H5HF_sect_single_can_merge
+ *
+ * Purpose: Can two sections of this type merge?
+ *
+ * Note: Second section must be "after" first section
+ *
+ * Return: Success: non-negative (TRUE/FALSE)
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5HF_sect_single_can_merge(const H5FS_section_info_t *sect1,
+ const H5FS_section_info_t *sect2, void UNUSED *udata)
+{
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_single_can_merge)
+
+ /* Check arguments. */
+ HDassert(sect1);
+ HDassert(sect2);
+ HDassert(H5F_addr_lt(sect1->addr, sect2->addr));
+
+#ifdef QAK
+HDfprintf(stderr, "%s: sect1->size = %Hu, sect1->addr = %a\n", "H5HF_sect_single_can_merge", sect1->size, sect1->addr);
+HDfprintf(stderr, "%s: sect2->size = %Hu, sect2->addr = %a\n", "H5HF_sect_single_can_merge", sect2->size, sect2->addr);
+#endif /* QAK */
+
+ /* Single section can only merge with other single sections */
+ if(sect1->cls->type != sect2->cls->type)
+ HGOTO_DONE(FALSE)
+
+ /* Check if second section adjoins first section */
+ /* (This can only occurs within a direct block, due to the direct block
+ * overhead at the beginning of a block)
+ */
+ if(H5F_addr_eq(sect1->addr + sect1->size, sect2->addr))
+ HGOTO_DONE(TRUE)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_single_can_merge() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_merge
+ *
+ * Purpose: Merge two sections of this type
+ *
+ * Note: Second section always merges into first node
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_sect_single_merge(H5FS_section_info_t *sect1, H5FS_section_info_t *sect2,
+ void UNUSED *udata)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_merge)
+
+ /* Check arguments. */
+ HDassert(sect1);
+ HDassert(sect2);
+ HDassert(H5F_addr_eq(sect1->addr + sect1->size, sect2->addr));
+
+#ifdef QAK
+HDfprintf(stderr, "%s: sect1->size = %Hu, sect1->addr = %a\n", "H5HF_sect_single_merge", sect1->size, sect1->addr);
+HDfprintf(stderr, "%s: sect2->size = %Hu, sect2->addr = %a\n", "H5HF_sect_single_merge", sect2->size, sect2->addr);
+#endif /* QAK */
+
+ /* Add second section's size to first section */
+ sect1->size += sect2->size;
+
+ /* Get rid of second section */
+ if(H5HF_sect_single_free(sect2) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_single_merge() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_can_shrink
+ *
+ * Purpose: Can this section shrink the heap?
+ *
+ * Return: Success: non-negative (TRUE/FALSE)
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5HF_sect_single_can_shrink(H5FS_section_info_t *_sect, void *_udata)
+{
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Fractal heap free section */
+ H5HF_add_ud1_t *udata = (H5HF_add_ud1_t *)_udata; /* User callback data */
+ H5HF_hdr_t *hdr; /* Fractal heap header */
+ H5HF_direct_t *dblock = NULL; /* Pointer to direct block for section */
+ haddr_t dblock_addr; /* Section's direct block's address */
+ size_t dblock_size; /* Section's direct block's size */
+ size_t dblock_overhead; /* Direct block's overhead */
+ hid_t dxpl_id; /* DXPL ID for operation */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_can_shrink)
+
+ /* Check arguments. */
+ HDassert(sect);
+ HDassert(udata);
+ HDassert(udata->hdr);
+
+#ifdef QAK
+HDfprintf(stderr, "%s: sect->sect_info.size = %Hu, sect->sect_info.addr = %a\n", FUNC, sect->sect_info.size, sect->sect_info.addr);
+#endif /* QAK */
+
+ /* Initialize some local convenience variables */
+ hdr = udata->hdr;
+ dxpl_id = udata->dxpl_id;
+
+ /* Revive the section, if it's still serialized */
+ 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")
+ } /* end if */
+
+ /* Protect the direct block for the section */
+ dblock_addr = sect->u.single.dblock_addr;
+ dblock_size = sect->u.single.dblock_size;
+#ifdef QAK
+HDfprintf(stderr, "%s: dblock_size = %u, dblock_addr = %a\n", FUNC, dblock_size, dblock_addr);
+#endif /* QAK */
+ if(NULL == (dblock = H5HF_man_dblock_protect(hdr, dxpl_id, dblock_addr, dblock_size, sect->u.single.parent, sect->u.single.par_entry, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to load fractal heap direct block")
+
+ /* Check for section occupying entire direct block */
+ dblock_overhead = H5HF_MAN_ABS_DIRECT_OVERHEAD(hdr);
+ if(H5F_addr_eq(dblock->block_off + dblock_overhead, sect->sect_info.addr) &&
+ (dblock_size - dblock_overhead) == sect->sect_info.size) {
+ /* Stash the direct block pointer away for the 'shrink' callback */
+ udata->dblock = dblock;
+
+ /* Indicate that the heap can be shrunk */
+ HGOTO_DONE(TRUE)
+ } /* end if */
+
+done:
+ /* Unprotect the direct block, if we aren't going to use it in the 'shrink' callback */
+ if(ret_value != TRUE)
+ if(dblock && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap direct block")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_single_can_shrink() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_shrink
+ *
+ * Purpose: Shrink heap w/section
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5HF_sect_single_shrink(H5FS_section_info_t **_sect, void *_udata)
+{
+ H5HF_free_section_t **sect = (H5HF_free_section_t **)_sect; /* Fractal heap free section */
+ H5HF_add_ud1_t *udata = (H5HF_add_ud1_t *)_udata; /* User callback data */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_shrink)
+
+ /* Check arguments. */
+ HDassert(sect);
+ HDassert(*sect);
+ HDassert((*sect)->sect_info.state == H5FS_SECT_LIVE);
+ HDassert(udata);
+ HDassert(udata->hdr);
+ HDassert(udata->dblock);
+
+#ifdef QAK
+HDfprintf(stderr, "%s: (*sect)->sect_info.size = %Hu, (*sect)->sect_info.addr = %a\n", "H5HF_sect_single_shrink", (*sect)->sect_info.size, (*sect)->sect_info.addr);
+#endif /* QAK */
+
+ /* Destroy direct block */
+ if(H5HF_man_dblock_destroy(udata->hdr, udata->dxpl_id, udata->dblock, (*sect)->u.single.dblock_addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't release direct block")
+
+ /* Mark section as "dead", since it's direct block is destroyed */
+ (*sect)->sect_info.state = H5FS_SECT_SERIALIZED;
+
+ /* Release section */
+ if(H5HF_sect_single_free((H5FS_section_info_t *)*sect) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+ /* Set section pointer to NULL, to indicate that the section was released */
+ *sect = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_single_shrink() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_single_free
+ *
+ * Purpose: Free a 'single' section node
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_single_free(H5FS_section_info_t *_sect)
+{
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Pointer to section to free */
+ H5HF_indirect_t *parent = NULL; /* Parent indirect block for section */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_single_free)
+
+ HDassert(sect);
+
+ /* Check for live reference to an indirect block */
+ if(sect->sect_info.state == H5FS_SECT_LIVE) {
+ /* Get parent indirect block, if there was one */
+ if(sect->u.single.parent)
+ parent = sect->u.single.parent;
+ } /* end if */
+
+ /* Release the section */
+ if(H5HF_sect_node_free(sect, parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_single_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_range_init_cls
*
* Purpose: Initialize the "range" class structure
*
@@ -277,9 +634,9 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_sect_range_init(H5FS_section_class_t *cls, const void UNUSED *udata)
+H5HF_sect_range_init_cls(H5FS_section_class_t *cls, const void UNUSED *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_range_init)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_range_init_cls)
/* Check arguments. */
HDassert(cls);
@@ -290,7 +647,61 @@ H5HF_sect_range_init(H5FS_section_class_t *cls, const void UNUSED *udata)
+ 2; /* # of entries */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_sect_range_init() */
+} /* H5HF_sect_range_init_cls() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_range_revive
+ *
+ * Purpose: Update the memory information for a 'range' free section
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * May 8 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_range_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *sect)
+{
+ H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
+ unsigned sec_entry; /* Entry within section indirect block */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_range_revive)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(sect);
+ HDassert(sect->sect_info.state == H5FS_SECT_SERIALIZED);
+
+ /* Look up indirect block containing direct blocks for range */
+ if(H5HF_man_locate_block(hdr, dxpl_id, sect->sect_info.addr, FALSE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
+
+ /* Increment reference count on indirect block that free section is in */
+ if(H5HF_iblock_incr(sec_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
+
+ /* Set the pointer to the section's indirect block */
+ sect->u.range.iblock = sec_iblock;
+
+ /* 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")
+ sec_iblock = NULL;
+
+ /* Section is "live" now */
+ sect->sect_info.state = H5FS_SECT_LIVE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_range_revive() */
/*-------------------------------------------------------------------------
@@ -379,6 +790,47 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_range_free
+ *
+ * Purpose: Free a 'range' section node
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_range_free(H5FS_section_info_t *_sect)
+{
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Pointer to section to free */
+ H5HF_indirect_t *parent = NULL; /* Parent indirect block for section */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_range_free)
+
+ HDassert(sect);
+
+ /* Check for live reference to an indirect block */
+ if(sect->sect_info.state == H5FS_SECT_LIVE) {
+ /* Get parent indirect block, if there was one */
+ if(sect->u.range.iblock)
+ parent = sect->u.range.iblock;
+ } /* end if */
+
+ /* Release the section */
+ if(H5HF_sect_node_free(sect, parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_range_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_sect_range_debug
*
* Purpose: Dump debugging information about an range free space section
@@ -419,7 +871,7 @@ H5HF_sect_range_debug(const H5FS_section_info_t *_sect,
/*-------------------------------------------------------------------------
- * Function: H5HF_sect_indirect_init
+ * Function: H5HF_sect_indirect_init_cls
*
* Purpose: Initialize the "indirect" class structure
*
@@ -433,9 +885,9 @@ H5HF_sect_range_debug(const H5FS_section_info_t *_sect,
*-------------------------------------------------------------------------
*/
static herr_t
-H5HF_sect_indirect_init(H5FS_section_class_t *cls, const void UNUSED *udata)
+H5HF_sect_indirect_init_cls(H5FS_section_class_t *cls, const void UNUSED *udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_init)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_indirect_init_cls)
/* Check arguments. */
HDassert(cls);
@@ -448,7 +900,61 @@ H5HF_sect_indirect_init(H5FS_section_class_t *cls, const void UNUSED *udata)
+ 2; /* Indirect # of rows */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5HF_sect_indirect_init() */
+} /* H5HF_sect_indirect_init_cls() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_indirect_revive
+ *
+ * Purpose: Update the memory information for a 'indirect' free section
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * May 8 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_indirect_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
+ H5HF_free_section_t *sect)
+{
+ H5HF_indirect_t *sec_iblock; /* Pointer to section indirect block */
+ unsigned sec_entry; /* Entry within section indirect block */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_revive)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+ HDassert(sect);
+ HDassert(sect->sect_info.state == H5FS_SECT_SERIALIZED);
+
+ /* Look up indirect block containing indirect blocks for section */
+ if(H5HF_man_locate_block(hdr, dxpl_id, sect->sect_info.addr, TRUE, &sec_iblock, &sec_entry, H5AC_READ) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTCOMPUTE, FAIL, "can't compute row & column of section")
+
+ /* Increment reference count on indirect block that free section is in */
+ if(H5HF_iblock_incr(sec_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared indirect block")
+
+ /* Set the pointer to the section's indirect block */
+ sect->u.indirect.iblock = sec_iblock;
+
+ /* 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")
+ sec_iblock = NULL;
+
+ /* Section is "live" now */
+ sect->sect_info.state = H5FS_SECT_LIVE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HF_sect_indirect_revive() */
/*-------------------------------------------------------------------------
@@ -549,6 +1055,47 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_sect_indirect_free
+ *
+ * Purpose: Free a 'indirect' section node
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, May 17, 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_sect_indirect_free(H5FS_section_info_t *_sect)
+{
+ H5HF_free_section_t *sect = (H5HF_free_section_t *)_sect; /* Pointer to section to free */
+ H5HF_indirect_t *parent = NULL; /* Parent indirect block for section */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_indirect_free)
+
+ HDassert(sect);
+
+ /* Check for live reference to an indirect block */
+ if(sect->sect_info.state == H5FS_SECT_LIVE) {
+ /* Get parent indirect block, if there was one */
+ if(sect->u.indirect.iblock)
+ parent = sect->u.indirect.iblock;
+ } /* end if */
+
+ /* Release the sections */
+ if(H5HF_sect_node_free(sect, parent) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "can't free section node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5HF_sect_indirect_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_sect_indirect_debug
*
* Purpose: Dump debugging information about an indirect free space section