summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5B2.c473
-rw-r--r--src/H5B2cache.c17
-rw-r--r--src/H5B2hdr.c263
-rw-r--r--src/H5B2pkg.h23
-rw-r--r--src/H5B2private.h4
-rw-r--r--src/H5B2stat.c6
-rw-r--r--src/H5B2test.c33
-rw-r--r--src/H5HF.c18
-rw-r--r--src/H5HFcache.c18
-rw-r--r--src/H5HFhdr.c69
-rw-r--r--src/H5HFpkg.h5
11 files changed, 636 insertions, 293 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index e15c11e..a30a6e2 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -41,7 +41,6 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
-#include "H5MFprivate.h" /* File memory management */
/****************/
@@ -62,18 +61,15 @@
/********************/
/* Local Prototypes */
/********************/
-static H5B2_hdr_t *H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5AC_protect_t rw);
-static herr_t H5B2_close(H5B2_hdr_t *hdr, hid_t dxpl_id);
+static H5B2_t *H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls,
+ haddr_t addr);
+static herr_t H5B2_close(H5B2_t *bt2, hid_t dxpl_id);
/*********************/
/* Package Variables */
/*********************/
-/* Declare a free list to manage the H5B2_hdr_t struct */
-H5FL_DEFINE(H5B2_hdr_t);
-
/*****************************/
/* Library Private Variables */
@@ -84,6 +80,10 @@ H5FL_DEFINE(H5B2_hdr_t);
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5B2_t struct */
+H5FL_DEFINE_STATIC(H5B2_t);
+
+
/*-------------------------------------------------------------------------
* Function: H5B2_create
@@ -103,7 +103,7 @@ herr_t
H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam,
haddr_t *addr_p)
{
- H5B2_hdr_t *hdr = NULL; /* The new B-tree header information */
+ haddr_t hdr_addr; /* The new v2 B-tree header address */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_create, FAIL)
@@ -115,36 +115,14 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam,
HDassert(cparam);
HDassert(addr_p);
- /*
- * Allocate file and memory data structures.
- */
- if(NULL == (hdr = H5FL_CALLOC(H5B2_hdr_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree header")
-
- /* Assign non-zero information */
- hdr->root.addr = HADDR_UNDEF;
-
- /* Initialize shared B-tree info */
- if(H5B2_hdr_init(f, hdr, cparam, 0) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared B-tree info")
-
- /* Allocate space for the header on disk */
- if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(f))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree header")
-
- /* Cache the new B-tree node */
- if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree header to cache")
+ /* Create shared v2 B-tree header */
+ if(HADDR_UNDEF == (hdr_addr = H5B2_hdr_create(f, dxpl_id, cparam)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't create v2 B-tree header")
/* Set the B-tree's address to return */
- *addr_p = hdr->addr;
+ *addr_p = hdr_addr;
done:
- if(ret_value < 0) {
- if(hdr)
- (void)H5B2_cache_hdr_dest(f, hdr);
- } /* end if */
-
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_create() */
@@ -163,35 +141,53 @@ done:
*
*-------------------------------------------------------------------------
*/
-static H5B2_hdr_t *
-H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5AC_protect_t rw)
+static H5B2_t *
+H5B2_open(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr)
{
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
- H5B2_hdr_t *ret_value; /* Return value */
+ H5B2_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_open)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
/* Look up the B-tree header */
- if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, rw)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header")
- /* Set file pointer for this B-tree operation */
- hdr->f = f;
+ /* Check for pending heap deletion */
+ if(hdr->pending_delete)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, NULL, "can't open v2 B-tree pending deletion")
+
+ /* Create v2 B-tree info */
+ if(NULL == (bt2 = H5FL_MALLOC(H5B2_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for v2 B-tree info")
+
+ /* Point v2 B-tree wrapper at header */
+ bt2->hdr = hdr;
+ if(H5B2_hdr_incr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment reference count on shared v2 B-tree header")
+
+ /* Increment # of files using this v2 B-tree header */
+ if(H5B2_hdr_fuse_incr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, NULL, "can't increment file reference count on shared v2 B-tree header")
+
+ /* Set file pointer for this v2 B-tree open context */
+ bt2->f = f;
/* Set the return value */
- ret_value = hdr;
+ ret_value = bt2;
done:
- if(!ret_value) {
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close B-tree")
- } /* end if */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, NULL, "unable to release v2 B-tree header")
+ if(!ret_value && bt2)
+ if(H5B2_close(bt2, dxpl_id) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close v2 B-tree")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_open() */
@@ -211,23 +207,30 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
void *udata)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_insert, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Check if the root node is allocated yet */
if(!H5F_addr_defined(hdr->root.addr)) {
/* Create root node as leaf node in B-tree */
@@ -257,7 +260,7 @@ H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -282,24 +285,31 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
H5B2_operator_t op, void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_iterate, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(op);
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Iterate through records */
if(hdr->root.node_nrec > 0) {
/* Iterate through nodes */
@@ -309,7 +319,7 @@ H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -340,10 +350,11 @@ done:
*-------------------------------------------------------------------------
*/
htri_t
-H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
void *udata, H5B2_found_t op, void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
@@ -354,13 +365,19 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Make copy of the root node pointer to start search with */
curr_node_ptr = hdr->root;
@@ -455,7 +472,7 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -481,10 +498,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
herr_t ret_value = SUCCEED; /* Return value */
@@ -493,14 +511,20 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(op);
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Make copy of the root node pointer to start search with */
curr_node_ptr = hdr->root;
@@ -620,7 +644,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -641,23 +665,30 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
void *udata, H5B2_remove_t op, void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_remove, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Check for empty B-tree */
if(0 == hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
@@ -697,7 +728,7 @@ H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -718,24 +749,31 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
+H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls,
haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op,
void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_remove_by_idx, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Check for empty B-tree */
if(0 == hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
@@ -783,7 +821,7 @@ H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -804,30 +842,37 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
hsize_t *nrec)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_get_nrec, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(nrec);
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Get B-tree number of records */
*nrec = hdr->root.all_nrec;
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -860,24 +905,31 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_neighbor, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(op);
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Check for empty tree */
if(!H5F_addr_defined(hdr->root.addr))
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
@@ -894,7 +946,7 @@ H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -902,64 +954,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5B2_delete
- *
- * Purpose: Delete an entire B-tree from a file.
- *
- * The 'OP' routine is called for each record and the
- * OP_DATA pointer, to allow caller to perform an operation as
- * each record is removed from the B-tree.
- *
- * If 'OP' is NULL, the records are just removed in the process
- * of deleting the B-tree.
- *
- * Note: The records are _not_ guaranteed to be visited in order.
- *
- * Return: Non-negative on success, negative on failure.
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 9 2005
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5B2_remove_t op, void *op_data)
-{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5B2_delete, FAIL)
-
- /* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
-
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
-
- /* Delete all nodes in B-tree */
- if(H5F_addr_defined(hdr->root.addr))
- if(H5B2_delete_node(f, dxpl_id, hdr, hdr->depth, &hdr->root, op, op_data) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes")
-
- /* Mark B-tree header for deletion */
- if(H5B2_hdr_delete(hdr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to mark B-tree header for deletion")
-
-done:
- /* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_delete() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5B2_modify
*
* Purpose: Locate the specified information in a B-tree and modify it.
@@ -980,10 +974,11 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
void *udata, H5B2_modify_t op, void *op_data)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
unsigned depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
@@ -994,14 +989,20 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(op);
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Make copy of the root node pointer to start search with */
curr_node_ptr = hdr->root;
@@ -1119,7 +1120,7 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1140,23 +1141,30 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, hsize_t *btree_size)
+H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr, hsize_t *btree_size)
{
- H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
- herr_t ret_value = SUCCEED;/* Return value */
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_iterate_size, FAIL)
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(btree_size);
- /* Open the B-tree header */
- if(NULL == (hdr = H5B2_open(f, dxpl_id, type, addr, H5AC_READ)))
+ /* Open the B-tree */
+ if(NULL == (bt2 = H5B2_open(f, dxpl_id, cls, addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTOPENOBJ, FAIL, "unable to open B-tree")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Add size of header to B-tree metadata total */
*btree_size += H5B2_HEADER_SIZE(f);
@@ -1173,7 +1181,7 @@ H5B2_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t add
done:
/* Close the B-tree */
- if(hdr && H5B2_close(hdr, dxpl_id) < 0)
+ if(bt2 && H5B2_close(bt2, dxpl_id) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, FAIL, "unable to close B-tree")
FUNC_LEAVE_NOAPI(ret_value)
@@ -1194,27 +1202,136 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5B2_close(H5B2_hdr_t *hdr, hid_t dxpl_id)
+H5B2_close(H5B2_t *bt2, hid_t dxpl_id)
{
- unsigned hdr_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for unprotecting header */
- herr_t ret_value = SUCCEED; /* Return value */
+ const H5B2_class_t *cls = NULL; /* Class of v2 B-tree client */
+ haddr_t bt2_addr = HADDR_UNDEF; /* Address of v2 B-tree (for deletion) */
+ hbool_t pending_delete = FALSE; /* Whether the v2 B-tree is pending deletion */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B2_close)
/* Check arguments. */
- HDassert(hdr);
- HDassert(hdr->f);
- HDassert(H5F_addr_defined(hdr->addr));
+ HDassert(bt2);
+ HDassert(bt2->f);
+
+ /* Decrement file reference & check if this is the last open v2 B-tree using the shared B-tree header */
+ if(0 == H5B2_hdr_fuse_decr(bt2->hdr)) {
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Check for pending B-tree deletion */
+ if(bt2->hdr->pending_delete) {
+ /* Set local info, so B-tree deletion can occur after decrementing the
+ * header's ref count
+ */
+ pending_delete = TRUE;
+ bt2_addr = bt2->hdr->addr;
+ cls = bt2->hdr->cls;
+ } /* end if */
+ } /* end if */
- /* Check if we are supposed to delete the header */
- if(hdr->pending_delete)
- hdr_flags = H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
+ /* Decrement the reference count on the B-tree header */
+ /* (don't put in H5B2_hdr_fuse_decr() as the B-tree header may be evicted
+ * immediately -QAK)
+ */
+ if(H5B2_hdr_decr(bt2->hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement reference count on shared v2 B-tree header")
+
+ /* Check for pending v2 B-tree deletion */
+ if(pending_delete) {
+ H5B2_hdr_t *hdr; /* Another pointer to v2 B-tree header */
+
+ /* Sanity check */
+ HDassert(H5F_addr_defined(bt2_addr));
+ HDassert(cls);
- /* Release the B-tree header info */
- if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, hdr_flags) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header")
+ /* Lock the v2 B-tree header into memory */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(bt2->f, dxpl_id, H5AC_BT2_HDR, bt2_addr, cls, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header")
+
+ /* Set the shared v2 B-tree header's file context for this operation */
+ hdr->f = bt2->f;
+
+ /* Delete v2 B-tree, starting with header (unprotects header) */
+ if(H5B2_hdr_delete(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree")
+ } /* end if */
+
+ /* Release the v2 B-tree wrapper */
+ bt2 = H5FL_FREE(H5B2_t, bt2);
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_delete
+ *
+ * Purpose: Delete an entire B-tree from a file.
+ *
+ * The 'OP' routine is called for each record and the
+ * OP_DATA pointer, to allow caller to perform an operation as
+ * each record is removed from the B-tree.
+ *
+ * If 'OP' is NULL, the records are just removed in the process
+ * of deleting the B-tree.
+ *
+ * Note: The records are _not_ guaranteed to be visited in order.
+ *
+ * Return: Non-negative on success, negative on failure.
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 9 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_delete(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
+ H5B2_remove_t op, void *op_data)
+{
+ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B2_delete, FAIL)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(cls);
+ HDassert(H5F_addr_defined(addr));
+
+ /* Lock the v2 B-tree header into memory */
+#ifdef QAK
+HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
+#endif /* QAK */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header")
+
+ /* Remember the callback & context for later */
+ hdr->remove_op = op;
+ hdr->remove_op_data = op_data;
+
+ /* Check for files using shared v2 B-tree header */
+ if(hdr->file_rc)
+ hdr->pending_delete = TRUE;
+ else {
+ /* Set the shared v2 B-tree header's file context for this operation */
+ hdr->f = f;
+
+ /* Delete v2 B-tree now, starting with header (unprotects header) */
+ if(H5B2_hdr_delete(hdr, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete v2 B-tree")
+ hdr = NULL;
+ } /* end if */
+
+done:
+ /* Unprotect the header, if an error occurred */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release v2 B-tree header")
+
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2_delete() */
+
diff --git a/src/H5B2cache.c b/src/H5B2cache.c
index 688bc33..0148777 100644
--- a/src/H5B2cache.c
+++ b/src/H5B2cache.c
@@ -167,9 +167,8 @@ H5B2_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, voi
HDassert(cls);
/* Allocate new B-tree header and reset cache info */
- if(NULL == (hdr = H5FL_MALLOC(H5B2_hdr_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemset(&hdr->cache_info, 0, sizeof(H5AC_info_t));
+ if(NULL == (hdr = H5B2_hdr_alloc(f)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "allocation failed for B-tree header")
/* Wrap the local buffer for serialized header info */
if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf))))
@@ -249,7 +248,8 @@ done:
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && hdr)
- (void)H5B2_cache_hdr_dest(f, hdr);
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, NULL, "can't release v2 B-tree header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
@@ -404,9 +404,6 @@ H5B2_cache_hdr_dest(H5F_t *f, H5B2_hdr_t *hdr)
if(H5B2_hdr_free(hdr) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free v2 B-tree header info")
- /* Free B-tree header info */
- (void)H5FL_FREE(H5B2_hdr_t, hdr);
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2_cache_hdr_dest() */
@@ -730,6 +727,7 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal)
/*
* Check arguments.
*/
+ HDassert(f);
HDassert(internal);
HDassert(internal->hdr);
@@ -760,7 +758,7 @@ H5B2_cache_internal_dest(H5F_t *f, H5B2_internal_t *internal)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header")
/* Free B-tree internal node info */
- H5FL_FREE(H5B2_internal_t, internal);
+ internal = H5FL_FREE(H5B2_internal_t, internal);
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1052,6 +1050,7 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf)
/*
* Check arguments.
*/
+ HDassert(f);
HDassert(leaf);
HDassert(leaf->hdr);
@@ -1078,7 +1077,7 @@ H5B2_cache_leaf_dest(H5F_t *f, H5B2_leaf_t *leaf)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDEC, FAIL, "can't decrement ref. count on B-tree header")
/* Free B-tree leaf node info */
- H5FL_FREE(H5B2_leaf_t, leaf);
+ leaf = H5FL_FREE(H5B2_leaf_t, leaf);
done:
FUNC_LEAVE_NOAPI(ret_value)
diff --git a/src/H5B2hdr.c b/src/H5B2hdr.c
index ef57186..95bafdd 100644
--- a/src/H5B2hdr.c
+++ b/src/H5B2hdr.c
@@ -79,6 +79,9 @@
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5B2_hdr_t struct */
+H5FL_DEFINE_STATIC(H5B2_hdr_t);
+
/* Declare a free list to manage B-tree node pages to/from disk */
H5FL_BLK_DEFINE_STATIC(node_page);
@@ -214,57 +217,104 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5B2_hdr_free
+ * Function: H5B2_hdr_alloc
*
- * Purpose: Free B-tree header info
+ * Purpose: Allocate B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+H5B2_hdr_t *
+H5B2_hdr_alloc(H5F_t *f)
+{
+ H5B2_hdr_t *hdr = NULL; /* v2 B-tree header */
+ H5B2_hdr_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_alloc)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+
+ /* Allocate space for the shared information */
+ if(NULL == (hdr = H5FL_CALLOC(H5B2_hdr_t)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for B-tree header")
+
+ /* Assign non-zero information */
+ hdr->f = f;
+ hdr->root.addr = HADDR_UNDEF;
+
+ /* Set return value */
+ ret_value = hdr;
+
+done:
+ if(!ret_value && hdr)
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, NULL, "unable to free shared v2 B-tree info")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_alloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_create
+ *
+ * Purpose: Create new fractal heap header
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
- * Feb 2 2005
+ * Mar 21 2006
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5B2_hdr_free(H5B2_hdr_t *hdr)
+haddr_t
+H5B2_hdr_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam)
{
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr = NULL; /* The new v2 B-tree header information */
+ haddr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_free)
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_create)
- /* Sanity check */
- HDassert(hdr);
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(cparam);
- /* Free the B-tree node buffer */
- if(hdr->page)
- (void)H5FL_BLK_FREE(node_page, hdr->page);
+ /* Allocate v2 B-tree header */
+ if(NULL == (hdr = H5B2_hdr_alloc(f)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "allocation failed for B-tree header")
- /* Free the array of offsets into the native key block */
- if(hdr->nat_off)
- hdr->nat_off = H5FL_SEQ_FREE(size_t, hdr->nat_off);
+ /* Initialize shared B-tree info */
+ if(H5B2_hdr_init(f, hdr, cparam, 0) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, HADDR_UNDEF, "can't create shared B-tree info")
- /* Release the node info */
- if(hdr->node_info) {
- unsigned u; /* Local index variable */
+ /* Allocate space for the header on disk */
+ if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)H5B2_HEADER_SIZE(f))))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, HADDR_UNDEF, "file allocation failed for B-tree header")
- /* Destroy free list factories */
- for(u = 0; u < (hdr->depth + 1); u++) {
- if(hdr->node_info[u].nat_rec_fac)
- if(H5FL_fac_term(hdr->node_info[u].nat_rec_fac) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
- if(hdr->node_info[u].node_ptr_fac)
- if(H5FL_fac_term(hdr->node_info[u].node_ptr_fac) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
- } /* end for */
+ /* Cache the new B-tree node */
+ if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, HADDR_UNDEF, "can't add B-tree header to cache")
- /* Free the array of node info structs */
- hdr->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, hdr->node_info);
- } /* end if */
+ /* Set address of v2 B-tree header to return */
+ ret_value = hdr->addr;
done:
+ if(!H5F_addr_defined(ret_value) && hdr)
+ if(H5B2_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release v2 B-tree header")
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B2_hdr_free() */
+} /* end H5B2_hdr_create() */
/*-------------------------------------------------------------------------
@@ -343,6 +393,63 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_fuse_incr
+ *
+ * Purpose: Increment file reference count on shared v2 B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_fuse_incr)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Increment file reference count on shared header */
+ hdr->file_rc++;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2_hdr_fuse_incr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_fuse_decr
+ *
+ * Purpose: Decrement file reference count on shared v2 B-tree header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+size_t
+H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_fuse_decr)
+
+ /* Sanity check */
+ HDassert(hdr);
+ HDassert(hdr->file_rc);
+
+ /* Decrement file reference count on shared header */
+ hdr->file_rc--;
+
+ FUNC_LEAVE_NOAPI(hdr->file_rc)
+} /* end H5B2_hdr_fuse_decr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_hdr_dirty
*
* Purpose: Mark B-tree header as dirty
@@ -376,9 +483,66 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5B2_hdr_free
+ *
+ * Purpose: Free B-tree header info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Feb 2 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_hdr_free(H5B2_hdr_t *hdr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_hdr_free)
+
+ /* Sanity check */
+ HDassert(hdr);
+
+ /* Free the B-tree node buffer */
+ if(hdr->page)
+ (void)H5FL_BLK_FREE(node_page, hdr->page);
+
+ /* Free the array of offsets into the native key block */
+ if(hdr->nat_off)
+ hdr->nat_off = H5FL_SEQ_FREE(size_t, hdr->nat_off);
+
+ /* Release the node info */
+ if(hdr->node_info) {
+ unsigned u; /* Local index variable */
+
+ /* Destroy free list factories */
+ for(u = 0; u < (hdr->depth + 1); u++) {
+ if(hdr->node_info[u].nat_rec_fac)
+ if(H5FL_fac_term(hdr->node_info[u].nat_rec_fac) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
+ if(hdr->node_info[u].node_ptr_fac)
+ if(H5FL_fac_term(hdr->node_info[u].node_ptr_fac) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
+ } /* end for */
+
+ /* Free the array of node info structs */
+ hdr->node_info = H5FL_SEQ_FREE(H5B2_node_info_t, hdr->node_info);
+ } /* end if */
+
+ /* Free B-tree header info */
+ (void)H5FL_FREE(H5B2_hdr_t, hdr);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_hdr_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_hdr_delete
*
- * Purpose: Mark B-tree header for deletion
+ * Purpose: Delete a v2 B-tree, starting with the header
*
* Return: Non-negative on success/Negative on failure
*
@@ -389,15 +553,42 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_hdr_delete(H5B2_hdr_t *hdr)
+H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_hdr_delete)
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting v2 B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B2_hdr_delete, FAIL)
/* Sanity check */
HDassert(hdr);
- /* Mark B-tree header as pending deletion */
- hdr->pending_delete = TRUE;
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* v2 B-tree header's status in the metadata cache */
+
+ /* Check the v2 B-tree header's status in the metadata cache */
+ if(H5AC_get_entry_status(hdr->f, hdr->addr, &hdr_status) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to check metadata cache status for v2 B-tree header")
+
+ /* Sanity checks on v2 B-tree header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PROTECTED);
+} /* end block */
+#endif /* NDEBUG */
+
+ /* Delete all nodes in B-tree */
+ if(H5F_addr_defined(hdr->root.addr))
+ if(H5B2_delete_node(hdr->f, dxpl_id, hdr, hdr->depth, &hdr->root, hdr->remove_op, hdr->remove_op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes")
+
+ /* Indicate that the heap header should be deleted & file space freed */
+ cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG;
+
+done:
+ /* Unprotect the header with appropriate flags */
+ if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_HDR, hdr->addr, hdr, cache_flags) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header")
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5B2_hdr_delete() */
diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h
index b47cc32..3961fb5 100644
--- a/src/H5B2pkg.h
+++ b/src/H5B2pkg.h
@@ -158,7 +158,10 @@ typedef struct H5B2_hdr_t {
H5F_t *f; /* Pointer to the file that the B-tree is in */
haddr_t addr; /* Address of B-tree header in the file */
size_t rc; /* Reference count of nodes using this header */
+ size_t file_rc; /* Reference count of files using this header */
hbool_t pending_delete; /* B-tree is pending deletion */
+ H5B2_remove_t remove_op; /* Callback operator for deleting B-tree */
+ void *remove_op_data;/* B-tree deletion callback's context */
const H5B2_class_t *cls; /* Class of B-tree client */
uint8_t *page; /* Common disk page for I/O */
size_t *nat_off; /* Array of offsets of native records */
@@ -189,6 +192,12 @@ typedef struct H5B2_internal_t {
unsigned depth; /* Depth of this node in the B-tree */
} H5B2_internal_t;
+/* v2 B-tree */
+struct H5B2_t {
+ H5B2_hdr_t *hdr; /* Pointer to internal v2 B-tree header info */
+ H5F_t *f; /* Pointer to file for v2 B-tree */
+};
+
/* User data for metadata cache 'load' callback */
typedef struct {
H5B2_hdr_t *hdr; /* Pointer to the [pinned] v2 B-tree header */
@@ -218,9 +227,6 @@ H5_DLLVAR const H5AC_class_t H5AC_BT2_INT[1];
/* H5B2 leaf node inherits cache-like properties from H5AC */
H5_DLLVAR const H5AC_class_t H5AC_BT2_LEAF[1];
-/* Declare a free list to manage the H5B2_hdr_t struct */
-H5FL_EXTERN(H5B2_hdr_t);
-
/* Declare a free list to manage the H5B2_internal_t struct */
H5FL_EXTERN(H5B2_internal_t);
@@ -238,13 +244,18 @@ H5_DLLVAR const H5B2_class_t H5B2_TEST[1];
/******************************/
/* Routines for managing B-tree header info */
+H5_DLL H5B2_hdr_t *H5B2_hdr_alloc(H5F_t *f);
+H5_DLL haddr_t H5B2_hdr_create(H5F_t *f, hid_t dxpl_id,
+ const H5B2_create_t *cparam);
+H5_DLL herr_t H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr,
+ const H5B2_create_t *cparam, unsigned depth);
H5_DLL herr_t H5B2_hdr_incr(H5B2_hdr_t *hdr);
H5_DLL herr_t H5B2_hdr_decr(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_fuse_incr(H5B2_hdr_t *hdr);
+H5_DLL size_t H5B2_hdr_fuse_decr(H5B2_hdr_t *hdr);
H5_DLL herr_t H5B2_hdr_dirty(H5B2_hdr_t *hdr);
-H5_DLL herr_t H5B2_hdr_delete(H5B2_hdr_t *hdr);
-H5_DLL herr_t H5B2_hdr_init(H5F_t *f, H5B2_hdr_t *hdr,
- const H5B2_create_t *cparam, unsigned depth);
H5_DLL herr_t H5B2_hdr_free(H5B2_hdr_t *hdr);
+H5_DLL herr_t H5B2_hdr_delete(H5B2_hdr_t *hdr, hid_t dxpl_id);
/* Routines for operating on internal nodes */
H5_DLL H5B2_internal_t *H5B2_protect_internal(H5F_t *f, hid_t dxpl_id,
diff --git a/src/H5B2private.h b/src/H5B2private.h
index e99def0..481f910 100644
--- a/src/H5B2private.h
+++ b/src/H5B2private.h
@@ -116,6 +116,10 @@ typedef struct H5B2_stat_t {
hsize_t nrecords; /* Number of records */
} H5B2_stat_t;
+/* v2 B-tree info (forward decl - defined in H5B2pkg.h) */
+typedef struct H5B2_t H5B2_t;
+
+
/*****************************/
/* Library-private Variables */
/*****************************/
diff --git a/src/H5B2stat.c b/src/H5B2stat.c
index 4b97e17..5fc7659 100644
--- a/src/H5B2stat.c
+++ b/src/H5B2stat.c
@@ -85,7 +85,7 @@
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
H5B2_stat_t *info)
{
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
@@ -95,12 +95,12 @@ H5B2_stat_info(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(info);
/* Look up the B-tree header */
- if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
/* Get information about the B-tree */
diff --git a/src/H5B2test.c b/src/H5B2test.c
index 2413199..d073322 100644
--- a/src/H5B2test.c
+++ b/src/H5B2test.c
@@ -20,6 +20,7 @@
*
*/
+
/****************/
/* Module Setup */
/****************/
@@ -27,6 +28,7 @@
#define H5B2_PACKAGE /*suppress error about including H5B2pkg */
#define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/
+
/***********/
/* Headers */
/***********/
@@ -34,6 +36,7 @@
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
+
/****************/
/* Local Macros */
/****************/
@@ -52,6 +55,7 @@
/********************/
/* Local Prototypes */
/********************/
+
static herr_t H5B2_test_store(void *nrecord, const void *udata);
static herr_t H5B2_test_compare(const void *rec1, const void *rec2);
static herr_t H5B2_test_encode(const H5F_t *f, uint8_t *raw,
@@ -61,9 +65,11 @@ static herr_t H5B2_test_decode(const H5F_t *f, const uint8_t *raw,
static herr_t H5B2_test_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id,
int indent, int fwidth, const void *record, const void *_udata);
+
/*********************/
/* Package Variables */
/*********************/
+
const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
H5B2_TEST_ID, /* Type of B-tree */
"H5B2_TEST_ID", /* Name of B-tree class */
@@ -75,6 +81,7 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
H5B2_test_debug /* Record debugging callback */
}};
+
/*****************************/
/* Library Private Variables */
/*****************************/
@@ -84,6 +91,7 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
/* Local Variables */
/*******************/
+
/*-------------------------------------------------------------------------
* Function: H5B2_test_store
@@ -228,7 +236,7 @@ H5B2_test_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id,
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
+H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls,
haddr_t addr, haddr_t *root_addr)
{
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
@@ -238,12 +246,12 @@ H5B2_get_root_addr_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
HDassert(root_addr);
/* Look up the B-tree header */
- if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
/* Get B-tree root addr */
@@ -272,7 +280,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
+H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls,
haddr_t addr, void *udata, H5B2_node_info_test_t *ninfo)
{
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
@@ -286,11 +294,11 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
/* Look up the B-tree header */
- if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, cls, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
/* Set file pointer for this B-tree operation */
@@ -374,11 +382,8 @@ H5B2_get_node_info_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
done:
/* Release header */
- if(hdr) {
- hdr->f = NULL;
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- } /* end if */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_get_node_info_test() */
@@ -401,7 +406,7 @@ done:
*-------------------------------------------------------------------------
*/
int
-H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
+H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *cls, haddr_t addr,
void *udata)
{
H5B2_node_info_test_t ninfo; /* Node information */
@@ -411,11 +416,11 @@ H5B2_get_node_depth_test(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, hadd
/* Check arguments. */
HDassert(f);
- HDassert(type);
+ HDassert(cls);
HDassert(H5F_addr_defined(addr));
/* Get information abou the node */
- if(H5B2_get_node_info_test(f, dxpl_id, type, addr, udata, &ninfo) < 0)
+ if(H5B2_get_node_info_test(f, dxpl_id, cls, addr, udata, &ninfo) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "error looking up node info")
/* Set return value */
diff --git a/src/H5HF.c b/src/H5HF.c
index 389b118..8625633 100644
--- a/src/H5HF.c
+++ b/src/H5HF.c
@@ -172,7 +172,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
/* Allocate fractal heap wrapper */
if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed for fractal heap info")
/* Lock the heap header into memory */
if(NULL == (hdr = (H5HF_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, NULL, NULL, H5AC_WRITE)))
@@ -196,10 +196,9 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header")
- if(!ret_value) {
- if(fh)
- (void)H5HF_close(fh, dxpl_id);
- } /* end if */
+ if(!ret_value && fh)
+ if(H5HF_close(fh, dxpl_id) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, NULL, "unable to close fractal heap")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_create() */
@@ -250,7 +249,7 @@ HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fs
/* Create fractal heap info */
if(NULL == (fh = H5FL_MALLOC(H5HF_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap info")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "memory allocation failed for fractal heap info")
/* Point fractal heap wrapper at header */
fh->hdr = hdr;
@@ -270,10 +269,9 @@ HDfprintf(stderr, "%s: hdr->rc = %u, hdr->fspace = %p\n", FUNC, hdr->rc, hdr->fs
done:
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FHEAP_HDR, fh_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, NULL, "unable to release fractal heap header")
- if(!ret_value) {
- if(fh)
- (void)H5HF_close(fh, dxpl_id);
- } /* end if */
+ if(!ret_value && fh)
+ if(H5HF_close(fh, dxpl_id) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTCLOSEOBJ, NULL, "unable to close fractal heap")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_open() */
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index bf19044..08ad558 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -431,7 +431,8 @@ done:
if(wb && H5WB_unwrap(wb) < 0)
HDONE_ERROR(H5E_HEAP, H5E_CLOSEERROR, NULL, "can't close wrapped buffer")
if(!ret_value && hdr)
- (void)H5HF_cache_hdr_dest(f, hdr);
+ if(H5HF_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
@@ -479,9 +480,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
uint8_t heap_flags; /* Status flags for heap */
uint32_t metadata_chksum; /* Computed metadata checksum value */
- /* Sanity check */
- HDassert(hdr->dirty);
-
/* Set the shared heap header's file context for this operation */
hdr->f = f;
@@ -566,7 +564,6 @@ HDfprintf(stderr, "%s: Flushing heap header, addr = %a, destroy = %u\n", FUNC, a
if(H5F_block_write(f, H5FD_MEM_FHEAP_HDR, addr, size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap header to disk")
- hdr->dirty = FALSE;
hdr->cache_info.is_dirty = FALSE;
} /* end if */
@@ -620,16 +617,9 @@ H5HF_cache_hdr_dest(H5F_t *f, H5HF_hdr_t *hdr)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap header")
} /* end if */
- /* Free the block size lookup table for the doubling table */
- H5HF_dtable_dest(&hdr->man_dtable);
-
- /* Release any I/O pipeline filter information */
- if(hdr->pline.nused)
- H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline));
-
/* Free the shared info itself */
- (void)H5FL_FREE(H5HF_hdr_t, hdr);
-
+ if(H5HF_hdr_free(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRELEASE, FAIL, "unable to release fractal heap header")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_cache_hdr_dest() */
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c
index d1f2675..c7dada2 100644
--- a/src/H5HFhdr.c
+++ b/src/H5HFhdr.c
@@ -79,7 +79,7 @@
/*********************/
/* Declare a free list to manage the H5HF_hdr_t struct */
-H5FL_DEFINE(H5HF_hdr_t);
+H5FL_DEFINE_STATIC(H5HF_hdr_t);
/*****************************/
@@ -110,7 +110,7 @@ H5HF_hdr_t *
H5HF_hdr_alloc(H5F_t *f)
{
H5HF_hdr_t *hdr = NULL; /* Shared fractal heap header */
- H5HF_hdr_t *ret_value = NULL; /* Return value */
+ H5HF_hdr_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_alloc)
@@ -121,7 +121,7 @@ H5HF_hdr_alloc(H5F_t *f)
/* Allocate space for the shared information */
if(NULL == (hdr = H5FL_CALLOC(H5HF_hdr_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "allocation failed for fractal heap shared header")
/* Set the internal parameters for the heap */
hdr->f = f;
@@ -132,9 +132,9 @@ H5HF_hdr_alloc(H5F_t *f)
ret_value = hdr;
done:
- if(!ret_value)
- if(hdr)
- (void)H5HF_cache_hdr_dest(f, hdr);
+ if(!ret_value && hdr)
+ if(H5HF_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_alloc() */
@@ -409,9 +409,6 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam)
/* Set "huge" object tracker v2 B-tree address to indicate that there aren't any yet */
hdr->huge_bt2_addr = HADDR_UNDEF;
- /* Note that the shared info is dirty (it's not written to the file yet) */
- hdr->dirty = TRUE;
-
/* First phase of header final initialization */
/* (doesn't need ID length set up) */
if(H5HF_hdr_finish_init_phase1(hdr) < 0)
@@ -457,7 +454,7 @@ HDfprintf(stderr, "%s: hdr->filter_len = %u\n", FUNC, hdr->filter_len);
*/
switch(cparam->id_len) {
case 0: /* Set the length of heap IDs to just enough to hold the offset & length of 'normal' objects in the heap */
- hdr->id_len = 1 + hdr->heap_off_size + hdr->heap_len_size;
+ hdr->id_len = (unsigned)1 + hdr->heap_off_size + hdr->heap_len_size;
break;
case 1: /* Set the length of heap IDs to just enough to hold the information needed to directly access 'huge' objects in the heap */
@@ -505,15 +502,15 @@ HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len);
/* Cache the new fractal heap header */
if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache")
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, HADDR_UNDEF, "can't add fractal heap header to cache")
/* Set address of heap header to return */
ret_value = hdr->heap_addr;
done:
- if(!H5F_addr_defined(ret_value))
- if(hdr)
- (void)H5HF_cache_hdr_dest(NULL, hdr);
+ if(!H5F_addr_defined(ret_value) && hdr)
+ if(H5HF_hdr_free(hdr) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release fractal heap header")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_create() */
@@ -681,9 +678,6 @@ HDfprintf(stderr, "%s: Marking heap header as dirty\n", FUNC);
if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark fractal heap header as dirty")
- /* Set the dirty flags for the heap header */
- hdr->dirty = TRUE;
-
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5HF_hdr_dirty() */
@@ -1493,6 +1487,43 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5HF_hdr_free
+ *
+ * Purpose: Free shared fractal heap header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 27 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HF_hdr_free(H5HF_hdr_t *hdr)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_free)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(hdr);
+
+ /* Free the block size lookup table for the doubling table */
+ H5HF_dtable_dest(&hdr->man_dtable);
+
+ /* Release any I/O pipeline filter information */
+ if(hdr->pline.nused)
+ H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline));
+
+ /* Free the shared info itself */
+ hdr = H5FL_FREE(H5HF_hdr_t, hdr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5HF_hdr_free() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5HF_hdr_delete
*
* Purpose: Delete a fractal heap, starting with the header
@@ -1508,8 +1539,8 @@ done:
herr_t
H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id)
{
- unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap header */
- herr_t ret_value = SUCCEED;
+ unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5HF_hdr_delete, FAIL)
diff --git a/src/H5HFpkg.h b/src/H5HFpkg.h
index 21e2865..a4e7037 100644
--- a/src/H5HFpkg.h
+++ b/src/H5HFpkg.h
@@ -335,7 +335,6 @@ typedef struct H5HF_hdr_t {
/* Cached/computed values (not stored in header) */
size_t rc; /* Reference count of heap's components using heap header */
- hbool_t dirty; /* Shared info is modified */
haddr_t heap_addr; /* Address of heap header in the file */
size_t heap_size; /* Size of heap header in the file */
H5AC_protect_t mode; /* Access mode for heap */
@@ -504,9 +503,6 @@ H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_NORMAL_ROW[1];
/* H5HF indirect section inherits serializable properties from H5FS_section_class_t */
H5_DLLVAR H5FS_section_class_t H5HF_FSPACE_SECT_CLS_INDIRECT[1];
-/* Declare a free list to manage the H5HF_hdr_t struct */
-H5FL_EXTERN(H5HF_hdr_t);
-
/* Declare a free list to manage the H5HF_indirect_t struct */
H5FL_EXTERN(H5HF_indirect_t);
@@ -564,6 +560,7 @@ H5_DLL herr_t H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id,
haddr_t dblock_addr);
H5_DLL herr_t H5HF_hdr_reset_iter(H5HF_hdr_t *hdr, hsize_t curr_off);
H5_DLL herr_t H5HF_hdr_empty(H5HF_hdr_t *hdr);
+H5_DLL herr_t H5HF_hdr_free(H5HF_hdr_t *hdr);
H5_DLL herr_t H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id);
/* Indirect block routines */