[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)
This commit is contained in:
Quincey Koziol 2015-12-29 12:06:36 -05:00
parent 6d8b831b31
commit b5504be6cc
12 changed files with 3089 additions and 377 deletions

View File

@ -116,9 +116,7 @@ const H5B2_class_t H5A_BT2_NAME[1]={{ /* B-tree class information */
H5A__dense_btree2_name_compare, /* Record comparison callback */
H5A__dense_btree2_name_encode, /* Record encoding callback */
H5A__dense_btree2_name_decode, /* Record decoding callback */
H5A__dense_btree2_name_debug, /* Record debugging callback */
NULL, /* Create debugging context */
NULL /* Destroy debugging context */
H5A__dense_btree2_name_debug /* Record debugging callback */
}};
/* v2 B-tree class for indexing 'creation order' field of attributes */
@ -132,9 +130,7 @@ const H5B2_class_t H5A_BT2_CORDER[1]={{ /* B-tree class information */
H5A__dense_btree2_corder_compare, /* Record comparison callback */
H5A__dense_btree2_corder_encode, /* Record encoding callback */
H5A__dense_btree2_corder_decode, /* Record decoding callback */
H5A__dense_btree2_corder_debug, /* Record debugging callback */
NULL, /* Create debugging context */
NULL /* Destroy debugging context */
H5A__dense_btree2_corder_debug /* Record debugging callback */
}};

View File

@ -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)

View File

