summaryrefslogtreecommitdiffstats
path: root/src/H5B2.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-11-16 20:45:05 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-11-16 20:45:05 (GMT)
commitd2b87ec47ebdb096c331c7b62a195b9cea2f33ae (patch)
treea066f01361afaf5df457cef612bb0bb9fd80fe18 /src/H5B2.c
parentee5a1e07350f0dcf3ef07d9443aa2f4c073392f4 (diff)
downloadhdf5-d2b87ec47ebdb096c331c7b62a195b9cea2f33ae.zip
hdf5-d2b87ec47ebdb096c331c7b62a195b9cea2f33ae.tar.gz
hdf5-d2b87ec47ebdb096c331c7b62a195b9cea2f33ae.tar.bz2
[svn-r17896] Description:
Bring r17546:17895 from trunk to revise_chunks branch. Changes to fixed and extensible array dataset chunk indexing code to accommodate changes to private APIs in those interfaces. Also, other adjustments to source code and expected output in response to changes on the trunk. 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.2 (amazon) in debug mode Mac OS X/32 10.6.2 (amazon) w/C++ & FORTRAN, w/threadsafe, in production mode
Diffstat (limited to 'src/H5B2.c')
-rw-r--r--src/H5B2.c919
1 files changed, 452 insertions, 467 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index 45bfff0..b6e8392 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_BT2_INDIR[1];
+extern const H5B2_class_t H5HF_BT2_FILT_INDIR[1];
+extern const H5B2_class_t H5HF_BT2_DIR[1];
+extern const H5B2_class_t H5HF_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_BT2_INDIR, /* 1 - H5B2_FHEAP_HUGE_INDIR_ID */
+ H5HF_BT2_FILT_INDIR, /* 2 - H5B2_FHEAP_HUGE_FILT_INDIR_ID */
+ H5HF_BT2_DIR, /* 3 - H5B2_FHEAP_HUGE_DIR_ID */
+ H5HF_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)
{
- 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)))
+ 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")
- /* 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;
+ /* Look up the B-tree header */
+ if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, NULL, "unable to load B-tree header")
+
+ /* 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)
+{
+ 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, NULL, 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;
+ /* 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);
-
- /* Make copy of the root node pointer */
- root_ptr = bt2->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;
+ /* 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() */
@@ -326,49 +411,32 @@ done:
*-------------------------------------------------------------------------
*/
htri_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)
+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 */
- htri_t ret_value = TRUE /* Return value */;
+ 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)
@@ -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,16 +470,16 @@ 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")
/* Indicate record found */
@@ -426,15 +494,15 @@ 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")
/* Record not found */
@@ -442,9 +510,9 @@ 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_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")
@@ -452,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() */
@@ -484,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)
@@ -546,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 */
@@ -557,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 */
@@ -570,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);
@@ -599,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 */
@@ -618,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() */
@@ -661,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() */
@@ -743,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() */
@@ -834,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;
-
-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")
+ *nrec = bt2->hdr->root.all_nrec;
- FUNC_LEAVE_NOAPI(ret_value)
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2_get_nrec() */
@@ -890,112 +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")
-
-done:
- /* Release the B-tree header info */
- if(bt2 && H5AC_unprotect(f, dxpl_id, H5AC_BT2_HDR, addr, bt2, H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_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.
@@ -1016,53 +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;
- 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 */
@@ -1073,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 */
@@ -1096,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")
@@ -1111,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);
@@ -1127,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,
@@ -1150,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")
@@ -1166,94 +1090,155 @@ 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")
+ /* 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")
- /* 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;
+ /* Check for pending v2 B-tree deletion */
+ if(pending_delete) {
+ H5B2_hdr_t *hdr; /* Another pointer to v2 B-tree header */
- /* Get the pointer to the shared B-tree info */
- shared = (H5B2_shared_t *)H5RC_GET_OBJ(bt2->shared);
- HDassert(shared);
+ /* Sanity check */
+ HDassert(H5F_addr_defined(bt2_addr));
- /* Add size of header to B-tree metadata total */
- *btree_size += H5B2_HEADER_SIZE(f);
+ /* 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, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header")
- /* Make copy of the root node pointer */
- root_ptr = bt2->root;
+ /* Set the shared v2 B-tree header's file context for this operation */
+ hdr->f = bt2->f;
- /* Current depth of the tree */
- depth = shared->depth;
+ /* 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 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;
+ /* Release the v2 B-tree wrapper */
+ bt2 = H5FL_FREE(H5B2_t, bt2);
- /* 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");
+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, 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(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, 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:
- /* 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() */