mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-31 17:10:47 +08:00
[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:
parent
46ef9d9c26
commit
5cae951549
84
src/H5B.c
84
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
|
||||
|
@ -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*);
|
||||
|
43
src/H5C.c
43
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;
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
13
src/H5F.c
13
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));
|
||||
|
31
src/H5G.c
31
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */ \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user