[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.
This commit is contained in:
Robb Matzke 1997-08-13 10:36:47 -05:00
parent 46ef9d9c26
commit 5cae951549
13 changed files with 186 additions and 93 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */ \

View File

@ -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;
}

View File

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

View File

@ -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 */

View File

@ -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 */