summaryrefslogtreecommitdiffstats
path: root/src/H5B2.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-10-29 13:58:52 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-10-29 13:58:52 (GMT)
commit56276c02cdfe8d16c9663a5875803e89112700ed (patch)
tree64628715223d2a751300768f75e3ea76187845ba /src/H5B2.c
parent0475c8ce57f84ced2e8ab35dabbcde6bd4e4e3fa (diff)
downloadhdf5-56276c02cdfe8d16c9663a5875803e89112700ed.zip
hdf5-56276c02cdfe8d16c9663a5875803e89112700ed.tar.gz
hdf5-56276c02cdfe8d16c9663a5875803e89112700ed.tar.bz2
[svn-r17785] Description:
Further refactor v2 B-tree code to bring it closer to modern data structure designed in the library, mainly by introducing a H5B2_t type so that the v2 B-tree could be held open, but not require the B-tree header to be protected the whole time. A few other minor tweaks as well. Also, remove unused 'dirty' flag from fractal heap header. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers, w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.6.1 (amazon) in debug mode Mac OS X/32 10.6.1 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'src/H5B2.c')
-rw-r--r--src/H5B2.c436
1 files changed, 290 insertions, 146 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index 6408dc4..a30a6e2 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -61,9 +61,9 @@
/********************/
/* 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);
/*********************/
@@ -80,6 +80,10 @@ static herr_t H5B2_close(H5B2_hdr_t *hdr, hid_t dxpl_id);
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5B2_t struct */
+H5FL_DEFINE_STATIC(H5B2_t);
+
+
/*-------------------------------------------------------------------------
* Function: H5B2_create
@@ -137,34 +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 && hdr)
- if(H5B2_close(hdr, dxpl_id) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTCLOSEOBJ, NULL, "unable to close B-tree")
+ 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() */
@@ -184,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 */
@@ -230,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)
@@ -255,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 */
@@ -282,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)
@@ -313,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 */
@@ -327,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;
@@ -428,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)
@@ -454,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 */
@@ -466,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;
@@ -593,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)
@@ -614,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")
@@ -670,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)
@@ -691,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")
@@ -756,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)
@@ -777,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)
@@ -833,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")
@@ -867,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)
@@ -875,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.
@@ -953,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 */
@@ -967,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;
@@ -1092,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)
@@ -1113,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);
@@ -1146,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)
@@ -1167,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 */
- /* 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")
+ /* Sanity check */
+ HDassert(H5F_addr_defined(bt2_addr));
+ HDassert(cls);
+
+ /* 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() */
+