diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2015-12-29 17:06:36 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2015-12-29 17:06:36 (GMT) |
commit | b5504be6cc6f61b5a8ce78f243b81b6afe9d13c9 (patch) | |
tree | 34c12b398509a0b7585009bd10f4e22982ad9cdb /src/H5B2.c | |
parent | 6d8b831b3125ce66e23aba1f3ec16a03e00b5b82 (diff) | |
download | hdf5-b5504be6cc6f61b5a8ce78f243b81b6afe9d13c9.zip hdf5-b5504be6cc6f61b5a8ce78f243b81b6afe9d13c9.tar.gz hdf5-b5504be6cc6f61b5a8ce78f243b81b6afe9d13c9.tar.bz2 |
[svn-r28742] Description:
Add 'update' operation to v2 B-trees, which will insert a new record, or
modify an existing one, depending on if the record exists or not.
Tested on:
MacOSX/64 10.11.2 (amazon) w/serial & parallel
(h5committest forthcoming)
Diffstat (limited to 'src/H5B2.c')
-rw-r--r-- | src/H5B2.c | 74 |
1 files changed, 59 insertions, 15 deletions
@@ -86,6 +86,7 @@ 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 H5B2_TEST2[1]; const H5B2_class_t *const H5B2_client_class_g[] = { H5B2_TEST, /* 0 - H5B2_TEST_ID */ @@ -98,6 +99,7 @@ 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 */ + H5B2_TEST2, /* 10 - H5B2_TEST_ID */ }; @@ -282,36 +284,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() */ /*------------------------------------------------------------------------- @@ -1202,7 +1246,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) |