summaryrefslogtreecommitdiffstats
path: root/src/H5B2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5B2.c')
-rw-r--r--src/H5B2.c251
1 files changed, 224 insertions, 27 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index 7eb88c4..84ff8de 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -86,6 +86,8 @@ 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];
+extern const H5B2_class_t H5D_BT2[1];
+extern const H5B2_class_t H5D_BT2_FILT[1];
const H5B2_class_t *const H5B2_client_class_g[] = {
H5B2_TEST, /* 0 - H5B2_TEST_ID */
@@ -98,6 +100,8 @@ const H5B2_class_t *const H5B2_client_class_g[] = {
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 */
+ H5D_BT2, /* 10 - H5B2_CDSET_ID */
+ H5D_BT2_FILT, /* 11 - H5B2_CDSET_FILT_ID */
};
@@ -130,7 +134,8 @@ H5FL_DEFINE_STATIC(H5B2_t);
*-------------------------------------------------------------------------
*/
H5B2_t *
-H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, void *ctx_udata)
+H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam,
+ void *ctx_udata, void *parent)
{
H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
@@ -150,7 +155,7 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, void *ctx_udat
HDcompile_assert(H5B2_NUM_BTREE_ID == NELMTS(H5B2_client_class_g));
/* Create shared v2 B-tree header */
- if(HADDR_UNDEF == (hdr_addr = H5B2__hdr_create(f, dxpl_id, cparam, ctx_udata)))
+ if(HADDR_UNDEF == (hdr_addr = H5B2__hdr_create(f, dxpl_id, cparam, ctx_udata, parent)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, NULL, "can't create v2 B-tree header")
/* Create v2 B-tree wrapper */
@@ -159,6 +164,7 @@ H5B2_create(H5F_t *f, hid_t dxpl_id, const H5B2_create_t *cparam, void *ctx_udat
/* Look up the B-tree header */
cache_udata.f = f;
+ cache_udata.parent = parent;
cache_udata.addr = hdr_addr;
cache_udata.ctx_udata = ctx_udata;
if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, hdr_addr, &cache_udata, H5AC__NO_FLAGS_SET)))
@@ -205,7 +211,7 @@ done:
*-------------------------------------------------------------------------
*/
H5B2_t *
-H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata)
+H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata, void *parent)
{
H5B2_t *bt2 = NULL; /* Pointer to the B-tree */
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
@@ -220,6 +226,7 @@ H5B2_open(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata)
/* Look up the B-tree header */
cache_udata.f = f;
+ cache_udata.parent = parent;
cache_udata.addr = addr;
cache_udata.ctx_udata = ctx_udata;
if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, &cache_udata, H5AC__READ_ONLY_FLAG)))
@@ -293,7 +300,7 @@ H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *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->root)) < 0)
+ 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) */
@@ -305,11 +312,11 @@ H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata)
/* 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, udata) < 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, udata) < 0)
+ 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 */
@@ -391,7 +398,7 @@ H5B2_iterate(H5B2_t *bt2, hid_t dxpl_id, H5B2_operator_t op, void *op_data)
/* Iterate through records */
if(hdr->root.node_nrec > 0) {
/* Iterate through nodes */
- if((ret_value = H5B2__iterate_node(hdr, dxpl_id, hdr->depth, &hdr->root, op, op_data)) < 0)
+ if((ret_value = H5B2__iterate_node(hdr, dxpl_id, hdr->depth, &hdr->root, hdr, op, op_data)) < 0)
HERROR(H5E_BTREE, H5E_CANTLIST, "node iteration failed");
} /* end if */
@@ -428,6 +435,7 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
{
H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
+ void *parent = NULL; /* Parent of current node */
uint16_t depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
unsigned idx; /* Location of record which matches key */
@@ -477,6 +485,10 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
/* Current depth of the tree */
depth = hdr->depth;
+ /* Set initial parent, if doing swmr writes */
+ if(hdr->swmr_write)
+ parent = hdr;
+
/* Walk down B-tree to find record or leaf node where record is located */
cmp = -1;
curr_pos = H5B2_POS_ROOT;
@@ -485,9 +497,16 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC__READ_ONLY_FLAG)))
+ if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr.addr, parent, curr_node_ptr.node_nrec, depth, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
+ /* Unpin parent if necessary */
+ if(parent) {
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ parent = NULL;
+ } /* end if */
+
/* Locate node pointer for child */
cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
@@ -516,9 +535,13 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(hdr->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, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
+ /* Keep track of parent if necessary */
+ if(hdr->swmr_write)
+ parent = internal;
+
/* Set pointer to next node to load */
curr_node_ptr = next_node_ptr;
} /* end if */
@@ -548,9 +571,16 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, H5AC__READ_ONLY_FLAG)))
+ if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr.addr, parent, curr_node_ptr.node_nrec, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")
+ /* Unpin parent if necessary */
+ if(parent) {
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ parent = NULL;
+ } /* end if */
+
/* Locate record */
cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
@@ -600,6 +630,12 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
} /* end block */
done:
+ if(parent) {
+ HDassert(ret_value < 0);
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_find() */
@@ -628,6 +664,7 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
{
H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
+ void *parent = NULL; /* Parent of current node */
uint16_t depth; /* Current depth of the tree */
herr_t ret_value = SUCCEED; /* Return value */
@@ -657,6 +694,10 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
/* Current depth of the tree */
depth = hdr->depth;
+ /* Set initial parent, if doing swmr writes */
+ if(hdr->swmr_write)
+ parent = hdr;
+
/* Check for reverse indexing and map requested index to appropriate forward index */
if(order == H5_ITER_DEC)
idx = curr_node_ptr.all_nrec - (idx + 1);
@@ -668,9 +709,16 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
unsigned u; /* Local index variable */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC__READ_ONLY_FLAG)))
+ if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr.addr, parent, curr_node_ptr.node_nrec, depth, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
+ /* Unpin parent if necessary */
+ if(parent) {
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ parent = NULL;
+ } /* end if */
+
/* Search for record with correct index */
for(u = 0; u < internal->nrec; u++) {
/* Check if record is in child node */
@@ -679,9 +727,13 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
next_node_ptr = internal->node_ptrs[u];
/* Unlock current node */
- if(H5AC_unprotect(hdr->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, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
+ /* Keep track of parent if necessary */
+ if(hdr->swmr_write)
+ parent = internal;
+
/* Set pointer to next node to load */
curr_node_ptr = next_node_ptr;
@@ -721,9 +773,13 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
next_node_ptr = internal->node_ptrs[u];
/* Unlock current node */
- if(H5AC_unprotect(hdr->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, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
+ /* Keep track of parent if necessary */
+ if(hdr->swmr_write)
+ parent = internal;
+
/* Set pointer to next node to load */
curr_node_ptr = next_node_ptr;
} /* end if */
@@ -740,9 +796,16 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
H5B2_leaf_t *leaf; /* Pointer to leaf node in B-tree */
/* Lock B-tree leaf node */
- if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, H5AC__READ_ONLY_FLAG)))
+ if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr.addr, parent, curr_node_ptr.node_nrec, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")
+ /* Unpin parent if necessary */
+ if(parent) {
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ parent = NULL;
+ } /* end if */
+
/* Sanity check index */
HDassert(idx < leaf->nrec);
@@ -761,6 +824,12 @@ H5B2_index(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order, hsize_t idx,
} /* end block */
done:
+ if(parent) {
+ HDassert(ret_value < 0);
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_index() */
@@ -804,8 +873,9 @@ H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op,
if(hdr->depth > 0) {
hbool_t depth_decreased = FALSE; /* Flag to indicate whether the depth of the B-tree decreased */
- if(H5B2__remove_internal(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth,
- &(hdr->cache_info), NULL, H5B2_POS_ROOT, &hdr->root, udata, op, op_data) < 0)
+ if(H5B2__remove_internal(hdr, dxpl_id, &depth_decreased, NULL, NULL,
+ hdr->depth, &(hdr->cache_info), NULL, H5B2_POS_ROOT, &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 */
@@ -823,7 +893,7 @@ H5B2_remove(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_remove_t op,
} /* end for */
} /* end if */
else {
- if(H5B2__remove_leaf(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, udata, op, op_data) < 0)
+ if(H5B2__remove_leaf(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, hdr, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -844,6 +914,12 @@ done:
*
* Purpose: Removes the n'th record from a B-tree.
*
+ * The 'udata' parameter is only used to pass through to the
+ * crt_flush_dep and upd_flush_dep callbacks, so it only
+ * needs to contain enough information for those (if any - it
+ * can be NULL). Specifically, it does not need to identify
+ * the specific record to search for.
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
@@ -854,7 +930,7 @@ done:
*/
herr_t
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)
+ hsize_t idx, void *udata, H5B2_remove_t op, void *op_data)
{
H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
herr_t ret_value = SUCCEED; /* Return value */
@@ -886,8 +962,9 @@ H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
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(hdr, dxpl_id, &depth_decreased, NULL, hdr->depth,
- &(hdr->cache_info), NULL, &hdr->root, H5B2_POS_ROOT, idx, op, op_data) < 0)
+ if(H5B2__remove_internal_by_idx(hdr, dxpl_id, &depth_decreased, NULL,
+ NULL, hdr->depth, &(hdr->cache_info), NULL, &hdr->root,
+ H5B2_POS_ROOT, idx, 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 */
@@ -905,7 +982,7 @@ H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id, H5_iter_order_t order,
} /* end for */
} /* end if */
else {
- if(H5B2__remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, (unsigned)idx, op, op_data) < 0)
+ if(H5B2__remove_leaf_by_idx(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, hdr, (unsigned)idx, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTDELETE, FAIL, "unable to remove record from B-tree leaf node")
} /* end else */
@@ -1000,11 +1077,11 @@ H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range, void *udata,
/* Attempt to find neighbor record in B-tree */
if(hdr->depth > 0) {
- if(H5B2__neighbor_internal(hdr, dxpl_id, hdr->depth, &hdr->root, NULL, range, udata, op, op_data) < 0)
+ if(H5B2__neighbor_internal(hdr, dxpl_id, hdr->depth, &hdr->root, NULL, range, hdr, 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(hdr, dxpl_id, &hdr->root, NULL, range, udata, op, op_data) < 0)
+ if(H5B2__neighbor_leaf(hdr, dxpl_id, &hdr->root, NULL, range, hdr, udata, op, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to find neighbor record in B-tree leaf node")
} /* end else */
@@ -1039,6 +1116,7 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
{
H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
H5B2_node_ptr_t curr_node_ptr; /* Node pointer info for current node */
+ void *parent = NULL; /* Parent of current node */
H5B2_nodepos_t curr_pos; /* Position of current node */
uint16_t depth; /* Current depth of the tree */
int cmp; /* Comparison value of records */
@@ -1067,6 +1145,10 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
/* Current depth of the tree */
depth = hdr->depth;
+ /* Set initial parent, if doing swmr writes */
+ if(hdr->swmr_write)
+ parent = hdr;
+
/* Walk down B-tree to find record or leaf node where record is located */
cmp = -1;
curr_pos = H5B2_POS_ROOT;
@@ -1076,9 +1158,16 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
H5B2_node_ptr_t next_node_ptr; /* Node pointer info for next node */
/* Lock B-tree current node */
- if(NULL == (internal = H5B2__protect_internal(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, depth, H5AC__NO_FLAGS_SET)))
+ 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 load B-tree internal node")
+ /* Unpin parent if necessary */
+ if(parent) {
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ parent = NULL;
+ } /* end if */
+
/* Locate node pointer for child */
cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
if(cmp > 0)
@@ -1107,9 +1196,13 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
} /* end if */
/* Unlock current node */
- if(H5AC_unprotect(hdr->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, (unsigned)(hdr->swmr_write ? H5AC__PIN_ENTRY_FLAG : H5AC__NO_FLAGS_SET)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPROTECT, FAIL, "unable to release B-tree node")
+ /* Keep track of parent if necessary */
+ if(hdr->swmr_write)
+ parent = internal;
+
/* Set pointer to next node to load */
curr_node_ptr = next_node_ptr;
} /* end if */
@@ -1148,9 +1241,16 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
hbool_t changed = FALSE;/* Whether the 'modify' callback changed the record */
/* Lock B-tree leaf node */
- if(NULL == (leaf = H5B2__protect_leaf(hdr, dxpl_id, curr_node_ptr.addr, curr_node_ptr.node_nrec, H5AC__NO_FLAGS_SET)))
+ 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")
+ /* Unpin parent if necessary */
+ if(parent) {
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ parent = NULL;
+ } /* end if */
+
/* Locate record */
cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
@@ -1213,6 +1313,12 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
}
done:
+ if(parent) {
+ HDassert(ret_value < 0);
+ if(parent != hdr && H5AC_unpin_entry(parent) < 0)
+ HDONE_ERROR(H5E_BTREE, H5E_CANTUNPIN, FAIL, "unable to unpin parent entry")
+ } /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_modify() */
@@ -1341,7 +1447,7 @@ done:
*/
herr_t
H5B2_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata,
- H5B2_remove_t op, void *op_data)
+ void *parent, H5B2_remove_t op, void *op_data)
{
H5B2_hdr_t *hdr = NULL; /* Pointer to the B-tree header */
H5B2_hdr_cache_ud_t cache_udata; /* User-data for callback */
@@ -1358,6 +1464,7 @@ H5B2_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *ctx_udata,
HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr);
#endif /* QAK */
cache_udata.f = f;
+ cache_udata.parent = parent;
cache_udata.addr = addr;
cache_udata.ctx_udata = ctx_udata;
if(NULL == (hdr = (H5B2_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_BT2_HDR, addr, &cache_udata, H5AC__NO_FLAGS_SET)))
@@ -1388,3 +1495,93 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_depend
+ *
+ * Purpose: Make a child flush dependency between the v2 B-tree's
+ * header and another piece of metadata in the file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Dana Robinson
+ * Fall 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_depend(H5AC_info_t *parent_entry, H5B2_t *bt2)
+{
+ /* Local variables */
+ H5B2_hdr_t *hdr = bt2->hdr; /* Header for B-tree */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(SUCCEED)
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt2);
+ HDassert(hdr);
+
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Set up flush dependency between parent entry and B-tree header */
+ if(H5B2__create_flush_depend(parent_entry, (H5AC_info_t *)hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDEPEND, FAIL, "unable to create flush dependency on file metadata")
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_depend() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_undepend
+ *
+ * Purpose: Remove a child flush dependency between the v2 B-tree's
+ * header and another piece of metadata in the file.
+ *
+ * Return: SUCCEED/FAIL
+ *
+ * Programmer: Dana Robinson
+ * Fall 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_undepend(H5AC_info_t *parent_entry, H5B2_t *bt2)
+{
+ /* Local variables */
+ H5B2_hdr_t *hdr = bt2->hdr; /* Header for B-tree */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(SUCCEED)
+
+#ifdef QAK
+HDfprintf(stderr, "%s: Called\n", FUNC);
+#endif /* QAK */
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt2);
+ HDassert(hdr);
+
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Remove flush dependency between parent entry and B-tree header */
+ if(H5B2__destroy_flush_depend(parent_entry, (H5AC_info_t *)hdr) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency on file metadata")
+
+done:
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B2_undepend() */
+