summaryrefslogtreecommitdiffstats
path: root/src/H5B2int.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5B2int.c')
-rw-r--r--src/H5B2int.c578
1 files changed, 517 insertions, 61 deletions
diff --git a/src/H5B2int.c b/src/H5B2int.c
index 01b747f..8f6cf7a 100644
--- a/src/H5B2int.c
+++ b/src/H5B2int.c
@@ -80,9 +80,10 @@ static herr_t H5B2__swap_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
H5B2_internal_t *internal, unsigned *internal_flags_ptr, unsigned idx,
void *swap_loc);
static herr_t H5B2__shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id,
- uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, H5B2_internal_t **internal);
+ uint16_t depth, H5B2_node_ptr_t *curr_node_ptr, H5B2_internal_t **internal,
+ hbool_t *was_shadowed);
static herr_t H5B2__shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
- H5B2_node_ptr_t *curr_node_ptr, H5B2_leaf_t **leaf);
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_leaf_t **leaf, hbool_t *was_shadowed);
static herr_t H5B2__create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, void *parent,
H5B2_node_ptr_t *node_ptr, uint16_t depth);
#ifdef H5B2_DEBUG
@@ -232,7 +233,7 @@ H5B2__split1(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow the left node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &left_int) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &left_int, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
left_addr = internal->node_ptrs[idx].addr;
} /* end if */
@@ -268,7 +269,7 @@ H5B2__split1(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow the left node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &left_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &left_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
left_addr = internal->node_ptrs[idx].addr;
} /* end if */
@@ -571,9 +572,9 @@ H5B2__redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow both nodes if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &left_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &left_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx + 1]), &right_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx + 1]), &right_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
left_addr = internal->node_ptrs[idx].addr;
right_addr = internal->node_ptrs[idx + 1].addr;
@@ -606,9 +607,9 @@ H5B2__redistribute2(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow both nodes if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &left_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &left_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx + 1]), &right_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx + 1]), &right_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
left_addr = internal->node_ptrs[idx].addr;
right_addr = internal->node_ptrs[idx + 1].addr;
@@ -881,10 +882,6 @@ done:
if(right_child && H5AC_unprotect(hdr->f, dxpl_id, child_class, right_addr, right_child, right_child_flags) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree child node")
- /* Release grandchild node if protected (only on error) */
- if(grandchild && H5AC_unprotect(hdr->f, dxpl_id, grandchild_class, left_node_ptrs[u].addr, grandchild, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
-
/* Unprotect the grandchild on error */
if(grandchild) {
HDassert(ret_value < 0);
@@ -964,11 +961,11 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow all nodes if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx - 1]), &left_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx - 1]), &left_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &middle_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &middle_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx + 1]), &right_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx + 1]), &right_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
@@ -1010,11 +1007,11 @@ H5B2__redistribute3(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow all nodes if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx - 1]), &left_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx - 1]), &left_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &middle_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &middle_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx + 1]), &right_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx + 1]), &right_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
@@ -1611,7 +1608,7 @@ H5B2__merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow the left node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &left_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &left_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
left_addr = internal->node_ptrs[idx].addr;
} /* end if */
@@ -1643,7 +1640,7 @@ H5B2__merge2(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow the left node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &left_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &left_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
left_addr = internal->node_ptrs[idx].addr;
} /* end if */
@@ -1861,9 +1858,9 @@ H5B2__merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow left and middle nodes if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx - 1]), &left_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx - 1]), &left_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
- if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &middle_internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &(internal->node_ptrs[idx]), &middle_internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
@@ -1904,9 +1901,9 @@ H5B2__merge3(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
/* Shadow left and middle nodes if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx - 1]), &left_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx - 1]), &left_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
- if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &middle_leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, &(internal->node_ptrs[idx]), &middle_leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
left_addr = internal->node_ptrs[idx - 1].addr;
middle_addr = internal->node_ptrs[idx].addr;
@@ -2261,6 +2258,62 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5B2__insert_hdr
+ *
+ * Purpose: Adds a new record to the B-tree.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Dec 23 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2__insert_hdr(H5B2_hdr_t *hdr, hid_t dxpl_id, void *udata)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check arguments. */
+ HDassert(hdr);
+ HDassert(udata);
+
+ /* Check if the root node is allocated yet */
+ if(!H5F_addr_defined(hdr->root.addr)) {
+ /* Create root node as leaf node in B-tree */
+ if(H5B2__create_leaf(hdr, dxpl_id, hdr, &(hdr->root)) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create root node")
+ } /* end if */
+ /* Check if we need to split the root node (equiv. to a 1->2 node split) */
+ else if(hdr->root.node_nrec == hdr->node_info[hdr->depth].split_nrec) {
+ /* Split root node */
+ 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(hdr->depth > 0) {
+ if(H5B2__insert_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, H5B2_POS_ROOT, hdr, 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(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, hdr, udata) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
+ } /* end else */
+
+ /* 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:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2__insert_hdr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2__insert_leaf
*
* Purpose: Adds a new record to a B-tree leaf node.
@@ -2278,6 +2331,7 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
H5B2_nodepos_t curr_pos, void *parent, void *udata)
{
H5B2_leaf_t *leaf; /* Pointer to leaf node */
+ unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting the leaf node */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2293,11 +2347,6 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr->addr, parent, curr_node_ptr->node_nrec, H5AC__NO_FLAGS_SET)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")
- /* Shadow the node if doing SWMR writes */
- if(hdr->swmr_write)
- if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
-
/* Must have a leaf node with enough space to insert a record now */
HDassert(curr_node_ptr->node_nrec < hdr->node_info[0].max_nrec);
@@ -2324,6 +2373,9 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
if((hdr->cls->store)(H5B2_LEAF_NREC(leaf, hdr, idx), udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into leaf node")
+ /* Mark the node as dirty */
+ leaf_flags |= H5AC__DIRTIED_FLAG;
+
/* Update record count for node pointer to current node */
curr_node_ptr->all_nrec++;
curr_node_ptr->node_nrec++;
@@ -2337,7 +2389,7 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
if(idx == 0) {
if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
if(hdr->min_native_rec == NULL)
- if(NULL == (hdr->min_native_rec = (uint8_t *)H5MM_malloc(hdr->cls->nrec_size)))
+ if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info")
HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
} /* end if */
@@ -2345,7 +2397,7 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
if(idx == (unsigned)(leaf->nrec - 1)) {
if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
if(hdr->max_native_rec == NULL)
- if(NULL == (hdr->max_native_rec = (uint8_t *)H5MM_malloc(hdr->cls->nrec_size)))
+ if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info")
HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
} /* end if */
@@ -2354,8 +2406,14 @@ H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
done:
/* Release the B-tree leaf node (marked as dirty) */
- if(leaf && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, H5AC__DIRTIED_FLAG) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
+ if(leaf) {
+ /* Shadow the node if doing SWMR writes */
+ if(hdr->swmr_write && (leaf_flags & H5AC__DIRTIED_FLAG))
+ if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf, NULL) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf B-tree node")
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, leaf_flags) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2__insert_leaf() */
@@ -2397,10 +2455,8 @@ H5B2__insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr->addr, parent, curr_node_ptr->node_nrec, depth, H5AC__NO_FLAGS_SET)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node")
- /* Shadow the node if doing SWMR writes */
- if(hdr->swmr_write)
- if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
+ /* Sanity check number of records */
+ HDassert(internal->nrec == curr_node_ptr->node_nrec);
/* Split or redistribute child node pointers, if necessary */
{
@@ -2505,14 +2561,401 @@ H5B2__insert_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
done:
/* Release the B-tree internal node */
- if(internal && H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0)
- HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
+ if(internal) {
+ /* Shadow the node if doing SWMR writes */
+ if(hdr->swmr_write && (internal_flags & H5AC__DIRTIED_FLAG))
+ if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal, NULL) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal B-tree node")
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2__insert_internal() */
/*-------------------------------------------------------------------------
+ * Function: H5B2__update_leaf
+ *
+ * Purpose: Insert or modify a record in a B-tree leaf node.
+ * If the record exists already, it is modified as if H5B2_modify
+ * was called). If it doesn't exist, it is inserted as if
+ * H5B2_insert was called.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Dec 23 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2__update_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr,
+ H5B2_update_status_t *status, H5B2_nodepos_t curr_pos, void *parent,
+ void *udata, H5B2_modify_t op, void *op_data)
+{
+ H5B2_leaf_t *leaf; /* Pointer to leaf node */
+ unsigned leaf_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting the leaf node */
+ int cmp = -1; /* Comparison value of records */
+ unsigned idx; /* Location of record which matches key */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check arguments. */
+ HDassert(hdr);
+ HDassert(curr_node_ptr);
+ HDassert(H5F_addr_defined(curr_node_ptr->addr));
+
+ /* Lock current B-tree node */
+ if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr->addr, parent, curr_node_ptr->node_nrec, H5AC__NO_FLAGS_SET)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")
+
+ /* Sanity check number of records */
+ HDassert(curr_node_ptr->all_nrec == curr_node_ptr->node_nrec);
+ HDassert(leaf->nrec == curr_node_ptr->node_nrec);
+
+ /* Check for inserting into empty leaf */
+ if(leaf->nrec == 0)
+ idx = 0;
+ else {
+ /* Find correct location to insert this record */
+ cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
+
+ /* Check for inserting a record */
+ if(0 != cmp) {
+ /* Check if the leaf node is full */
+ if(curr_node_ptr->node_nrec == hdr->node_info[0].split_nrec) {
+ /* Indicate that the leaf is full, but we need to insert */
+ *status = H5B2_UPDATE_INSERT_CHILD_FULL;
+
+ /* Let calling routine handle insertion */
+ HGOTO_DONE(SUCCEED)
+ } /* end if */
+
+ /* Adjust index to leave room for record to insert */
+ if(cmp > 0)
+ idx++;
+
+ /* Make room for new record */
+ if(idx < leaf->nrec)
+ HDmemmove(H5B2_LEAF_NREC(leaf, hdr, idx + 1), H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size * (leaf->nrec - idx));
+ } /* end if */
+ } /* end else */
+
+ /* Check for modifying existing record */
+ if(0 == cmp) {
+ hbool_t changed = FALSE; /* Whether the 'modify' callback changed the record */
+
+ /* Make callback for current record */
+ 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);
+
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree update operation")
+ } /* end if */
+
+ /* Mark the node as dirty if it changed */
+ leaf_flags |= (changed ? H5AC__DIRTIED_FLAG : 0);
+
+ /* Indicate that the record was modified */
+ *status = H5B2_UPDATE_MODIFY_DONE;
+ } /* end if */
+ else {
+ /* Must have a leaf node with enough space to insert a record now */
+ HDassert(curr_node_ptr->node_nrec < hdr->node_info[0].max_nrec);
+
+ /* Make callback to store record in native form */
+ if((hdr->cls->store)(H5B2_LEAF_NREC(leaf, hdr, idx), udata) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into leaf node")
+
+ /* Mark the node as dirty */
+ leaf_flags |= H5AC__DIRTIED_FLAG;
+
+ /* Indicate that the record was inserted */
+ *status = H5B2_UPDATE_INSERT_DONE;
+
+ /* Update record count for node pointer to current node */
+ curr_node_ptr->all_nrec++;
+ curr_node_ptr->node_nrec++;
+
+ /* Update record count for current node */
+ leaf->nrec++;
+ } /* end else */
+
+ /* Check for new record being the min or max for the tree */
+ /* (Don't use 'else' for the idx check, to allow for root leaf node) */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->min_native_rec == NULL)
+ if(NULL == (hdr->min_native_rec = H5MM_malloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree min record info")
+ HDmemcpy(hdr->min_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ if(idx == (unsigned)(leaf->nrec - 1)) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos) {
+ if(hdr->max_native_rec == NULL)
+ if(NULL == (hdr->max_native_rec = H5MM_malloc(hdr->cls->nrec_size)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, FAIL, "memory allocation failed for v2 B-tree max record info")
+ HDmemcpy(hdr->max_native_rec, H5B2_LEAF_NREC(leaf, hdr, idx), hdr->cls->nrec_size);
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ /* Release the B-tree leaf node */
+ if(leaf) {
+ /* Check if we should shadow this node */
+ if(hdr->swmr_write && (leaf_flags & H5AC__DIRTIED_FLAG)) {
+ hbool_t was_shadowed; /* Whether the node was actually shadowed */
+
+ /* Attempt to shadow the node if doing SWMR writes */
+ if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf, &was_shadowed) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf B-tree node")
+
+ /* Change the state to "shadowed" if only modified currently */
+ /* (Triggers parent to be marked dirty) */
+ if(*status == H5B2_UPDATE_MODIFY_DONE)
+ *status = H5B2_UPDATE_SHADOW_DONE;
+ } /* end if */
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr->addr, leaf, leaf_flags) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release leaf B-tree node")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2__update_leaf() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2__update_internal
+ *
+ * Purpose: Insert or modify a record in a B-tree leaf node.
+ * If the record exists already, it is modified as if H5B2_modify
+ * was called). If it doesn't exist, it is inserted as if
+ * H5B2_insert was called.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@hdfgroup.org
+ * Dec 24 2015
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2__update_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
+ unsigned *parent_cache_info_flags_ptr, H5B2_node_ptr_t *curr_node_ptr,
+ H5B2_update_status_t *status, H5B2_nodepos_t curr_pos, void *parent,
+ void *udata, H5B2_modify_t op, void *op_data)
+{
+ H5B2_internal_t *internal = NULL; /* Pointer to internal node */
+ unsigned internal_flags = H5AC__NO_FLAGS_SET;
+ int cmp; /* Comparison value of records */
+ unsigned idx; /* Location of record which matches key */
+ H5B2_nodepos_t next_pos = H5B2_POS_MIDDLE; /* Position of node */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Check arguments. */
+ HDassert(hdr);
+ HDassert(depth > 0);
+ HDassert(curr_node_ptr);
+ HDassert(H5F_addr_defined(curr_node_ptr->addr));
+
+ /* Lock current B-tree node */
+ if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr->addr, parent, curr_node_ptr->node_nrec, depth, H5AC__NO_FLAGS_SET)))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree internal node")
+
+ /* Sanity check number of records */
+ HDassert(internal->nrec == curr_node_ptr->node_nrec);
+
+ /* Locate node pointer for child */
+ cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
+
+ /* Check for modifying existing record */
+ if(0 == cmp) {
+ hbool_t changed = FALSE; /* Whether the 'modify' callback changed the record */
+
+ /* Make callback for current record */
+ 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);
+
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTMODIFY, FAIL, "'modify' callback failed for B-tree update operation")
+ } /* end if */
+
+ /* Mark the node as dirty if it changed */
+ internal_flags |= (changed ? H5AC__DIRTIED_FLAG : 0);
+
+ /* Indicate that the record was modified */
+ *status = H5B2_UPDATE_MODIFY_DONE;
+ } /* end if */
+ else {
+ /* Adjust index to leave room for node to insert */
+ if(cmp > 0)
+ idx++;
+
+ /* Check if this node is left/right-most */
+ if(H5B2_POS_MIDDLE != curr_pos) {
+ if(idx == 0) {
+ if(H5B2_POS_LEFT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_LEFT;
+ } /* end if */
+ else if(idx == internal->nrec) {
+ if(H5B2_POS_RIGHT == curr_pos || H5B2_POS_ROOT == curr_pos)
+ next_pos = H5B2_POS_RIGHT;
+ } /* end else */
+ } /* end if */
+
+ /* Attempt to update record in child */
+ if(depth > 1) {
+ if(H5B2__update_internal(hdr, dxpl_id, (uint16_t)(depth - 1), &internal_flags, &internal->node_ptrs[idx], status, next_pos, internal, udata, op, op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUPDATE, FAIL, "unable to update record in internal B-tree node")
+ } /* end if */
+ else {
+ if(H5B2__update_leaf(hdr, dxpl_id, &internal->node_ptrs[idx], status, next_pos, internal, udata, op, op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUPDATE, FAIL, "unable to update record in leaf B-tree node")
+ } /* end else */
+
+ /* Take actions based on child's status report */
+ switch(*status) {
+ case H5B2_UPDATE_MODIFY_DONE:
+ /* No action */
+ break;
+
+ case H5B2_UPDATE_SHADOW_DONE:
+ /* If child node was shadowed (if SWMR is enabled), mark this node dirty */
+ if(hdr->swmr_write)
+ internal_flags |= H5AC__DIRTIED_FLAG;
+
+ /* No further modifications up the tree are necessary though, so downgrade to merely "modified" */
+ *status = H5B2_UPDATE_MODIFY_DONE;
+ break;
+
+ case H5B2_UPDATE_INSERT_DONE:
+ /* Mark node as dirty */
+ internal_flags |= H5AC__DIRTIED_FLAG;
+
+ /* Update total record count for node pointer to current node */
+ curr_node_ptr->all_nrec++;
+ break;
+
+ case H5B2_UPDATE_INSERT_CHILD_FULL:
+ /* Split/redistribute this node */
+ if(internal->nrec == hdr->node_info[depth].split_nrec) {
+ hbool_t could_split = FALSE; /* Whether the child node could split */
+
+#ifdef QAK
+HDfprintf(stderr, "%s: idx = %u, internal->nrec = %u\n", FUNC, idx, internal->nrec);
+HDfprintf(stderr, "%s: hdr->node_info[%u].split_nrec = %u\n", FUNC, (unsigned)depth, (unsigned)hdr->node_info[depth].split_nrec);
+HDfprintf(stderr, "%s: hdr->node_info[%u].split_nrec = %u\n", FUNC, (unsigned)(depth - 1), (unsigned)hdr->node_info[depth - 1].split_nrec);
+#endif /* QAK */
+ if(idx == 0) { /* Left-most child */
+#ifdef QAK
+HDfprintf(stderr, "%s: Left-most child\n", FUNC);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)idx, (unsigned)internal->node_ptrs[idx].node_nrec);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)(idx + 1), (unsigned)internal->node_ptrs[idx + 1].node_nrec);
+#endif /* QAK */
+ /* Check for left-most child and its neighbor being close to full */
+ if((internal->node_ptrs[idx].node_nrec + internal->node_ptrs[idx + 1].node_nrec)
+ >= ((hdr->node_info[depth - 1].split_nrec * 2) - 1))
+ could_split = TRUE;
+ } /* end if */
+ else if(idx == internal->nrec) { /* Right-most child */
+#ifdef QAK
+HDfprintf(stderr, "%s: Right-most child\n", FUNC);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)(idx - 1), (unsigned)internal->node_ptrs[idx - 1].node_nrec);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)idx, (unsigned)internal->node_ptrs[idx].node_nrec);
+#endif /* QAK */
+ /* Check for right-most child and its neighbor being close to full */
+ if((internal->node_ptrs[idx - 1].node_nrec + internal->node_ptrs[idx].node_nrec)
+ >= ((hdr->node_info[depth - 1].split_nrec * 2) - 1))
+ could_split = TRUE;
+ } /* end else-if */
+ else { /* Middle child */
+#ifdef QAK
+HDfprintf(stderr, "%s: Middle child\n", FUNC);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)(idx - 1), (unsigned)internal->node_ptrs[idx - 1].node_nrec);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)idx, (unsigned)internal->node_ptrs[idx].node_nrec);
+HDfprintf(stderr, "%s: internal->node_ptrs[%u].node_nrec = %u\n", FUNC, (unsigned)(idx + 1), (unsigned)internal->node_ptrs[idx + 1].node_nrec);
+#endif /* QAK */
+ /* Check for middle child and its left neighbor being close to full */
+ if((internal->node_ptrs[idx - 1].node_nrec + internal->node_ptrs[idx].node_nrec)
+ >= ((hdr->node_info[depth - 1].split_nrec * 2) - 1))
+ could_split = TRUE;
+ /* Check for middle child and its right neighbor being close to full */
+ else if((internal->node_ptrs[idx].node_nrec + internal->node_ptrs[idx + 1].node_nrec)
+ >= ((hdr->node_info[depth - 1].split_nrec * 2) - 1))
+ could_split = TRUE;
+ } /* end if */
+
+ /* If this node is full and the child node insertion could
+ * cause a split, punt back up to caller, leaving the
+ * "insert child full" status.
+ */
+ if(could_split) {
+ /* Release the internal B-tree node */
+ 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 internal B-tree node")
+ internal = NULL;
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Punting back to caller\n", FUNC);
+#endif /* QAK */
+ /* Punt back to caller */
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+ } /* end if */
+
+ /* Release the internal B-tree node */
+ 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 internal B-tree node")
+ internal = NULL;
+
+ /* Indicate that the record was inserted */
+ *status = H5B2_UPDATE_INSERT_DONE;
+
+ /* Dodge sideways into inserting a record into this node */
+ if(H5B2__insert_internal(hdr, dxpl_id, depth, parent_cache_info_flags_ptr, curr_node_ptr, curr_pos, parent, udata) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into internal B-tree node")
+ break;
+
+ case H5B2_UPDATE_UNKNOWN:
+ default:
+ HDassert(0 && "Invalid update status");
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUPDATE, FAIL, "invalid update status")
+ } /* end switch */
+ } /* end else */
+
+done:
+ /* Release the internal B-tree node */
+ if(internal) {
+ /* Check if we should shadow this node */
+ if(hdr->swmr_write && (internal_flags & H5AC__DIRTIED_FLAG)) {
+ hbool_t was_shadowed; /* Whether the node was actually shadowed */
+
+ /* Attempt to shadow the node if doing SWMR writes */
+ if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal, &was_shadowed) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal B-tree node")
+
+ /* Change the state to "shadowed" if only modified currently */
+ /* (Triggers parent to be marked dirty) */
+ if(*status == H5B2_UPDATE_MODIFY_DONE)
+ *status = H5B2_UPDATE_SHADOW_DONE;
+ } /* end if */
+ if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr->addr, internal, internal_flags) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release internal B-tree node")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2__update_internal() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5B2__create_leaf
*
* Purpose: Creates empty leaf node of a B-tree and update node pointer
@@ -2547,17 +2990,15 @@ H5B2__create_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, void *parent, H5B2_node_ptr_t
/* Increment ref. count on B-tree header */
if(H5B2__hdr_incr(hdr) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINC, FAIL, "can't increment ref. count on B-tree header")
/* Share B-tree header information */
leaf->hdr = hdr;
/* Allocate space for the native keys in memory */
if(NULL == (leaf->leaf_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[0].nat_rec_fac)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec);
-#endif /* H5_CLEAR_MEMORY */
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree leaf native keys")
+ HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec);
/* Set number of records */
leaf->nrec = 0;
@@ -2571,15 +3012,15 @@ HDmemset(leaf->leaf_native, 0, hdr->cls->nrec_size * hdr->node_info[0].max_nrec)
/* Allocate space on disk for the leaf */
if(HADDR_UNDEF == (node_ptr->addr = H5MF_alloc(hdr->f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)hdr->node_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree leaf node")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree leaf node")
/* Cache the new B-tree node */
if(H5AC_insert_entry(hdr->f, dxpl_id, H5AC_BT2_LEAF, node_ptr->addr, leaf, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree leaf to cache")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree leaf to cache")
done:
if(ret_value < 0) {
- if(leaf)
+ if(leaf)
if(H5B2__leaf_free(leaf) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to release v2 B-tree leaf node")
} /* end if */
@@ -2677,16 +3118,12 @@ H5B2__create_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, void *parent,
/* Allocate space for the native keys in memory */
if(NULL == (internal->int_native = (uint8_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].nat_rec_fac)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal native keys")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(internal->int_native, 0, hdr->cls->nrec_size * hdr->node_info[depth].max_nrec);
-#endif /* H5_CLEAR_MEMORY */
+ HDmemset(internal->int_native, 0, hdr->cls->nrec_size * hdr->node_info[depth].max_nrec);
/* Allocate space for the node pointers in memory */
if(NULL == (internal->node_ptrs = (H5B2_node_ptr_t *)H5FL_FAC_MALLOC(hdr->node_info[depth].node_ptr_fac)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree internal node pointers")
-#ifdef H5_CLEAR_MEMORY
-HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (hdr->node_info[depth].max_nrec + 1));
-#endif /* H5_CLEAR_MEMORY */
+ HDmemset(internal->node_ptrs, 0, sizeof(H5B2_node_ptr_t) * (hdr->node_info[depth].max_nrec + 1));
/* Set number of records & depth of the node */
internal->nrec = 0;
@@ -2957,7 +3394,7 @@ H5B2__remove_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id, H5B2_node_ptr_t *curr_node_ptr
if(leaf->nrec > 0) {
/* Shadow the node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
leaf_addr = curr_node_ptr->addr;
} /* end if */
@@ -3133,7 +3570,7 @@ H5B2__remove_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, hbool_t *depth_decreased,
/* Shadow the node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
internal_addr = curr_node_ptr->addr;
} /* end if */
@@ -3350,7 +3787,7 @@ H5B2__remove_leaf_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
if(leaf->nrec > 0) {
/* Shadow the node if doing SWMR writes */
if(hdr->swmr_write) {
- if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf) < 0)
+ if(H5B2__shadow_leaf(hdr, dxpl_id, curr_node_ptr, &leaf, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow leaf node")
leaf_addr = curr_node_ptr->addr;
} /* end if */
@@ -3532,7 +3969,7 @@ H5B2__remove_internal_by_idx(H5B2_hdr_t *hdr, hid_t dxpl_id,
/* Shadow the node if doing SWMR writes */
if(hdr->swmr_write && !collapsed_root) {
- if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal) < 0)
+ if(H5B2__shadow_internal(hdr, dxpl_id, depth, curr_node_ptr, &internal, NULL) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTCOPY, FAIL, "unable to shadow internal node")
internal_addr = curr_node_ptr->addr;
} /* end if */
@@ -4128,7 +4565,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5B2__shadow_internal
*
- * Purpose: "Shadow: an internal node - copy it to a new location,
+ * Purpose: "Shadow" an internal node - copy it to a new location,
* leaving the data in the old location intact (for now).
* This is done when writing in SWMR mode to ensure that
* readers do not see nodes that are out of date with
@@ -4143,7 +4580,8 @@ done:
*/
static herr_t
H5B2__shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
- H5B2_node_ptr_t *curr_node_ptr, H5B2_internal_t **internal)
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_internal_t **internal,
+ hbool_t *was_shadowed)
{
hbool_t node_pinned = FALSE;
hbool_t node_protected = TRUE;
@@ -4210,7 +4648,16 @@ H5B2__shadow_internal(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
else
(*internal)->shadowed_next = *internal;
hdr->shadowed_internal = *internal;
+
+ /* Indicate that the node was shadowed to parent */
+ if(was_shadowed)
+ *was_shadowed = TRUE;
} /* end if */
+ else {
+ /* Indicate that the node was _not_ shadowed to parent */
+ if(was_shadowed)
+ *was_shadowed = FALSE;
+ } /* end else */
done:
if(node_pinned)
@@ -4229,7 +4676,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5B2__shadow_leaf
*
- * Purpose: "Shadow: a leaf node - copy it to a new location, leaving
+ * Purpose: "Shadow" a leaf node - copy it to a new location, leaving
* the data in the old location intact (for now). This is
* done when writing in SWMR mode to ensure that readers do
* not see nodes that are out of date with respect to each
@@ -4244,7 +4691,7 @@ done:
*/
static herr_t
H5B2__shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
- H5B2_node_ptr_t *curr_node_ptr, H5B2_leaf_t **leaf)
+ H5B2_node_ptr_t *curr_node_ptr, H5B2_leaf_t **leaf, hbool_t *was_shadowed)
{
hbool_t node_pinned = FALSE;
hbool_t node_protected = TRUE;
@@ -4310,7 +4757,16 @@ H5B2__shadow_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
else
(*leaf)->shadowed_next = *leaf;
hdr->shadowed_leaf = *leaf;
+
+ /* Indicate that the node was shadowed to parent */
+ if(was_shadowed)
+ *was_shadowed = TRUE;
} /* end if */
+ else {
+ /* Indicate that the node was _not_ shadowed to parent */
+ if(was_shadowed)
+ *was_shadowed = FALSE;
+ } /* end else */
done:
if(node_pinned)