diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2008-06-03 19:44:12 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2008-06-03 19:44:12 (GMT) |
commit | 771bae88881f4ae8102c9553fd10e0938aa3094c (patch) | |
tree | 62ac7bce1e109e1b0b8899ea14da603a2b6e6ffc /src/H5B.c | |
parent | d36f67c0e27a39a54f870c4f917ab2c1754e80d6 (diff) | |
download | hdf5-771bae88881f4ae8102c9553fd10e0938aa3094c.zip hdf5-771bae88881f4ae8102c9553fd10e0938aa3094c.tar.gz hdf5-771bae88881f4ae8102c9553fd10e0938aa3094c.tar.bz2 |
[svn-r15131] Description:
Finish omnibus chunked dataset I/O refactoring, to separate general
actions on chunked datasets from actions that are specific to using the v1
B-tree index.
Cleaned up a few bugs and added some additional tests also.
Tested on:
FreeBSD/32 6.2 (duty) in debug mode
FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe,
in debug mode
Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN,
in production mode
Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN,
in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, in production mode
Mac OS X/32 10.5.2 (amazon) in debug mode
Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
Diffstat (limited to 'src/H5B.c')
-rw-r--r-- | src/H5B.c | 469 |
1 files changed, 324 insertions, 145 deletions
@@ -128,6 +128,13 @@ /* Local Typedefs */ /******************/ +/* "user data" for iterating over B-tree (collects B-tree metadata size) */ +typedef struct H5B_iter_ud_t { + H5B_info_t *bt_info; /* Information about B-tree */ + void *udata; /* Node type's 'udata' for loading & iterator callback */ +} H5B_info_ud_t; + + /********************/ /* Local Prototypes */ /********************/ @@ -168,13 +175,20 @@ H5FL_DEFINE(H5B_t); /* Library Private Variables */ /*****************************/ -/* Declare a free list to manage the H5B_shared_t struct */ -H5FL_DEFINE(H5B_shared_t); - /*******************/ /* Local Variables */ /*******************/ +/* Declare a free list to manage the H5B_shared_t struct */ +H5FL_DEFINE_STATIC(H5B_shared_t); + +/* Declare a free list to manage the raw page information */ +H5FL_BLK_DEFINE_STATIC(page); + +/* Declare a free list to manage the native key offset sequence information */ +H5FL_SEQ_DEFINE_STATIC(size_t); + + /*------------------------------------------------------------------------- * Function: H5B_create @@ -1143,10 +1157,10 @@ done: /*------------------------------------------------------------------------- - * Function: H5B_iterate + * Function: H5B_iterate_helper * * Purpose: Calls the list callback for each leaf node of the - * B-tree, passing it the UDATA structure. + * B-tree, passing it the caller's UDATA structure. * * Return: Non-negative on success/Negative on failure * @@ -1154,106 +1168,167 @@ done: * matzke@llnl.gov * Jun 23 1997 * - * Modifications: - * Robb Matzke, 1999-04-21 - * The key values are passed to the function which is called. - * - * Robb Matzke, 1999-07-28 - * The ADDR argument is passed by value. - * - * Quincey Koziol, 2002-04-22 - * Changed callback to function pointer from static function - * - * John Mainzer, 6/10/05 - * Modified the function to use the new dirtied parameter of - * of H5AC_unprotect() instead of modifying the is_dirty - * field of the cache info. - * *------------------------------------------------------------------------- */ -herr_t -H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op, haddr_t addr, void *udata) +static herr_t +H5B_iterate_helper(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, + H5B_operator_t op, void *udata) { H5B_t *bt = NULL; /* Pointer to current B-tree node */ + uint8_t *native = NULL; /* Array of keys in native format */ + haddr_t *child = NULL; /* Array of child pointers */ herr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5B_iterate, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5B_iterate_helper) /* * Check arguments. */ HDassert(f); HDassert(type); - HDassert(op); HDassert(H5F_addr_defined(addr)); + HDassert(op); HDassert(udata); /* Protect the initial/current node */ if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node") + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5_ITER_ERROR, "unable to load B-tree node") if(bt->level > 0) { + haddr_t left_child = bt->child[0]; /* Address of left-most child in node */ + + /* Release current node */ + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node") + bt = NULL; + /* Keep following the left-most child until we reach a leaf node. */ - if((ret_value = H5B_iterate(f, dxpl_id, type, op, bt->child[0], udata)) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "unable to list B-tree node") + if((ret_value = H5B_iterate_helper(f, dxpl_id, type, left_child, op, udata)) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, H5_ITER_ERROR, "unable to list B-tree node") } /* end if */ else { + H5B_shared_t *shared; /* Pointer to shared B-tree info */ + unsigned nchildren; /* Number of child pointers */ + haddr_t next_addr; /* Address of next node to the right */ + + /* Get the shared B-tree information */ + shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); + HDassert(shared); + + /* Allocate space for a copy of the native records & child pointers */ + if(NULL == (native = H5FL_BLK_MALLOC(native_block, shared->sizeof_keys))) + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for shared B-tree native records") + if(NULL == (child = H5FL_SEQ_MALLOC(haddr_t, (size_t)shared->two_k))) + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, H5_ITER_ERROR, "memory allocation failed for shared B-tree child addresses") + + /* Cache information from this node */ + nchildren = bt->nchildren; + next_addr = bt->right; + + /* Copy the native keys & child pointers into local arrays */ + HDmemcpy(native, bt->native, shared->sizeof_keys); + HDmemcpy(child, bt->child, (nchildren * sizeof(haddr_t))); + + /* Release current node */ + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node") + bt = NULL; + /* * We've reached the left-most leaf. Now follow the right-sibling * pointer from leaf to leaf until we've processed all leaves. */ ret_value = H5_ITER_CONT; - while(bt && ret_value == H5_ITER_CONT) { - haddr_t *child; /* Pointer to node's child addresses */ - uint8_t *key; /* Pointer to node's native keys */ + while(ret_value == H5_ITER_CONT) { + haddr_t *curr_child; /* Pointer to node's child addresses */ + uint8_t *curr_native; /* Pointer to node's native keys */ unsigned u; /* Local index variable */ /* * Perform the iteration operator, which might invoke an * application callback. */ - for(u = 0, child = bt->child, key = bt->native; u < bt->nchildren && ret_value == H5_ITER_CONT; u++, child++, key += type->sizeof_nkey) { - ret_value = (*op)(f, dxpl_id, key, *child, key + type->sizeof_nkey, udata); + for(u = 0, curr_child = child, curr_native = native; u < nchildren && ret_value == H5_ITER_CONT; u++, curr_child++, curr_native += type->sizeof_nkey) { + ret_value = (*op)(f, dxpl_id, curr_native, *curr_child, curr_native + type->sizeof_nkey, udata); if(ret_value < 0) HERROR(H5E_BTREE, H5E_CANTLIST, "iterator function failed"); } /* end for */ /* Check for continuing iteration */ if(ret_value == H5_ITER_CONT) { - H5B_t *next_bt; /* Pointer to next B-tree node */ - haddr_t next_addr; /* Address of next node to iterate over */ - - /* Protect the next node to the right, if there is one */ - if(H5F_addr_defined(bt->right)) { + /* Check for another node */ + if(H5F_addr_defined(next_addr)) { + /* Protect the next node to the right */ + addr = next_addr; + if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5_ITER_ERROR, "B-tree node") + + /* Cache information from this node */ + nchildren = bt->nchildren; next_addr = bt->right; - if(NULL == (next_bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, next_addr, type, udata, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node") - } /* end if */ - else { - next_addr = HADDR_UNDEF; - next_bt = NULL; - } /* end if */ - /* Unprotect this node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) { - if(next_bt) { - HDassert(H5F_addr_defined(next_addr)); - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, next_addr, next_bt, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") - } /* end if */ - HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") - } /* end if */ + /* Copy the native keys & child pointers into local arrays */ + HDmemcpy(native, bt->native, shared->sizeof_keys); + HDmemcpy(child, bt->child, nchildren * sizeof(haddr_t)); - /* Advance to the next node */ - bt = next_bt; - addr = next_addr; + /* Unprotect node */ + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node") + bt = NULL; + } /* end if */ + else + /* Exit loop */ + break; } /* end if */ - } /* end for */ + } /* end while */ } /* end else */ done: if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) - HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") + HDONE_ERROR(H5E_BTREE, H5E_PROTECT, H5_ITER_ERROR, "unable to release B-tree node") + if(native) + (void)H5FL_BLK_FREE(native_block, native); + if(child) + (void)H5FL_SEQ_FREE(haddr_t, child); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B_iterate_helper() */ + + +/*------------------------------------------------------------------------- + * Function: H5B_iterate + * + * Purpose: Calls the list callback for each leaf node of the + * B-tree, passing it the UDATA structure. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B_iterate(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, + H5B_operator_t op, void *udata) +{ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5B_iterate, FAIL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(type); + HDassert(H5F_addr_defined(addr)); + HDassert(op); + HDassert(udata); + + /* Iterate over the B-tree records */ + if((ret_value = H5B_iterate_helper(f, dxpl_id, type, addr, op, udata)) < 0) + HERROR(H5E_BTREE, H5E_BADITER, "B-tree iteration failed"); FUNC_LEAVE_NOAPI(ret_value) } /* end H5B_iterate() */ @@ -1704,59 +1779,99 @@ done: /*------------------------------------------------------------------------- - * Function: H5B_nodesize - * - * Purpose: Returns the number of bytes needed for this type of - * B-tree node. The size is the size of the header plus - * enough space for 2t child pointers and 2t+1 keys. + * Function: H5B_shared_new * - * If TOTAL_NKEY_SIZE is non-null, what it points to will - * be initialized with the total number of bytes required to - * hold all the key values in native order. + * Purpose: Allocates & constructs a shared v1 B-tree struct for client. * - * Return: Success: Size of node in file. + * Return: Success: non-NULL pointer to struct allocated + * Failure: NULL * - * Failure: 0 - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 3 1997 - * - * Modifications: + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * May 27 2008 * *------------------------------------------------------------------------- */ -size_t -H5B_nodesize(const H5F_t *f, const H5B_shared_t *shared, - size_t *total_nkey_size/*out*/) +H5B_shared_t * +H5B_shared_new(const H5F_t *f, const H5B_class_t *type, size_t sizeof_rkey) { - size_t size; + H5B_shared_t *shared; /* New shared B-tree struct */ + size_t u; /* Local index variable */ + H5B_shared_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_nodesize) + FUNC_ENTER_NOAPI(H5B_shared_new, NULL) /* * Check arguments. */ - assert(f); - assert(shared); - assert(shared->two_k > 0); - assert(shared->sizeof_rkey > 0); - - /* - * Total native key size. - */ - if (total_nkey_size) - *total_nkey_size = (shared->two_k + 1) * shared->type->sizeof_nkey; + HDassert(type); - /* - * Total node size. - */ - size = (H5B_SIZEOF_HDR(f) + /*node header */ + /* Allocate space for the shared structure */ + if(NULL == (shared = H5FL_MALLOC(H5B_shared_t))) + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for shared B-tree info") + + /* Set up the "global" information for this file's groups */ + shared->type = type; + shared->two_k = 2 * H5F_KVALUE(f, type); + shared->sizeof_rkey = sizeof_rkey; + HDassert(shared->sizeof_rkey); + shared->sizeof_keys = (shared->two_k + 1) * type->sizeof_nkey; + shared->sizeof_rnode = (H5B_SIZEOF_HDR(f) + /*node header */ shared->two_k * H5F_SIZEOF_ADDR(f) + /*child pointers */ (shared->two_k + 1) * shared->sizeof_rkey); /*keys */ + HDassert(shared->sizeof_rnode); - FUNC_LEAVE_NOAPI(size) -} + /* Allocate shared buffers */ + if(NULL == (shared->page = H5FL_BLK_MALLOC(page, shared->sizeof_rnode))) + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree page") +#ifdef H5_CLEAR_MEMORY +HDmemset(shared->page, 0, shared->sizeof_rnode); +#endif /* H5_CLEAR_MEMORY */ + if(NULL == (shared->nkey = H5FL_SEQ_MALLOC(size_t, (size_t)(2 * H5F_KVALUE(f, type) + 1)))) + HGOTO_ERROR(H5E_BTREE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree page") + + /* Initialize the offsets into the native key buffer */ + for(u = 0; u < (2 * H5F_KVALUE(f, type) + 1); u++) + shared->nkey[u] = u * type->sizeof_nkey; + + /* Set return value */ + ret_value = shared; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B_shared_new() */ + + +/*------------------------------------------------------------------------- + * Function: H5B_shared_free + * + * Purpose: Free B-tree shared info + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, May 27, 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B_shared_free(void *_shared) +{ + H5B_shared_t *shared = (H5B_shared_t *)_shared; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_shared_free) + + /* Free the raw B-tree node buffer */ + (void)H5FL_BLK_FREE(page, shared->page); + + /* Free the B-tree native key offsets buffer */ + (void)H5FL_SEQ_FREE(size_t, shared->nkey); + + /* Free the shared B-tree info */ + (void)H5FL_FREE(H5B_shared_t, shared); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5B_shared_free() */ /*------------------------------------------------------------------------- @@ -1827,29 +1942,31 @@ done: /*------------------------------------------------------------------------- - * Function: H5B_iterate_size + * Function: H5B_get_info_helper * - * Purpose: Return the amount of storage used for the btree. - * Keep following the left-most child until reaching the leaf node. - * For each level, gather storage for all the nodes on that level. - * For 0 level, also gather storage for the SNODs. + * Purpose: Walks the B-tree nodes, getting information for all of them. * - * Return: Non-negative on success/Negative on failure + * Return: Non-negative on success/Negative on failure * - * Programmer: Vailin Choi - * June 19, 2007 + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Jun 3 2008 * *------------------------------------------------------------------------- */ -herr_t -H5B_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, - H5B_operator_t op, haddr_t addr, H5B_info_ud_t *bh_udata) +static herr_t +H5B_get_info_helper(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, + const H5B_info_ud_t *info_udata) { - H5B_t *bt = NULL; /* Pointer to current B-tree node */ - H5B_shared_t *shared; /* Pointer to shared B-tree info */ - herr_t ret_value = SUCCEED; /* Return value */ + H5B_t *bt = NULL; /* Pointer to current B-tree node */ + H5B_shared_t *shared; /* Pointer to shared B-tree info */ + unsigned level; /* Node level */ + size_t sizeof_rnode; /* Size of raw (disk) node */ + haddr_t next_addr; /* Address of next node to the right */ + haddr_t left_child; /* Address of left-most child in node */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5B_iterate_size, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5B_get_info_helper) /* * Check arguments. @@ -1857,61 +1974,123 @@ H5B_iterate_size(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, HDassert(f); HDassert(type); HDassert(H5F_addr_defined(addr)); - HDassert(bh_udata); + HDassert(info_udata); + HDassert(info_udata->bt_info); + HDassert(info_udata->udata); /* Protect the initial/current node */ - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, bh_udata->udata, H5AC_READ))) + if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, info_udata->udata, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node") - shared = H5RC_GET_OBJ(bt->rc_shared); + + /* Get the shared B-tree information */ + shared = (H5B_shared_t *)H5RC_GET_OBJ(bt->rc_shared); HDassert(shared); - /* Keep following the left-most child until we reach a leaf node. */ - if(bt->level > 0) - if(H5B_iterate_size(f, dxpl_id, type, op, bt->child[0], bh_udata) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "unable to list B-tree node") + /* Get the raw node size for iteration */ + sizeof_rnode = shared->sizeof_rnode; - /* Iterate through all nodes at this level of the tree */ - while(bt) { - haddr_t next_addr; /* Address of next node to iterate over */ + /* Cache information from this node */ + left_child = bt->child[0]; + next_addr = bt->right; + level = bt->level; - /* for leaf node with callback, add in the space pointed to by each key */ - /* (currently only used for symbol table nodes) */ - if(bt->level == 0 && op) { - haddr_t *child; /* Pointer to node's child addresses */ - uint8_t *key; /* Pointer to node's native keys */ - unsigned u; /* Local index variable */ + /* Update B-tree info */ + info_udata->bt_info->size += sizeof_rnode; + info_udata->bt_info->num_nodes++; - for(u = 0, child = bt->child, key = bt->native; u < bt->nchildren; u++, child++, key += type->sizeof_nkey) - if((*op)(f, dxpl_id, key, *child, key + type->sizeof_nkey, bh_udata->btree_size) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "iterator function failed") - } /* end if */ + /* Release current node */ + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") + bt = NULL; - /* count the size of this node */ - *(bh_udata->btree_size) += H5B_nodesize(f, shared, NULL); + /* + * Follow the right-sibling pointer from node to node until we've + * processed all nodes. + */ + while(H5F_addr_defined(next_addr)) { + /* Protect the next node to the right */ + addr = next_addr; + if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, info_udata->udata, H5AC_READ))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node") - /* Get the address of the next node to the right */ + /* Cache information from this node */ next_addr = bt->right; - /* Unprotect current node */ - if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") + /* Update B-tree info */ + info_udata->bt_info->size += sizeof_rnode; + info_udata->bt_info->num_nodes++; - /* Protect bt's next node to the right, if there is one */ - if(H5F_addr_defined(next_addr)) { - addr = next_addr; - if(NULL == (bt = (H5B_t *)H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, bh_udata->udata, H5AC_READ))) - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node") - } /* end if */ - else - bt = NULL; + /* Unprotect node */ + if(H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") + bt = NULL; } /* end while */ + /* Check for another "row" of B-tree nodes to iterate over */ + if(level > 0) { + /* Keep following the left-most child until we reach a leaf node. */ + if(H5B_get_info_helper(f, dxpl_id, type, left_child, info_udata) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, "unable to list B-tree node") + } /* end if */ + done: if(bt && H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") FUNC_LEAVE_NOAPI(ret_value) -} /* end H5B_iterate_size() */ +} /* end H5B_get_info_helper() */ + + +/*------------------------------------------------------------------------- + * Function: H5B_get_info + * + * Purpose: Return the amount of storage used for the btree. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * June 19, 2007 + * + *------------------------------------------------------------------------- + */ +herr_t +H5B_get_info(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, + H5B_info_t *bt_info, H5B_operator_t op, void *udata) +{ + H5B_info_ud_t info_udata; /* User-data for B-tree size iteration */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5B_get_info, FAIL) + + /* + * Check arguments. + */ + HDassert(f); + HDassert(type); + HDassert(bt_info); + HDassert(H5F_addr_defined(addr)); + HDassert(udata); + + /* Portably initialize B-tree info struct */ + HDmemset(bt_info, 0, sizeof(*bt_info)); + + /* Set up internal user-data for the B-tree 'get info' helper routine */ + info_udata.bt_info = bt_info; + info_udata.udata = udata; + + /* Iterate over the B-tree nodes */ + if(H5B_get_info_helper(f, dxpl_id, type, addr, &info_udata) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_BADITER, FAIL, "B-tree iteration failed") + + /* Iterate over the B-tree records, making any "leaf" callbacks */ + /* (Only if operator defined) */ + if(op) + if((ret_value = H5B_iterate_helper(f, dxpl_id, type, addr, op, udata)) < 0) + HERROR(H5E_BTREE, H5E_BADITER, "B-tree iteration failed"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5B_get_info() */ /*------------------------------------------------------------------------- |