summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1998-03-24 14:53:57 (GMT)
committerRobb Matzke <matzke@llnl.gov>1998-03-24 14:53:57 (GMT)
commit2ed9aa69f74cc2002fb9a03c8893056a1daea1db (patch)
treeadf512fcc40417123f7e464b2b92b555eab5fb96
parentaf6558c7cb0f2b4ef3a789eca7554da4db521f03 (diff)
downloadhdf5-2ed9aa69f74cc2002fb9a03c8893056a1daea1db.zip
hdf5-2ed9aa69f74cc2002fb9a03c8893056a1daea1db.tar.gz
hdf5-2ed9aa69f74cc2002fb9a03c8893056a1daea1db.tar.bz2
[svn-r328] Changes since 19980318
---------------------- ./src/H5B.c ./src/H5Bprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5Gpublic.h ./src/H5Gstab.c Implemented H5Giterate(). However, since most functions can't take a group ID in place of a file ID yet, there's not a whole lot that the operator can do besides print the name or something. ./test/H5O.c Fixed writing of four uninitialized bytes to the file as part of an object header. ./test/istore.c For some reason, `mpirun -np 1 istore' results in extra arguments on the command line that istore doesn't understand. I'm probably forgetting to call some MPI function in main(). Albert, Kim? So I commented out the `exit(1)' for the time being.
-rw-r--r--MANIFEST8
-rwxr-xr-xconfigure2
-rw-r--r--src/H5B.c1773
-rw-r--r--src/H5Bprivate.h5
-rw-r--r--src/H5G.c125
-rw-r--r--src/H5Gnode.c233
-rw-r--r--src/H5Gpkg.h18
-rw-r--r--src/H5Gpublic.h5
-rw-r--r--src/H5Gstab.c70
-rw-r--r--src/H5O.c3
-rw-r--r--test/istore.c2
11 files changed, 1138 insertions, 1106 deletions
diff --git a/MANIFEST b/MANIFEST
index 8182b81..d06f7eb 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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
diff --git a/configure b/configure
index bd18570..8ed46c1 100755
--- a/configure
+++ b/configure
@@ -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
diff --git a/src/H5B.c b/src/H5B.c
index 4ab57ca..e061625 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -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, &lt_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
diff --git a/src/H5G.c b/src/H5G.c
index e033bd5..1b7a700 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -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);
-}
diff --git a/src/H5O.c b/src/H5O.c
index 2c12ea2..af9ec82 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -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
}
}
}