diff options
-rw-r--r-- | MANIFEST | 8 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | src/H5B.c | 1773 | ||||
-rw-r--r-- | src/H5Bprivate.h | 5 | ||||
-rw-r--r-- | src/H5G.c | 125 | ||||
-rw-r--r-- | src/H5Gnode.c | 233 | ||||
-rw-r--r-- | src/H5Gpkg.h | 18 | ||||
-rw-r--r-- | src/H5Gpublic.h | 5 | ||||
-rw-r--r-- | src/H5Gstab.c | 70 | ||||
-rw-r--r-- | src/H5O.c | 3 | ||||
-rw-r--r-- | test/istore.c | 2 |
11 files changed, 1138 insertions, 1106 deletions
@@ -75,14 +75,14 @@ ./html/ph5example.c ./html/ph5implement.txt ./html/pipe1.gif -./html/pipe1.gif -./html/pipe2.gif +./html/pipe1.obj ./html/pipe2.gif +./html/pipe2.obj ./html/pipe3.gif ./html/pipe3.obj +./html/pipe4.gif ./html/pipe4.obj -./html/pipe4.obj -./html/pipe5.obj +./html/pipe5.gif ./html/pipe5.obj ./html/heap.txt ./html/index.html @@ -1982,7 +1982,7 @@ fi echo $ac_n "checking for parallel support""... $ac_c" 1>&6 echo "configure:1984: checking for parallel support" >&5; - RUNTEST="" + case "X-$PARALLEL" in @@ -1,138 +1,138 @@ /*------------------------------------------------------------------------- - * Copyright (C) 1997 National Center for Supercomputing Applications. - * All rights reserved. + * Copyright (C) 1997 National Center for Supercomputing Applications. + * All rights reserved. * *------------------------------------------------------------------------- * - * Created: hdf5btree.c - * Jul 10 1997 - * Robb Matzke <matzke@llnl.gov> + * Created: hdf5btree.c + * Jul 10 1997 + * Robb Matzke <matzke@llnl.gov> * - * Purpose: Implements balanced, sibling-linked, N-ary trees - * capable of storing any type of data with unique key - * values. + * Purpose: Implements balanced, sibling-linked, N-ary trees + * capable of storing any type of data with unique key + * values. * - * A B-link-tree is a balanced tree where each node has - * a pointer to its left and right siblings. A - * B-link-tree is a rooted tree having the following - * properties: + * A B-link-tree is a balanced tree where each node has + * a pointer to its left and right siblings. A + * B-link-tree is a rooted tree having the following + * properties: * - * 1. Every node, x, has the following fields: + * 1. Every node, x, has the following fields: * - * a. level[x], the level in the tree at which node - * x appears. Leaf nodes are at level zero. + * a. level[x], the level in the tree at which node + * x appears. Leaf nodes are at level zero. * - * b. n[x], the number of children pointed to by the - * node. Internal nodes point to subtrees while - * leaf nodes point to arbitrary data. + * b. n[x], the number of children pointed to by the + * node. Internal nodes point to subtrees while + * leaf nodes point to arbitrary data. * - * c. The child pointers themselves, child[x,i] such - * that 0 <= i < n[x]. + * c. The child pointers themselves, child[x,i] such + * that 0 <= i < n[x]. * - * d. n[x]+1 key values stored in increasing - * order: + * d. n[x]+1 key values stored in increasing + * order: * - * key[x,0] < key[x,1] < ... < key[x,n[x]]. + * key[x,0] < key[x,1] < ... < key[x,n[x]]. * - * e. left[x] is a pointer to the node's left sibling - * or the null pointer if this is the left-most - * node at this level in the tree. - * - * f. right[x] is a pointer to the node's right - * sibling or the null pointer if this is the - * right-most node at this level in the tree. + * e. left[x] is a pointer to the node's left sibling + * or the null pointer if this is the left-most + * node at this level in the tree. + * + * f. right[x] is a pointer to the node's right + * sibling or the null pointer if this is the + * right-most node at this level in the tree. * - * 3. The keys key[x,i] partition the key spaces of the - * children of x: + * 3. The keys key[x,i] partition the key spaces of the + * children of x: * - * key[x,i] <= key[child[x,i],j] <= key[x,i+1] + * key[x,i] <= key[child[x,i],j] <= key[x,i+1] * - * for any valid combination of i and j. + * for any valid combination of i and j. * - * 4. There are lower and upper bounds on the number of - * child pointers a node can contain. These bounds - * can be expressed in terms of a fixed integer k>=2 - * called the `minimum degree' of the B-tree. + * 4. There are lower and upper bounds on the number of + * child pointers a node can contain. These bounds + * can be expressed in terms of a fixed integer k>=2 + * called the `minimum degree' of the B-tree. * - * a. Every node other than the root must have at least - * k child pointers and k+1 keys. If the tree is - * nonempty, the root must have at least one child - * pointer and two keys. + * a. Every node other than the root must have at least + * k child pointers and k+1 keys. If the tree is + * nonempty, the root must have at least one child + * pointer and two keys. * - * b. Every node can contain at most 2k child pointers - * and 2k+1 keys. A node is `full' if it contains - * exactly 2k child pointers and 2k+1 keys. + * b. Every node can contain at most 2k child pointers + * and 2k+1 keys. A node is `full' if it contains + * exactly 2k child pointers and 2k+1 keys. * - * 5. When searching for a particular value, V, and - * key[V] = key[x,i] for some node x and entry i, - * then: + * 5. When searching for a particular value, V, and + * key[V] = key[x,i] for some node x and entry i, + * then: * - * a. If i=0 the child[0] is followed. + * a. If i=0 the child[0] is followed. * - * b. If i=n[x] the child[n[x]-1] is followed. + * b. If i=n[x] the child[n[x]-1] is followed. * - * c. Otherwise, the child that is followed - * (either child[x,i-1] or child[x,i]) is - * determined by the type of object to which the - * leaf nodes of the tree point and is controlled - * by the key comparison function registered for - * that type of B-tree. + * c. Otherwise, the child that is followed + * (either child[x,i-1] or child[x,i]) is + * determined by the type of object to which the + * leaf nodes of the tree point and is controlled + * by the key comparison function registered for + * that type of B-tree. * * * Modifications: * - * Robb Matzke, 4 Aug 1997 - * Added calls to H5E. + * Robb Matzke, 4 Aug 1997 + * Added calls to H5E. * *------------------------------------------------------------------------- */ /* private headers */ -#include <H5private.h> /*library */ -#include <H5ACprivate.h> /*cache */ -#include <H5Bprivate.h> /*B-link trees */ -#include <H5Eprivate.h> /*error handling */ -#include <H5MFprivate.h> /*File memory management */ -#include <H5MMprivate.h> /*Core memory management */ +#include <H5private.h> /*library */ +#include <H5ACprivate.h> /*cache */ +#include <H5Bprivate.h> /*B-link trees */ +#include <H5Eprivate.h> /*error handling */ +#include <H5MFprivate.h> /*File memory management */ +#include <H5MMprivate.h> /*Core memory management */ -#define PABLO_MASK H5B_mask +#define PABLO_MASK H5B_mask #define BOUND(MIN,X,MAX) ((X)<(MIN)?(MIN):((X)>(MAX)?(MAX):(X))) /* PRIVATE PROTOTYPES */ -static H5B_ins_t H5B_insert_helper(H5F_t *f, const haddr_t *addr, - const H5B_class_t *type, +static H5B_ins_t H5B_insert_helper(H5F_t *f, const haddr_t *addr, + const H5B_class_t *type, uint8 *lt_key, hbool_t *lt_key_changed, - uint8 *md_key, void *udata, + uint8 *md_key, void *udata, uint8 *rt_key, hbool_t *rt_key_changed, - haddr_t *retval); -static herr_t H5B_insert_child(H5F_t *f, const H5B_class_t *type, + haddr_t *retval); +static herr_t H5B_insert_child(H5F_t *f, const H5B_class_t *type, H5B_t *bt, intn idx, const haddr_t *child, - H5B_ins_t anchor, void *md_key); -static herr_t H5B_flush(H5F_t *f, hbool_t destroy, + H5B_ins_t anchor, void *md_key); +static herr_t H5B_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5B_t *b); -static H5B_t *H5B_load(H5F_t *f, const haddr_t *addr, +static H5B_t *H5B_load(H5F_t *f, const haddr_t *addr, const void *_type, void *udata); -static herr_t H5B_decode_key(H5F_t *f, H5B_t *bt, intn idx); -static herr_t H5B_decode_keys(H5F_t *f, H5B_t *bt, intn idx); -static size_t H5B_nodesize(H5F_t *f, const H5B_class_t *type, - size_t *total_nkey_size, size_t sizeof_rkey); -static herr_t H5B_split(H5F_t *f, const H5B_class_t *type, +static herr_t H5B_decode_key(H5F_t *f, H5B_t *bt, intn idx); +static herr_t H5B_decode_keys(H5F_t *f, H5B_t *bt, intn idx); +static size_t H5B_nodesize(H5F_t *f, const H5B_class_t *type, + size_t *total_nkey_size, size_t sizeof_rkey); +static herr_t H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, const haddr_t *old_addr, void *udata, haddr_t *new_addr /*out*/ ); #ifdef H5B_DEBUG -static herr_t H5B_assert(H5F_t *f, const haddr_t *addr, - const H5B_class_t *type, void *udata); +static herr_t H5B_assert(H5F_t *f, const haddr_t *addr, + const H5B_class_t *type, void *udata); #endif /* H5B inherits cache-like properties from H5AC */ static const H5AC_class_t H5AC_BT[1] = { { - H5AC_BT_ID, - (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5B_load, - (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5B_flush, + H5AC_BT_ID, + (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5B_load, + (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5B_flush, } }; @@ -141,20 +141,20 @@ static const H5AC_class_t H5AC_BT[1] = { static hbool_t interface_initialize_g = FALSE; /*------------------------------------------------------------------------- - * Function: H5B_create + * Function: H5B_create * - * Purpose: Creates a new empty B-tree leaf node. The UDATA pointer is - * passed as an argument to the sizeof_rkey() method for the - * B-tree. + * Purpose: Creates a new empty B-tree leaf node. The UDATA pointer is + * passed as an argument to the sizeof_rkey() method for the + * B-tree. * - * Return: Success: SUCCEED, address of new node is returned - * through the RETVAL argument. + * Return: Success: SUCCEED, address of new node is returned + * through the RETVAL argument. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -163,11 +163,11 @@ static hbool_t interface_initialize_g = FALSE; herr_t H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *retval) { - H5B_t *bt = NULL; - size_t size, sizeof_rkey; - size_t total_native_keysize; - size_t offset; - intn i; + H5B_t *bt = NULL; + size_t size, sizeof_rkey; + size_t total_native_keysize; + size_t offset; + intn i; FUNC_ENTER(H5B_create, FAIL); @@ -184,8 +184,8 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *retval) sizeof_rkey = (type->get_sizeof_rkey) (f, udata); size = H5B_nodesize(f, type, &total_native_keysize, sizeof_rkey); if (H5MF_alloc(f, H5MF_META, size, retval) < 0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "can't allocate file space for B-tree root node"); + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "can't allocate file space for B-tree root node"); } bt = H5MM_xmalloc(sizeof(H5B_t)); bt->type = type; @@ -197,7 +197,7 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *retval) H5F_addr_undef(&(bt->left)); H5F_addr_undef(&(bt->right)); bt->nchildren = 0; - bt->page = H5MM_xcalloc(1, size); /*use calloc() to keep file clean */ + bt->page = H5MM_xcalloc(1, size); /*use calloc() to keep file clean */ bt->native = H5MM_xmalloc(total_native_keysize); bt->child = H5MM_xmalloc(2 * H5B_K(f, type) * sizeof(haddr_t)); bt->key = H5MM_xmalloc((2 * H5B_K(f, type) + 1) * sizeof(H5B_key_t)); @@ -208,13 +208,13 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *retval) * translated to native format. */ for (i = 0, offset = H5B_SIZEOF_HDR(f); - i < 2 * H5B_K(f, type); - i++, offset += bt->sizeof_rkey + H5F_SIZEOF_ADDR(f)) { + i < 2 * H5B_K(f, type); + i++, offset += bt->sizeof_rkey + H5F_SIZEOF_ADDR(f)) { - bt->key[i].dirty = FALSE; - bt->key[i].rkey = bt->page + offset; - bt->key[i].nkey = NULL; - H5F_addr_undef(bt->child + i); + bt->key[i].dirty = FALSE; + bt->key[i].rkey = bt->page + offset; + bt->key[i].nkey = NULL; + H5F_addr_undef(bt->child + i); } /* @@ -228,8 +228,8 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *retval) * Cache the new B-tree node. */ if (H5AC_set(f, H5AC_BT, retval, bt) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, - "can't add B-tree root node to cache"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, + "can't add B-tree root node to cache"); } #ifdef H5B_DEBUG H5B_assert(f, retval, type, udata); @@ -238,31 +238,31 @@ H5B_create(H5F_t *f, const H5B_class_t *type, void *udata, haddr_t *retval) } /*------------------------------------------------------------------------- - * Function: H5B_load + * Function: H5B_load * - * Purpose: Loads a B-tree node from the disk. + * Purpose: Loads a B-tree node from the disk. * - * Return: Success: Pointer to a new B-tree node. + * Return: Success: Pointer to a new B-tree node. * - * Failure: NULL + * Failure: NULL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * *------------------------------------------------------------------------- */ -static H5B_t * +static H5B_t * H5B_load(H5F_t *f, const haddr_t *addr, const void *_type, void *udata) { - const H5B_class_t *type = (const H5B_class_t *) _type; - size_t size, total_nkey_size; - H5B_t *bt = NULL; - intn i; - uint8 *p; - H5B_t *ret_value = NULL; + const H5B_class_t *type = (const H5B_class_t *) _type; + size_t size, total_nkey_size; + H5B_t *bt = NULL; + intn i; + uint8 *p; + H5B_t *ret_value = NULL; FUNC_ENTER(H5B_load, NULL); @@ -283,22 +283,22 @@ H5B_load(H5F_t *f, const haddr_t *addr, const void *_type, void *udata) bt->key = H5MM_xmalloc((2 * H5B_K(f, type) + 1) * sizeof(H5B_key_t)); bt->child = H5MM_xmalloc(2 * H5B_K(f, type) * sizeof(haddr_t)); if (H5F_block_read(f, addr, size, bt->page) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_READERROR, NULL, - "can't read B-tree node"); + HRETURN_ERROR(H5E_BTREE, H5E_READERROR, NULL, + "can't read B-tree node"); } p = bt->page; /* magic number */ if (HDmemcmp(p, H5B_MAGIC, H5B_SIZEOF_MAGIC)) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, - "wrong B-tree signature"); + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, + "wrong B-tree signature"); } p += 4; /* node type and level */ if (*p++ != type->id) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, - "incorrect B-tree node level"); + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, + "incorrect B-tree node level"); } bt->level = *p++; @@ -312,17 +312,17 @@ H5B_load(H5F_t *f, const haddr_t *addr, const void *_type, void *udata) /* the child/key pairs */ for (i = 0; i < 2 * H5B_K(f, type); i++) { - bt->key[i].dirty = FALSE; - bt->key[i].rkey = p; - p += bt->sizeof_rkey; - bt->key[i].nkey = NULL; - - if (i < bt->nchildren) { - H5F_addr_decode(f, (const uint8 **) &p, bt->child + i); - } else { - H5F_addr_undef(bt->child + i); - p += H5F_SIZEOF_ADDR(f); - } + bt->key[i].dirty = FALSE; + bt->key[i].rkey = p; + p += bt->sizeof_rkey; + bt->key[i].nkey = NULL; + + if (i < bt->nchildren) { + H5F_addr_decode(f, (const uint8 **) &p, bt->child + i); + } else { + H5F_addr_undef(bt->child + i); + p += H5F_SIZEOF_ADDR(f); + } } bt->key[2 * H5B_K(f, type)].dirty = FALSE; @@ -332,27 +332,27 @@ H5B_load(H5F_t *f, const haddr_t *addr, const void *_type, void *udata) done: if (!ret_value && bt) { - H5MM_xfree(bt->child); - H5MM_xfree(bt->key); - H5MM_xfree(bt->page); - H5MM_xfree(bt->native); - H5MM_xfree(bt); + H5MM_xfree(bt->child); + H5MM_xfree(bt->key); + H5MM_xfree(bt->page); + H5MM_xfree(bt->native); + H5MM_xfree(bt); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5B_flush + * Function: H5B_flush * - * Purpose: Flushes a dirty B-tree node to disk. + * Purpose: Flushes a dirty B-tree node to disk. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -361,9 +361,9 @@ H5B_load(H5F_t *f, const haddr_t *addr, const void *_type, void *udata) static herr_t H5B_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5B_t *bt) { - intn i; - size_t size = 0; - uint8 *p = bt->page; + intn i; + size_t size = 0; + uint8 *p = bt->page; FUNC_ENTER(H5B_flush, FAIL); @@ -380,89 +380,89 @@ H5B_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5B_t *bt) if (bt->dirty) { - /* magic number */ - HDmemcpy(p, H5B_MAGIC, H5B_SIZEOF_MAGIC); - p += 4; - - /* node type and level */ - *p++ = bt->type->id; - *p++ = bt->level; - - /* entries used */ - UINT16ENCODE(p, bt->nchildren); - - /* sibling pointers */ - H5F_addr_encode(f, &p, &(bt->left)); - H5F_addr_encode(f, &p, &(bt->right)); - - /* child keys and pointers */ - for (i = 0; i <= bt->nchildren; i++) { - - /* encode the key */ - assert(bt->key[i].rkey == p); - if (bt->key[i].dirty) { - if (bt->key[i].nkey) { - if ((bt->type->encode) (f, bt, bt->key[i].rkey, - bt->key[i].nkey) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, - "unable to encode B-tree key"); - } - } - bt->key[i].dirty = FALSE; - } - p += bt->sizeof_rkey; - - /* encode the child address */ - if (i < bt->ndirty) { - H5F_addr_encode(f, &p, &(bt->child[i])); - } else { - p += H5F_SIZEOF_ADDR(f); - } - } - - /* - * Write the disk page. We always write the header, but we don't - * bother writing data for the child entries that don't exist or - * for the final unchanged children. - */ - if (H5F_block_write(f, addr, size, bt->page) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, - "unable to save B-tree node to disk"); - } - bt->dirty = FALSE; - bt->ndirty = 0; + /* magic number */ + HDmemcpy(p, H5B_MAGIC, H5B_SIZEOF_MAGIC); + p += 4; + + /* node type and level */ + *p++ = bt->type->id; + *p++ = bt->level; + + /* entries used */ + UINT16ENCODE(p, bt->nchildren); + + /* sibling pointers */ + H5F_addr_encode(f, &p, &(bt->left)); + H5F_addr_encode(f, &p, &(bt->right)); + + /* child keys and pointers */ + for (i = 0; i <= bt->nchildren; i++) { + + /* encode the key */ + assert(bt->key[i].rkey == p); + if (bt->key[i].dirty) { + if (bt->key[i].nkey) { + if ((bt->type->encode) (f, bt, bt->key[i].rkey, + bt->key[i].nkey) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, + "unable to encode B-tree key"); + } + } + bt->key[i].dirty = FALSE; + } + p += bt->sizeof_rkey; + + /* encode the child address */ + if (i < bt->ndirty) { + H5F_addr_encode(f, &p, &(bt->child[i])); + } else { + p += H5F_SIZEOF_ADDR(f); + } + } + + /* + * Write the disk page. We always write the header, but we don't + * bother writing data for the child entries that don't exist or + * for the final unchanged children. + */ + if (H5F_block_write(f, addr, size, bt->page) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, + "unable to save B-tree node to disk"); + } + bt->dirty = FALSE; + bt->ndirty = 0; } if (destroy) { - H5MM_xfree(bt->child); - H5MM_xfree(bt->key); - H5MM_xfree(bt->page); - H5MM_xfree(bt->native); - H5MM_xfree(bt); + H5MM_xfree(bt->child); + H5MM_xfree(bt->key); + H5MM_xfree(bt->page); + H5MM_xfree(bt->native); + H5MM_xfree(bt); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5B_find + * Function: H5B_find * - * Purpose: Locate the specified information in a B-tree and return - * that information by filling in fields of the caller-supplied - * UDATA pointer depending on the type of leaf node - * requested. The UDATA can point to additional data passed - * to the key comparison function. + * Purpose: Locate the specified information in a B-tree and return + * that information by filling in fields of the caller-supplied + * UDATA pointer depending on the type of leaf node + * requested. The UDATA can point to additional data passed + * to the key comparison function. * - * Note: This function does not follow the left/right sibling - * pointers since it assumes that all nodes can be reached - * from the parent node. + * Note: This function does not follow the left/right sibling + * pointers since it assumes that all nodes can be reached + * from the parent node. * - * Return: Success: SUCCEED if found, values returned through the - * UDATA argument. + * Return: Success: SUCCEED if found, values returned through the + * UDATA argument. * - * Failure: FAIL if not found, UDATA is undefined. + * Failure: FAIL if not found, UDATA is undefined. * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -471,9 +471,9 @@ H5B_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5B_t *bt) herr_t H5B_find(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata) { - H5B_t *bt = NULL; - intn idx = -1, lt = 0, rt, cmp = 1; - int ret_value = FAIL; + H5B_t *bt = NULL; + intn idx = -1, lt = 0, rt, cmp = 1; + int ret_value = FAIL; FUNC_ENTER(H5B_find, FAIL); @@ -492,76 +492,76 @@ H5B_find(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata) * the thing for which we're searching. */ if (NULL == (bt = H5AC_protect(f, H5AC_BT, addr, type, udata))) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load B-tree node"); + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load B-tree node"); } rt = bt->nchildren; while (lt < rt && cmp) { - idx = (lt + rt) / 2; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, - "unable to decode B-tree key(s)"); - } - /* compare */ - if ((cmp = (type->cmp3) (f, bt->key[idx].nkey, udata, - bt->key[idx + 1].nkey)) < 0) { - rt = idx; - } else { - lt = idx + 1; - } + idx = (lt + rt) / 2; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, + "unable to decode B-tree key(s)"); + } + /* compare */ + if ((cmp = (type->cmp3) (f, bt->key[idx].nkey, udata, + bt->key[idx + 1].nkey)) < 0) { + rt = idx; + } else { + lt = idx + 1; + } } if (cmp) { - HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, - "B-tree key not found"); + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, + "B-tree key not found"); } /* * Follow the link to the subtree or to the data node. */ assert(idx >= 0 && idx < bt->nchildren); if (bt->level > 0) { - if ((ret_value = H5B_find(f, type, bt->child + idx, udata)) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, - "key not found in subtree"); - } + if ((ret_value = H5B_find(f, type, bt->child + idx, udata)) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, + "key not found in subtree"); + } } else { - ret_value = (type->found) (f, bt->child + idx, bt->key[idx].nkey, - udata, bt->key[idx + 1].nkey); - if (ret_value < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, - "key not found in leaf node"); - } + ret_value = (type->found) (f, bt->child + idx, bt->key[idx].nkey, + udata, bt->key[idx + 1].nkey); + if (ret_value < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, + "key not found in leaf node"); + } } done: if (bt && H5AC_unprotect(f, H5AC_BT, addr, bt) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, - "unable to release node"); + HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, + "unable to release node"); } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5B_split + * Function: H5B_split * - * Purpose: Split a single node into two nodes. The old node will - * contain the left children and the new node will contain the - * right children. + * Purpose: Split a single node into two nodes. The old node will + * contain the left children and the new node will contain the + * right children. * - * The UDATA pointer is passed to the sizeof_rkey() method but is - * otherwise unused. + * The UDATA pointer is passed to the sizeof_rkey() method but is + * otherwise unused. * - * The OLD_BT argument is a pointer to a protected B-tree - * node. + * The OLD_BT argument is a pointer to a protected B-tree + * node. * - * Return: Success: SUCCEED. The address of the new node is - * returned through the NEW_ADDR argument. + * Return: Success: SUCCEED. The address of the new node is + * returned through the NEW_ADDR argument. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 3 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 3 1997 * * Modifications: * @@ -569,12 +569,12 @@ H5B_find(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata) */ static herr_t H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, - const haddr_t *old_addr, void *udata, haddr_t *new_addr /*out */ ) + const haddr_t *old_addr, void *udata, haddr_t *new_addr /*out */ ) { - H5B_t *new_bt = NULL, *tmp_bt = NULL; - herr_t ret_value = FAIL; - intn i, k; - size_t recsize = 0; + H5B_t *new_bt = NULL, *tmp_bt = NULL; + herr_t ret_value = FAIL; + intn i, k; + size_t recsize = 0; FUNC_ENTER(H5B_split, FAIL); @@ -596,12 +596,12 @@ H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, * Create the new B-tree node. */ if (H5B_create(f, type, udata, new_addr /*out */ ) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, - "unable to create B-tree"); + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, + "unable to create B-tree"); } if (NULL == (new_bt = H5AC_protect(f, H5AC_BT, new_addr, type, udata))) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to protect B-tree"); + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to protect B-tree"); } new_bt->level = old_bt->level; @@ -609,22 +609,22 @@ H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, * Copy data from the old node to the new node. */ HDmemcpy(new_bt->page + H5B_SIZEOF_HDR(f), - old_bt->page + H5B_SIZEOF_HDR(f) + k * recsize, - k * recsize + new_bt->sizeof_rkey); + old_bt->page + H5B_SIZEOF_HDR(f) + k * recsize, + k * recsize + new_bt->sizeof_rkey); HDmemcpy(new_bt->native, - old_bt->native + k * type->sizeof_nkey, - (k + 1) * type->sizeof_nkey); + old_bt->native + k * type->sizeof_nkey, + (k + 1) * type->sizeof_nkey); for (i = 0; i <= k; i++) { - /* key */ - new_bt->key[i].dirty = old_bt->key[k + i].dirty; - if (old_bt->key[k + i].nkey) { - new_bt->key[i].nkey = new_bt->native + i * type->sizeof_nkey; - } - /* child */ - if (i < k) { - new_bt->child[i] = old_bt->child[k + i]; - } + /* key */ + new_bt->key[i].dirty = old_bt->key[k + i].dirty; + if (old_bt->key[k + i].nkey) { + new_bt->key[i].nkey = new_bt->native + i * type->sizeof_nkey; + } + /* child */ + if (i < k) { + new_bt->child[i] = old_bt->child[k + i]; + } } new_bt->ndirty = new_bt->nchildren = k; @@ -641,13 +641,13 @@ H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, new_bt->right = old_bt->right; if (H5F_addr_defined(&(old_bt->right))) { - if (NULL == (tmp_bt = H5AC_find(f, H5AC_BT, &(old_bt->right), type, - udata))) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load right sibling"); - } - tmp_bt->dirty = TRUE; - tmp_bt->left = *new_addr; + if (NULL == (tmp_bt = H5AC_find(f, H5AC_BT, &(old_bt->right), type, + udata))) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load right sibling"); + } + tmp_bt->dirty = TRUE; + tmp_bt->left = *new_addr; } old_bt->right = *new_addr; @@ -655,26 +655,26 @@ H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt, done: { - if (new_bt && H5AC_unprotect(f, H5AC_BT, new_addr, new_bt) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, - "unable to release B-tree node"); - } + if (new_bt && H5AC_unprotect(f, H5AC_BT, new_addr, new_bt) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, + "unable to release B-tree node"); + } } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5B_decode_key + * Function: H5B_decode_key * - * Purpose: Decode the specified key into native format. + * Purpose: Decode the specified key into native format. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 8 1997 * * Modifications: * @@ -687,24 +687,24 @@ H5B_decode_key(H5F_t *f, H5B_t *bt, intn idx) bt->key[idx].nkey = bt->native + idx * bt->type->sizeof_nkey; if ((bt->type->decode) (f, bt, bt->key[idx].rkey, - bt->key[idx].nkey) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, - "unable to decode key"); + bt->key[idx].nkey) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, + "unable to decode key"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5B_decode_keys + * Function: H5B_decode_keys * - * Purpose: Decode keys on either side of the specified branch. + * Purpose: Decode keys on either side of the specified branch. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, October 14, 1997 + * Programmer: Robb Matzke + * Tuesday, October 14, 1997 * * Modifications: * @@ -720,29 +720,29 @@ H5B_decode_keys(H5F_t *f, H5B_t *bt, intn idx) assert(idx >= 0 && idx < bt->nchildren); if (!bt->key[idx].nkey && H5B_decode_key(f, bt, idx) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, - "unable to decode key"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, + "unable to decode key"); } if (!bt->key[idx + 1].nkey && H5B_decode_key(f, bt, idx + 1) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, - "unable to decode key"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, + "unable to decode key"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5B_insert + * Function: H5B_insert * - * Purpose: Adds a new item to the B-tree. If the root node of - * the B-tree splits then the B-tree gets a new address. + * Purpose: Adds a new item to the B-tree. If the root node of + * the B-tree splits then the B-tree gets a new address. * - * Return: Success: SUCCEED. + * Return: Success: SUCCEED. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * @@ -750,7 +750,7 @@ H5B_decode_keys(H5F_t *f, H5B_t *bt, intn idx) */ herr_t H5B_insert(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, - void *udata) + void *udata) { /* * These are defined this way to satisfy alignment constraints. @@ -760,13 +760,13 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, uint8 *md_key=(uint8*)_md_key; uint8 *rt_key=(uint8*)_rt_key; - hbool_t lt_key_changed = FALSE, rt_key_changed = FALSE; - haddr_t child, old_root; - intn level; - H5B_t *bt; - size_t size; - uint8 *buf; - H5B_ins_t my_ins = H5B_INS_ERROR; + hbool_t lt_key_changed = FALSE, rt_key_changed = FALSE; + haddr_t child, old_root; + intn level; + H5B_t *bt; + size_t size; + uint8 *buf; + H5B_ins_t my_ins = H5B_INS_ERROR; FUNC_ENTER(H5B_insert, FAIL); @@ -779,82 +779,82 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, assert(addr && H5F_addr_defined(addr)); if ((my_ins = H5B_insert_helper(f, addr, type, lt_key, <_key_changed, - md_key, udata, rt_key, &rt_key_changed, - &child/*out*/ )) < 0 || my_ins < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, - "unable to insert key"); + md_key, udata, rt_key, &rt_key_changed, + &child/*out*/ )) < 0 || my_ins < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, + "unable to insert key"); } if (H5B_INS_NOOP == my_ins) - HRETURN(SUCCEED); + HRETURN(SUCCEED); assert(H5B_INS_RIGHT == my_ins); /* the current root */ if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to locate root of B-tree"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to locate root of B-tree"); } level = bt->level; if (!lt_key_changed) { - if (!bt->key[0].nkey && H5B_decode_key(f, bt, 0) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, - "unable to decode key"); - } - HDmemcpy(lt_key, bt->key[0].nkey, type->sizeof_nkey); + if (!bt->key[0].nkey && H5B_decode_key(f, bt, 0) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, + "unable to decode key"); + } + HDmemcpy(lt_key, bt->key[0].nkey, type->sizeof_nkey); } /* the new node */ if (NULL == (bt = H5AC_find(f, H5AC_BT, &child, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load new node"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load new node"); } if (!rt_key_changed) { - if (!bt->key[bt->nchildren].nkey && - H5B_decode_key(f, bt, bt->nchildren) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, - "unable to decode key"); - } - HDmemcpy(rt_key, bt->key[bt->nchildren].nkey, type->sizeof_nkey); + if (!bt->key[bt->nchildren].nkey && + H5B_decode_key(f, bt, bt->nchildren) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, + "unable to decode key"); + } + HDmemcpy(rt_key, bt->key[bt->nchildren].nkey, type->sizeof_nkey); } /* * Copy the old root node to some other file location and make the new - * root at the old root's previous address. This prevents the B-tree + * root at the old root's previous address. This prevents the B-tree * from "moving". */ size = H5B_nodesize(f, type, NULL, bt->sizeof_rkey); buf = H5MM_xmalloc(size); if (H5MF_alloc(f, H5MF_META, size, &old_root /*out */ ) < 0) { - HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, - "unable to allocate file space to move root"); + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "unable to allocate file space to move root"); } if (H5AC_flush(f, H5AC_BT, addr, FALSE) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, - "unable to flush B-tree root node"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, + "unable to flush B-tree root node"); } if (H5F_block_read(f, addr, size, buf) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_READERROR, FAIL, - "unable to read B-tree root node"); + HRETURN_ERROR(H5E_BTREE, H5E_READERROR, FAIL, + "unable to read B-tree root node"); } if (H5F_block_write(f, &old_root, size, buf) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_WRITEERROR, FAIL, - "unable to move B-tree root node"); + HRETURN_ERROR(H5E_BTREE, H5E_WRITEERROR, FAIL, + "unable to move B-tree root node"); } if (H5AC_rename(f, H5AC_BT, addr, &old_root) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, - "unable to move B-tree root node"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, + "unable to move B-tree root node"); } buf = H5MM_xfree(buf); /* update the new child's left pointer */ if (NULL == (bt = H5AC_find(f, H5AC_BT, &child, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load new child"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load new child"); } bt->dirty = TRUE; bt->left = old_root; /* clear the old root at the old address (we already copied it) */ if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to clear old root location"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to clear old root location"); } bt->dirty = TRUE; bt->ndirty = 0; @@ -864,8 +864,8 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, /* the new root */ if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load new root"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load new root"); } bt->dirty = TRUE; bt->ndirty = 2; @@ -893,19 +893,19 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, } /*------------------------------------------------------------------------- - * Function: H5B_insert_child + * Function: H5B_insert_child * - * Purpose: Insert a child at the specified address with the - * specified left or right key. The BT argument is a pointer - * to a protected B-tree node. + * Purpose: Insert a child at the specified address with the + * specified left or right key. The BT argument is a pointer + * to a protected B-tree node. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 8 1997 * * Modifications: * @@ -913,11 +913,11 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, */ static herr_t H5B_insert_child(H5F_t *f, const H5B_class_t *type, H5B_t *bt, - intn idx, const haddr_t *child, H5B_ins_t anchor, - void *md_key) + intn idx, const haddr_t *child, H5B_ins_t anchor, + void *md_key) { - size_t recsize; - intn i; + size_t recsize; + intn i; FUNC_ENTER(H5B_insert_child, FAIL); assert(bt); @@ -927,59 +927,59 @@ H5B_insert_child(H5F_t *f, const H5B_class_t *type, H5B_t *bt, recsize = bt->sizeof_rkey + H5F_SIZEOF_ADDR(f); if (H5B_INS_RIGHT == anchor) { - /* - * The MD_KEY is the left key of the new node. - */ - HDmemmove(bt->page + H5B_SIZEOF_HDR(f) + (idx + 1) * recsize, - bt->page + H5B_SIZEOF_HDR(f) + idx * recsize, - (bt->nchildren - idx) * recsize + bt->sizeof_rkey); - - HDmemmove(bt->native + (idx + 1) * type->sizeof_nkey, - bt->native + idx * type->sizeof_nkey, - ((bt->nchildren - idx) + 1) * type->sizeof_nkey); - - for (i = bt->nchildren; i >= idx; --i) { - bt->key[i + 1].dirty = bt->key[i].dirty; - if (bt->key[i].nkey) { - bt->key[i + 1].nkey = bt->native + (i + 1) * type->sizeof_nkey; - } else { - bt->key[i + 1].nkey = NULL; - } - } - bt->key[idx].dirty = TRUE; - bt->key[idx].nkey = bt->native + idx * type->sizeof_nkey; - HDmemcpy(bt->key[idx].nkey, md_key, type->sizeof_nkey); + /* + * The MD_KEY is the left key of the new node. + */ + HDmemmove(bt->page + H5B_SIZEOF_HDR(f) + (idx + 1) * recsize, + bt->page + H5B_SIZEOF_HDR(f) + idx * recsize, + (bt->nchildren - idx) * recsize + bt->sizeof_rkey); + + HDmemmove(bt->native + (idx + 1) * type->sizeof_nkey, + bt->native + idx * type->sizeof_nkey, + ((bt->nchildren - idx) + 1) * type->sizeof_nkey); + + for (i = bt->nchildren; i >= idx; --i) { + bt->key[i + 1].dirty = bt->key[i].dirty; + if (bt->key[i].nkey) { + bt->key[i + 1].nkey = bt->native + (i + 1) * type->sizeof_nkey; + } else { + bt->key[i + 1].nkey = NULL; + } + } + bt->key[idx].dirty = TRUE; + bt->key[idx].nkey = bt->native + idx * type->sizeof_nkey; + HDmemcpy(bt->key[idx].nkey, md_key, type->sizeof_nkey); } else { - /* - * The MD_KEY is the right key of the new node. - */ - HDmemmove(bt->page + (H5B_SIZEOF_HDR(f) + - (idx + 1) * recsize + bt->sizeof_rkey), - bt->page + (H5B_SIZEOF_HDR(f) + - idx * recsize + bt->sizeof_rkey), - (bt->nchildren - idx) * recsize); - - HDmemmove(bt->native + (idx + 2) * type->sizeof_nkey, - bt->native + (idx + 1) * type->sizeof_nkey, - (bt->nchildren - idx) * type->sizeof_nkey); - - for (i = bt->nchildren; i > idx; --i) { - bt->key[i + 1].dirty = bt->key[i].dirty; - if (bt->key[i].nkey) { - bt->key[i + 1].nkey = bt->native + (i + 1) * type->sizeof_nkey; - } else { - bt->key[i + 1].nkey = NULL; - } - } - bt->key[idx + 1].dirty = TRUE; - bt->key[idx + 1].nkey = bt->native + (idx + 1) * type->sizeof_nkey; - HDmemcpy(bt->key[idx + 1].nkey, md_key, type->sizeof_nkey); + /* + * The MD_KEY is the right key of the new node. + */ + HDmemmove(bt->page + (H5B_SIZEOF_HDR(f) + + (idx + 1) * recsize + bt->sizeof_rkey), + bt->page + (H5B_SIZEOF_HDR(f) + + idx * recsize + bt->sizeof_rkey), + (bt->nchildren - idx) * recsize); + + HDmemmove(bt->native + (idx + 2) * type->sizeof_nkey, + bt->native + (idx + 1) * type->sizeof_nkey, + (bt->nchildren - idx) * type->sizeof_nkey); + + for (i = bt->nchildren; i > idx; --i) { + bt->key[i + 1].dirty = bt->key[i].dirty; + if (bt->key[i].nkey) { + bt->key[i + 1].nkey = bt->native + (i + 1) * type->sizeof_nkey; + } else { + bt->key[i + 1].nkey = NULL; + } + } + bt->key[idx + 1].dirty = TRUE; + bt->key[idx + 1].nkey = bt->native + (idx + 1) * type->sizeof_nkey; + HDmemcpy(bt->key[idx + 1].nkey, md_key, type->sizeof_nkey); } HDmemmove(bt->child + idx + 1, - bt->child + idx, - (bt->nchildren - idx) * sizeof(haddr_t)); + bt->child + idx, + (bt->nchildren - idx) * sizeof(haddr_t)); bt->child[idx] = *child; bt->nchildren += 1; @@ -989,30 +989,30 @@ H5B_insert_child(H5F_t *f, const H5B_class_t *type, H5B_t *bt, } /*------------------------------------------------------------------------- - * Function: H5B_insert_helper + * Function: H5B_insert_helper * - * Purpose: Inserts the item UDATA into the tree rooted at ADDR and having - * the specified type. + * Purpose: Inserts the item UDATA into the tree rooted at ADDR and having + * the specified type. * - * On return, if LT_KEY_CHANGED is non-zero, then LT_KEY is - * the new native left key. Similarily for RT_KEY_CHANGED - * and RT_KEY. + * On return, if LT_KEY_CHANGED is non-zero, then LT_KEY is + * the new native left key. Similarily for RT_KEY_CHANGED + * and RT_KEY. * - * If the node splits, then MD_KEY contains the key that - * was split between the two nodes (that is, the key that - * appears as the max key in the left node and the min key - * in the right node). + * If the node splits, then MD_KEY contains the key that + * was split between the two nodes (that is, the key that + * appears as the max key in the left node and the min key + * in the right node). * - * Return: Success: A B-tree operation. The address of the new - * node, if the node splits, is returned through - * the NEW_NODE argument. The new node is always - * to the right of the previous node. + * Return: Success: A B-tree operation. The address of the new + * node, if the node splits, is returned through + * the NEW_NODE argument. The new node is always + * to the right of the previous node. * - * Failure: H5B_INS_ERROR + * Failure: H5B_INS_ERROR * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 9 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 9 1997 * * Modifications: * @@ -1020,16 +1020,16 @@ H5B_insert_child(H5F_t *f, const H5B_class_t *type, H5B_t *bt, */ static H5B_ins_t H5B_insert_helper(H5F_t *f, const haddr_t *addr, const H5B_class_t *type, - uint8 *lt_key, hbool_t *lt_key_changed, - uint8 *md_key, void *udata, - uint8 *rt_key, hbool_t *rt_key_changed, - haddr_t *new_node /*out */ ) + uint8 *lt_key, hbool_t *lt_key_changed, + uint8 *md_key, void *udata, + uint8 *rt_key, hbool_t *rt_key_changed, + haddr_t *new_node /*out */ ) { - H5B_t *bt = NULL, *twin = NULL, *tmp_bt = NULL; - intn lt = 0, idx = -1, rt, cmp = -1; - haddr_t child_addr; - H5B_ins_t my_ins = H5B_INS_ERROR; - H5B_ins_t ret_value = H5B_INS_ERROR; + H5B_t *bt = NULL, *twin = NULL, *tmp_bt = NULL; + intn lt = 0, idx = -1, rt, cmp = -1; + haddr_t child_addr; + H5B_ins_t my_ins = H5B_INS_ERROR; + H5B_ins_t ret_value = H5B_INS_ERROR; FUNC_ENTER(H5B_insert_helper, H5B_INS_ERROR); @@ -1057,206 +1057,206 @@ H5B_insert_helper(H5F_t *f, const haddr_t *addr, const H5B_class_t *type, * should get the new data. */ if (NULL == (bt = H5AC_protect(f, H5AC_BT, addr, type, udata))) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, - "unable to load node"); + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, + "unable to load node"); } rt = bt->nchildren; while (lt < rt && cmp) { - idx = (lt + rt) / 2; - if (H5B_decode_keys(f, bt, idx) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - if ((cmp = (type->cmp3) (f, bt->key[idx].nkey, udata, - bt->key[idx + 1].nkey)) < 0) { - rt = idx; - } else { - lt = idx + 1; - } + idx = (lt + rt) / 2; + if (H5B_decode_keys(f, bt, idx) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + if ((cmp = (type->cmp3) (f, bt->key[idx].nkey, udata, + bt->key[idx + 1].nkey)) < 0) { + rt = idx; + } else { + lt = idx + 1; + } } if (0 == bt->nchildren) { - /* - * The value being inserted will be the only value in this tree. We - * must necessarily be at level zero. - */ - assert(0 == bt->level); - bt->key[0].nkey = bt->native; - bt->key[1].nkey = bt->native + type->sizeof_nkey; - if ((type->new_node) (f, H5B_INS_FIRST, bt->key[0].nkey, udata, + /* + * The value being inserted will be the only value in this tree. We + * must necessarily be at level zero. + */ + assert(0 == bt->level); + bt->key[0].nkey = bt->native; + bt->key[1].nkey = bt->native + type->sizeof_nkey; + if ((type->new_node) (f, H5B_INS_FIRST, bt->key[0].nkey, udata, bt->key[1].nkey, bt->child + 0/*out*/) < 0) { - bt->key[0].nkey = bt->key[1].nkey = NULL; - HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, H5B_INS_ERROR, - "unable to create leaf node"); - } - bt->nchildren = 1; - bt->dirty = TRUE; - bt->ndirty = 1; - bt->key[0].dirty = TRUE; - bt->key[1].dirty = TRUE; - idx = 0; - - if (type->follow_min) { - if ((my_ins = (type->insert) (f, bt->child + idx, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr/*out*/)) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "unable to insert first leaf node"); - } - } else { - my_ins = H5B_INS_NOOP; - } + bt->key[0].nkey = bt->key[1].nkey = NULL; + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, H5B_INS_ERROR, + "unable to create leaf node"); + } + bt->nchildren = 1; + bt->dirty = TRUE; + bt->ndirty = 1; + bt->key[0].dirty = TRUE; + bt->key[1].dirty = TRUE; + idx = 0; + + if (type->follow_min) { + if ((my_ins = (type->insert) (f, bt->child + idx, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr/*out*/)) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "unable to insert first leaf node"); + } + } else { + my_ins = H5B_INS_NOOP; + } } else if (cmp < 0 && idx <= 0 && bt->level > 0) { - /* + /* * The value being inserted is less than any value in this tree. * Follow the minimum branch out of this node to a subtree. - */ - idx = 0; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - if ((my_ins = H5B_insert_helper(f, bt->child + idx, type, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr /*out */ )) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert minimum subtree"); - } + */ + idx = 0; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + if ((my_ins = H5B_insert_helper(f, bt->child + idx, type, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr /*out */ )) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert minimum subtree"); + } } else if (cmp < 0 && idx <= 0 && type->follow_min) { - /* - * The value being inserted is less than any leaf node out of this - * current node. Follow the minimum branch to a leaf node and let the - * subclass handle the problem. - */ - idx = 0; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - if ((my_ins = (type->insert) (f, bt->child + idx, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr /*out */ )) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert minimum leaf node"); - } + /* + * The value being inserted is less than any leaf node out of this + * current node. Follow the minimum branch to a leaf node and let the + * subclass handle the problem. + */ + idx = 0; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + if ((my_ins = (type->insert) (f, bt->child + idx, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr /*out */ )) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert minimum leaf node"); + } } else if (cmp < 0 && idx <= 0) { - /* - * The value being inserted is less than any leaf node out of the - * current node. Create a new minimum leaf node out of this B-tree - * node. This node is not empty (handled above). - */ - idx = 0; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - my_ins = H5B_INS_LEFT; - HDmemcpy(md_key, bt->key[idx].nkey, type->sizeof_nkey); - if ((type->new_node) (f, H5B_INS_LEFT, bt->key[idx].nkey, udata, + /* + * The value being inserted is less than any leaf node out of the + * current node. Create a new minimum leaf node out of this B-tree + * node. This node is not empty (handled above). + */ + idx = 0; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + my_ins = H5B_INS_LEFT; + HDmemcpy(md_key, bt->key[idx].nkey, type->sizeof_nkey); + if ((type->new_node) (f, H5B_INS_LEFT, bt->key[idx].nkey, udata, md_key, &child_addr/*out*/) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert minimum leaf node"); - } - *lt_key_changed = TRUE; + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert minimum leaf node"); + } + *lt_key_changed = TRUE; } else if (cmp > 0 && idx + 1 >= bt->nchildren && bt->level > 0) { - /* - * The value being inserted is larger than any value in this tree. - * Follow the maximum branch out of this node to a subtree. - */ - idx = bt->nchildren - 1; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - if ((my_ins = H5B_insert_helper(f, bt->child + idx, type, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr /*out */ )) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert maximum subtree"); - } + /* + * The value being inserted is larger than any value in this tree. + * Follow the maximum branch out of this node to a subtree. + */ + idx = bt->nchildren - 1; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + if ((my_ins = H5B_insert_helper(f, bt->child + idx, type, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr /*out */ )) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert maximum subtree"); + } } else if (cmp > 0 && idx + 1 >= bt->nchildren && type->follow_max) { - /* - * The value being inserted is larger than any leaf node out of the - * current node. Follow the maximum branch to a leaf node and let the - * subclass handle the problem. - */ - idx = bt->nchildren - 1; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - if ((my_ins = (type->insert) (f, bt->child + idx, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr /*out */ )) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert maximum leaf node"); - } + /* + * The value being inserted is larger than any leaf node out of the + * current node. Follow the maximum branch to a leaf node and let the + * subclass handle the problem. + */ + idx = bt->nchildren - 1; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + if ((my_ins = (type->insert) (f, bt->child + idx, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr /*out */ )) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert maximum leaf node"); + } } else if (cmp > 0 && idx + 1 >= bt->nchildren) { - /* - * The value being inserted is larger than any leaf node out of the - * current node. Create a new maximum leaf node out of this B-tree - * node. - */ - idx = bt->nchildren - 1; - if (H5B_decode_keys(f, bt, idx) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - my_ins = H5B_INS_RIGHT; - HDmemcpy(md_key, bt->key[idx + 1].nkey, type->sizeof_nkey); - if ((type->new_node) (f, H5B_INS_RIGHT, md_key, udata, + /* + * The value being inserted is larger than any leaf node out of the + * current node. Create a new maximum leaf node out of this B-tree + * node. + */ + idx = bt->nchildren - 1; + if (H5B_decode_keys(f, bt, idx) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + my_ins = H5B_INS_RIGHT; + HDmemcpy(md_key, bt->key[idx + 1].nkey, type->sizeof_nkey); + if ((type->new_node) (f, H5B_INS_RIGHT, md_key, udata, bt->key[idx + 1].nkey, &child_addr/*out*/) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert maximum leaf node"); - } - *rt_key_changed = TRUE; + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert maximum leaf node"); + } + *rt_key_changed = TRUE; } else if (cmp) { - /* - * We couldn't figure out which branch to follow out of this node. THIS - * IS A MAJOR PROBLEM THAT NEEDS TO BE FIXED --rpm. - */ - assert("INTERNAL HDF5 ERROR (see rpm)" && 0); + /* + * We couldn't figure out which branch to follow out of this node. THIS + * IS A MAJOR PROBLEM THAT NEEDS TO BE FIXED --rpm. + */ + assert("INTERNAL HDF5 ERROR (see rpm)" && 0); } else if (bt->level > 0) { - /* - * Follow a branch out of this node to another subtree. - */ - assert(idx >= 0 && idx < bt->nchildren); - if ((my_ins = H5B_insert_helper(f, bt->child + idx, type, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr /*out */ )) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert subtree"); - } + /* + * Follow a branch out of this node to another subtree. + */ + assert(idx >= 0 && idx < bt->nchildren); + if ((my_ins = H5B_insert_helper(f, bt->child + idx, type, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr /*out */ )) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert subtree"); + } } else { - /* - * Follow a branch out of this node to a leaf node of some other type. - */ - assert(idx >= 0 && idx < bt->nchildren); - if ((my_ins = (type->insert) (f, bt->child + idx, - bt->key[idx].nkey, lt_key_changed, - md_key, udata, - bt->key[idx + 1].nkey, rt_key_changed, - &child_addr /*out */ )) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert leaf node"); - } + /* + * Follow a branch out of this node to a leaf node of some other type. + */ + assert(idx >= 0 && idx < bt->nchildren); + if ((my_ins = (type->insert) (f, bt->child + idx, + bt->key[idx].nkey, lt_key_changed, + md_key, udata, + bt->key[idx + 1].nkey, rt_key_changed, + &child_addr /*out */ )) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert leaf node"); + } } assert(my_ins >= 0); @@ -1264,136 +1264,138 @@ H5B_insert_helper(H5F_t *f, const haddr_t *addr, const H5B_class_t *type, * Update the left and right keys of the current node. */ if (*lt_key_changed) { - bt->dirty = TRUE; - bt->key[idx].dirty = TRUE; - if (idx > 0) { - *lt_key_changed = FALSE; - } else { - HDmemcpy(lt_key, bt->key[idx].nkey, type->sizeof_nkey); - } + bt->dirty = TRUE; + bt->key[idx].dirty = TRUE; + if (idx > 0) { + *lt_key_changed = FALSE; + } else { + HDmemcpy(lt_key, bt->key[idx].nkey, type->sizeof_nkey); + } } if (*rt_key_changed) { - bt->dirty = TRUE; - bt->key[idx + 1].dirty = TRUE; - if (idx + 1 < bt->nchildren) { - *rt_key_changed = FALSE; - } else { - HDmemcpy(rt_key, bt->key[idx + 1].nkey, type->sizeof_nkey); - } + bt->dirty = TRUE; + bt->key[idx + 1].dirty = TRUE; + if (idx + 1 < bt->nchildren) { + *rt_key_changed = FALSE; + } else { + HDmemcpy(rt_key, bt->key[idx + 1].nkey, type->sizeof_nkey); + } } if (H5B_INS_CHANGE == my_ins) { - /* - * The insertion simply changed the address for the child. - */ - bt->child[idx] = child_addr; - bt->dirty = TRUE; - bt->ndirty = MAX(bt->ndirty, idx + 1); - ret_value = H5B_INS_NOOP; + /* + * The insertion simply changed the address for the child. + */ + bt->child[idx] = child_addr; + bt->dirty = TRUE; + bt->ndirty = MAX(bt->ndirty, idx + 1); + ret_value = H5B_INS_NOOP; } else if (H5B_INS_LEFT == my_ins || H5B_INS_RIGHT == my_ins) { - /* Make sure IDX is the slot number for the new node. */ - if (H5B_INS_RIGHT == my_ins) - idx++; + /* Make sure IDX is the slot number for the new node. */ + if (H5B_INS_RIGHT == my_ins) + idx++; - /* + /* * If this node is full then split it before inserting the new child. */ - if (bt->nchildren == 2 * H5B_K(f, type)) { - if (H5B_split(f, type, bt, addr, udata, new_node /*out */ ) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, H5B_INS_ERROR, - "can't split node"); - } - if (NULL == (twin = H5AC_protect(f, H5AC_BT, new_node, type, + if (bt->nchildren == 2 * H5B_K(f, type)) { + if (H5B_split(f, type, bt, addr, udata, new_node /*out */ ) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, H5B_INS_ERROR, + "can't split node"); + } + if (NULL == (twin = H5AC_protect(f, H5AC_BT, new_node, type, udata))) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, - "can't load B-tree"); - } - if (idx <= H5B_K(f, type)) { - tmp_bt = bt; - } else { - idx -= H5B_K(f, type); - tmp_bt = twin; - } - } else { - tmp_bt = bt; - } - - /* Insert the child */ - if (H5B_insert_child(f, type, tmp_bt, idx, &child_addr, my_ins, - md_key) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, - "can't insert child"); - } + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, + "can't load B-tree"); + } + if (idx <= H5B_K(f, type)) { + tmp_bt = bt; + } else { + idx -= H5B_K(f, type); + tmp_bt = twin; + } + } else { + tmp_bt = bt; + } + + /* Insert the child */ + if (H5B_insert_child(f, type, tmp_bt, idx, &child_addr, my_ins, + md_key) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, + "can't insert child"); + } } /* * If this node split, return the mid key (the one that is shared * by the left and right node). */ if (twin) { - if (!twin->key[0].nkey && H5B_decode_key(f, twin, 0) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, - "unable to decode key"); - } - HDmemcpy(md_key, twin->key[0].nkey, type->sizeof_nkey); - ret_value = H5B_INS_RIGHT; + if (!twin->key[0].nkey && H5B_decode_key(f, twin, 0) < 0) { + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, + "unable to decode key"); + } + HDmemcpy(md_key, twin->key[0].nkey, type->sizeof_nkey); + ret_value = H5B_INS_RIGHT; #ifdef H5B_DEBUG - /* - * The max key in the original left node must be equal to the min key - * in the new node. - */ - if (!bt->key[bt->nchildren].nkey) { - herr_t status = H5B_decode_key(f, bt, bt->nchildren); - assert(status >= 0); - } - cmp = (type->cmp2) (f, bt->key[bt->nchildren].nkey, udata, - twin->key[0].nkey); - assert(0 == cmp); + /* + * The max key in the original left node must be equal to the min key + * in the new node. + */ + if (!bt->key[bt->nchildren].nkey) { + herr_t status = H5B_decode_key(f, bt, bt->nchildren); + assert(status >= 0); + } + cmp = (type->cmp2) (f, bt->key[bt->nchildren].nkey, udata, + twin->key[0].nkey); + assert(0 == cmp); #endif } else { - ret_value = H5B_INS_NOOP; + ret_value = H5B_INS_NOOP; } done: { - herr_t e1 = (bt && H5AC_unprotect(f, H5AC_BT, addr, bt) < 0); - herr_t e2 = (twin && H5AC_unprotect(f, H5AC_BT, new_node, twin) < 0); - if (e1 || e2) { /*use vars to prevent short-circuit of side effects */ - HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, H5B_INS_ERROR, - "unable to release node(s)"); - } + herr_t e1 = (bt && H5AC_unprotect(f, H5AC_BT, addr, bt) < 0); + herr_t e2 = (twin && H5AC_unprotect(f, H5AC_BT, new_node, twin) < 0); + if (e1 || e2) { /*use vars to prevent short-circuit of side effects */ + HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, H5B_INS_ERROR, + "unable to release node(s)"); + } } FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- - * Function: H5B_list + * Function: H5B_iterate * - * Purpose: Calls the list callback for each leaf node of the - * B-tree, passing it the UDATA structure. + * Purpose: Calls the list callback for each leaf node of the + * B-tree, passing it the UDATA structure. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jun 23 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jun 23 1997 * * Modifications: * *------------------------------------------------------------------------- */ herr_t -H5B_list(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata) +H5B_iterate (H5F_t *f, const H5B_class_t *type, const haddr_t *addr, + void *udata) { - H5B_t *bt = NULL; - haddr_t next_addr; - const haddr_t *cur_addr = NULL; - intn i; - herr_t ret_value = FAIL; + H5B_t *bt = NULL; + haddr_t next_addr; + const haddr_t *cur_addr = NULL; + haddr_t *child = NULL; + intn i, nchildren; + herr_t ret_value = FAIL; - FUNC_ENTER(H5B_list, FAIL); + FUNC_ENTER(H5B_iterate, FAIL); /* * Check arguments. @@ -1405,69 +1407,76 @@ H5B_list(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata) assert(udata); if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load B-tree node"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load B-tree node"); } if (bt->level > 0) { - if (H5B_list(f, type, bt->child + 0, udata) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, - "unable to list B-tree node"); - } else { - HRETURN(SUCCEED); - } + /* Keep following the left-most child until we reach a leaf node. */ + if (H5B_iterate(f, type, bt->child + 0, udata) < 0) { + HRETURN_ERROR(H5E_BTREE, H5E_CANTLIST, FAIL, + "unable to list B-tree node"); + } else { + HRETURN(SUCCEED); + } } else { - - for (cur_addr = addr; - !H5F_addr_defined(cur_addr); - cur_addr = &next_addr) { - if (NULL == (bt = H5AC_protect(f, H5AC_BT, cur_addr, type, - udata))) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to protect B-tree node"); - } - for (i = 0; i < bt->nchildren; i++) { - if ((type->list) (f, bt->child + i, udata) < 0) { - HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to list leaf node"); - } - } - - next_addr = bt->right; - if (H5AC_unprotect(f, H5AC_BT, addr, bt) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, - "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. + */ + child = H5MM_xmalloc (2*H5B_K(f,type)*sizeof(haddr_t)); + for (cur_addr=addr, ret_value=0; + H5F_addr_defined(cur_addr); + cur_addr=&next_addr) { + + /* + * Save all the child addresses since we can't leave the B-tree + * node protected during an application callback. + */ + if (NULL==(bt=H5AC_find (f, H5AC_BT, cur_addr, type, udata))) { + HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node"); + } + child = H5MM_xmalloc (bt->nchildren*sizeof(haddr_t)); + for (i=0; i<bt->nchildren; i++) { + child[i] = bt->child[i]; + } + next_addr = bt->right; + nchildren = bt->nchildren; + bt = NULL; + + /* + * Perform the iteration operator, which might invoke an + * application callback. + */ + for (i=0, ret_value=0; i<nchildren && !ret_value; i++) { + ret_value = (type->list)(f, child+i, udata); + } + } + H5MM_xfree (child); } - HGOTO_DONE(SUCCEED); done: - if (bt && H5AC_unprotect(f, H5AC_BT, cur_addr, bt) < 0) { - HRETURN_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, - "unable to release B-tree node"); - } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5B_nodesize + * 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. + * 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. * - * 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. + * 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. * - * Return: Success: Size of node in file. + * Return: Success: Size of node in file. * - * Failure: 0 + * Failure: 0 * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 3 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Jul 3 1997 * * Modifications: * @@ -1475,9 +1484,9 @@ H5B_list(H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata) */ static size_t H5B_nodesize(H5F_t *f, const H5B_class_t *type, - size_t *total_nkey_size, size_t sizeof_rkey) + size_t *total_nkey_size, size_t sizeof_rkey) { - size_t size; + size_t size; FUNC_ENTER(H5B_nodesize, (size_t) 0); @@ -1493,30 +1502,30 @@ H5B_nodesize(H5F_t *f, const H5B_class_t *type, * Total native key size. */ if (total_nkey_size) { - *total_nkey_size = (2 * H5B_K(f, type) + 1) * type->sizeof_nkey; + *total_nkey_size = (2 * H5B_K(f, type) + 1) * type->sizeof_nkey; } /* * Total node size. */ - size = (H5B_SIZEOF_HDR(f) + /*node header */ - 2 * H5B_K(f, type) * H5F_SIZEOF_ADDR(f) + /*child pointers */ - (2 * H5B_K(f, type) + 1) * sizeof_rkey); /*keys */ + size = (H5B_SIZEOF_HDR(f) + /*node header */ + 2 * H5B_K(f, type) * H5F_SIZEOF_ADDR(f) + /*child pointers */ + (2 * H5B_K(f, type) + 1) * sizeof_rkey); /*keys */ FUNC_LEAVE(size); } /*------------------------------------------------------------------------- - * Function: H5B_debug + * Function: H5B_debug * - * Purpose: Prints debugging info about a B-tree. + * Purpose: Prints debugging info about a B-tree. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 4 1997 + * Programmer: Robb Matzke + * matzke@llnl.gov + * Aug 4 1997 * * Modifications: * @@ -1524,10 +1533,10 @@ H5B_nodesize(H5F_t *f, const H5B_class_t *type, */ herr_t H5B_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, - intn fwidth, const H5B_class_t *type, void *udata) + intn fwidth, const H5B_class_t *type, void *udata) { - H5B_t *bt = NULL; - int i; + H5B_t *bt = NULL; + int i; FUNC_ENTER(H5B_debug, FAIL); @@ -1545,68 +1554,68 @@ H5B_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, * Load the tree node. */ if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) { - HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, - "unable to load B-tree node"); + HRETURN_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, + "unable to load B-tree node"); } /* * Print the values. */ fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, - "Tree type ID:", - (int) (bt->type->id)); + "Tree type ID:", + (int) (bt->type->id)); fprintf(stream, "%*s%-*s %lu\n", indent, "", fwidth, - "Size of raw (disk) key:", - (unsigned long) (bt->sizeof_rkey)); + "Size of raw (disk) key:", + (unsigned long) (bt->sizeof_rkey)); fprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Dirty flag:", - bt->dirty ? "True" : "False"); + "Dirty flag:", + bt->dirty ? "True" : "False"); fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, - "Number of initial dirty children:", - (int) (bt->ndirty)); + "Number of initial dirty children:", + (int) (bt->ndirty)); fprintf(stream, "%*s%-*s %d\n", indent, "", fwidth, - "Level:", - (int) (bt->level)); + "Level:", + (int) (bt->level)); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Address of left sibling:"); + "Address of left sibling:"); H5F_addr_print(stream, &(bt->left)); fprintf(stream, "\n"); fprintf(stream, "%*s%-*s ", indent, "", fwidth, - "Address of right sibling:"); + "Address of right sibling:"); H5F_addr_print(stream, &(bt->right)); fprintf(stream, "\n"); fprintf(stream, "%*s%-*s %d (%d)\n", indent, "", fwidth, - "Number of children (max):", - (int) (bt->nchildren), - (int) (2 * H5B_K(f, type))); + "Number of children (max):", + (int) (bt->nchildren), + (int) (2 * H5B_K(f, type))); /* * Print the child addresses */ for (i = 0; i < bt->nchildren; i++) { - fprintf(stream, "%*sChild %d...\n", indent, "", i); - fprintf(stream, "%*s%-*s ", indent + 3, "", MAX(0, fwidth - 3), - "Address:"); - H5F_addr_print(stream, bt->child + i); - fprintf(stream, "\n"); + fprintf(stream, "%*sChild %d...\n", indent, "", i); + fprintf(stream, "%*s%-*s ", indent + 3, "", MAX(0, fwidth - 3), + "Address:"); + H5F_addr_print(stream, bt->child + i); + fprintf(stream, "\n"); } FUNC_LEAVE(SUCCEED); } /*------------------------------------------------------------------------- - * Function: H5B_assert + * Function: H5B_assert * - * Purpose: Verifies that the tree is structured correctly. + * Purpose: Verifies that the tree is structured correctly. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: aborts if something is wrong. + * Failure: aborts if something is wrong. * - * Programmer: Robb Matzke - * Tuesday, November 4, 1997 + * Programmer: Robb Matzke + * Tuesday, November 4, 1997 * * Modifications: * @@ -1615,23 +1624,23 @@ H5B_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent, #ifdef H5B_DEBUG static herr_t H5B_assert(H5F_t *f, const haddr_t *addr, const H5B_class_t *type, - void *udata) + void *udata) { - H5B_t *bt = NULL; - intn i, ncell, cmp; - static int ncalls = 0; - herr_t status; + H5B_t *bt = NULL; + intn i, ncell, cmp; + static int ncalls = 0; + herr_t status; /* A queue of child data */ struct child_t { - haddr_t addr; - int level; - struct child_t *next; + haddr_t addr; + int level; + struct child_t *next; } *head = NULL, *tail = NULL, *prev = NULL, *cur = NULL, *tmp = NULL; FUNC_ENTER(H5B_assert, FAIL); if (0 == ncalls++) { - fprintf(stderr, "HDF5-DIAG: debugging B-trees (expensive)\n"); + fprintf(stderr, "HDF5-DIAG: debugging B-trees (expensive)\n"); } /* Initialize the queue */ bt = H5AC_find(f, H5AC_BT, addr, type, udata); @@ -1648,63 +1657,63 @@ H5B_assert(H5F_t *f, const haddr_t *addr, const H5B_class_t *type, * test. */ for (ncell = 0; cur; ncell++) { - bt = H5AC_protect(f, H5AC_BT, &(cur->addr), type, udata); - assert(bt); - - /* Check node header */ - assert(bt->ndirty >= 0 && bt->ndirty <= bt->nchildren); - assert(bt->level == cur->level); - if (cur->next && cur->next->level == bt->level) { - assert(H5F_addr_eq(&(bt->right), &(cur->next->addr))); - } else { - assert(!H5F_addr_defined(&(bt->right))); - } - if (prev && prev->level == bt->level) { - assert(H5F_addr_eq(&(bt->left), &(prev->addr))); - } else { - assert(!H5F_addr_defined(&(bt->left))); - } - - if (cur->level > 0) { - for (i = 0; i < bt->nchildren; i++) { - - /* - * Check that child nodes haven't already been seen. If they - * have then the tree has a cycle. - */ - for (tmp = head; tmp; tmp = tmp->next) { - assert(H5F_addr_ne(&(tmp->addr), bt->child + i)); - } - - /* Add the child node to the end of the queue */ - tmp = H5MM_xcalloc(1, sizeof(struct child_t)); - tmp->addr = bt->child[i]; - tmp->level = bt->level - 1; - tail->next = tmp; - tail = tmp; - - /* Check that the keys are monotonically increasing */ - status = H5B_decode_keys(f, bt, i); - assert(status >= 0); - cmp = (type->cmp2) (f, bt->key[i].nkey, udata, + bt = H5AC_protect(f, H5AC_BT, &(cur->addr), type, udata); + assert(bt); + + /* Check node header */ + assert(bt->ndirty >= 0 && bt->ndirty <= bt->nchildren); + assert(bt->level == cur->level); + if (cur->next && cur->next->level == bt->level) { + assert(H5F_addr_eq(&(bt->right), &(cur->next->addr))); + } else { + assert(!H5F_addr_defined(&(bt->right))); + } + if (prev && prev->level == bt->level) { + assert(H5F_addr_eq(&(bt->left), &(prev->addr))); + } else { + assert(!H5F_addr_defined(&(bt->left))); + } + + if (cur->level > 0) { + for (i = 0; i < bt->nchildren; i++) { + + /* + * Check that child nodes haven't already been seen. If they + * have then the tree has a cycle. + */ + for (tmp = head; tmp; tmp = tmp->next) { + assert(H5F_addr_ne(&(tmp->addr), bt->child + i)); + } + + /* Add the child node to the end of the queue */ + tmp = H5MM_xcalloc(1, sizeof(struct child_t)); + tmp->addr = bt->child[i]; + tmp->level = bt->level - 1; + tail->next = tmp; + tail = tmp; + + /* Check that the keys are monotonically increasing */ + status = H5B_decode_keys(f, bt, i); + assert(status >= 0); + cmp = (type->cmp2) (f, bt->key[i].nkey, udata, bt->key[i + 1].nkey); - assert(cmp < 0); - } - } - /* Release node */ - status = H5AC_unprotect(f, H5AC_BT, &(cur->addr), bt); - assert(status >= 0); - - /* Advance current location in queue */ - prev = cur; - cur = cur->next; + assert(cmp < 0); + } + } + /* Release node */ + status = H5AC_unprotect(f, H5AC_BT, &(cur->addr), bt); + assert(status >= 0); + + /* Advance current location in queue */ + prev = cur; + cur = cur->next; } /* Free all entries from queue */ while (head) { - tmp = head->next; - H5MM_xfree(head); - head = tmp; + tmp = head->next; + H5MM_xfree(head); + head = tmp; } FUNC_LEAVE(SUCCEED); diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 8a9420a..a7db2fc 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -38,6 +38,7 @@ (H5B_SIZEOF_MAGIC + /*magic number */ \ 4 + /*type, level, num entries */ \ 2*H5F_SIZEOF_ADDR(F)) /*left and right sibling addresses */ + #define H5B_K(F,TYPE) /*K value given file and Btree subclass */ \ ((F)->shared->create_parms.btree_k[(TYPE)->id]) @@ -121,6 +122,6 @@ herr_t H5B_find (H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata); herr_t H5B_insert (H5F_t *f, const H5B_class_t *type, const haddr_t *addr, void *udata); -herr_t H5B_list (H5F_t *f, const H5B_class_t *type, const haddr_t *addr, - void *udata); +herr_t H5B_iterate (H5F_t *f, const H5B_class_t *type, const haddr_t *addr, + void *udata); #endif @@ -48,7 +48,7 @@ /* Interface initialization */ static hbool_t interface_initialize_g = FALSE; -#define INTERFACE_INIT H5G_init_interface +#define INTERFACE_INIT H5G_init_interface static herr_t H5G_init_interface(void); static void H5G_term_interface(void); @@ -364,6 +364,86 @@ H5Gpop(hid_t file_id) FUNC_LEAVE(SUCCEED); } + +/*------------------------------------------------------------------------- + * Function: H5Giterate + * + * Purpose: Iterates over the entries of a group. The FILE_ID and NAME + * identify the group over which to iterate and INDEX indicates + * where to start iterating (zero means at the beginning). The + * OPERATOR is called for each member and the iteration + * continues until the operator returns non-zero or all members + * are processed. The operator is passed a group ID for the + * group being iterated, a member name, and OP_DATA for each + * member. + * + * Return: Success: The return value of the first operator that + * returns non-zero, or zero if all members were + * processed with no operator returning non-zero. + * + * Failure: FAIL if something goes wrong within the + * library, or a negative value returned by one + * of the operators. + * + * Programmer: Robb Matzke + * Monday, March 23, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Giterate (hid_t file_id, const char *name, int *index, + H5G_iterate_t op, void *op_data) +{ + H5F_t *f = NULL; + int _index = 0; + H5G_bt_ud2_t udata; + herr_t ret_value = FAIL; + + FUNC_ENTER (H5Giterate, FAIL); + + /* Check args */ + if (H5_FILE!=H5I_group (file_id) || + NULL==(f=H5I_object (file_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a file"); + } + if (!name || !*name) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); + } + if (!index) index = &_index; + if (!op) { + HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified"); + } + + /* + * Open the group on which to operate. We also create a group ID which + * we can pass to the application-defined operator. + */ + if (NULL==(udata.group = H5G_open (f, name))) { + HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to open group"); + } + if ((udata.group_id=H5I_register (H5_GROUP, udata.group))<0) { + H5G_close (udata.group); + HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, + "unable to register group"); + } + + /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ + udata.skip = *index; + udata.op = op; + udata.op_data = op_data; + + /* Iterate over the group members */ + if ((ret_value = H5B_iterate (f, H5B_SNODE, + &(udata.group->ent.cache.stab.btree_addr), + &udata))<0) { + HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed"); + } + H5I_dec_ref (udata.group_id); /*also closes udata.group*/ + FUNC_LEAVE (ret_value); +} + /* *------------------------------------------------------------------------- *------------------------------------------------------------------------- @@ -523,22 +603,19 @@ H5G_component(const char *name, size_t *size_p) */ static herr_t H5G_namei(H5F_t *f, H5G_entry_t *cwg, const char *name, - const char **rest /*out */ , H5G_entry_t *grp_ent /*out */ , - H5G_entry_t *obj_ent /*out */ ) + const char **rest/*out*/, H5G_entry_t *grp_ent/*out*/, + H5G_entry_t *obj_ent/*out*/) { - H5G_entry_t _grp_ent; /*entry for current group */ - H5G_entry_t _obj_ent; /*entry found */ - size_t nchars; /*component name length */ - char comp[1024]; /*component name buffer */ - hbool_t aside = FALSE; /*did we look at a name message? */ + H5G_entry_t _grp_ent; /*entry for current group */ + H5G_entry_t _obj_ent; /*entry found */ + size_t nchars; /*component name length */ + char comp[1024]; /*component name buffer */ + hbool_t aside = FALSE; /*did we look at a name message?*/ /* clear output args before FUNC_ENTER() in case it fails */ - if (rest) - *rest = name; - if (!grp_ent) - grp_ent = &_grp_ent; - if (!obj_ent) - obj_ent = &_obj_ent; + if (rest) *rest = name; + if (!grp_ent) grp_ent = &_grp_ent; + if (!obj_ent) obj_ent = &_obj_ent; memset(grp_ent, 0, sizeof(H5G_entry_t)); H5F_addr_undef(&(grp_ent->header)); memset(obj_ent, 0, sizeof(H5G_entry_t)); @@ -754,15 +831,15 @@ H5G_mkroot(H5F_t *f, size_t size_hint) * *------------------------------------------------------------------------- */ -H5G_t * +H5G_t * H5G_create(H5F_t *f, const char *name, size_t size_hint) { - const char *rest = NULL; /*the base name */ - H5G_entry_t grp_ent; /*group containing new group */ - char _comp[1024]; /*name component */ - size_t nchars; /*number of characters in compon */ - herr_t status; /*function return status */ - H5G_t *grp = NULL; /*new group */ + const char *rest = NULL; /*the base name */ + H5G_entry_t grp_ent; /*group containing new group */ + char _comp[1024]; /*name component */ + size_t nchars; /*number of characters in compon*/ + herr_t status; /*function return status */ + H5G_t *grp = NULL; /*new group */ FUNC_ENTER(H5G_create, NULL); @@ -774,7 +851,7 @@ H5G_create(H5F_t *f, const char *name, size_t size_hint) * Try to create the root group. Ignore the error if this function * fails because the root group already exists. */ - if ((status = H5G_mkroot(f, H5G_SIZE_HINT)) < 0 && -2 != status) { + if ((status=H5G_mkroot(f, H5G_SIZE_HINT))<0 && -2!=status) { HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create root group"); } H5E_clear(); @@ -801,12 +878,14 @@ H5G_create(H5F_t *f, const char *name, size_t size_hint) rest = _comp; } } + /* create an open group */ grp = H5MM_xcalloc(1, sizeof(H5G_t)); - if (H5G_stab_create(f, size_hint, &(grp->ent) /*out */ ) < 0) { + if (H5G_stab_create(f, size_hint, &(grp->ent)/*out*/) < 0) { grp = H5MM_xfree(grp); HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp"); } + /* insert child name into parent */ if (H5G_stab_insert(&grp_ent, rest, &(grp->ent)) < 0) { H5O_close(&(grp->ent)); diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 390ea7d..79b016a 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -17,7 +17,7 @@ * *------------------------------------------------------------------------- */ -#define H5G_PACKAGE /*suppress error message about including H5Gpkg.h */ +#define H5G_PACKAGE /*suppress error message about including H5Gpkg.h */ /* Packages needed by this file... */ #include <H5private.h> /*library */ @@ -33,64 +33,61 @@ #define PABLO_MASK H5G_node_mask /* PRIVATE PROTOTYPES */ -static herr_t H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static herr_t H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static size_t H5G_node_size(H5F_t *f); -static herr_t H5G_node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, - void *_udata, void *_rt_key, - haddr_t *addr /*out */ ); -static herr_t H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, - H5G_node_t *sym); -static H5G_node_t *H5G_node_load(H5F_t *f, const haddr_t *addr, - const void *_udata1, void *_udata2); -static intn H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static intn H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static herr_t H5G_node_found(H5F_t *f, const haddr_t *addr, - const void *_lt_key, void *_udata, - const void *_rt_key); -static H5B_ins_t H5G_node_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *new_node /*out */ ); -static herr_t H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata); -static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *_udata); +static herr_t H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static herr_t H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static size_t H5G_node_size(H5F_t *f); +static herr_t H5G_node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, + void *_udata, void *_rt_key, + haddr_t *addr/*out*/); +static herr_t H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, + H5G_node_t *sym); +static H5G_node_t *H5G_node_load(H5F_t *f, const haddr_t *addr, + const void *_udata1, void *_udata2); +static intn H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static intn H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static herr_t H5G_node_found(H5F_t *f, const haddr_t *addr, + const void *_lt_key, void *_udata, + const void *_rt_key); +static H5B_ins_t H5G_node_insert(H5F_t *f, const haddr_t *addr, + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node/*out*/); +static herr_t H5G_node_iterate(H5F_t *f, const haddr_t *addr, void *_udata); +static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *_udata); /* H5G inherits cache-like properties from H5AC */ -const H5AC_class_t H5AC_SNODE[1] = -{ - { - H5AC_SNODE_ID, - (void *(*)(H5F_t *, const haddr_t *, const void *, void *)) H5G_node_load, - (herr_t (*)(H5F_t *, hbool_t, const haddr_t *, void *)) H5G_node_flush, - }}; +const H5AC_class_t H5AC_SNODE[1] = {{ + H5AC_SNODE_ID, + (void *(*)(H5F_t*, const haddr_t*, const void*, void*))H5G_node_load, + (herr_t (*)(H5F_t*, hbool_t, const haddr_t*, void*))H5G_node_flush, +}}; /* H5G inherits B-tree like properties from H5B */ -H5B_class_t H5B_SNODE[1] = -{ - { - H5B_SNODE_ID, /*id */ - sizeof(H5G_node_key_t), /*sizeof_nkey */ - H5G_node_sizeof_rkey, /*get_sizeof_rkey */ - H5G_node_create, /*new */ - H5G_node_cmp2, /*cmp2 */ - H5G_node_cmp3, /*cmp3 */ - H5G_node_found, /*found */ - H5G_node_insert, /*insert */ - TRUE, /*follow min branch? */ - TRUE, /*follow max branch? */ - H5G_node_list, /*list */ - H5G_node_decode_key, /*decode */ - H5G_node_encode_key, /*encode */ - }}; +H5B_class_t H5B_SNODE[1] = {{ + H5B_SNODE_ID, /*id */ + sizeof(H5G_node_key_t), /*sizeof_nkey */ + H5G_node_sizeof_rkey, /*get_sizeof_rkey */ + H5G_node_create, /*new */ + H5G_node_cmp2, /*cmp2 */ + H5G_node_cmp3, /*cmp3 */ + H5G_node_found, /*found */ + H5G_node_insert, /*insert */ + TRUE, /*follow min branch? */ + TRUE, /*follow max branch? */ + H5G_node_iterate, /*list */ + H5G_node_decode_key, /*decode */ + H5G_node_encode_key, /*encode */ +}}; /* Interface initialization */ -static intn interface_initialize_g = FALSE; +static intn interface_initialize_g = FALSE; #define INTERFACE_INIT NULL + /*------------------------------------------------------------------------- * Function: H5G_node_sizeof_rkey @@ -115,6 +112,7 @@ H5G_node_sizeof_rkey(H5F_t *f, const void *udata __attribute__((unused))) { return H5F_SIZEOF_SIZE(f); /*the name offset */ } + /*------------------------------------------------------------------------- * Function: H5G_node_decode_key @@ -148,6 +146,7 @@ H5G_node_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5G_node_encode_key @@ -181,6 +180,7 @@ H5G_node_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5G_node_size @@ -205,6 +205,7 @@ H5G_node_size(H5F_t *f) return H5G_NODE_SIZEOF_HDR(f) + (2 * H5G_NODE_K(f)) * H5G_SIZEOF_ENTRY(f); } + /*------------------------------------------------------------------------- * Function: H5G_node_create @@ -230,7 +231,7 @@ H5G_node_size(H5F_t *f) static herr_t H5G_node_create(H5F_t *f, H5B_ins_t op, void *_lt_key, void *_udata, void *_rt_key, - haddr_t *addr /*out */ ) + haddr_t *addr/*out*/) { H5G_node_key_t *lt_key = (H5G_node_key_t *) _lt_key; H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key; @@ -247,7 +248,7 @@ H5G_node_create(H5F_t *f, H5B_ins_t op, sym = H5MM_xcalloc(1, sizeof(H5G_node_t)); size = H5G_node_size(f); - if (H5MF_alloc(f, H5MF_META, size, addr /*out */ ) < 0) { + if (H5MF_alloc(f, H5MF_META, size, addr/*out*/) < 0) { H5MM_xfree(sym); HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to allocate file space"); @@ -266,13 +267,12 @@ H5G_node_create(H5F_t *f, H5B_ins_t op, * allows the comparison functions to work correctly without knowing * that there are no symbols. */ - if (lt_key) - lt_key->offset = 0; - if (rt_key) - rt_key->offset = 0; + if (lt_key) lt_key->offset = 0; + if (rt_key) rt_key->offset = 0; FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5G_node_flush @@ -295,10 +295,10 @@ static herr_t H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5G_node_t *sym) { - uint8 *buf = NULL, *p = NULL; - size_t size; - herr_t status; - int i; + uint8 *buf = NULL, *p = NULL; + size_t size; + herr_t status; + int i; FUNC_ENTER(H5G_node_flush, FAIL); @@ -313,8 +313,8 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, * Look for dirty entries and set the node dirty flag. */ for (i = 0; i < sym->nsyms; i++) { - if (sym->entry[i].dirty) - sym->dirty = TRUE; + if (sym->entry[i].dirty) + sym->dirty = TRUE; } /* @@ -358,6 +358,7 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- * Function: H5G_node_load @@ -376,7 +377,7 @@ H5G_node_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, * *------------------------------------------------------------------------- */ -static H5G_node_t * +static H5G_node_t * H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, void *_udata2) { @@ -445,6 +446,7 @@ H5G_node_load(H5F_t *f, const haddr_t *addr, const void *_udata1, } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5G_node_cmp2 @@ -496,6 +498,7 @@ H5G_node_cmp2(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) FUNC_LEAVE(cmp); } + /*------------------------------------------------------------------------- * Function: H5G_node_cmp3 @@ -552,6 +555,7 @@ H5G_node_cmp3(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) FUNC_LEAVE(0); } + /*------------------------------------------------------------------------- * Function: H5G_node_found @@ -585,11 +589,11 @@ static herr_t H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, void *_udata, const void *_rt_key) { - H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; - H5G_node_t *sn = NULL; - intn lt = 0, idx = 0, rt, cmp = 1; - const char *s; - herr_t ret_value = FAIL; + H5G_bt_ud1_t *bt_udata = (H5G_bt_ud1_t *) _udata; + H5G_node_t *sn = NULL; + intn lt = 0, idx = 0, rt, cmp = 1; + const char *s; + herr_t ret_value = FAIL; FUNC_ENTER(H5G_node_found, FAIL); @@ -607,6 +611,7 @@ H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node"); } + /* * Binary search. */ @@ -639,8 +644,8 @@ H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, break; default: - HRETURN_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, - "internal erorr (unknown symbol find operation)"); + HRETURN_ERROR(H5E_SYM, H5E_UNSUPPORTED, FAIL, + "internal erorr (unknown symbol find operation)"); } ret_value = SUCCEED; @@ -651,6 +656,7 @@ H5G_node_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5G_node_insert @@ -726,6 +732,7 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node"); } + /* * Where does the new symbol get inserted? We use a binary search. */ @@ -832,12 +839,12 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5G_node_list + * Function: H5G_node_iterate * - * Purpose: This function gets called during a group list operation. - * It should fill in data in the UDATA struct. + * Purpose: This function gets called during a group iterate operation. * * Return: Success: SUCCEED * @@ -852,15 +859,17 @@ H5G_node_insert(H5F_t *f, const haddr_t *addr, *------------------------------------------------------------------------- */ static herr_t -H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) +H5G_node_iterate (H5F_t *f, const haddr_t *addr, void *_udata) { - H5G_bt_ud2_t *bt_udata = (H5G_bt_ud2_t *) _udata; - H5G_node_t *sn = NULL; - intn i; - const char *s; - herr_t ret_value = FAIL; + H5G_bt_ud2_t *bt_udata = (H5G_bt_ud2_t *)_udata; + H5G_node_t *sn = NULL; + intn i, nsyms; + size_t n, *name_off=NULL; + const char *name; + char buf[1024], *s; + herr_t ret_value = FAIL; - FUNC_ENTER(H5G_node_list, FAIL); + FUNC_ENTER(H5G_node_iterate, FAIL); /* * Check arguments. @@ -869,50 +878,46 @@ H5G_node_list(H5F_t *f, const haddr_t *addr, void *_udata) assert(addr && H5F_addr_defined(addr)); assert(bt_udata); - if (NULL == (sn = H5AC_protect(f, H5AC_SNODE, addr, NULL, NULL))) { - HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, - "unable to protect symbol table node"); - } /* - * If we've already overflowed the user-supplied buffer, then just - * keep track of how many names we've seen and don't bother doing - * anything else. + * Save information about the symbol table node since we can't lock it + * because we're about to call an application function. */ - if (bt_udata->nsyms >= bt_udata->maxentries) { - bt_udata->nsyms += sn->nsyms; - HGOTO_DONE(SUCCEED); + if (NULL == (sn = H5AC_find(f, H5AC_SNODE, addr, NULL, NULL))) { + HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, + "unable to load symbol table node"); } + nsyms = sn->nsyms; + name_off = H5MM_xmalloc (nsyms*sizeof(name_off[0])); + for (i=0; i<nsyms; i++) name_off[i] = sn->entry[i].name_off; + sn = NULL; + /* - * Save the symbol table entries. + * Iterate over the symbol table node entries. */ - if (bt_udata->entry) { - for (i = 0; i < sn->nsyms && bt_udata->nsyms + i < bt_udata->maxentries; i++) { - bt_udata->entry[bt_udata->nsyms + i] = sn->entry[i]; + for (i=0, ret_value=0; i<nsyms && 0==ret_value; i++) { + if (bt_udata->skip>0) { + --bt_udata->skip; + } else { + name = H5H_peek (f, &(bt_udata->group->ent.cache.stab.heap_addr), + name_off[i]); + assert (name); + n = strlen (name); + s = n+1>sizeof(buf) ? H5MM_xmalloc (n+1) : buf; + strcpy (s, name); + ret_value = (bt_udata->op)(bt_udata->group_id, s, + bt_udata->op_data); + if (s!=buf) H5MM_xfree (s); } } - if (bt_udata->name) { - for (i = 0; i < sn->nsyms && bt_udata->nsyms + i < bt_udata->maxentries; i++) { - if (NULL == (s = H5H_peek(f, &(bt_udata->heap_addr), - sn->entry[i].name_off))) { - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, - "unable to read symbol name"); - } - bt_udata->name[bt_udata->nsyms + i] = H5MM_xstrdup(s); - } + if (ret_value<0) { + HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed"); } - /* - * Update the number of symbols. - */ - bt_udata->nsyms += sn->nsyms; - ret_value = SUCCEED; done: - if (sn && H5AC_unprotect(f, H5AC_SNODE, addr, sn) < 0) { - HRETURN_ERROR(H5E_CACHE, H5E_PROTECT, FAIL, - "unable to release symbol table node"); - } + name_off = H5MM_xfree (name_off); FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- * Function: H5G_node_debug diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index cd59aef..f78071a 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -93,19 +93,18 @@ typedef struct H5G_bt_ud1_t { /* * Data exchange structure to pass through the B-tree layer for the - * H5B_list function. + * H5B_iterate function. */ typedef struct H5G_bt_ud2_t { - /* downward */ - H5G_entry_t *entry; /*array of entries, alloc'd by caller */ - char **name; /*array of string ptrs, allocd by caller */ - intn maxentries; /*size of the ADDR and NAME arrays */ - haddr_t heap_addr; /*heap address */ + hid_t group_id; /*group id to pass to iteration operator */ + struct H5G_t *group; /*the group to which group_id points */ + int skip; /*initial entries to skip */ + H5G_iterate_t op; /*iteration operator */ + void *op_data; /*user-defined operator data */ /* upward */ - intn nsyms; /*num. symbols processed */ - + } H5G_bt_ud2_t; /* @@ -126,9 +125,6 @@ herr_t H5G_stab_find (H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent/*out*/); herr_t H5G_stab_insert (H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent); -intn H5G_stab_list (H5G_entry_t *self, intn maxentries, char *names[]/*out*/, - H5G_entry_t entries[]/*out*/); - /* * Functions that understand symbol table entries. */ diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index b0a33b8..435d384 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -27,12 +27,17 @@ extern "C" { #endif +typedef herr_t (*H5G_iterate_t)(hid_t group, const char *group_name, + void *op_data); + hid_t H5Gcreate (hid_t file_id, const char *name, size_t size_hint); hid_t H5Gopen (hid_t file_id, const char *name); herr_t H5Gclose (hid_t grp_id); herr_t H5Gset (hid_t file, const char *name); herr_t H5Gpush (hid_t file, const char *name); herr_t H5Gpop (hid_t file); +herr_t H5Giterate (hid_t file, const char *name, int *idx, H5G_iterate_t op, + void *op_data); #ifdef __cplusplus } diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 7ef971c..db12c05 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -47,7 +47,7 @@ static hbool_t interface_initialize_g = FALSE; *------------------------------------------------------------------------- */ herr_t -H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self /*out */ ) +H5G_stab_create(H5F_t *f, size_t init, H5G_entry_t *self/*out*/) { size_t name; /*offset of "" name */ H5O_stab_t stab; /*symbol table message */ @@ -207,71 +207,3 @@ H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent) obj_ent->name_off = udata.ent.name_off; FUNC_LEAVE(SUCCEED); } - -/*------------------------------------------------------------------------- - * Function: H5G_stab_list - * - * Purpose: Returns a list of all the symbols in a symbol table. - * The caller allocates an array of pointers which this - * function will fill in with malloc'd names. The caller - * also allocates an array of symbol table entries which will - * be filled in with data from the symbol table. Each of these - * arrays should have at least MAXENTRIES elements. - * - * Errors: - * SYM BADMESG Not a symbol table. - * SYM CANTLIST B-tree list failure. - * - * Return: Success: The total number of symbols in the - * symbol table. This may exceed MAXENTRIES, - * but at most MAXENTRIES values are copied - * into the NAMES and ENTRIES arrays. - * - * Failure: FAIL, the pointers in NAMES are undefined but - * no memory is allocated. The values in - * ENTRIES are undefined. - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 1 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -intn -H5G_stab_list(H5G_entry_t *grp_ent, intn maxentries, char *names[] /*out */ , - H5G_entry_t entries[] /*out */ ) -{ - H5G_bt_ud2_t udata; - H5O_stab_t stab; - intn i; - - FUNC_ENTER(H5G_stab_list, FAIL); - - /* check args */ - assert(grp_ent && grp_ent->file); - assert(maxentries >= 0); - - /* initialize data to pass through B-tree */ - if (NULL == H5O_read(grp_ent, H5O_STAB, 0, &stab)) { - HRETURN_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table"); - } - udata.entry = entries; - udata.name = names; - udata.heap_addr = stab.heap_addr; - udata.maxentries = maxentries; - udata.nsyms = 0; - if (names) - HDmemset(names, 0, maxentries); - - /* list */ - if (H5B_list(grp_ent->file, H5B_SNODE, &(stab.btree_addr), &udata) < 0) { - if (names) { - for (i = 0; i < maxentries; i++) - H5MM_xfree(names[i]); - } - HRETURN_ERROR(H5E_SYM, H5E_CANTLIST, FAIL, "b-tree list failure"); - } - FUNC_LEAVE(udata.nsyms); -} @@ -516,6 +516,9 @@ H5O_flush(H5F_t *f, hbool_t destroy, const haddr_t *addr, H5O_t *oh) /* encode body size */ UINT32ENCODE(p, oh->chunk[0].size); + /* zero to alignment */ + HDmemset (p, 0, H5O_SIZEOF_HDR(f)-12); + /* write the object header header */ if (H5F_block_write(f, addr, H5O_SIZEOF_HDR(f), buf) < 0) { HRETURN_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, diff --git a/test/istore.c b/test/istore.c index 2ba7142..e11cb04 100644 --- a/test/istore.c +++ b/test/istore.c @@ -559,7 +559,9 @@ main(int argc, char *argv[]) size_of_test |= TEST_LARGE; } else { printf("unrecognized argument: %s\n", argv[i]); +#if 0 exit(1); +#endif } } } |