summaryrefslogtreecommitdiffstats
path: root/src/H5B2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5B2.c')
-rw-r--r--src/H5B2.c159
1 files changed, 131 insertions, 28 deletions
diff --git a/src/H5B2.c b/src/H5B2.c
index a171917..bce6a9f 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -42,6 +42,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
+#include "H5MMprivate.h" /* Memory management */
/****************/
@@ -86,6 +87,9 @@ 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];
+extern const H5B2_class_t H5B2_TEST2[1];
const H5B2_class_t *const H5B2_client_class_g[] = {
H5B2_TEST, /* 0 - H5B2_TEST_ID */
@@ -98,6 +102,9 @@ 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 */
+ H5B2_TEST2 /* 12 - H5B2_TEST_ID */
};
@@ -282,36 +289,78 @@ H5B2_insert(H5B2_t *bt2, hid_t dxpl_id, void *udata)
/* Get the v2 B-tree header */
hdr = bt2->hdr;
+ /* Insert the record */
+ if(H5B2__insert_hdr(hdr, dxpl_id, udata) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B2_insert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_update
+ *
+ * Purpose: Insert or modify a record to the B-tree.
+ * 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(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op, void *op_data)
+{
+ H5B2_hdr_t *hdr; /* Pointer to the B-tree header */
+ H5B2_update_status_t status = H5B2_UPDATE_UNKNOWN; /* Whether the record was inserted/modified */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check arguments. */
+ HDassert(bt2);
+ HDassert(udata);
+
+ /* Set the shared v2 B-tree header's file context for this operation */
+ bt2->hdr->f = bt2->f;
+
+ /* Get the v2 B-tree header */
+ hdr = bt2->hdr;
+
/* Check if the root node is allocated yet */
if(!H5F_addr_defined(hdr->root.addr)) {
/* Create root node as leaf node in B-tree */
if(H5B2__create_leaf(hdr, dxpl_id, &(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, udata) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
+ if(H5B2__update_internal(hdr, dxpl_id, hdr->depth, NULL, &hdr->root, &status, H5B2_POS_ROOT, udata, op, op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to update record in B-tree internal node")
} /* end if */
else {
- if(H5B2__insert_leaf(hdr, dxpl_id, &hdr->root, H5B2_POS_ROOT, udata) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree leaf node")
+ if(H5B2__update_leaf(hdr, dxpl_id, &hdr->root, &status, H5B2_POS_ROOT, udata, op, op_data) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to update record in 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")
+ /* Sanity check */
+ HDassert(H5B2_UPDATE_UNKNOWN != status);
+
+ /* Use insert algorithm if nodes to leaf full */
+ if(H5B2_UPDATE_INSERT_CHILD_FULL == status)
+ if(H5B2__insert_hdr(hdr, dxpl_id, udata) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B2_insert() */
+} /* H5B2_update() */
/*-------------------------------------------------------------------------
@@ -448,8 +497,10 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
* find candidates or avoid further searching.
*/
if(hdr->min_native_rec != NULL) {
- if((cmp = (hdr->cls->compare)(udata, hdr->min_native_rec)) < 0)
- HGOTO_DONE(FALSE) /* Less than the least record--not found */
+ if((hdr->cls->compare)(udata, hdr->min_native_rec, &cmp) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
+ if(cmp < 0)
+ HGOTO_DONE(FALSE) /* Less than the least record--not found */
else if(cmp == 0) { /* Record is found */
if(op && (op)(hdr->min_native_rec, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
@@ -457,8 +508,10 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
} /* end if */
} /* end if */
if(hdr->max_native_rec != NULL) {
- if((cmp = (hdr->cls->compare)(udata, hdr->max_native_rec)) > 0)
- HGOTO_DONE(FALSE) /* Greater than the greatest record--not found */
+ if((hdr->cls->compare)(udata, hdr->max_native_rec, &cmp) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
+ if(cmp > 0)
+ HGOTO_DONE(FALSE) /* Less than the least record--not found */
else if(cmp == 0) { /* Record is found */
if(op && (op)(hdr->max_native_rec, op_data) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "'found' callback failed for B-tree find operation")
@@ -481,10 +534,15 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
+ if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native,
+ udata, &idx, &cmp) < 0) {
+ /* Unlock current node before failing */
+ H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET);
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
+ } /* end if */
+
if(cmp > 0)
idx++;
-
if(cmp != 0) {
/* Get node pointer for next node to search */
next_node_ptr=internal->node_ptrs[idx];
@@ -544,7 +602,12 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")
/* Locate record */
- cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
+ if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native,
+ udata, &idx, &cmp) < 0) {
+ /* unlock current node before failing */
+ H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET);
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
+ }
if(cmp != 0) {
/* Unlock leaf node */
@@ -570,7 +633,7 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
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 *)HDmalloc(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 */
@@ -578,7 +641,7 @@ H5B2_find(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_found_t op,
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 *)HDmalloc(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 */
@@ -1072,7 +1135,13 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to load B-tree internal node")
/* Locate node pointer for child */
- cmp = H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native, udata, &idx);
+ if(H5B2__locate_record(hdr->cls, internal->nrec, hdr->nat_off, internal->int_native,
+ udata, &idx, &cmp) < 0) {
+ /* Unlock current node */
+ H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_INT, curr_node_ptr.addr, internal, H5AC__NO_FLAGS_SET);
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
+ }
+
if(cmp > 0)
idx++;
@@ -1144,7 +1213,11 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect B-tree leaf node")
/* Locate record */
- cmp = H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native, udata, &idx);
+ if(H5B2__locate_record(hdr->cls, leaf->nrec, hdr->nat_off, leaf->leaf_native,
+ udata, &idx, &cmp) < 0) {
+ H5AC_unprotect(hdr->f, dxpl_id, H5AC_BT2_LEAF, curr_node_ptr.addr, leaf, H5AC__NO_FLAGS_SET);
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTCOMPARE, FAIL, "can't compare btree2 records")
+ }
if(cmp != 0) {
/* Unlock leaf node */
@@ -1180,7 +1253,7 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
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 *)HDmalloc(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 */
@@ -1188,7 +1261,7 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
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 *)HDmalloc(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 */
@@ -1202,7 +1275,7 @@ H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata, H5B2_modify_t op,
/* Unlock current node */
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")
- }
+ } /* end block */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1376,3 +1449,33 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5B2_patch_file
+ *
+ * Purpose: Patch the top-level file pointer contained in bt2
+ * to point to idx_info->f if they are different.
+ * This is possible because the file pointer in bt2 can be
+ * closed out if bt2 remains open.
+ *
+ * Return: SUCCEED
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B2_patch_file(H5B2_t *bt2, H5F_t *f)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt2);
+ HDassert(f);
+
+ if(bt2->f != f || bt2->hdr->f != f)
+ bt2->f = bt2->hdr->f = f;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5B2_patch_file() */
+