summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1997-08-13 15:36:47 (GMT)
committerRobb Matzke <matzke@llnl.gov>1997-08-13 15:36:47 (GMT)
commit5cae95154903ecd6564f0712e42168892df17b7d (patch)
treeffc18b449e49921bbe15cb7a02c6b2f0785f3324
parent46ef9d9c266b704ba93ed55296ed2ebab600a2a4 (diff)
downloadhdf5-5cae95154903ecd6564f0712e42168892df17b7d.zip
hdf5-5cae95154903ecd6564f0712e42168892df17b7d.tar.gz
hdf5-5cae95154903ecd6564f0712e42168892df17b7d.tar.bz2
[svn-r27] ./src/H5B.c
./src/H5Bprivate.h The B-tree K value comes from a combination of the B-tree subclass and the file. ./src/H5C.c ./src/H5F.c ./src/hdf5lims.h ./src/hdf5type.h Removed the B-tree size parameter and added an array of B-tree K values. Also added symbol table node K value. ./src/H5Eprivate.h ./src/H5Eproto.h Added H5E_LINK for errors involving link counts. ./src/H5G.c Inserting something into a directory with H5G_insert() increments the link count in the object header. The root object should always have a link count of at least 1. ./src/H5Gnode.c ./src/H5Gprivate.h The symbol table node K value comes from the file instead of being a constant. ./src/H5Olink.c Added an assert(), fixed a hard-link bug.
-rw-r--r--src/H5B.c84
-rw-r--r--src/H5Bprivate.h11
-rw-r--r--src/H5C.c45
-rw-r--r--src/H5Eprivate.h1
-rw-r--r--src/H5Eproto.h3
-rw-r--r--src/H5F.c13
-rw-r--r--src/H5G.c31
-rw-r--r--src/H5Gnode.c66
-rw-r--r--src/H5Gprivate.h2
-rw-r--r--src/H5O.c4
-rw-r--r--src/debug.c2
-rw-r--r--src/hdf5lims.h13
-rw-r--r--src/hdf5type.h6
13 files changed, 187 insertions, 94 deletions
diff --git a/src/H5B.c b/src/H5B.c
index 21dc174..e932dc7 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -193,8 +193,8 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type)
bt->nchildren = 0;
bt->page = H5MM_xmalloc (size);
bt->native = H5MM_xmalloc (total_native_keysize);
- bt->child = H5MM_xmalloc (2*type->k * sizeof(haddr_t));
- bt->key = H5MM_xmalloc ((2*type->k+1) * sizeof(H5B_key_t));
+ 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));
/*
* Initialize each entry's raw child and key pointers to point into the
@@ -202,7 +202,7 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type)
* translated to native format.
*/
for (i=0,offset=H5B_SIZEOF_HDR(f);
- i<2*type->k;
+ i<2*H5B_K(f,type);
i++,offset+=bt->sizeof_rkey+H5F_SIZEOF_OFFSET(f)) {
bt->key[i].dirty = 0;
@@ -214,9 +214,9 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type)
/*
* The last possible key...
*/
- bt->key[2*type->k].dirty = 0;
- bt->key[2*type->k].rkey = bt->page + offset;
- bt->key[2*type->k].nkey = NULL;
+ bt->key[2*H5B_K(f,type)].dirty = 0;
+ bt->key[2*H5B_K(f,type)].rkey = bt->page + offset;
+ bt->key[2*H5B_K(f,type)].nkey = NULL;
/*
* Cache the new B-tree node.
@@ -271,8 +271,8 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
bt->ndirty = 0;
bt->page = H5MM_xmalloc (size);
bt->native = H5MM_xmalloc (total_nkey_size);
- bt->key = H5MM_xmalloc ((2*type->k+1) * sizeof(H5B_key_t));
- bt->child = H5MM_xmalloc (2 * type->k * sizeof(haddr_t));
+ 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);
}
@@ -294,7 +294,7 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
H5F_decode_offset (f, p, bt->right);
/* the child/key pairs */
- for (i=0; i<2*type->k; i++) {
+ for (i=0; i<2*H5B_K(f,type); i++) {
bt->key[i].dirty = 0;
bt->key[i].rkey = p;
@@ -309,9 +309,9 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
}
}
- bt->key[2*type->k].dirty = 0;
- bt->key[2*type->k].rkey = p;
- bt->key[2*type->k].nkey = NULL;
+ bt->key[2*H5B_K(f,type)].dirty = 0;
+ bt->key[2*H5B_K(f,type)].rkey = p;
+ bt->key[2*H5B_K(f,type)].nkey = NULL;
FUNC_LEAVE (bt);
error:
@@ -563,7 +563,7 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
H5B_t *bt = NULL;
size_t total_nkey_size, size;
intn i, offset;
- intn delta = H5B_ANCHOR_LT==anchor ? type->k : 0;
+ intn delta = H5B_ANCHOR_LT==anchor ? H5B_K(f,type) : 0;
size_t recsize = 0;
haddr_t tmp_addr, new_addr;
H5B_t *tmp=NULL;
@@ -583,7 +583,7 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
if (NULL==(old=H5AC_find (f, H5AC_BT, addr, type))) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
- assert (old->nchildren == 2*type->k);
+ assert (old->nchildren == 2*H5B_K(f,type));
bt = H5MM_xmalloc (sizeof(H5B_t));
recsize = old->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
@@ -593,29 +593,31 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
size = H5B_nodesize (f, type, &total_nkey_size, old->sizeof_rkey);
bt->dirty = 1;
bt->sizeof_rkey = old->sizeof_rkey;
- bt->ndirty = BOUND (0, old->ndirty-delta, type->k);
+ bt->ndirty = BOUND (0, old->ndirty-delta, H5B_K(f,type));
bt->type = type;
bt->level = old->level;
- bt->nchildren = type->k;
+ bt->nchildren = H5B_K(f,type);
bt->page = H5MM_xcalloc (size, 1); /*use calloc() to keep file clean*/
bt->native = H5MM_xmalloc (total_nkey_size);
- bt->child = H5MM_xmalloc (2*type->k * sizeof(haddr_t));
- bt->key = H5MM_xmalloc ((2*type->k+1) * sizeof(H5B_key_t));
+ 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));
/*
* Copy data into the new node from the old node.
*/
memcpy (bt->page + H5B_SIZEOF_HDR(f),
old->page + H5B_SIZEOF_HDR(f) + delta*recsize,
- type->k * recsize + bt->sizeof_rkey);
+ H5B_K(f,type) * recsize + bt->sizeof_rkey);
memcpy (bt->native,
old->native + delta * type->sizeof_nkey,
- (type->k+1) * type->sizeof_nkey);
+ (H5B_K(f,type)+1) * type->sizeof_nkey);
- for (i=0,offset=H5B_SIZEOF_HDR(f); i<=2*type->k; i++,offset+=recsize) {
+ for (i=0, offset=H5B_SIZEOF_HDR(f);
+ i<=2*H5B_K(f,type);
+ i++,offset+=recsize) {
/* key */
- if (i<=type->k) {
+ if (i<=H5B_K(f,type)) {
bt->key[i].dirty = old->key[delta+i].dirty;
bt->key[i].rkey = bt->page + offset;
if (old->key[delta+i].nkey) {
@@ -630,9 +632,9 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
}
/* child */
- if (i<type->k) {
+ if (i<H5B_K(f,type)) {
bt->child[i] = old->child[delta+i];
- } else if (i<2*type->k) {
+ } else if (i<2*H5B_K(f,type)) {
bt->child[i] = 0;
}
}
@@ -641,22 +643,22 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
/*
* Truncate the old node.
*/
- delta = H5B_ANCHOR_LT==anchor ? 0 : type->k;
+ delta = H5B_ANCHOR_LT==anchor ? 0 : H5B_K(f,type);
old->dirty += 1;
- old->ndirty = BOUND (0, old->ndirty-delta, type->k);
- old->nchildren = type->k;
+ old->ndirty = BOUND (0, old->ndirty-delta, H5B_K(f,type));
+ old->nchildren = H5B_K(f,type);
if (H5B_ANCHOR_RT==anchor) {
memcpy (old->page + H5B_SIZEOF_HDR(f),
old->page + H5B_SIZEOF_HDR(f) + delta*recsize,
- type->k * recsize);
+ H5B_K(f,type) * recsize);
memmove (old->native,
old->native + delta * type->sizeof_nkey,
- (type->k+1) * type->sizeof_nkey);
+ (H5B_K(f,type)+1) * type->sizeof_nkey);
- for (i=0; i<=2*type->k; i++) {
+ for (i=0; i<=2*H5B_K(f,type); i++) {
- if (i<=type->k) {
+ if (i<=H5B_K(f,type)) {
old->key[i].dirty = old->key[delta+i].dirty;
if (old->key[delta+i].nkey) {
old->key[i].nkey = old->native + i * type->sizeof_nkey;
@@ -666,9 +668,9 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
} else {
old->key[i].nkey = NULL;
}
- if (i<type->k) {
+ if (i<H5B_K(f,type)) {
old->child[i] = old->child[delta+i];
- } else if (i<2*type->k) {
+ } else if (i<2*H5B_K(f,type)) {
old->child[i] = 0;
}
}
@@ -1220,14 +1222,14 @@ H5B_insert_helper (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type,
* Make sure `addr' points to the node that gets the new child
* and that `idx' is adjusted appropriately.
*/
- if (child && bt->nchildren==2*type->k) {
+ if (child && bt->nchildren==2*H5B_K(f,type)) {
if ((twin = H5B_split (f, type, addr, anchor))<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
}
- if (idx<=type->k) {
+ if (idx<=H5B_K(f,type)) {
addr = H5B_ANCHOR_LT==anchor ? addr : twin;
} else {
- idx -= type->k;
+ idx -= H5B_K(f,type);
addr = H5B_ANCHOR_LT==anchor ? twin : addr;
}
}
@@ -1316,7 +1318,7 @@ H5B_list (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, void *udata)
HRETURN (SUCCEED);
}
} else {
- child = H5MM_xmalloc (2 * type->k * sizeof(haddr_t));
+ child = H5MM_xmalloc (2 * H5B_K(f,type) * sizeof(haddr_t));
list = type->list;
twin = addr;
@@ -1386,15 +1388,15 @@ H5B_nodesize (hdf5_file_t *f, const H5B_class_t *type,
* Total native key size.
*/
if (total_nkey_size) {
- *total_nkey_size = (2 * type->k + 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 * type->k * H5F_SIZEOF_OFFSET(f) + /*child pointers*/
- (2*type->k+1) * sizeof_rkey); /*keys */
+ 2 * H5B_K(f,type) * H5F_SIZEOF_OFFSET(f) + /*child pointers*/
+ (2*H5B_K(f,type)+1) * sizeof_rkey); /*keys */
FUNC_LEAVE (size);
}
@@ -1470,7 +1472,7 @@ H5B_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
fprintf (stream, "%*s%-*s %d (%d)\n", indent, "", fwidth,
"Number of children (max):",
(int)(bt->nchildren),
- (int)(2*type->k));
+ (int)(2*H5B_K(f,type)));
/*
* Print the child addresses
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 92c2985..618e344 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -29,21 +29,26 @@
4 + /*type, level, num entries */ \
2*H5F_SIZEOF_OFFSET(F)) /*left and right sibling addresses */
+#define H5B_K(F,TYPE) /*K value given file and Btree subclass */ \
+ ((F)->file_create_parms.btree_k[(TYPE)->id])
+
#define H5B_ANCHOR_LT 0 /* left node is anchored, right is new */
#define H5B_ANCHOR_RT 1 /* right node is anchored, left is new */
typedef enum H5B_subid_t {
- H5B_SUBTYPE_SNODE =0 /*B-tree is for symbol table nodes */
+ H5B_SNODE_ID =0 /*B-tree is for symbol table nodes */
} H5B_subid_t;
/*
* Each class of object that can be pointed to by a B-link tree has a
- * variable of this type that contains class variables and methods.
+ * variable of this type that contains class variables and methods. Each
+ * tree has a K (1/2 rank) value on a per-file basis. The file_create_parms
+ * has an array of K values indexed by the `id' class field below. The
+ * array is initialized with the HDF5_BTREE_K_DEFAULT macro.
*/
typedef struct H5B_class_t {
H5B_subid_t id; /*id as found in file */
- intn k; /* max children is 2k */
size_t sizeof_nkey; /*size of native (memory) key */
size_t (*get_sizeof_rkey)(hdf5_file_t*);
haddr_t (*new)(hdf5_file_t*,void*,void*,void*);
diff --git a/src/H5C.c b/src/H5C.c
index 1ed0c31..67f4d72 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -36,6 +36,7 @@ static char RcsId[] = "@(#)$Revision$";
/* private header files */
#include "H5private.h" /* Generic Functions */
+#include "H5Bprivate.h" /* B-tree subclass names */
#include "H5Cprivate.h" /* Template information */
#define PABLO_MASK H5C_mask
@@ -48,7 +49,8 @@ static intn interface_initialize_g = FALSE;
/* Define the library's default file creation template (constants in hdf5lims.h) */
const file_create_temp_t default_file_create={
HDF5_USERBLOCK_DEFAULT, /* Default user-block size */
- HDF5_BTREEPAGE_DEFAULT, /* Default B-tree page size */
+ HDF5_SYM_LEAF_K_DEFAULT, /* Default 1/2 rank for symtab leaf nodes */
+ HDF5_BTREE_K_DEFAULT, /* Default 1/2 rank for btree internal nodes */
HDF5_OFFSETSIZE_DEFAULT, /* Default offset size */
HDF5_LENGTHSIZE_DEFAULT, /* Default length size */
HDF5_BOOTBLOCK_VERSION, /* Current Boot-Block version # */
@@ -293,6 +295,11 @@ done:
DESCRIPTION
This function retrieves the value of a specific parameter from a
template
+
+ MODIFICATIONS
+ Robb Matzke, 13 Aug 1997
+ Removed H5_BTREE_SIZE and replaced it with H5_SYM_LEAF_K and
+ H5_SYM_INTERN_K.
--------------------------------------------------------------------------*/
herr_t H5Cgetparm(hatom_t tid, file_create_param_t parm, VOIDP buf)
{
@@ -324,9 +331,13 @@ herr_t H5Cgetparm(hatom_t tid, file_create_param_t parm, VOIDP buf)
*(uintn *)buf=template->length_size;
break;
- case H5_BTREE_SIZE:
- *(uintn *)buf=template->btree_page_size;
- break;
+ case H5_SYM_LEAF_K:
+ *(uintn *)buf=template->sym_leaf_k;
+ break;
+
+ case H5_SYM_INTERN_K:
+ *(uintn *)buf = template->btree_k[H5B_SNODE_ID];
+ break;
case H5_BOOTBLOCK_VER:
*(uint8 *)buf=template->bootblock_ver;
@@ -377,11 +388,17 @@ done:
SUCCEED/FAIL
DESCRIPTION
This function stores the value of a specific parameter for a template
+
+ MODIFICATIONS
+ Robb Matzke, 13 Aug 1997
+ Removed H5_BTREE_SIZE and replaced it with H5_SYM_LEAF_K and
+ H5_SYM_INTERN_K.
--------------------------------------------------------------------------*/
herr_t H5Csetparm(hatom_t tid, file_create_param_t parm, const VOIDP buf)
{
file_create_temp_t *template; /* template to query */
herr_t ret_value = SUCCEED;
+ uintn val;
FUNC_ENTER(H5Csetparm, H5C_init_interface, FAIL);
@@ -408,10 +425,22 @@ herr_t H5Csetparm(hatom_t tid, file_create_param_t parm, const VOIDP buf)
template->length_size=*(const uintn *)buf;
break;
- case H5_BTREE_SIZE:
- template->btree_page_size=*(const uintn *)buf;
- break;
-
+ case H5_SYM_LEAF_K:
+ val = *(const uintn *)buf;
+ if (val<2) {
+ HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);
+ }
+ template->sym_leaf_k = val;
+ break;
+
+ case H5_SYM_INTERN_K:
+ val = *(const uintn *)buf;
+ if (val<2) {
+ HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);
+ }
+ template->btree_k[H5B_SNODE_ID] = val;
+ break;
+
case H5_BOOTBLOCK_VER:
template->bootblock_ver=*(const uint8 *)buf;
break;
diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h
index c8678cc..dcce767 100644
--- a/src/H5Eprivate.h
+++ b/src/H5Eprivate.h
@@ -108,6 +108,7 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
{H5E_ALIGNMENT, "Alignment error"},
{H5E_BADMESG, "Unrecognized message"},
{H5E_COMPLEN, "Name component is too long"},
+ {H5E_LINK, "Link count failure"},
};
/* We use a stack to hold the errors plus we keep track of the function,
diff --git a/src/H5Eproto.h b/src/H5Eproto.h
index c61704c..cd3f58a 100644
--- a/src/H5Eproto.h
+++ b/src/H5Eproto.h
@@ -142,7 +142,8 @@ typedef enum
H5E_BADMESG, /* Unrecognized message */
/* Directory related errors */
- H5E_COMPLEN /* Name component is too long */
+ H5E_COMPLEN, /* Name component is too long */
+ H5E_LINK /* Link count failure */
}
hdf_min_err_code_t;
diff --git a/src/H5F.c b/src/H5F.c
index 38eb17c..3020dab 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -508,7 +508,8 @@ hatom_t H5Fcreate(const char *filename, uintn flags, hatom_t create_temp, hatom_
*p++=f_create_parms->offset_size; /* Encode the number of bytes for the offset */
*p++=f_create_parms->length_size; /* Encode the number of bytes for the length */
*p++=0; /* Encode the reserved byte :-) */
- UINT32ENCODE(p,f_create_parms->btree_page_size); /* Encode the B-Tree page size */
+ UINT16ENCODE(p,f_create_parms->sym_leaf_k); /*symbol table leaf node 1/2 rank */
+ UINT16ENCODE(p,f_create_parms->btree_k[H5B_SNODE_ID]);/*stab internal node 1/2 rank */
UINT32ENCODE(p,new_file->consist_flags); /* Encode File-Consistancy flags */
H5F_encode_offset(new_file,p,new_file->smallobj_off); /* Encode offset of global small-object heap */
H5F_encode_offset(new_file,p,new_file->freespace_off); /* Encode offset of global free-space heap */
@@ -686,7 +687,8 @@ hatom_t H5Fopen(const char *filename, uintn flags, hatom_t access_temp)
new_file->file_create_parms.offset_size=*p++; /* Decode the number of bytes for the offset */
new_file->file_create_parms.length_size=*p++; /* Decode the number of bytes for the length */
p++; /* Decode the reserved byte :-) */
- UINT32DECODE(p,new_file->file_create_parms.btree_page_size); /* Decode the B-Tree page size */
+ UINT16DECODE (p, new_file->file_create_parms.sym_leaf_k); /*stab leaf 1/2 rank*/
+ UINT16DECODE (p, new_file->file_create_parms.btree_k[H5B_SNODE_ID]); /*stab internal 1/2 rank*/
UINT32DECODE(p,new_file->consist_flags); /* Decode File-Consistancy flags */
/* Read the variable-size part of the boot-block */
@@ -931,8 +933,11 @@ H5F_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
"Size of file off_t type:",
(unsigned)(f->file_create_parms.length_size));
fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Bytes per B-tree page:",
- (unsigned)(f->file_create_parms.btree_page_size));
+ "Symbol table leaf node 1/2 rank:",
+ (unsigned)(f->file_create_parms.sym_leaf_k));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Symbol table internal node 1/2 rank:",
+ (unsigned)(f->file_create_parms.btree_k[H5B_SNODE_ID]));
fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
"Boot block version number:",
(unsigned)(f->file_create_parms.bootblock_ver));
diff --git a/src/H5G.c b/src/H5G.c
index 45aada7..f6cbb9b 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -279,6 +279,7 @@ H5G_mkroot (hdf5_file_t *f, size_t size_hint)
H5O_name_t name; /*object name message */
H5G_entry_t root; /*old root entry */
const char *root_name=NULL; /*name of old root object */
+ intn nlinks; /*number of links */
FUNC_ENTER (H5G_mkroot, NULL, FAIL);
@@ -310,9 +311,19 @@ H5G_mkroot (hdf5_file_t *f, size_t size_hint)
}
/*
- * Insert the old root object.
+ * Increase the link count for the root symbol table!
+ */
+ nlinks = H5O_link (f, f->root_sym->header, f->root_sym, 1);
+ assert (1==nlinks);
+
+ /*
+ * Insert the old root object. It should already have a link count
+ * of 1.
*/
if (root_name) {
+ nlinks = H5O_link (f, root.header, &root, 0);
+ assert (1==nlinks);
+
if (H5G_stab_insert (f, f->root_sym, root_name, &root)) {
/* can't insert old root object in new root directory */
H5O_reset (H5O_NAME, &name);
@@ -472,6 +483,9 @@ H5G_find (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
* ('/') since that is a special case. If NAME is the root
* symbol table entry, then this function will return failure.
*
+ * Inserting an object entry into the symbol table increments
+ * the link counter for that object.
+ *
* Return: Success: SUCCEED with optional DIR_ENT initialized with
* the symbol table entry for the directory
* which contains the new ENT.
@@ -532,6 +546,11 @@ H5G_insert (hdf5_file_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
}
}
+ /* increment the link count */
+ if (H5O_link (f, ent->header, ent, 1)<0) {
+ HRETURN_ERROR (H5E_DIRECTORY, H5E_LINK, FAIL); /*can't increase linkage*/
+ }
+
/* insert entry into parent */
if (H5G_stab_insert (f, dir_ent, rest, ent)<0) {
HRETURN_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL); /*can't insert*/
@@ -668,8 +687,12 @@ H5G_stab_new (hdf5_file_t *f, H5G_entry_t *self, size_t init)
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
- /* Create symbol table object header with a single link */
- if ((addr = H5O_new (f, 1, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
+ /*
+ * Create symbol table object header. It has a zero link count
+ * since nothing refers to it yet. The link count will be
+ * incremented if the object is added to the directory hierarchy.
+ */
+ if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
@@ -839,6 +862,8 @@ H5G_stab_insert (hdf5_file_t *f, H5G_entry_t *self, const char *name,
HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL);
}
+ /* update the name offset in the entry */
+ ent->name_off = udata.entry.name_off;
FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 9b33515..9cab6f1 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -67,8 +67,7 @@ static const H5AC_class_t H5AC_SNODE[1] = {{
/* H5G inherits B-tree like properties from H5B */
const H5B_class_t H5B_SNODE[1] = {{
- H5B_SUBTYPE_SNODE, /*id */
- 16, /*k */
+ H5B_SNODE_ID, /*id */
sizeof (H5G_node_key_t), /*sizeof_nkey */
H5G_node_sizeof_rkey, /*get_sizeof_rkey */
H5G_node_new, /*new */
@@ -198,7 +197,7 @@ static size_t
H5G_node_size (hdf5_file_t *f)
{
return H5G_NODE_SIZEOF_HDR(f) +
- (2*H5G_NODE_K) * H5G_SIZEOF_ENTRY(f);
+ (2*H5G_NODE_K(f)) * H5G_SIZEOF_ENTRY(f);
}
@@ -246,7 +245,7 @@ H5G_node_new (hdf5_file_t *f, void *_lt_key, void *_udata, void *_rt_key)
}
sym->dirty = 1;
- sym->entry = H5MM_xcalloc (2 * H5G_NODE_K, sizeof(H5G_entry_t));
+ sym->entry = H5MM_xcalloc (2 * H5G_NODE_K(f), sizeof(H5G_entry_t));
if (H5AC_set (f, H5AC_SNODE, addr, sym)<0) {
H5MM_xfree (sym->entry);
H5MM_xfree (sym);
@@ -373,7 +372,7 @@ H5G_node_load (hdf5_file_t *f, haddr_t addr, const void *_udata)
size = H5G_node_size (f);
buf = p = H5MM_xmalloc (size);
sym = H5MM_xcalloc (1, sizeof(H5G_node_t));
- sym->entry = H5MM_xcalloc (2*H5G_NODE_K, sizeof(H5G_entry_t));
+ sym->entry = H5MM_xcalloc (2*H5G_NODE_K(f), sizeof(H5G_entry_t));
if (H5F_block_read (f, addr, size, buf)<0) {
H5MM_xfree (sym->entry);
@@ -600,11 +599,13 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
H5G_node_ud1_t *udata = (H5G_node_ud1_t *)_udata;
H5G_node_t *sn;
- H5G_entry_t ent[2*H5G_NODE_K];
+ H5G_entry_t *ent, _ent[128];
haddr_t new_node=0, offset;
const char *s;
intn idx=-1, nsyms, cmp=1;
intn lt=0, rt; /*binary search cntrs */
+ hbool_t malloced;
+ haddr_t ret_value = FAIL;
FUNC_ENTER (H5G_node_insert, NULL, FAIL);
@@ -617,6 +618,13 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
assert (md_key);
assert (rt_key);
assert (udata);
+ if (2*H5G_NODE_K(f)>NELMTS(_ent)) {
+ ent = H5MM_xmalloc (2*H5G_NODE_K(f) * sizeof(H5G_entry_t));
+ malloced = TRUE;
+ } else {
+ ent = _ent;
+ malloced = FALSE;
+ }
/*
* Symbol tables are always split so the new symbol table node is
@@ -631,7 +639,7 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
* worry about the cached value disappearing.
*/
if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
HDmemcpy (ent, sn->entry, sn->nsyms * sizeof(H5G_entry_t));
rt = nsyms = sn->nsyms;
@@ -643,10 +651,10 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
while (lt<rt) {
idx = (lt + rt) / 2;
if (NULL==(s=H5H_peek (f, udata->heap, ent[idx].name_off))) {
- HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
if (0==(cmp=HDstrcmp (udata->name, s))) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL); /*already present*/
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL); /*already present*/
}
if (cmp<0) {
rt = idx;
@@ -662,9 +670,10 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
* with the new heap address.
*/
offset = H5H_insert (f, udata->heap, strlen(udata->name)+1, udata->name);
- if (offset<0) HRETURN_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL);
+ udata->entry.name_off = offset;
+ if (offset<0) HGOTO_ERROR (H5E_SYM, H5E_CANTINSERT, FAIL);
- if (nsyms>=2*H5G_NODE_K) {
+ if (nsyms>=2*H5G_NODE_K(f)) {
/*
* The node is full. Split it into a left and right
* node and return the address of the new right node (the
@@ -673,15 +682,15 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
/* The left node */
if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
- HDmemset (sn->entry+H5G_NODE_K, 0, H5G_NODE_K*sizeof(H5G_entry_t));
- sn->nsyms = H5G_NODE_K;
+ HDmemset (sn->entry+H5G_NODE_K(f), 0, H5G_NODE_K(f)*sizeof(H5G_entry_t));
+ sn->nsyms = H5G_NODE_K(f);
sn->dirty += 1;
- if (idx<=H5G_NODE_K) {
+ if (idx<=H5G_NODE_K(f)) {
memmove (sn->entry+idx+1, sn->entry+idx,
- (H5G_NODE_K-idx) * sizeof(H5G_entry_t));
+ (H5G_NODE_K(f)-idx) * sizeof(H5G_entry_t));
sn->entry[idx] = udata->entry;
sn->entry[idx].name_off = offset;
sn->nsyms += 1;
@@ -692,20 +701,20 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
/* The right node */
if ((new_node = H5G_node_new (f, NULL, NULL, NULL))<0) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
if (NULL==(sn=H5AC_find (f, H5AC_SNODE, new_node, NULL))) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
- HDmemcpy (sn->entry, ent+H5G_NODE_K,
- H5G_NODE_K*sizeof(H5G_entry_t));
- sn->nsyms = H5G_NODE_K;
+ HDmemcpy (sn->entry, ent+H5G_NODE_K(f),
+ H5G_NODE_K(f)*sizeof(H5G_entry_t));
+ sn->nsyms = H5G_NODE_K(f);
sn->dirty += 1;
- if (idx>H5G_NODE_K) {
- idx -= H5G_NODE_K;
+ if (idx>H5G_NODE_K(f)) {
+ idx -= H5G_NODE_K(f);
HDmemmove (sn->entry+idx+1, sn->entry+idx,
- (H5G_NODE_K-idx) * sizeof (H5G_entry_t));
+ (H5G_NODE_K(f)-idx) * sizeof (H5G_entry_t));
sn->entry[idx] = udata->entry;
sn->entry[idx].name_off = offset;
sn->nsyms += 1;
@@ -721,7 +730,7 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
* Add the new symbol to the node.
*/
if (NULL==(sn=H5AC_find (f, H5AC_SNODE, addr, NULL))) {
- HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
+ HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
sn->dirty += 1;
HDmemmove (sn->entry+idx+1, sn->entry+idx,
@@ -735,8 +744,11 @@ H5G_node_insert (hdf5_file_t *f, haddr_t addr, intn *anchor,
*rt_key_changed = TRUE;
}
}
+ HRETURN (new_node);
- FUNC_LEAVE (new_node);
+done: /*error*/
+ if (malloced) ent = H5MM_xfree (ent);
+ FUNC_LEAVE (FAIL);
}
@@ -890,7 +902,7 @@ H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
sn->dirty);
fprintf (stream, "%*s%-*s %d of %d\n", indent, "", fwidth,
"Number of Symbols:",
- sn->nsyms, 2*H5G_NODE_K);
+ sn->nsyms, 2*H5G_NODE_K(f));
indent += 3;
fwidth = MAX (0, fwidth-3);
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index bbfe9a0..d5956bd 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -27,7 +27,7 @@
#define H5G_NODE_MAGIC "SNOD" /*symbol table node magic number */
#define H5G_NODE_SIZEOF_MAGIC 4 /*sizeof symbol node magic number */
#define H5G_NODE_VERS 1 /*symbol table node version number */
-#define H5G_NODE_K 4 /*min degree. max degree is twice this */
+#define H5G_NODE_K(F) ((F)->file_create_parms.sym_leaf_k)
#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
#define H5G_SIZEOF_ENTRY(F) \
(H5F_SIZEOF_OFFSET(F) + /*offset of name into heap */ \
diff --git a/src/H5O.c b/src/H5O.c
index c594964..9ac0cd8 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -99,7 +99,7 @@ H5O_new (hdf5_file_t *f, intn nlink, size_t size_hint)
/* check args */
assert (f);
- assert (nlink>0);
+ assert (nlink>=0);
if (size_hint<H5O_MIN_SIZE) size_hint = H5O_MIN_SIZE;
H5O_ALIGN (size_hint, H5O_ALIGNMENT);
@@ -759,7 +759,7 @@ H5O_modify (hdf5_file_t *f, haddr_t addr, H5G_entry_t *ent,
oh->dirty = TRUE;
/* Copy into the symbol table entry */
- if (1==oh->nlink && ent && type->cache) {
+ if (oh->nlink<=1 && ent && type->cache) {
hbool_t modified = (type->cache)(ent, mesg);
if (ent_modified) *ent_modified = modified;
}
diff --git a/src/debug.c b/src/debug.c
index 220b461..882a164 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -113,7 +113,7 @@ main (int argc, char *argv[])
*/
H5B_subid_t subtype = sig[H5B_SIZEOF_MAGIC];
switch (subtype) {
- case H5B_SUBTYPE_SNODE:
+ case H5B_SNODE_ID:
status = H5G_node_debug (f, addr, stdout, 0, VCOL, extra);
break;
diff --git a/src/hdf5lims.h b/src/hdf5lims.h
index 385b8a4..363ea54 100644
--- a/src/hdf5lims.h
+++ b/src/hdf5lims.h
@@ -55,7 +55,18 @@
#define HDF5_USERBLOCK_DEFAULT 0 /* Default to 0-byte sized user blocks */
#define HDF5_OFFSETSIZE_DEFAULT 4 /* Default to 4-byte offsets */
#define HDF5_LENGTHSIZE_DEFAULT 4 /* Default to 4-byte lengths */
-#define HDF5_BTREEPAGE_DEFAULT 1024 /* Default to 1024-byte B-tree pages */
+#define HDF5_SYM_LEAF_K_DEFAULT 4 /* Default 1/2 rank for symtab leaf nodes */
+#define HDF5_BTREE_K_DEFAULT { \
+ 16, /* Symbol table internal nodes */ \
+ 0, /* unused */ \
+ 0, /* unused */ \
+ 0, /* unused */ \
+ 0, /* unused */ \
+ 0, /* unused */ \
+ 0, /* unused */ \
+ 0 /* unused */ \
+}
+
#endif /* HDF5LIMS_H */
diff --git a/src/hdf5type.h b/src/hdf5type.h
index 2296991..25496a3 100644
--- a/src/hdf5type.h
+++ b/src/hdf5type.h
@@ -33,7 +33,8 @@ typedef struct {
/* These object aren't ref. counted, I can't think of a good reason why you'd access each one more than once */
/* uintn ref_count; Reference count for number of times object is accessed */
uintn userblock_size; /* Size of the user block in the file in bytes */
- uintn btree_page_size; /* Number of bytes for B-Tree pages */
+ uintn sym_leaf_k; /* 1/2 rank for symbol table leaf nodes */
+ uintn btree_k[8]; /* 1/2 rank for btree internal nodes */
uint8 offset_size; /* Number of bytes for offsets */
uint8 length_size; /* Number of bytes for lengths */
uint8 bootblock_ver; /* Version # of the bootblock */
@@ -48,7 +49,8 @@ typedef enum {
H5_USERBLOCK_SIZE, /* (uintn) Size of the user block in the file in bytes */
H5_OFFSET_SIZE, /* (uintn) Number of bytes for offsets */
H5_LENGTH_SIZE, /* (uintn) Number of bytes for lengths */
- H5_BTREE_SIZE, /* (uintn) Number of bytes for B-Tree pages */
+ H5_SYM_LEAF_K, /* (uintn) 1/2 rank for symbol table leaf nodes */
+ H5_SYM_INTERN_K, /* (uintn) 1/2 rank for symbol table internal nodes */
H5_BOOTBLOCK_VER, /* (uint8) Version # of the boot-block format */
H5_SMALLOBJECT_VER, /* (uint8) Version # of the small-object heap format */
H5_FREESPACE_VER, /* (uint8) Version # of the free-space info format */