@ -92,7 +92,6 @@ H5B2__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
const H5B2_class_t *type, haddr_t obj_addr)
{
H5B2_hdr_t *hdr = NULL; /* B-tree header info */
void *dbg_ctx = NULL; /* v2 B-tree debugging context */
unsigned u; /* Local index variable */
char temp_str[128]; /* Temporary string, for formatting */
herr_t ret_value = SUCCEED; /* Return value */
@ -109,17 +108,9 @@ H5B2__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(type);
HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) ||
(NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx));
/* Check for debugging context callback available */
if(type->crt_dbg_ctx)
/* Create debugging context */
if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, obj_addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context")
/* Load the B-tree header */
if(NULL == (hdr = H5B2__hdr_protect(f, dxpl_id, addr, dbg_ctx, H5AC__READ_ONLY_FLAG)))
if(NULL == (hdr = H5B2__hdr_protect(f, dxpl_id, addr, f, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree header")
/* Set file pointer for this B-tree operation */
@ -171,8 +162,6 @@ H5B2__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
} /* end for */
done:
if(dbg_ctx && (type->dst_dbg_ctx)(dbg_ctx) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to release v2 B-tree debugging context")
if(hdr && H5B2__hdr_unprotect(hdr, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release v2 B-tree header")
@ -199,7 +188,6 @@ H5B2__int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
{
H5B2_hdr_t *hdr = NULL; /* B-tree header */
H5B2_internal_t *internal = NULL; /* B-tree internal node */
void *dbg_ctx = NULL; /* v2 B-tree debugging context */
unsigned u; /* Local index variable */
char temp_str[128]; /* Temporary string, for formatting */
herr_t ret_value=SUCCEED; /* Return value */
@ -215,21 +203,12 @@ H5B2__int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(type);
HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) ||
(NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx));
HDassert(H5F_addr_defined(hdr_addr));
HDassert(H5F_addr_defined(obj_addr));
HDassert(nrec > 0);
/* Check for debugging context callback available */
if(type->crt_dbg_ctx) {
/* Create debugging context */
if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, obj_addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context")
} /* end if */
/* Load the B-tree header */
if(NULL == (hdr = H5B2__hdr_protect(f, dxpl_id, hdr_addr, dbg_ctx, H5AC__READ_ONLY_FLAG)))
if(NULL == (hdr = H5B2__hdr_protect(f, dxpl_id, hdr_addr, f, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load v2 B-tree header")
/* Set file pointer for this B-tree operation */
@ -279,7 +258,7 @@ H5B2__int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
HDassert(H5B2_INT_NREC(internal, hdr, u));
(void)(type->debug)(stream, indent + 6, MAX (0, fwidth-6), H5B2_INT_NREC(internal, hdr, u), dbg_ctx);
(void)(type->debug)(stream, indent + 6, MAX (0, fwidth-6), H5B2_INT_NREC(internal, hdr, u), hdr->cb_ctx);
} /* end for */
/* Print final node pointer */
@ -291,8 +270,6 @@ H5B2__int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
internal->node_ptrs[u].addr);
done:
if(dbg_ctx && (type->dst_dbg_ctx)(dbg_ctx) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to release v2 B-tree debugging context")
if(hdr && H5B2__hdr_unprotect(hdr, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release v2 B-tree header")
if(internal && H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, addr, internal, H5AC__NO_FLAGS_SET) < 0)
@ -321,7 +298,6 @@ H5B2__leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent
{
H5B2_hdr_t *hdr = NULL; /* B-tree header */
H5B2_leaf_t *leaf = NULL; /* B-tree leaf node */
void *dbg_ctx = NULL; /* v2 B-tree debugging context */
unsigned u; /* Local index variable */
char temp_str[128]; /* Temporary string, for formatting */
herr_t ret_value = SUCCEED; /* Return value */
@ -337,20 +313,12 @@ H5B2__leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent
HDassert(indent >= 0);
HDassert(fwidth >= 0);
HDassert(type);
HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) ||
(NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx));
HDassert(H5F_addr_defined(hdr_addr));
HDassert(H5F_addr_defined(obj_addr));
HDassert(nrec > 0);
/* Check for debugging context callback available */
if(type->crt_dbg_ctx)
/* Create debugging context */
if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, obj_addr)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context")
/* Load the B-tree header */
if(NULL == (hdr = H5B2__hdr_protect(f, dxpl_id, hdr_addr, dbg_ctx, H5AC__READ_ONLY_FLAG)))
if(NULL == (hdr = H5B2__hdr_protect(f, dxpl_id, hdr_addr, f, H5AC__READ_ONLY_FLAG)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTPROTECT, FAIL, "unable to protect v2 B-tree header")
/* Set file pointer for this B-tree operation */
@ -391,12 +359,10 @@ H5B2__leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
temp_str);
HDassert(H5B2_LEAF_NREC(leaf, hdr, u));
(void)(type->debug)(stream, indent + 6, MAX (0, fwidth-6), H5B2_LEAF_NREC(leaf, hdr, u), dbg_ctx);
(void)(type->debug)(stream, indent + 6, MAX (0, fwidth-6), H5B2_LEAF_NREC(leaf, hdr, u), hdr->cb_ctx);
} /* end for */
done:
if(dbg_ctx && (type->dst_dbg_ctx)(dbg_ctx) < 0)
HDONE_ERROR(H5E_BTREE, H5E_CANTRELEASE, FAIL, "unable to release v2 B-tree debugging context")
if(hdr && H5B2__hdr_unprotect(hdr, dxpl_id, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree header")
if(leaf && H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, addr, leaf, H5AC__NO_FLAGS_SET) < 0)

View File

@ -1511,6 +1511,62 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5B2__swap_leaf() */
/*-------------------------------------------------------------------------
* 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->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")
} /* 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")
} /* 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
@ -1644,6 +1700,9 @@ 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, 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);
/* Split or redistribute child node pointers, if necessary */
{
int cmp; /* Comparison value of records */
@ -1753,6 +1812,348 @@ done:
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 *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, 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 if it changed */
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 = (uint8_t *)HDmalloc(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 = (uint8_t *)HDmalloc(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 && 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")
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 *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, 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, 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, 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_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, 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 && 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")
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2__update_internal() */
/*-------------------------------------------------------------------------
* Function: H5B2__create_leaf

View File

@ -228,6 +228,14 @@ typedef enum H5B2_nodepos_t {
H5B2_POS_MIDDLE /* Node is neither right or left-most in tree */
} H5B2_nodepos_t;
/* Update status */
typedef enum H5B2_update_status_t {
H5B2_UPDATE_UNKNOWN, /* Unknown update status (initial state) */
H5B2_UPDATE_MODIFY_DONE, /* Update successfully modified existing record */
H5B2_UPDATE_INSERT_DONE, /* Update inserted record successfully */
H5B2_UPDATE_INSERT_CHILD_FULL /* Update will insert record, but child is full */
} H5B2_update_status_t;
/* Callback info for loading a free space header into the cache */
typedef struct H5B2_hdr_cache_ud_t {
H5F_t *f; /* File that v2 b-tree header is within */
@ -252,7 +260,7 @@ typedef struct H5B2_leaf_cache_ud_t {
#ifdef H5B2_TESTING
/* Node information for testing */
typedef struct {
typedef struct H5B2_node_info_test_t {
unsigned depth; /* Depth of node */
unsigned nrec; /* Number of records in node */
} H5B2_node_info_test_t;
@ -281,6 +289,13 @@ H5FL_EXTERN(H5B2_leaf_t);
/* Internal v2 B-tree testing class */
#ifdef H5B2_TESTING
H5_DLLVAR const H5B2_class_t H5B2_TEST[1];
H5_DLLVAR const H5B2_class_t H5B2_TEST2[1];
/* B-tree record for testing H5B2_TEST2 class */
typedef struct H5B2_test_rec_t {
hsize_t key; /* Key for record */
hsize_t val; /* Value for record */
} H5B2_test_rec_t;
#endif /* H5B2_TESTING */
/* Array of v2 B-tree client ID -> client class mappings */
@ -327,12 +342,22 @@ H5_DLL herr_t H5B2__leaf_free(H5B2_leaf_t *l);
H5_DLL herr_t H5B2__internal_free(H5B2_internal_t *i);
/* Routines for inserting records */
H5_DLL herr_t H5B2__insert_hdr(H5B2_hdr_t *hdr, hid_t dxpl_id, void *udata);
H5_DLL herr_t H5B2__insert_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_nodepos_t curr_pos, void *udata);
H5_DLL herr_t H5B2__insert_leaf(H5B2_hdr_t *hdr, hid_t dxpl_id,
H5B2_node_ptr_t *curr_node_ptr, H5B2_nodepos_t curr_pos, void *udata);
/* Routines for update records */
H5_DLL 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 *udata, H5B2_modify_t op, void *op_data);
H5_DLL 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 *udata, H5B2_modify_t op, void *op_data);
/* Routines for iterating over nodes/records */
H5_DLL herr_t H5B2__iterate_node(H5B2_hdr_t *hdr, hid_t dxpl_id, uint16_t depth,
const H5B2_node_ptr_t *curr_node, H5B2_operator_t op, void *op_data);

View File

@ -54,6 +54,7 @@ typedef enum H5B2_subid_t {
H5B2_SOHM_INDEX_ID, /* B-tree is an index for shared object header messages */
H5B2_ATTR_DENSE_NAME_ID, /* B-tree is for indexing 'name' field for "dense" attribute storage on objects */
H5B2_ATTR_DENSE_CORDER_ID, /* B-tree is for indexing 'creation order' field for "dense" attribute storage on objects */
H5B2_TEST2_ID, /* Another B-tree is for testing (do not use for actual data) */
H5B2_NUM_BTREE_ID /* Number of B-tree IDs (must be last) */
} H5B2_subid_t;
@ -94,8 +95,6 @@ struct H5B2_class_t {
herr_t (*decode)(const uint8_t *raw, void *record, void *ctx); /* Decode record from disk storage form to native form */
herr_t (*debug)(FILE *stream, int indent, int fwidth, /* Print a record for debugging */
const void *record, const void *ctx);
void *(*crt_dbg_ctx)(H5F_t *f, hid_t dxpl_id, haddr_t obj_addr); /* Create debugging context */
herr_t (*dst_dbg_ctx)(void *dbg_ctx); /* Destroy debugging context */
};
/* v2 B-tree creation parameters */
@ -140,6 +139,8 @@ H5_DLL herr_t H5B2_neighbor(H5B2_t *bt2, hid_t dxpl_id, H5B2_compare_t range,
void *udata, H5B2_found_t op, void *op_data);
H5_DLL herr_t H5B2_modify(H5B2_t *bt2, hid_t dxpl_id, void *udata,
H5B2_modify_t op, void *op_data);
H5_DLL herr_t H5B2_update(H5B2_t *bt2, hid_t dxpl_id, void *udata,
H5B2_modify_t op, void *op_data);
H5_DLL herr_t H5B2_remove(H5B2_t *b2, hid_t dxpl_id, void *udata,
H5B2_remove_t op, void *op_data);
H5_DLL herr_t H5B2_remove_by_idx(H5B2_t *bt2, hid_t dxpl_id,

View File

@ -61,6 +61,7 @@ typedef struct H5B2_test_ctx_t {
/* Local Prototypes */
/********************/
/* v2 B-tree driver callbacks for 'test' B-trees */
static void *H5B2__test_crt_context(void *udata);
static herr_t H5B2__test_dst_context(void *ctx);
static herr_t H5B2__test_store(void *nrecord, const void *udata);
@ -69,13 +70,21 @@ static herr_t H5B2__test_encode(uint8_t *raw, const void *nrecord, void *ctx);
static herr_t H5B2__test_decode(const uint8_t *raw, void *nrecord, void *ctx);
static herr_t H5B2__test_debug(FILE *stream, int indent, int fwidth,
const void *record, const void *_udata);
static void *H5B2__test_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
/* v2 B-tree driver callbacks for 'test2' B-trees */
static herr_t H5B2__test2_store(void *nrecord, const void *udata);
static herr_t H5B2__test2_compare(const void *rec1, const void *rec2);
static herr_t H5B2__test2_encode(uint8_t *raw, const void *nrecord, void *ctx);
static herr_t H5B2__test2_decode(const uint8_t *raw, void *nrecord, void *ctx);
static herr_t H5B2__test2_debug(FILE *stream, int indent, int fwidth,
const void *record, const void *_udata);
/*********************/
/* Package Variables */
/*********************/
/* Class structure for testing simple B-tree records */
const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
H5B2_TEST_ID, /* Type of B-tree */
"H5B2_TEST_ID", /* Name of B-tree class */
@ -86,9 +95,21 @@ const H5B2_class_t H5B2_TEST[1]={{ /* B-tree class information */
H5B2__test_compare, /* Record comparison callback */
H5B2__test_encode, /* Record encoding callback */
H5B2__test_decode, /* Record decoding callback */
H5B2__test_debug, /* Record debugging callback */
H5B2__test_crt_dbg_context, /* Create debugging context */
H5B2__test_dst_context /* Destroy debugging context */
H5B2__test_debug /* Record debugging callback */
}};
/* Class structure for testing key/value B-tree records */
const H5B2_class_t H5B2_TEST2[1]={{ /* B-tree class information */
H5B2_TEST2_ID, /* Type of B-tree */
"H5B2_TEST2_ID", /* Name of B-tree class */
sizeof(H5B2_test_rec_t), /* Size of native record */
H5B2__test_crt_context, /* Create client callback context */
H5B2__test_dst_context, /* Destroy client callback context */
H5B2__test2_store, /* Record storage callback */
H5B2__test2_compare, /* Record comparison callback */
H5B2__test2_encode, /* Record encoding callback */
H5B2__test2_decode, /* Record decoding callback */
H5B2__test2_debug /* Record debugging callback */
}};
@ -310,42 +331,139 @@ H5B2__test_debug(FILE *stream, int indent, int fwidth, const void *record,
/*-------------------------------------------------------------------------
* Function: H5B2__test_crt_dbg_context
* Function: H5B2__test2_store
*
* Purpose: Create context for debugging callback
* Purpose: Store native information into record for B-tree
*
* Return: Success: non-NULL
* Failure: NULL
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* Tuesday, December 1, 2009
* Friday, December 25, 2015
*
*-------------------------------------------------------------------------
*/
static void *
H5B2__test_crt_dbg_context(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t H5_ATTR_UNUSED addr)
static herr_t
H5B2__test2_store(void *nrecord, const void *udata)
{
H5B2_test_ctx_t *ctx; /* Callback context structure */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC_NOERR
FUNC_ENTER_STATIC
*(H5B2_test_rec_t *)nrecord = *(const H5B2_test_rec_t *)udata;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2__test2_store() */
/*-------------------------------------------------------------------------
* Function: H5B2__test2_compare
*
* Purpose: Compare two native information records, according to some key
*
* Return: <0 if rec1 < rec2
* =0 if rec1 == rec2
* >0 if rec1 > rec2
*
* Programmer: Quincey Koziol
* Friday, December 25, 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
H5B2__test2_compare(const void *rec1, const void *rec2)
{
FUNC_ENTER_STATIC_NOERR
FUNC_LEAVE_NOAPI((herr_t)(((const H5B2_test_rec_t *)rec1)->key - ((const H5B2_test_rec_t *)rec2)->key))
} /* H5B2__test2_compare() */
/*-------------------------------------------------------------------------
* Function: H5B2__test2_encode
*
* Purpose: Encode native information into raw form for storing on disk
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* Friday, December 25, 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
H5B2__test2_encode(uint8_t *raw, const void *nrecord, void *_ctx)
{
H5B2_test_ctx_t *ctx = (H5B2_test_ctx_t *)_ctx; /* Callback context structure */
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
HDassert(f);
HDassert(ctx);
/* Allocate callback context */
if(NULL == (ctx = H5FL_MALLOC(H5B2_test_ctx_t)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTALLOC, NULL, "can't allocate callback context")
H5F_ENCODE_LENGTH_LEN(raw, ((const H5B2_test_rec_t *)nrecord)->key, ctx->sizeof_size);
H5F_ENCODE_LENGTH_LEN(raw, ((const H5B2_test_rec_t *)nrecord)->val, ctx->sizeof_size);
/* Determine the size of addresses & lengths in the file */
ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2__test2_encode() */
/* Set return value */
ret_value = ctx;
/*-------------------------------------------------------------------------
* Function: H5B2__test2_decode
*
* Purpose: Decode raw disk form of record into native form
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* Friday, December 25, 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
H5B2__test2_decode(const uint8_t *raw, void *nrecord, void *_ctx)
{
H5B2_test_ctx_t *ctx = (H5B2_test_ctx_t *)_ctx; /* Callback context structure */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5B2__test_crt_dbg_context() */
FUNC_ENTER_STATIC_NOERR
/* Sanity check */
HDassert(ctx);
H5F_DECODE_LENGTH_LEN(raw, ((H5B2_test_rec_t *)nrecord)->key, ctx->sizeof_size);
H5F_DECODE_LENGTH_LEN(raw, ((H5B2_test_rec_t *)nrecord)->val, ctx->sizeof_size);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2__test2_decode() */
/*-------------------------------------------------------------------------
* Function: H5B2__test2_debug
*
* Purpose: Debug native form of record
*
* Return: Success: non-negative
* Failure: negative
*
* Programmer: Quincey Koziol
* Friday, December 25, 2015
*
*-------------------------------------------------------------------------
*/
static herr_t
H5B2__test2_debug(FILE *stream, int indent, int fwidth, const void *record,
const void H5_ATTR_UNUSED *_udata)
{
FUNC_ENTER_STATIC_NOERR
HDassert(record);
HDfprintf(stream, "%*s%-*s (%Hu, %Hu)\n", indent, "", fwidth, "Record:",
((const H5B2_test_rec_t *)record)->key,
((const H5B2_test_rec_t *)record)->val);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5B2__test2_debug() */
/*-------------------------------------------------------------------------

View File

@ -114,9 +114,7 @@ const H5B2_class_t H5G_BT2_NAME[1]={{ /* B-tree class information */
H5G_dense_btree2_name_compare, /* Record comparison callback */
H5G_dense_btree2_name_encode, /* Record encoding callback */
H5G_dense_btree2_name_decode, /* Record decoding callback */
H5G_dense_btree2_name_debug, /* Record debugging callback */
NULL, /* Create debugging context */
NULL /* Destroy debugging context */
H5G_dense_btree2_name_debug /* Record debugging callback */
}};
/* v2 B-tree class for indexing 'creation order' field of links */
@ -130,9 +128,7 @@ const H5B2_class_t H5G_BT2_CORDER[1]={{ /* B-tree class information */
H5G_dense_btree2_corder_compare, /* Record comparison callback */
H5G_dense_btree2_corder_encode, /* Record encoding callback */
H5G_dense_btree2_corder_decode, /* Record decoding callback */
H5G_dense_btree2_corder_debug, /* Record debugging callback */
NULL, /* Create debugging context */
NULL /* Destroy debugging context */
H5G_dense_btree2_corder_debug /* Record debugging callback */
}};
/*****************************/

View File

@ -71,7 +71,6 @@ typedef struct H5HF_huge_bt2_ctx_t {
/* Common callbacks */
static void *H5HF__huge_bt2_crt_context(void *udata);
static herr_t H5HF__huge_bt2_dst_context(void *ctx);
static void *H5HF__huge_bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
/* Callbacks for indirect objects */
static herr_t H5HF__huge_bt2_indir_store(void *native, const void *udata);
@ -127,9 +126,7 @@ const H5B2_class_t H5HF_HUGE_BT2_INDIR[1]={{ /* B-tree class information */
H5HF__huge_bt2_indir_compare, /* Record comparison callback */
H5HF__huge_bt2_indir_encode, /* Record encoding callback */
H5HF__huge_bt2_indir_decode, /* Record decoding callback */
H5HF__huge_bt2_indir_debug, /* Record debugging callback */
H5HF__huge_bt2_crt_dbg_context, /* Create debugging context */
H5HF__huge_bt2_dst_context /* Destroy debugging context */
H5HF__huge_bt2_indir_debug /* Record debugging callback */
}};
/* v2 B-tree class for indirectly accessed, filtered 'huge' objects */
@ -143,9 +140,7 @@ const H5B2_class_t H5HF_HUGE_BT2_FILT_INDIR[1]={{ /* B-tree class information */
H5HF__huge_bt2_filt_indir_compare, /* Record comparison callback */
H5HF__huge_bt2_filt_indir_encode, /* Record encoding callback */
H5HF__huge_bt2_filt_indir_decode, /* Record decoding callback */
H5HF__huge_bt2_filt_indir_debug, /* Record debugging callback */
H5HF__huge_bt2_crt_dbg_context, /* Create debugging context */
H5HF__huge_bt2_dst_context /* Destroy debugging context */
H5HF__huge_bt2_filt_indir_debug /* Record debugging callback */
}};
/* v2 B-tree class for directly accessed 'huge' objects */
@ -159,9 +154,7 @@ const H5B2_class_t H5HF_HUGE_BT2_DIR[1]={{ /* B-tree class information */
H5HF__huge_bt2_dir_compare, /* Record comparison callback */
H5HF__huge_bt2_dir_encode, /* Record encoding callback */
H5HF__huge_bt2_dir_decode, /* Record decoding callback */
H5HF__huge_bt2_dir_debug, /* Record debugging callback */
H5HF__huge_bt2_crt_dbg_context, /* Create debugging context */
H5HF__huge_bt2_dst_context /* Destroy debugging context */
H5HF__huge_bt2_dir_debug /* Record debugging callback */
}};
/* v2 B-tree class for directly accessed, filtered 'huge' objects */
@ -175,9 +168,7 @@ const H5B2_class_t H5HF_HUGE_BT2_FILT_DIR[1]={{ /* B-tree class information */
H5HF__huge_bt2_filt_dir_compare, /* Record comparison callback */
H5HF__huge_bt2_filt_dir_encode, /* Record encoding callback */
H5HF__huge_bt2_filt_dir_decode, /* Record decoding callback */
H5HF__huge_bt2_filt_dir_debug, /* Record debugging callback */
H5HF__huge_bt2_crt_dbg_context, /* Create debugging context */
H5HF__huge_bt2_dst_context /* Destroy debugging context */
H5HF__huge_bt2_filt_dir_debug /* Record debugging callback */
}};
/*****************************/
@ -268,46 +259,6 @@ H5HF__huge_bt2_dst_context(void *_ctx)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HF__huge_bt2_dst_context() */
/*-------------------------------------------------------------------------
* Function: H5HF__huge_bt2_crt_dbg_context
*
* Purpose: Create context for debugging callback
*
* Return: Success: non-NULL
* Failure: NULL
*
* Programmer: Quincey Koziol
* Tuesday, December 1, 2009
*
*-------------------------------------------------------------------------
*/
static void *
H5HF__huge_bt2_crt_dbg_context(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t H5_ATTR_UNUSED addr)
{
H5HF_huge_bt2_ctx_t *ctx; /* Callback context structure */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC
/* Sanity check */
HDassert(f);
/* Allocate callback context */
if(NULL == (ctx = H5FL_MALLOC(H5HF_huge_bt2_ctx_t)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
/* Determine the size of addresses & lengths in the file */
ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
ctx->sizeof_size = H5F_SIZEOF_SIZE(f);
/* Set return value */
ret_value = ctx;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5HF__huge_bt2_crt_dbg_context() */
/*-------------------------------------------------------------------------
* Function: H5HF__huge_bt2_indir_found

View File

@ -50,7 +50,6 @@ static herr_t H5SM__bt2_dst_context(void *ctx);
static herr_t H5SM__bt2_store(void *native, const void *udata);
static herr_t H5SM__bt2_debug(FILE *stream, int indent, int fwidth,
const void *record, const void *_udata);
static void *H5SM__bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t addr);
/*****************************/
@ -67,9 +66,7 @@ const H5B2_class_t H5SM_INDEX[1]={{ /* B-tree class information */
H5SM__message_compare, /* Record comparison callback */
H5SM__message_encode, /* Record encoding callback */
H5SM__message_decode, /* Record decoding callback */
H5SM__bt2_debug, /* Record debugging callback */
H5SM__bt2_crt_dbg_context, /* Create debugging context */
H5SM__bt2_dst_context /* Destroy debugging context */
H5SM__bt2_debug /* Record debugging callback */
}};
@ -216,45 +213,6 @@ H5SM__bt2_debug(FILE *stream, int indent, int fwidth,
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5SM__bt2_debug */
/*-------------------------------------------------------------------------
* Function: H5SM__bt2_crt_dbg_context
*
* Purpose: Create context for debugging callback
*
* Return: Success: non-NULL
* Failure: NULL
*
* Programmer: Quincey Koziol
* Tuesday, December 1, 2009
*
*-------------------------------------------------------------------------
*/
static void *
H5SM__bt2_crt_dbg_context(H5F_t *f, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t H5_ATTR_UNUSED addr)
{
H5SM_bt2_ctx_t *ctx; /* Callback context structure */
void *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC
/* Sanity check */
HDassert(f);
/* Allocate callback context */
if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate callback context")
/* Determine the size of addresses & lengths in the file */
ctx->sizeof_addr = H5F_SIZEOF_ADDR(f);
/* Set return value */
ret_value = ctx;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5SM__bt2_crt_dbg_context() */
/*-------------------------------------------------------------------------
* Function: H5SM_bt2_convert_to_list_op

File diff suppressed because it is too large Load Diff

View File

@ -121,6 +121,10 @@ get_H5B2_class(const uint8_t *sig)
cls = H5A_BT2_CORDER;
break;
case H5B2_TEST2_ID:
cls = H5B2_TEST2;
break;
case H5B2_NUM_BTREE_ID:
default:
HDfprintf(stderr, "Unknown v2 B-tree subtype %u\n", (unsigned)(subtype));