summaryrefslogtreecommitdiffstats
path: root/src/H5B2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5B2.c')
-rw-r--r--src/H5B2.c971
1 files changed, 485 insertions, 486 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index 070d3b3..5ab9e8a 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -41,7 +41,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
-#include "H5MFprivate.h" /* File memory management */
+
/****************/
/* Local Macros */
@@ -67,8 +67,35 @@
/* Package Variables */
/*********************/
-/* Declare a free list to manage the H5B2_t struct */
-H5FL_DEFINE(H5B2_t);
+/* v2 B-tree client ID to class mapping */
+
+/* Remember to add client ID to H5B2_subid_t in H5B2private.h when adding a new
+ * client class..
+ */
+extern const H5B2_class_t H5B2_TEST[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_INDIR[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_FILT_INDIR[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_DIR[1];
+extern const H5B2_class_t H5HF_HUGE_BT2_FILT_DIR[1];
+extern const H5B2_class_t H5G_BT2_NAME[1];
+extern const H5B2_class_t H5G_BT2_CORDER[1];
+extern const H5B2_class_t H5SM_INDEX[1];
+extern const H5B2_class_t H5A_BT2_NAME[1];
+extern const H5B2_class_t H5A_BT2_CORDER[1];
+
+const H5B2_class_t *const H5B2_client_class_g[] = {
+ H5B2_TEST, /* 0 - H5B2_TEST_ID */
+ H5HF_HUGE_BT2_INDIR, /* 1 - H5B2_FHEAP_HUGE_INDIR_ID */
+ H5HF_HUGE_BT2_FILT_INDIR, /* 2 - H5B2_FHEAP_HUGE_FILT_INDIR_ID */
+ H5HF_HUGE_BT2_DIR, /* 3 - H5B2_FHEAP_HUGE_DIR_ID */
+ H5HF_HUGE_BT2_FILT_DIR, /* 4 - H5B2_FHEAP_HUGE_FILT_DIR_ID */
+ H5G_BT2_NAME, /* 5 - H5B2_GRP_DENSE_NAME_ID */
+ H5G_BT2_CORDER, /* 6 - H5B2_GRP_DENSE_CORDER_ID */
+ H5SM_INDEX, /* 7 - H5B2_SOHM_INDEX_ID */
+ H5A_BT2_NAME, /* 8 - H5B2_ATTR_DENSE_NAME_ID */
+ H5A_BT2_CORDER, /* 9 - H5B2_ATTR_DENSE_CORDER_ID */
+};
+
/*****************************/
/* Library Private Variables */
@@ -79,6 +106,10 @@ H5FL_DEFINE(H5B2_t);
/* Local Variables */
/*******************/
+/* Declare a free list to manage the H5B2_t struct */
+H5FL_DEFINE_STATIC(H5B2_t);
+
+
/*-------------------------------------------------------------------------
* Function: H5B2_create
@@ -94,63 +125,129 @@ H5FL_DEFINE(H5B2_t);
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- size_t node_size, size_t rrec_size,
- unsigned split_percent, unsigned merge_percent, haddr_t *addr_p)
+H5B2_t *
+H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, void *ctx_udata)
{
- H5B2_t *bt2 = NULL; /* The new B-tree header information */
- herr_t ret_value = SUCCEED;
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ haddr_t hdr_addr; /* B-tree header address */
+ H5B2_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5B2_create, FAIL)
+ FUNC_ENTER_NOAPI(H5B2_create, NULL)
/*
* Check arguments.
*/
HDassert(f);
- HDassert(type);
- HDassert(node_size > 0);
- HDassert(rrec_size > 0);
- HDassert(merge_percent > 0 && merge_percent <= 100);
- HDassert(split_percent > 0 && split_percent <= 100);
- HDassert(merge_percent < (split_percent / 2));
- HDassert(addr_p);
+ HDassert(cparam);
- /*
- * Allocate file and memory data structures.
- */
+ /* H5B2 interface sanity check */
+ HDcompile_assert(H5B2_NUM_BTREE_ID == NELMTS(H5B2_client_class_g));
+
+ /* Create shared v2 B-tree header */
+ if(HADDR_UNDEF == (hdr_addr = H5B2_hdr_create(f, dxpl_id, cparam, ctx_udata)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't create v2 B-tree header")
+
+ /* Create v2 B-tree wrapper */
if(NULL == (bt2 = H5FL_MALLOC(H5B2_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree header")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "memory allocation failed for v2 B-tree info")
+
+ /* Look up the B-tree header */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, NULL, ctx_udata, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header")
- /* Assign internal information */
- HDmemset(&bt2->cache_info, 0, sizeof(H5AC_info_t));
- bt2->root.addr = HADDR_UNDEF;
- bt2->root.node_nrec = 0;
- bt2->root.all_nrec = 0;
+ /* Point v2 B-tree wrapper at header and bump it's ref count */
+ 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")
- /* Initialize shared B-tree info */
- if(H5B2_shared_init(f, bt2, type, 0, node_size, rrec_size, split_percent, merge_percent) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create shared B-tree info")
+ /* 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")
- /* Allocate space for the header on disk */
- if(HADDR_UNDEF == (*addr_p = 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")
+ /* Set file pointer for this v2 B-tree open context */
+ bt2->f = f;
- /* Cache the new B-tree node */
- if(H5AC_set(f, dxpl_id, H5AC_BT2_HDR, *addr_p, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree header to cache")
+ /* Set the return value */
+ ret_value = bt2;
done:
- if(ret_value < 0) {
- if(bt2)
- (void)H5B2_cache_hdr_dest(f, bt2);
- } /* end if */
+ if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, 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)
} /* end H5B2_create() */
/*-------------------------------------------------------------------------
+ * Function: H5B2_open
+ *
+ * Purpose: Opens an existing v2 B-tree in the file.
+ *
+ * Return: Pointer to v2 B-tree wrapper on success
+ * NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 15 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+H5B2_t *
+H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata)
+{
+ H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
+ H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
+ H5B2_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_open)
+
+ /* Check arguments. */
+ HDassert(f);
+ 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, NULL, ctx_udata, H5AC_READ)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header")
+
+ /* 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 = bt2;
+
+done:
+ 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() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_insert
*
* Purpose: Adds a new record to the B-tree.
@@ -164,68 +261,87 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata)
+H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- unsigned bt2_flags = H5AC__NO_FLAGS_SET; /* Metadata cache flags for B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ 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(H5F_addr_defined(addr));
+ HDassert(bt2);
+ HDassert(udata);
- /* Look up the b-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check if the root node is allocated yet */
- if(!H5F_addr_defined(bt2->root.addr)) {
+ if(!H5F_addr_defined(hdr->root.addr)) {
/* Create root node as leaf node in B-tree */
- if(H5B2_create_leaf(f, dxpl_id, bt2->shared, &(bt2->root)) < 0)
+ if(H5B2_create_leaf(hdr, dxpl_id, &(hdr->root)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create root node")
-
- /* Mark B-tree header as dirty, since we updated the address of the root node */
- bt2_flags |= H5AC__DIRTIED_FLAG;
} /* end if */
/* Check if we need to split the root node (equiv. to a 1->2 node split) */
- else if(bt2->root.node_nrec == shared->node_info[shared->depth].split_nrec) {
+ else if(hdr->root.node_nrec == hdr->node_info[hdr->depth].split_nrec) {
/* Split root node */
- if(H5B2_split_root(f, dxpl_id, bt2, &bt2_flags) < 0)
+ if(H5B2_split_root(hdr, dxpl_id) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split root node")
} /* end if */
/* Attempt to insert record into B-tree */
- if(shared->depth > 0) {
- if(H5B2_insert_internal(f, dxpl_id, bt2->shared, shared->depth, &bt2_flags, &bt2->root, udata) < 0)
+ if(hdr->depth > 0) {
+ if(H5B2_insert_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
- if(H5B2_insert_leaf(f, dxpl_id, bt2->shared, &bt2->root, udata) < 0)
+ if(H5B2_insert_leaf(hdr, dxpl_id, &hdr->root, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
} /* end else */
- /* Mark parent node as dirty */
- bt2_flags |= H5AC__DIRTIED_FLAG;
+ /* Mark B-tree header as dirty */
+ if(H5B2_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty")
done:
- /* Release the B-tree header info */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_insert() */
/*-------------------------------------------------------------------------
+ * Function: H5B2_get_addr
+ *
+ * Purpose: Get the address of a v2 B-tree
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Nov 5 2009
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_get_addr(const H5B2_t *bt2, haddr_t *addr_p)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5B2_get_addr)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt2);
+ HDassert(addr_p);
+
+ /* Retrieve the header address for this v2 B-tree */
+ *addr_p = bt2->hdr->addr;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B2_get_addr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2_iterate
*
* Purpose: Iterate over all the records in the B-tree, in "in-order"
@@ -243,61 +359,30 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_iterate(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5B2_operator_t op, void *op_data)
+H5B2_iterate(H5B2_t *bt2, hid_t dxpl_id, H5B2_operator_t op, void *op_data)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
- H5B2_node_ptr_t root_ptr; /* Node pointer info for root node */
- unsigned depth; /* Current depth of the tree */
- herr_t ret_value = SUCCEED;
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5B2_iterate, FAIL)
+ FUNC_ENTER_NOAPI_NOERR(H5B2_iterate, -)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
-
- /* Make copy of the root node pointer */
- root_ptr = bt2->root;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Iterate through records */
- if(root_ptr.node_nrec > 0) {
+ if(hdr->root.node_nrec > 0) {
/* Iterate through nodes */
- if((ret_value = H5B2_iterate_node(f, dxpl_id, bt2_shared, depth, &root_ptr, op, op_data)) < 0)
+ if((ret_value = H5B2_iterate_node(hdr, dxpl_id, hdr->depth, &hdr->root, op, op_data)) < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed");
} /* end if */
-done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_iterate() */
@@ -314,10 +399,10 @@ done:
* OP_DATA pointer, to allow caller to return information about
* the record.
*
- * If 'OP' is NULL, then this routine just returns "SUCCEED" when
+ * If 'OP' is NULL, then this routine just returns "TRUE" when
* a record is present in the B-tree.
*
- * Return: Non-negative on success, negative on failure.
+ * Return: Non-negative (TRUE/FALSE) on success, negative on failure.
*
* Programmer: Quincey Koziol
* koziol@ncsa.uiuc.edu
@@ -325,54 +410,37 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_found_t op, void *op_data)
+htri_t
+H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
+ void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared = NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc = FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ 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 */
unsigned idx; /* Location of record which matches key */
- herr_t ret_value = SUCCEED;
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI(H5B2_find, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
-
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ HDassert(bt2);
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
if(curr_node_ptr.node_nrec == 0)
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
+ HGOTO_DONE(FALSE)
/* Walk down B-tree to find record or leaf node where record is located */
cmp = -1;
@@ -381,11 +449,11 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
idx++;
@@ -394,7 +462,7 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
next_node_ptr=internal->node_ptrs[idx];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -402,19 +470,20 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
} /* end if */
else {
/* Make callback for current record */
- if(op && (op)(H5B2_INT_NREC(internal, shared, idx), op_data) < 0) {
+ if(op && (op)(H5B2_INT_NREC(internal, hdr, idx), op_data) < 0) {
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
- HGOTO_DONE(SUCCEED);
+ /* Indicate record found */
+ HGOTO_DONE(TRUE)
} /* end else */
/* Decrement depth we're at in B-tree */
@@ -425,32 +494,25 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate record */
- cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
if(cmp != 0) {
/* Unlock leaf node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
- /* Note: don't push error on stack, leave that to next higher level,
- * since many times the B-tree is searched in order to determine
- * if an object exists in the B-tree or not. -QAK
- */
-#ifdef OLD_WAY
- HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "key not found in leaf node")
-#else /* OLD_WAY */
- HGOTO_DONE(FAIL)
-#endif /* OLD_WAY */
+ /* Record not found */
+ HGOTO_DONE(FALSE)
} /* end if */
else {
/* Make callback for current record */
- if(op && (op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) {
+ if(op && (op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
@@ -458,15 +520,11 @@ H5B2_find(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
} /* end else */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
} /* end block */
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_find() */
@@ -490,48 +548,31 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5_iter_order_t order, hsize_t idx, H5B2_found_t op, void *op_data)
+H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
+ H5B2_found_t op, void *op_data)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ 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;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_index, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
if(curr_node_ptr.node_nrec == 0)
@@ -552,7 +593,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
unsigned u; /* Local index variable */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Search for record with correct index */
@@ -563,7 +604,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
next_node_ptr = internal->node_ptrs[u];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -576,16 +617,16 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Check if record is in this node */
if(internal->node_ptrs[u].all_nrec == idx) {
/* Make callback for current record */
- if((op)(H5B2_INT_NREC(internal, shared, u), op_data) < 0) {
+ if((op)(H5B2_INT_NREC(internal, hdr, u), op_data) < 0) {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_DONE(SUCCEED);
@@ -605,7 +646,7 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
next_node_ptr = internal->node_ptrs[u];
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -624,31 +665,27 @@ H5B2_index(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_READ)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Sanity check index */
HDassert(idx < leaf->nrec);
/* Make callback for correct record */
- if((op)(H5B2_LEAF_NREC(leaf, shared, idx), op_data) < 0) {
+ if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data) < 0) {
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
} /* end block */
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_index() */
@@ -667,70 +704,61 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_remove_t op, void *op_data)
+H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op,
+ void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- unsigned bt2_flags = H5AC__NO_FLAGS_SET;
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ 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(H5F_addr_defined(addr));
+ HDassert(bt2);
- /* Look up the b-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check for empty B-tree */
- if(bt2->root.all_nrec == 0)
+ if(0 == hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
/* Attempt to remove record from B-tree */
- if(shared->depth > 0) {
+ if(hdr->depth > 0) {
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
- if(H5B2_remove_internal(f, dxpl_id, bt2->shared, &depth_decreased, NULL, shared->depth,
- &(bt2->cache_info), &bt2_flags, &bt2->root, udata, op, op_data) < 0)
+ if(H5B2_remove_internal(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth,
+ &(hdr->cache_info), NULL, &hdr->root, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
/* Check for decreasing the depth of the B-tree */
if(depth_decreased) {
/* Destroy free list factories for previous depth */
- if(shared->node_info[shared->depth].nat_rec_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].nat_rec_fac) < 0)
+ if(hdr->node_info[hdr->depth].nat_rec_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].nat_rec_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
- if(shared->node_info[shared->depth].node_ptr_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].node_ptr_fac) < 0)
+ if(hdr->node_info[hdr->depth].node_ptr_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].node_ptr_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
- shared->depth -= depth_decreased;
+ hdr->depth -= (uint16_t)depth_decreased;
} /* end for */
} /* end if */
else {
- if(H5B2_remove_leaf(f, dxpl_id, bt2->shared, &bt2->root, udata, op, op_data) < 0)
+ if(H5B2_remove_leaf(hdr, dxpl_id, &hdr->root, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
/* Decrement # of records in B-tree */
- bt2->root.all_nrec--;
+ hdr->root.all_nrec--;
- /* Mark parent node as dirty */
- bt2_flags |= H5AC__DIRTIED_FLAG;
+ /* Mark B-tree header as dirty */
+ if(H5B2_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty")
done:
- /* Release the B-tree header info */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_remove() */
@@ -749,79 +777,69 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_remove_by_idx(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type,
- haddr_t addr, H5_iter_order_t order, hsize_t idx, H5B2_remove_t op,
- void *op_data)
+H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
+ hsize_t idx, H5B2_remove_t op, void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- unsigned bt2_flags = H5AC__NO_FLAGS_SET;
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ 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(H5F_addr_defined(addr));
+ HDassert(bt2);
- /* Look up the b-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check for empty B-tree */
- if(bt2->root.all_nrec == 0)
+ if(0 == hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "record is not in B-tree")
/* Check for index greater than the number of records in the tree */
- if(idx >= bt2->root.all_nrec)
+ if(idx >= hdr->root.all_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree doesn't have that many records")
/* Check for reverse indexing and map requested index to appropriate forward index */
- if(order == H5_ITER_DEC)
- idx = bt2->root.all_nrec - (idx + 1);
+ if(H5_ITER_DEC == order)
+ idx = hdr->root.all_nrec - (idx + 1);
/* Attempt to remove record from B-tree */
- if(shared->depth > 0) {
+ if(hdr->depth > 0) {
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
- if(H5B2_remove_internal_by_idx(f, dxpl_id, bt2->shared, &depth_decreased, NULL, shared->depth,
- &(bt2->cache_info), &bt2_flags, &bt2->root, idx, op, op_data) < 0)
+ if(H5B2_remove_internal_by_idx(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth,
+ &(hdr->cache_info), NULL, &hdr->root, idx, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree internal node")
/* Check for decreasing the depth of the B-tree */
if(depth_decreased) {
/* Destroy free list factories for previous depth */
- if(shared->node_info[shared->depth].nat_rec_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].nat_rec_fac) < 0)
+ if(hdr->node_info[hdr->depth].nat_rec_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].nat_rec_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's native record block factory")
- if(shared->node_info[shared->depth].node_ptr_fac)
- if(H5FL_fac_term(shared->node_info[shared->depth].node_ptr_fac) < 0)
+ if(hdr->node_info[hdr->depth].node_ptr_fac)
+ if(H5FL_fac_term(hdr->node_info[hdr->depth].node_ptr_fac) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "can't destroy node's node pointer block factory")
- shared->depth -= depth_decreased;
+ hdr->depth -= (uint16_t)depth_decreased;
} /* end for */
} /* end if */
else {
- if(H5B2_remove_leaf_by_idx(f, dxpl_id, bt2->shared, &bt2->root, (unsigned)idx, op, op_data) < 0)
+ if(H5B2_remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, (unsigned)idx, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
/* Decrement # of records in B-tree */
- bt2->root.all_nrec--;
+ hdr->root.all_nrec--;
- /* Mark parent node as dirty */
- bt2_flags |= H5AC__DIRTIED_FLAG;
+ /* Mark B-tree header as dirty */
+ if(H5B2_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMARKDIRTY, FAIL, "unable to mark B-tree header dirty")
done:
- /* Release the B-tree header info */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, bt2_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_remove_by_idx() */
@@ -840,33 +858,18 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_get_nrec(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- hsize_t *nrec)
+H5B2_get_nrec(const H5B2_t *bt2, hsize_t *nrec)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5B2_get_nrec, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B2_get_nrec)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(nrec);
- /* Look up the B-tree header */
- if (NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
/* Get B-tree number of records */
- *nrec = bt2->root.all_nrec;
+ *nrec = bt2->hdr->root.all_nrec;
-done:
- /* Release B-tree header node */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
-
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_get_nrec() */
@@ -896,116 +899,44 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_neighbor(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- H5B2_compare_t range, void *udata, H5B2_found_t op, void *op_data)
+H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range, void *udata,
+ H5B2_found_t op, void *op_data)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
+ 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(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Check for empty tree */
- if(!H5F_addr_defined(bt2->root.addr))
+ if(!H5F_addr_defined(hdr->root.addr))
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
/* Attempt to find neighbor record in B-tree */
- if(shared->depth > 0) {
- if(H5B2_neighbor_internal(f, dxpl_id, bt2->shared, shared->depth, &bt2->root, NULL, range, udata, op, op_data)<0)
+ if(hdr->depth > 0) {
+ if(H5B2_neighbor_internal(hdr, dxpl_id, hdr->depth, &hdr->root, NULL, range, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree internal node")
} /* end if */
else {
- if(H5B2_neighbor_leaf(f, dxpl_id, bt2->shared, &bt2->root, NULL, range, udata, op, op_data)<0)
+ if(H5B2_neighbor_leaf(hdr, dxpl_id, &hdr->root, NULL, range, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree leaf node")
} /* end else */
done:
- /* Release the B-tree header info */
- if (bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, 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_neighbor() */
/*-------------------------------------------------------------------------
- * 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_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5B2_delete, FAIL)
-
- /* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
-
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
-
- /* Delete all nodes in B-tree */
- if(H5F_addr_defined(bt2->root.addr))
- if(H5B2_delete_node(f, dxpl_id, bt2->shared, shared->depth, &bt2->root, op, op_data) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to delete B-tree nodes")
-
- /* Release space for B-tree node on disk */
- if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5B2_HEADER_SIZE(f))<0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree header info")
-
-done:
- /* Release the B-tree header info */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__DELETED_FLAG) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to delete B-tree header info")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_delete() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5B2_modify
*
* Purpose: Locate the specified information in a B-tree and modify it.
@@ -1026,54 +957,36 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
- void *udata, H5B2_modify_t op, void *op_data)
+H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
+ void *op_data)
{
- H5B2_t *bt2=NULL; /* Pointer to the B-tree header */
- H5RC_t *bt2_shared=NULL; /* Pointer to ref-counter for shared B-tree info */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- hbool_t incr_rc=FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
+ 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 */
unsigned idx; /* Location of record which matches key */
- herr_t ret_value = SUCCEED;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B2_modify, FAIL)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
+ HDassert(bt2);
HDassert(op);
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
-
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- HDassert(bt2_shared);
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
- /* Get the pointer to the shared B-tree info */
- shared=(H5B2_shared_t *)H5RC_GET_OBJ(bt2_shared);
- HDassert(shared);
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
/* Make copy of the root node pointer to start search with */
- curr_node_ptr = bt2->root;
+ curr_node_ptr = hdr->root;
/* Current depth of the tree */
- depth = shared->depth;
-
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ depth = hdr->depth;
/* Check for empty tree */
- if(curr_node_ptr.node_nrec==0)
+ if(0 == curr_node_ptr.node_nrec)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "B-tree has no records")
/* Walk down B-tree to find record or leaf node where record is located */
@@ -1084,20 +997,20 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2_protect_internal(f, dxpl_id, bt2_shared, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_WRITE)))
+ if(NULL == (internal = H5B2_protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2_locate_record(shared->type, internal->nrec, shared->nat_off, internal->int_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
idx++;
if(cmp != 0) {
/* Get node pointer for next node to search */
- next_node_ptr=internal->node_ptrs[idx];
+ next_node_ptr = internal->node_ptrs[idx];
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Set pointer to next node to load */
@@ -1107,12 +1020,12 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
hbool_t changed; /* Whether the 'modify' callback changed the record */
/* Make callback for current record */
- if ( (op)(H5B2_INT_NREC(internal,shared,idx), op_data, &changed) <0) {
+ if((op)(H5B2_INT_NREC(internal, hdr, idx), op_data, &changed) < 0) {
/* Make certain that the callback didn't modify the value if it failed */
- HDassert(changed==FALSE);
+ HDassert(changed == FALSE);
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation")
@@ -1122,7 +1035,7 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
internal_flags |= changed ? H5AC__DIRTIED_FLAG : 0;
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, internal_flags) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, internal_flags) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_DONE(SUCCEED);
@@ -1138,15 +1051,15 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
hbool_t changed = FALSE;/* Whether the 'modify' callback changed the record */
/* Lock B-tree leaf node */
- if (NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), bt2_shared, H5AC_WRITE)))
+ if(NULL == (leaf = (H5B2_leaf_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, &(curr_node_ptr.node_nrec), hdr, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate record */
- cmp = H5B2_locate_record(shared->type, leaf->nrec, shared->nat_off, leaf->leaf_native, udata, &idx);
+ cmp = H5B2_locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
if(cmp != 0) {
/* Unlock leaf node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
/* Note: don't push error on stack, leave that to next higher level,
@@ -1161,12 +1074,12 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
} /* end if */
else {
/* Make callback for current record */
- if ((op)(H5B2_LEAF_NREC(leaf,shared,idx), op_data, &changed) <0) {
+ if((op)(H5B2_LEAF_NREC(leaf, hdr, idx), op_data, &changed) < 0) {
/* Make certain that the callback didn't modify the value if it failed */
- HDassert(changed==FALSE);
+ HDassert(changed == FALSE);
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree find operation")
@@ -1177,94 +1090,180 @@ H5B2_modify(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
leaf_flags |= (changed ? H5AC__DIRTIED_FLAG : 0);
/* Unlock current node */
- if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, leaf_flags) < 0)
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, leaf_flags) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
}
done:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
-
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_modify() */
/*-------------------------------------------------------------------------
- * Function: H5B2_iterate_size
+ * Function: H5B2_close
*
- * Purpose: Iterate over all the records in the B-tree, collecting
- * storage info.
+ * Purpose: Close a v2 B-tree
*
- * Return: non-negative on success, negative on error
+ * Return: Non-negative on success/Negative on failure
*
- * Programmer: Vailin Choi
- * June 19 2007
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Oct 15 2009
*
*-------------------------------------------------------------------------
*/
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_close(H5B2_t *bt2, hid_t dxpl_id)
{
- H5B2_t *bt2 = NULL; /* Pointer to the B-tree header */
- H5B2_shared_t *shared; /* Pointer to B-tree's shared information */
- H5RC_t *bt2_shared = NULL; /* Pointer to ref-counter for shared B-tree info */
- hbool_t incr_rc = FALSE; /* Flag to indicate that we've incremented the B-tree's shared info reference count */
- H5B2_node_ptr_t root_ptr; /* Node pointer info for root node */
- unsigned depth; /* Current depth of the tree */
- herr_t ret_value = SUCCEED;
+ 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(H5B2_iterate_size, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT(H5B2_close)
/* Check arguments. */
- HDassert(f);
- HDassert(type);
- HDassert(H5F_addr_defined(addr));
- HDassert(btree_size);
+ 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;
+ } /* end if */
+ } /* end if */
- /* Look up the B-tree header */
- if(NULL == (bt2 = (H5B2_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, type, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree header")
+ /* Check for pending v2 B-tree deletion */
+ if(pending_delete) {
+ H5B2_hdr_t *hdr; /* Another pointer to v2 B-tree header */
- /* Safely grab pointer to reference counted shared B-tree info, so we can release the B-tree header if necessary */
- bt2_shared = bt2->shared;
- H5RC_INC(bt2_shared);
- incr_rc = TRUE;
+ /* Sanity check */
+ HDassert(H5F_addr_defined(bt2_addr));
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+#ifndef NDEBUG
+{
+ unsigned hdr_status = 0; /* Header's status in the metadata cache */
+
+ /* Check the header's status in the metadata cache */
+ if(H5AC_get_entry_status(bt2->f, bt2_addr, &hdr_status) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to check metadata cache status for v2 B-tree header, address = %llu", (unsigned long long)bt2_addr)
+
+ /* Sanity checks on header */
+ HDassert(hdr_status & H5AC_ES__IN_CACHE);
+ HDassert(hdr_status & H5AC_ES__IS_PINNED);
+ HDassert(!(hdr_status & H5AC_ES__IS_PROTECTED));
+}
+#endif /* NDEBUG */
+
+ /* Lock the v2 B-tree header into memory */
+ /* (OK to pass in NULL for callback context, since we know the header must be in the cache) */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(bt2->f, dxpl_id, H5AC_BT2_HDR, bt2_addr, NULL, 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;
+
+ /* 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")
+
+ /* 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 */
+ else {
+ /* 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")
- /* Add size of header to B-tree metadata total */
- *btree_size += H5B2_HEADER_SIZE(f);
+ } /* end else */
- /* Make copy of the root node pointer */
- root_ptr = bt2->root;
+ /* Release the v2 B-tree wrapper */
+ bt2 = H5FL_FREE(H5B2_t, bt2);
- /* Current depth of the tree */
- depth = shared->depth;
+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, haddr_t addr, void *ctx_udata,
+ 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 */
- /* Release header */
- if(H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree header info")
- bt2 = NULL;
+ FUNC_ENTER_NOAPI(H5B2_delete, FAIL)
- /* Iterate through records */
- if(root_ptr.node_nrec > 0) {
- /* Check for root node being a leaf */
- if(depth == 0)
- *btree_size += shared->node_size;
- else
- /* Iterate through nodes */
- if(H5B2_iterate_size_node(f, dxpl_id, bt2_shared, depth, &root_ptr, btree_size) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "node iteration failed");
+ /* Check arguments. */
+ HDassert(f);
+ 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, NULL, ctx_udata, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect 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:
- /* Check if we need to decrement the reference count for the B-tree's shared info */
- if(incr_rc)
- H5RC_DEC(bt2_shared);
+ /* 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_iterate_size() */
+} /* H5B2_delete() */