From 5cae95154903ecd6564f0712e42168892df17b7d Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Wed, 13 Aug 1997 10:36:47 -0500 Subject: [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. --- src/H5B.c | 84 +++++++++++++++++++++++++++++--------------------------- src/H5Bprivate.h | 11 ++++++-- src/H5C.c | 45 ++++++++++++++++++++++++------ src/H5Eprivate.h | 1 + src/H5Eproto.h | 3 +- src/H5F.c | 13 ++++++--- src/H5G.c | 31 +++++++++++++++++++-- src/H5Gnode.c | 66 ++++++++++++++++++++++++++------------------ src/H5Gprivate.h | 2 +- src/H5O.c | 4 +-- src/debug.c | 2 +- src/hdf5lims.h | 13 ++++++++- src/hdf5type.h | 6 ++-- 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 (ik) { + if (ichild[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 (ik) { + if (ichild[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 (ltheap, 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_hintdirty = 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 */ -- cgit v0.12