From 585d31b7cb6cacfec86f68fc3dd66c0e67aafbd8 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 7 Jul 2004 16:23:45 -0500 Subject: [svn-r8823] Purpose: Code optimization Description: Since the raw B-tree nodes are the same size and only used when reading in or writing out a B-tree node, move raw B-tree node buffer from being per node to a single node that is shared among all B-tree nodes of a particular tree, freeing up a lot of space and eliminating lots of memory copies, etc. Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.10 (sleipnir) w/parallel Too minor to require h5committest --- src/H5B.c | 576 +++++++++++++++++-------------------------------------- src/H5Bpkg.h | 11 +- src/H5Bprivate.h | 3 + src/H5Distore.c | 58 +++++- src/H5F.c | 40 ++++ src/H5Fpkg.h | 1 + src/H5Fprivate.h | 4 + src/H5Gnode.c | 115 ++++++++++- src/H5Gprivate.h | 2 + src/H5Oprivate.h | 1 + 10 files changed, 398 insertions(+), 413 deletions(-) diff --git a/src/H5B.c b/src/H5B.c index bee1cd4..0da67bb 100644 --- a/src/H5B.c +++ b/src/H5B.c @@ -137,15 +137,11 @@ static H5B_ins_t H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, static herr_t H5B_insert_child(const H5F_t *f, const H5B_class_t *type, H5B_t *bt, unsigned idx, haddr_t child, H5B_ins_t anchor, const void *md_key); -static herr_t H5B_decode_key(H5F_t *f, H5B_t *bt, unsigned idx); -static herr_t H5B_decode_keys(H5F_t *f, H5B_t *bt, unsigned idx); -static size_t H5B_nodesize(const H5F_t *f, const H5B_class_t *type, - size_t *total_nkey_size, size_t sizeof_rkey); static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr, unsigned idx, void *udata, haddr_t *new_addr/*out*/); static H5B_t * H5B_copy(const H5F_t *f, const H5B_t *old_bt); -static herr_t H5B_serialize(H5F_t *f, H5B_t *bt, uint8_t *buf); +static herr_t H5B_serialize(H5F_t *f, H5B_t *bt); #ifdef H5B_DEBUG static herr_t H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void *udata); @@ -168,14 +164,12 @@ static const H5AC_class_t H5AC_BT[1] = {{ (H5AC_size_func_t)H5B_compute_size, }}; -/* Declare a free list to manage the page information */ -H5FL_BLK_DEFINE_STATIC(page); - /* Declare a PQ free list to manage the native block information */ H5FL_BLK_DEFINE_STATIC(native_block); -/* Declare a free list to manage the H5B_key_t sequence information */ -H5FL_SEQ_DEFINE_STATIC(H5B_key_t); +/* Declare a free list to manage the native key sequence information */ +typedef void *voidp; +H5FL_SEQ_DEFINE_STATIC(voidp); /* Declare a free list to manage the haddr_t sequence information */ H5FL_SEQ_DEFINE_STATIC(haddr_t); @@ -215,7 +209,6 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, size_t sizeof_rkey; size_t size=0; size_t total_native_keysize; - size_t offset; unsigned u; herr_t ret_value = SUCCEED; @@ -236,22 +229,23 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, H5_CHECK_OVERFLOW(size,size_t,hsize_t); if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree root node") - if (NULL==(bt = H5FL_CALLOC(H5B_t))) + if (NULL==(bt = H5FL_MALLOC(H5B_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree root node") bt->type = type; bt->sizeof_node = size; bt->total_native_keysize = total_native_keysize; bt->sizeof_rkey = sizeof_rkey; + HDmemset(&bt->cache_info,0,sizeof(H5AC_info_t)); bt->cache_info.is_dirty = TRUE; - bt->ndirty = 0; bt->level = 0; bt->left = HADDR_UNDEF; bt->right = HADDR_UNDEF; bt->nchildren = 0; - if (NULL==(bt->page=H5FL_BLK_MALLOC(page,size)) || - NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_native_keysize)) || + if((bt->raw_page=(type->get_page)(f, udata))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer") + if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_native_keysize)) || NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type)))) || - NULL==(bt->key=H5FL_SEQ_MALLOC(H5B_key_t,(size_t)(2*H5F_KVALUE(f,type)+1)))) + NULL==(bt->nkey=H5FL_SEQ_MALLOC(voidp,(size_t)(2*H5F_KVALUE(f,type)+1)))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree root node") /* @@ -259,22 +253,15 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, * `page' buffer. Each native key pointer should be null until the key is * translated to native format. */ - for (u = 0, offset = H5B_SIZEOF_HDR(f); - u < 2 * H5F_KVALUE(f, type); - u++, offset += bt->sizeof_rkey + H5F_SIZEOF_ADDR(f)) { - - bt->key[u].dirty = FALSE; - bt->key[u].rkey = bt->page + offset; - bt->key[u].nkey = NULL; + for (u = 0; u < 2 * H5F_KVALUE(f, type); u++) { + bt->nkey[u] = NULL; bt->child[u] = HADDR_UNDEF; } /* * The last possible key... */ - bt->key[2 * H5F_KVALUE(f, type)].dirty = FALSE; - bt->key[2 * H5F_KVALUE(f, type)].rkey = bt->page + offset; - bt->key[2 * H5F_KVALUE(f, type)].nkey = NULL; + bt->nkey[2 * H5F_KVALUE(f, type)] = NULL; /* * Cache the new B-tree node. @@ -328,7 +315,8 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) size_t total_nkey_size; size_t size; H5B_t *bt = NULL; - uint8_t *p; + uint8_t *p; /* Pointer into raw data buffer */ + uint8_t *native; /* Pointer to native keys */ unsigned u; /* Local index variable */ H5B_t *ret_value; @@ -340,22 +328,24 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) assert(type); assert(type->get_sizeof_rkey); - if (NULL==(bt = H5FL_CALLOC(H5B_t))) + if (NULL==(bt = H5FL_MALLOC(H5B_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") bt->sizeof_rkey = (type->get_sizeof_rkey) (f, udata); bt->sizeof_node = size = H5B_nodesize(f, type, &total_nkey_size, bt->sizeof_rkey); bt->total_native_keysize = total_nkey_size; bt->type = type; - bt->cache_info.is_dirty = FALSE; - bt->ndirty = 0; - if (NULL==(bt->page=H5FL_BLK_MALLOC(page,size)) || - NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_nkey_size)) || - NULL==(bt->key=H5FL_SEQ_MALLOC(H5B_key_t,(size_t)(2*H5F_KVALUE(f,type)+1))) || + HDmemset(&bt->cache_info,0,sizeof(H5AC_info_t)); + if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,total_nkey_size)) || + NULL==(bt->nkey=H5FL_SEQ_MALLOC(voidp,(size_t)(2*H5F_KVALUE(f,type)+1))) || NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type))))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, bt->page)<0) + + if((bt->raw_page=(type->get_page)(f, udata))==NULL) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer") + if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, bt->raw_page)<0) HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node") - p = bt->page; + + p = bt->raw_page; /* magic number */ if (HDmemcmp(p, H5B_MAGIC, H5B_SIZEOF_MAGIC)) @@ -375,24 +365,32 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata) H5F_addr_decode(f, (const uint8_t **) &p, &(bt->right)); /* the child/key pairs */ - for (u = 0; u < 2 * H5F_KVALUE(f, type); u++) { - - bt->key[u].dirty = FALSE; - bt->key[u].rkey = p; - p += bt->sizeof_rkey; - bt->key[u].nkey = NULL; + native=bt->native; + for (u = 0; u < bt->nchildren; u++) { + /* Decode native key value */ + if ((type->decode) (f, bt, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key") + bt->nkey[u]=native; + p += bt->sizeof_rkey; + native += type->sizeof_nkey; - if (u < bt->nchildren) { - H5F_addr_decode(f, (const uint8_t **) &p, bt->child + u); - } else { - bt->child[u] = HADDR_UNDEF; - p += H5F_SIZEOF_ADDR(f); - } + /* Decode address value */ + H5F_addr_decode(f, (const uint8_t **) &p, bt->child + u); } - bt->key[2 * H5F_KVALUE(f, type)].dirty = FALSE; - bt->key[2 * H5F_KVALUE(f, type)].rkey = p; - bt->key[2 * H5F_KVALUE(f, type)].nkey = NULL; + /* Decode final key */ + if(bt->nchildren>0) { + /* Decode native key value */ + if ((type->decode) (f, bt, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key") + bt->nkey[bt->nchildren]=native; + } /* end if */ + + /* Reset remainder of native keys and child addresses */ + for (u++ ; u < 2 * H5F_KVALUE(f, type); u++) { + bt->child[u] = HADDR_UNDEF; + bt->nkey[u] = NULL; + } /* Set return value */ ret_value = bt; @@ -422,10 +420,11 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5B_serialize(H5F_t *f, H5B_t *bt, uint8_t *buf) +H5B_serialize(H5F_t *f, H5B_t *bt) { unsigned u; - uint8_t *p = NULL; + uint8_t *p; /* Pointer into raw data buffer */ + uint8_t *native; /* Pointer to native keys */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B_serialize, FAIL) @@ -433,10 +432,10 @@ H5B_serialize(H5F_t *f, H5B_t *bt, uint8_t *buf) /* check arguments */ assert(f); assert(bt); - assert(bt->page); + assert(bt->raw_page); assert(bt->type); - p = buf; + p = bt->raw_page; /* magic number */ HDmemcpy(p, H5B_MAGIC, H5B_SIZEOF_MAGIC); @@ -455,22 +454,22 @@ H5B_serialize(H5F_t *f, H5B_t *bt, uint8_t *buf) H5F_addr_encode(f, &p, bt->right); /* child keys and pointers */ - for (u = 0; u <= bt->nchildren; ++u) { + native=bt->native; + for (u = 0; u < bt->nchildren; ++u) { /* encode the key */ - assert(bt->key[u].rkey == p); + if (bt->type->encode(f, bt, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") p += bt->sizeof_rkey; - - /* encode the key */ - if (bt->key[u].dirty && bt->key[u].nkey) - if (bt->type->encode(f, bt, bt->key[u].rkey, bt->key[u].nkey) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") + native += bt->type->sizeof_nkey; /* encode the child address */ - if (u < bt->ndirty) - H5F_addr_encode(f, &p, bt->child[u]); - else - p += H5F_SIZEOF_ADDR(f); - } + H5F_addr_encode(f, &p, bt->child[u]); + } /* end for */ + if(bt->nchildren>0) { + /* Encode the final key */ + if (bt->type->encode(f, bt, p, native) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key") + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -520,26 +519,19 @@ H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt) assert(bt->type->encode); if (bt->cache_info.is_dirty) { - unsigned u; - - if (H5B_serialize(f, bt, bt->page) < 0) + if (H5B_serialize(f, bt) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTSERIALIZE, FAIL, "unable to serialize B-tree") - /* child keys and pointers */ - for (u = 0; u <= bt->nchildren; ++u) - bt->key[u].dirty = FALSE; - /* * Write the disk page. We always write the header, but we don't * bother writing data for the child entries that don't exist or * for the final unchanged children. */ - if (H5F_block_write(f, H5FD_MEM_BTREE, addr, bt->sizeof_node, dxpl_id, bt->page) < 0) + if (H5F_block_write(f, H5FD_MEM_BTREE, addr, bt->sizeof_node, dxpl_id, bt->raw_page) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk") bt->cache_info.is_dirty = FALSE; - bt->ndirty = 0; - } + } /* end if */ if (destroy) if (H5B_dest(f,bt) < 0) @@ -580,8 +572,7 @@ H5B_dest(H5F_t UNUSED *f, H5B_t *bt) assert(bt->cache_info.is_dirty==0); H5FL_SEQ_FREE(haddr_t,bt->child); - H5FL_SEQ_FREE(H5B_key_t,bt->key); - H5FL_BLK_FREE(page,bt->page); + H5FL_SEQ_FREE(voidp,bt->nkey); H5FL_BLK_FREE(native_block,bt->native); H5FL_FREE(H5B_t,bt); @@ -607,7 +598,6 @@ H5B_dest(H5F_t UNUSED *f, H5B_t *bt) static herr_t H5B_clear(H5F_t *f, H5B_t *bt, hbool_t destroy) { - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5B_clear) @@ -617,9 +607,7 @@ H5B_clear(H5F_t *f, H5B_t *bt, hbool_t destroy) */ assert(bt); - /* Look for dirty keys and reset the dirty flag. */ - for (u=0; u<=bt->nchildren; u++) - bt->key[u].dirty = FALSE; + /* Reset the dirty flag. */ bt->cache_info.is_dirty = FALSE; if (destroy) @@ -713,9 +701,6 @@ H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *u H5B_t *bt = NULL; unsigned idx=0, lt = 0, rt; /* Final, left & right key indices */ int cmp = 1; /* Key comparison value */ - unsigned level; /* Level of B-tree node */ - haddr_t child; /* Address of child to recurse to */ - void *nkey1, *nkey2; /* Native keys of child */ int ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5B_find, FAIL) @@ -740,11 +725,9 @@ H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *u while (lt < rt && cmp) { idx = (lt + rt) / 2; - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode B-tree key(s)") /* compare */ - if ((cmp = (type->cmp3) (f, dxpl_id, bt->key[idx].nkey, udata, - bt->key[idx+1].nkey)) < 0) { + if ((cmp = (type->cmp3) (f, dxpl_id, bt->nkey[idx], udata, + bt->nkey[idx+1])) < 0) { rt = idx; } else { lt = idx+1; @@ -766,19 +749,8 @@ H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *u */ assert(idx < bt->nchildren); - /* Retrieve the rest of the B-tree information, so we can unlock it before recursing */ - level = bt->level; - child = bt->child[idx]; - nkey1=bt->key[idx].nkey; - nkey2=bt->key[idx+1].nkey; - - if (H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, FALSE) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") - - bt = NULL; /* Make certain future references will be caught */ - - if (level > 0) { - if (H5B_find(f, dxpl_id, type, child, udata) < 0) + if (bt->level > 0) { + if (H5B_find(f, dxpl_id, type, bt->child[idx], udata) < 0) /* Note: don't push error on stack, leave that to next higher level, * since many times the B-tree is searched in order to determine * if an object exists in the B-tree or not. -QAK @@ -789,7 +761,7 @@ H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *u HGOTO_DONE(FAIL) #endif /* OLD_WAY */ } else { - if ((type->found) (f, dxpl_id, child, nkey1, udata, nkey2) < 0) + if ((type->found) (f, dxpl_id, bt->child[idx], bt->nkey[idx], udata, bt->nkey[idx+1]) < 0) /* Note: don't push error on stack, leave that to next higher level, * since many times the B-tree is searched in order to determine * if an object exists in the B-tree or not. -QAK @@ -931,31 +903,26 @@ H5B_split(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_t *old_bt, haddr /* * Copy data from the old node to the new node. */ - HDmemcpy(new_bt->page + H5B_SIZEOF_HDR(f), - old_bt->page + H5B_SIZEOF_HDR(f) + nleft * recsize, - nright * recsize + new_bt->sizeof_rkey); HDmemcpy(new_bt->native, old_bt->native + nleft * type->sizeof_nkey, (nright+1) * type->sizeof_nkey); for (u=0; u<=nright; u++) { /* key */ - new_bt->key[u].dirty = old_bt->key[nleft+u].dirty; - if (old_bt->key[nleft+u].nkey) - new_bt->key[u].nkey = new_bt->native + u * type->sizeof_nkey; + if (old_bt->nkey[nleft+u]) + new_bt->nkey[u] = new_bt->native + u * type->sizeof_nkey; /* child */ if (u < nright) new_bt->child[u] = old_bt->child[nleft+u]; } - new_bt->ndirty = new_bt->nchildren = nright; + new_bt->nchildren = nright; /* * Truncate the old node. */ old_bt->cache_info.is_dirty = TRUE; old_bt->nchildren = nleft; - old_bt->ndirty = MIN(old_bt->ndirty, old_bt->nchildren); /* * Update sibling pointers. @@ -986,76 +953,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5B_decode_key - * - * Purpose: Decode the specified key into native format. Do not call - * this function if the key is already decoded since it my - * decode a stale raw key into the native key. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Jul 8 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5B_decode_key(H5F_t *f, H5B_t *bt, unsigned idx) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5B_decode_key) - - assert(bt->key[idx].dirty==0); - - bt->key[idx].nkey = bt->native + idx * bt->type->sizeof_nkey; - if ((bt->type->decode) (f, bt, bt->key[idx].rkey, bt->key[idx].nkey) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode key") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- - * Function: H5B_decode_keys - * - * Purpose: Decode keys on either side of the specified branch. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Tuesday, October 14, 1997 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5B_decode_keys(H5F_t *f, H5B_t *bt, unsigned idx) -{ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5B_decode_keys) - - assert(f); - assert(bt); - assert(idx < bt->nchildren); - - if (!bt->key[idx].nkey && H5B_decode_key(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode key") - if (!bt->key[idx+1].nkey && H5B_decode_key(f, bt, idx+1) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode key") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} - - -/*------------------------------------------------------------------------- * Function: H5B_insert * * Purpose: Adds a new item to the B-tree. If the root node of @@ -1126,19 +1023,9 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, level = bt->level; if (!lt_key_changed) { - if (!bt->key[0].nkey && H5B_decode_key(f, bt, 0) < 0) { - /* We want the actual error to show up but also want to - * execute the "H5AC_unprotect" call. So we use the - * "HCOMMON_ERROR" macro. */ - HCOMMON_ERROR(H5E_BTREE, H5E_CANTDECODE, "unable to decode key"); + assert(bt->nkey[0]); - if (H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, FALSE) != SUCCEED) - HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release new child") - - HGOTO_DONE(FAIL) - } - - HDmemcpy(lt_key, bt->key[0].nkey, type->sizeof_nkey); + HDmemcpy(lt_key, bt->nkey[0], type->sizeof_nkey); } if (H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, FALSE) != SUCCEED) @@ -1151,17 +1038,9 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load new node") if (!rt_key_changed) { - if (!bt->key[bt->nchildren].nkey && - H5B_decode_key(f, bt, bt->nchildren) < 0) { - HCOMMON_ERROR(H5E_BTREE, H5E_CANTDECODE, "unable to decode key"); - - if (H5AC_unprotect(f, dxpl_id, H5AC_BT, child, bt, FALSE) != SUCCEED) - HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release new child") - - HGOTO_DONE(FAIL) - } + assert(bt->nkey[bt->nchildren]); - HDmemcpy(rt_key, bt->key[bt->nchildren].nkey, type->sizeof_nkey); + HDmemcpy(rt_key, bt->nkey[bt->nchildren], type->sizeof_nkey); } /* @@ -1228,23 +1107,19 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, new_bt->right = HADDR_UNDEF; /* Set the new information for the copy */ - new_bt->ndirty = 2; new_bt->level = level + 1; new_bt->nchildren = 2; new_bt->child[0] = old_root; - new_bt->key[0].dirty = TRUE; - new_bt->key[0].nkey = new_bt->native; - HDmemcpy(new_bt->key[0].nkey, lt_key, type->sizeof_nkey); + new_bt->nkey[0] = new_bt->native; + HDmemcpy(new_bt->nkey[0], lt_key, type->sizeof_nkey); new_bt->child[1] = child; - new_bt->key[1].dirty = TRUE; - new_bt->key[1].nkey = new_bt->native + type->sizeof_nkey; - HDmemcpy(new_bt->key[1].nkey, md_key, type->sizeof_nkey); + new_bt->nkey[1] = new_bt->native + type->sizeof_nkey; + HDmemcpy(new_bt->nkey[1], md_key, type->sizeof_nkey); - new_bt->key[2].dirty = TRUE; - new_bt->key[2].nkey = new_bt->native + 2 * type->sizeof_nkey; - HDmemcpy(new_bt->key[2].nkey, rt_key, type->sizeof_nkey); + new_bt->nkey[2] = new_bt->native + 2 * type->sizeof_nkey; + HDmemcpy(new_bt->nkey[2], rt_key, type->sizeof_nkey); /* Insert the modified copy of the old root into the file again */ if (H5AC_set(f, dxpl_id, H5AC_BT, addr, new_bt) < 0) @@ -1298,51 +1173,37 @@ H5B_insert_child(const H5F_t *f, const H5B_class_t *type, H5B_t *bt, */ idx++; - HDmemmove(bt->page + H5B_SIZEOF_HDR(f) + (idx+1) * recsize, - bt->page + H5B_SIZEOF_HDR(f) + idx * recsize, - (bt->nchildren - idx) * recsize + bt->sizeof_rkey); - HDmemmove(bt->native + (idx+1) * type->sizeof_nkey, bt->native + idx * type->sizeof_nkey, ((bt->nchildren - idx) + 1) * type->sizeof_nkey); for (u=bt->nchildren; u>=idx; --u) { - bt->key[u+1].dirty = bt->key[u].dirty; - if (bt->key[u].nkey) { - bt->key[u+1].nkey = bt->native + (u+1) * type->sizeof_nkey; + if (bt->nkey[u]) { + bt->nkey[u+1] = bt->native + (u+1) * type->sizeof_nkey; } else { - bt->key[u+1].nkey = NULL; + bt->nkey[u+1] = NULL; } } - bt->key[idx].dirty = TRUE; - bt->key[idx].nkey = bt->native + idx * type->sizeof_nkey; - HDmemcpy(bt->key[idx].nkey, md_key, type->sizeof_nkey); + bt->nkey[idx] = bt->native + idx * type->sizeof_nkey; + HDmemcpy(bt->nkey[idx], md_key, type->sizeof_nkey); } else { /* * The MD_KEY is the right key of the new node. */ - HDmemmove(bt->page + (H5B_SIZEOF_HDR(f) + - (idx+1) * recsize + bt->sizeof_rkey), - bt->page + (H5B_SIZEOF_HDR(f) + - idx * recsize + bt->sizeof_rkey), - (bt->nchildren - idx) * recsize); - HDmemmove(bt->native + (idx+2) * type->sizeof_nkey, bt->native + (idx+1) * type->sizeof_nkey, (bt->nchildren - idx) * type->sizeof_nkey); for (u = bt->nchildren; u > idx; --u) { - bt->key[u+1].dirty = bt->key[u].dirty; - if (bt->key[u].nkey) { - bt->key[u+1].nkey = bt->native + (u+1) * type->sizeof_nkey; + if (bt->nkey[u]) { + bt->nkey[u+1] = bt->native + (u+1) * type->sizeof_nkey; } else { - bt->key[u+1].nkey = NULL; + bt->nkey[u+1] = NULL; } } - bt->key[idx+1].dirty = TRUE; - bt->key[idx+1].nkey = bt->native + (idx+1) * type->sizeof_nkey; - HDmemcpy(bt->key[idx+1].nkey, md_key, type->sizeof_nkey); + bt->nkey[idx+1] = bt->native + (idx+1) * type->sizeof_nkey; + HDmemcpy(bt->nkey[idx+1], md_key, type->sizeof_nkey); } HDmemmove(bt->child + idx + 1, @@ -1351,7 +1212,6 @@ H5B_insert_child(const H5F_t *f, const H5B_class_t *type, H5B_t *bt, bt->child[idx] = child; bt->nchildren += 1; - bt->ndirty = bt->nchildren; FUNC_LEAVE_NOAPI(SUCCEED) } @@ -1448,10 +1308,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type while (lt < rt && cmp) { idx = (lt + rt) / 2; - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - if ((cmp = (type->cmp3) (f, dxpl_id, bt->key[idx].nkey, udata, - bt->key[idx+1].nkey)) < 0) { + if ((cmp = (type->cmp3) (f, dxpl_id, bt->nkey[idx], udata, + bt->nkey[idx+1])) < 0) { rt = idx; } else { lt = idx + 1; @@ -1464,23 +1322,20 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * must necessarily be at level zero. */ assert(0 == bt->level); - bt->key[0].nkey = bt->native; - bt->key[1].nkey = bt->native + type->sizeof_nkey; - if ((type->new_node)(f, dxpl_id, H5B_INS_FIRST, bt->key[0].nkey, udata, - bt->key[1].nkey, bt->child + 0/*out*/) < 0) { - bt->key[0].nkey = bt->key[1].nkey = NULL; + bt->nkey[0] = bt->native; + bt->nkey[1] = bt->native + type->sizeof_nkey; + if ((type->new_node)(f, dxpl_id, H5B_INS_FIRST, bt->nkey[0], udata, + bt->nkey[1], bt->child + 0/*out*/) < 0) { + bt->nkey[0] = bt->nkey[1] = NULL; HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, H5B_INS_ERROR, "unable to create leaf node") } bt->nchildren = 1; bt->cache_info.is_dirty = TRUE; - bt->ndirty = 1; - bt->key[0].dirty = TRUE; - bt->key[1].dirty = TRUE; idx = 0; if (type->follow_min) { - if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->key[idx].nkey, - lt_key_changed, md_key, udata, bt->key[idx+1].nkey, + if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx], + lt_key_changed, md_key, udata, bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert first leaf node") } else { @@ -1492,11 +1347,9 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * The value being inserted is less than any value in this tree. * Follow the minimum branch out of this node to a subtree. */ - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") if ((my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, - bt->key[idx].nkey, lt_key_changed, md_key, - udata, bt->key[idx+1].nkey, rt_key_changed, + bt->nkey[idx], lt_key_changed, md_key, + udata, bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/))<0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum subtree") } else if (cmp < 0 && idx == 0 && type->follow_min) { @@ -1505,10 +1358,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * current node. Follow the minimum branch to a leaf node and let the * subclass handle the problem. */ - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->key[idx].nkey, - lt_key_changed, md_key, udata, bt->key[idx+1].nkey, + if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx], + lt_key_changed, md_key, udata, bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") } else if (cmp < 0 && idx == 0) { @@ -1517,11 +1368,9 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * current node. Create a new minimum leaf node out of this B-tree * node. This node is not empty (handled above). */ - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") my_ins = H5B_INS_LEFT; - HDmemcpy(md_key, bt->key[idx].nkey, type->sizeof_nkey); - if ((type->new_node)(f, dxpl_id, H5B_INS_LEFT, bt->key[idx].nkey, udata, + HDmemcpy(md_key, bt->nkey[idx], type->sizeof_nkey); + if ((type->new_node)(f, dxpl_id, H5B_INS_LEFT, bt->nkey[idx], udata, md_key, &child_addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert minimum leaf node") *lt_key_changed = TRUE; @@ -1532,11 +1381,9 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * Follow the maximum branch out of this node to a subtree. */ idx = bt->nchildren - 1; - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") if ((my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, - bt->key[idx].nkey, lt_key_changed, md_key, udata, - bt->key[idx+1].nkey, rt_key_changed, &child_addr/*out*/)) < 0) + bt->nkey[idx], lt_key_changed, md_key, udata, + bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum subtree") } else if (cmp > 0 && idx + 1 >= bt->nchildren && type->follow_max) { /* @@ -1545,10 +1392,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * subclass handle the problem. */ idx = bt->nchildren - 1; - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->key[idx].nkey, - lt_key_changed, md_key, udata, bt->key[idx+1].nkey, + if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx], + lt_key_changed, md_key, udata, bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") } else if (cmp > 0 && idx + 1 >= bt->nchildren) { @@ -1558,12 +1403,10 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * node. */ idx = bt->nchildren - 1; - if (H5B_decode_keys(f, bt, idx) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") my_ins = H5B_INS_RIGHT; - HDmemcpy(md_key, bt->key[idx+1].nkey, type->sizeof_nkey); + HDmemcpy(md_key, bt->nkey[idx+1], type->sizeof_nkey); if ((type->new_node)(f, dxpl_id, H5B_INS_RIGHT, md_key, udata, - bt->key[idx+1].nkey, &child_addr/*out*/) < 0) + bt->nkey[idx+1], &child_addr/*out*/) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert maximum leaf node") *rt_key_changed = TRUE; @@ -1582,16 +1425,16 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ assert(idx < bt->nchildren); if ((my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type, - bt->key[idx].nkey, lt_key_changed, md_key, udata, - bt->key[idx+1].nkey, rt_key_changed, &child_addr/*out*/)) < 0) + bt->nkey[idx], lt_key_changed, md_key, udata, + bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert subtree") } else { /* * Follow a branch out of this node to a leaf node of some other type. */ assert(idx < bt->nchildren); - if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->key[idx].nkey, - lt_key_changed, md_key, udata, bt->key[idx+1].nkey, + if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx], + lt_key_changed, md_key, udata, bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0) HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert leaf node") } @@ -1602,21 +1445,17 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ if (*lt_key_changed) { bt->cache_info.is_dirty = TRUE; - bt->key[idx].dirty = TRUE; - if (idx > 0) { + if (idx > 0) *lt_key_changed = FALSE; - } else { - HDmemcpy(lt_key, bt->key[idx].nkey, type->sizeof_nkey); - } + else + HDmemcpy(lt_key, bt->nkey[idx], type->sizeof_nkey); } if (*rt_key_changed) { bt->cache_info.is_dirty = TRUE; - bt->key[idx+1].dirty = TRUE; - if (idx+1 < bt->nchildren) { + if (idx+1 < bt->nchildren) *rt_key_changed = FALSE; - } else { - HDmemcpy(rt_key, bt->key[idx+1].nkey, type->sizeof_nkey); - } + else + HDmemcpy(rt_key, bt->nkey[idx+1], type->sizeof_nkey); } if (H5B_INS_CHANGE == my_ins) { /* @@ -1624,7 +1463,6 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ bt->child[idx] = child_addr; bt->cache_info.is_dirty = TRUE; - bt->ndirty = MAX(bt->ndirty, idx+1); ret_value = H5B_INS_NOOP; } else if (H5B_INS_LEFT == my_ins || H5B_INS_RIGHT == my_ins) { @@ -1658,21 +1496,17 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * by the left and right node). */ if (twin) { - if (!twin->key[0].nkey && H5B_decode_key(f, twin, 0) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - HDmemcpy(md_key, twin->key[0].nkey, type->sizeof_nkey); + assert(twin->nkey[0]); + HDmemcpy(md_key, twin->nkey[0], type->sizeof_nkey); ret_value = H5B_INS_RIGHT; #ifdef H5B_DEBUG /* * The max key in the original left node must be equal to the min key * in the new node. */ - if (!bt->key[bt->nchildren].nkey) { - herr_t status = H5B_decode_key(f, bt, bt->nchildren); - assert(status >= 0); - } - cmp = (type->cmp2) (f, dxpl_id, bt->key[bt->nchildren].nkey, udata, - twin->key[0].nkey); + assert(bt->nkey[bt->nchildren]); + cmp = (type->cmp2) (f, dxpl_id, bt->nkey[bt->nchildren], udata, + twin->nkey[0]); assert(0 == cmp); #endif } else { @@ -1772,22 +1606,8 @@ H5B_iterate (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, cur_addr, type, udata, H5AC_READ))) HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node") - for (u=0; unchildren; u++) - child[u] = bt->child[u]; - - for (u=0; unchildren+1; u++) { - if (!bt->key[u].nkey) { - if (H5B_decode_key(f, bt, u) < 0) { - HCOMMON_ERROR(H5E_BTREE, H5E_CANTDECODE, "unable to decode key") - - if (H5AC_unprotect(f, dxpl_id, H5AC_BT, cur_addr, bt, FALSE) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node") - - HGOTO_DONE(FAIL) - } - } /* end if */ - HDmemcpy(key+u*type->sizeof_nkey, bt->key[u].nkey, type->sizeof_nkey); - } + HDmemcpy(child, bt->child, bt->nchildren*sizeof(haddr_t)); + HDmemcpy(key, bt->native, bt->total_native_keysize); next_addr = bt->right; nchildren = bt->nchildren; @@ -1880,10 +1700,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type rt = bt->nchildren; while (ltcmp3)(f, dxpl_id, bt->key[idx].nkey, udata, - bt->key[idx+1].nkey))<0) { + if ((cmp=(type->cmp3)(f, dxpl_id, bt->nkey[idx], udata, + bt->nkey[idx+1]))<0) { rt = idx; } else { lt = idx+1; @@ -1900,8 +1718,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type if (bt->level>0) { /* We're at an internal node -- call recursively */ if ((ret_value=H5B_remove_helper(f, dxpl_id, - bt->child[idx], type, level+1, bt->key[idx].nkey/*out*/, - lt_key_changed/*out*/, udata, bt->key[idx+1].nkey/*out*/, + bt->child[idx], type, level+1, bt->nkey[idx]/*out*/, + lt_key_changed/*out*/, udata, bt->nkey[idx+1]/*out*/, rt_key_changed/*out*/))<0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, H5B_INS_ERROR, "key not found in subtree") } else if (type->remove) { @@ -1911,8 +1729,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type * object and let it decide how to progress. */ if ((ret_value=(type->remove)(f, dxpl_id, - bt->child[idx], bt->key[idx].nkey, lt_key_changed, udata, - bt->key[idx+1].nkey, rt_key_changed))<0) + bt->child[idx], bt->nkey[idx], lt_key_changed, udata, + bt->nkey[idx+1], rt_key_changed))<0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, H5B_INS_ERROR, "key not found in leaf node") } else { /* @@ -1935,22 +1753,20 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ if (*lt_key_changed) { bt->cache_info.is_dirty = TRUE; - bt->key[idx].dirty = TRUE; if (idx>0) { /* Don't propagate change out of this B-tree node */ *lt_key_changed = FALSE; } else { - HDmemcpy(lt_key, bt->key[idx].nkey, type->sizeof_nkey); + HDmemcpy(lt_key, bt->nkey[idx], type->sizeof_nkey); } } if (*rt_key_changed) { bt->cache_info.is_dirty = TRUE; - bt->key[idx+1].dirty = TRUE; if (idx+1nchildren) { /* Don't propagate change out of this B-tree node */ *rt_key_changed = FALSE; } else { - HDmemcpy(rt_key, bt->key[idx+1].nkey, type->sizeof_nkey); + HDmemcpy(rt_key, bt->nkey[idx+1], type->sizeof_nkey); /* Since our right key was changed, we must check for a right * sibling and change it's left-most key as well. @@ -1962,10 +1778,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to unlink node from tree") /* Make certain the native key for the right sibling is set up */ - if (!sibling->key[0].nkey && H5B_decode_key(f, sibling, 0) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - HDmemcpy(sibling->key[0].nkey, bt->key[idx+1].nkey, type->sizeof_nkey); - sibling->key[0].dirty = TRUE; + assert(sibling->nkey[0]); + HDmemcpy(sibling->nkey[0], bt->nkey[idx+1], type->sizeof_nkey); sibling->cache_info.is_dirty = TRUE; if (H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, FALSE) != SUCCEED) @@ -1990,7 +1804,6 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ bt->cache_info.is_dirty = TRUE; bt->nchildren = 0; - bt->ndirty = 0; if (level>0) { if (H5F_addr_defined(bt->left)) { if (NULL == (sibling = H5AC_protect(f, dxpl_id, H5AC_BT, bt->left, type, udata, H5AC_WRITE))) @@ -2010,10 +1823,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type /* Copy left-most key from deleted node to left-most key in it's right neighbor */ /* (Make certain the native key for the right sibling is set up) */ - if (!sibling->key[0].nkey && H5B_decode_key(f, sibling, 0) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - HDmemcpy(sibling->key[0].nkey, bt->key[0].nkey, type->sizeof_nkey); - sibling->key[0].dirty = TRUE; + assert(sibling->nkey[0]); + HDmemcpy(sibling->nkey[0], bt->nkey[0], type->sizeof_nkey); sibling->left = bt->left; sibling->cache_info.is_dirty = TRUE; @@ -2043,11 +1854,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ bt->cache_info.is_dirty = TRUE; bt->nchildren -= 1; - bt->ndirty = bt->nchildren; - HDmemmove(bt->page+H5B_SIZEOF_HDR(f), - bt->page+H5B_SIZEOF_HDR(f)+sizeof_rec, - bt->nchildren*sizeof_rec + bt->sizeof_rkey); HDmemmove(bt->native, bt->native + type->sizeof_nkey, (bt->nchildren+1) * type->sizeof_nkey); @@ -2055,15 +1862,14 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type bt->child+1, bt->nchildren * sizeof(haddr_t)); for (u=0; u<=bt->nchildren; u++) { - bt->key[u].dirty = bt->key[u+1].dirty; - if (bt->key[u+1].nkey) { - bt->key[u].nkey = bt->native + u*type->sizeof_nkey; + if (bt->nkey[u+1]) { + bt->nkey[u] = bt->native + u*type->sizeof_nkey; } else { - bt->key[u].nkey = NULL; + bt->nkey[u] = NULL; } } - assert(bt->key[0].nkey); - HDmemcpy(lt_key, bt->key[0].nkey, type->sizeof_nkey); + assert(bt->nkey[0]); + HDmemcpy(lt_key, bt->nkey[0], type->sizeof_nkey); *lt_key_changed = TRUE; ret_value = H5B_INS_NOOP; @@ -2076,9 +1882,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ bt->cache_info.is_dirty = TRUE; bt->nchildren -= 1; - bt->ndirty = MIN(bt->ndirty, bt->nchildren); - assert(bt->key[bt->nchildren].nkey); - HDmemcpy(rt_key, bt->key[bt->nchildren].nkey, type->sizeof_nkey); + assert(bt->nkey[bt->nchildren]); + HDmemcpy(rt_key, bt->nkey[bt->nchildren], type->sizeof_nkey); *rt_key_changed = TRUE; /* Since our right key was changed, we must check for a right @@ -2091,10 +1896,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to unlink node from tree") /* Make certain the native key for the right sibling is set up */ - if (!sibling->key[0].nkey && H5B_decode_key(f, sibling, 0) < 0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, H5B_INS_ERROR, "unable to decode key") - HDmemcpy(sibling->key[0].nkey, bt->key[bt->nchildren].nkey, type->sizeof_nkey); - sibling->key[0].dirty = TRUE; + assert(sibling->nkey[0]); + HDmemcpy(sibling->nkey[0], bt->nkey[bt->nchildren], type->sizeof_nkey); sibling->cache_info.is_dirty = TRUE; if (H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, FALSE) != SUCCEED) @@ -2116,11 +1919,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type */ bt->cache_info.is_dirty = TRUE; bt->nchildren -= 1; - bt->ndirty = bt->nchildren; - HDmemmove(bt->page+H5B_SIZEOF_HDR(f)+idx*sizeof_rec, - bt->page+H5B_SIZEOF_HDR(f)+(idx+1)*sizeof_rec, - (bt->nchildren-idx)*sizeof_rec + bt->sizeof_rkey); HDmemmove(bt->native + idx * type->sizeof_nkey, bt->native + (idx+1) * type->sizeof_nkey, (bt->nchildren+1-idx) * type->sizeof_nkey); @@ -2128,11 +1927,10 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type bt->child+idx+1, (bt->nchildren-idx) * sizeof(haddr_t)); for (u=idx; u<=bt->nchildren; u++) { - bt->key[u].dirty = bt->key[u+1].dirty; - if (bt->key[u+1].nkey) { - bt->key[u].nkey = bt->native + u*type->sizeof_nkey; + if (bt->nkey[u+1]) { + bt->nkey[u] = bt->native + u*type->sizeof_nkey; } else { - bt->key[u].nkey = NULL; + bt->nkey[u] = NULL; } } ret_value = H5B_INS_NOOP; @@ -2265,14 +2063,10 @@ H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void if(type->remove) { /* Iterate over all entries in node, calling callback */ for (u=0; unchildren; u++) { - /* Decode native keys */ - if (H5B_decode_keys(f, bt, u)<0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode B-tree key(s)") - /* Call user's callback for each entry */ if ((type->remove)(f, dxpl_id, - bt->child[u], bt->key[u].nkey, <_key_changed, udata, - bt->key[u+1].nkey, &rt_key_changed)<0) + bt->child[u], bt->nkey[u], <_key_changed, udata, + bt->nkey[u+1], &rt_key_changed)<0) HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't remove B-tree node") } /* end for */ } /* end if */ @@ -2313,7 +2107,7 @@ done: * *------------------------------------------------------------------------- */ -static size_t +size_t H5B_nodesize(const H5F_t *f, const H5B_class_t *type, size_t *total_nkey_size/*out*/, size_t sizeof_rkey) { @@ -2389,24 +2183,25 @@ H5B_copy(const H5F_t *f, const H5B_t *old_bt) /* Compute the number of keys in this node */ nkeys=2*H5F_KVALUE(f,old_bt->type); - if (NULL==(new_node->page=H5FL_BLK_MALLOC(page,old_bt->sizeof_node)) || - NULL==(new_node->native=H5FL_BLK_MALLOC(native_block,old_bt->total_native_keysize)) || + if ( NULL==(new_node->native=H5FL_BLK_MALLOC(native_block,old_bt->total_native_keysize)) || NULL==(new_node->child=H5FL_SEQ_MALLOC(haddr_t,nkeys)) || - NULL==(new_node->key=H5FL_SEQ_MALLOC(H5B_key_t,(nkeys+1)))) + NULL==(new_node->nkey=H5FL_SEQ_MALLOC(voidp,(nkeys+1)))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node") /* Copy the other structures */ - HDmemcpy(new_node->page,old_bt->page,old_bt->sizeof_node); HDmemcpy(new_node->native,old_bt->native,old_bt->total_native_keysize); HDmemcpy(new_node->child,old_bt->child,(size_t)(sizeof(haddr_t)*nkeys)); - HDmemcpy(new_node->key,old_bt->key,(size_t)(sizeof(H5B_key_t)*(nkeys+1))); /* - * Translate the keys from pointers into the old 'page' buffer into - * pointers into the new 'page' buffer. + * Translate the keys from pointers into the old 'native' buffer into + * pointers into the new 'native' buffer. */ for (u = 0; u < (nkeys+1); u++) - new_node->key[u].rkey = (old_bt->key[u].rkey - old_bt->page) + new_node->page; + if (old_bt->nkey[u]) { + new_node->nkey[u] = new_node->native + u*new_node->type->sizeof_nkey; + } else { + new_node->nkey[u] = NULL; + } /* Set return value */ ret_value=new_node; @@ -2414,10 +2209,9 @@ H5B_copy(const H5F_t *f, const H5B_t *old_bt) done: if(ret_value==NULL) { if(new_node) { - H5FL_BLK_FREE (page,new_node->page); H5FL_BLK_FREE (native_block,new_node->native); H5FL_SEQ_FREE (haddr_t,new_node->child); - H5FL_SEQ_FREE (H5B_key_t,new_node->key); + H5FL_SEQ_FREE (voidp,new_node->nkey); H5FL_FREE (H5B_t,new_node); } /* end if */ } /* end if */ @@ -2485,9 +2279,6 @@ H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f "Dirty flag:", bt->cache_info.is_dirty ? "True" : "False"); HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, - "Number of initial dirty children:", - bt->ndirty); - HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, "Level:", bt->level); @@ -2516,22 +2307,16 @@ H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f /* Decode the 'left' key & print it */ HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), "Left Key:"); - if(bt->key[u].nkey==NULL) { - if(H5B_decode_key(f, bt, u)<0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode B-tree key(s)") - } /* end if */ + assert(bt->nkey[u]); (void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6), - bt->key[u].nkey, udata); + bt->nkey[u], udata); /* Decode the 'right' key & print it */ HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3), "Right Key:"); - if(bt->key[u+1].nkey==NULL) { - if(H5B_decode_key(f, bt, u+1)<0) - HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, FAIL, "unable to decode B-tree key(s)") - } /* end if */ + assert(bt->nkey[u+1]); (void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6), - bt->key[u+1].nkey, udata); + bt->nkey[u+1], udata); } } @@ -2608,7 +2393,6 @@ H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void assert(bt); /* Check node header */ - assert(bt->ndirty <= bt->nchildren); assert(bt->level == cur->level); if (cur->next && cur->next->level == bt->level) { assert(H5F_addr_eq(bt->right, cur->next->addr)); @@ -2641,10 +2425,8 @@ H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type, void tail = tmp; /* Check that the keys are monotonically increasing */ - status = H5B_decode_keys(f, bt, i); - assert(status >= 0); - cmp = (type->cmp2) (f, dxpl_id, bt->key[i].nkey, udata, - bt->key[i+1].nkey); + cmp = (type->cmp2) (f, dxpl_id, bt->nkey[i], udata, + bt->nkey[i+1]); assert(cmp < 0); } } diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h index 578de48..67b49db 100644 --- a/src/H5Bpkg.h +++ b/src/H5Bpkg.h @@ -43,12 +43,6 @@ /* * The B-tree node as stored in memory... */ -typedef struct H5B_key_t { - hbool_t dirty; /*native key is more recent than raw key */ - uint8_t *rkey; /*ptr into node->page for raw key */ - void *nkey; /*null or ptr into node->native for key */ -} H5B_key_t; - struct H5B_t { H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ @@ -56,14 +50,13 @@ struct H5B_t { size_t sizeof_node; /*size of raw (disk) node */ size_t sizeof_rkey; /*size of raw (disk) key */ size_t total_native_keysize; /*size of native keys */ - unsigned ndirty; /*num child ptrs to emit */ unsigned level; /*node level */ haddr_t left; /*address of left sibling */ haddr_t right; /*address of right sibling */ unsigned nchildren; /*number of child pointers */ - uint8_t *page; /*disk page */ + uint8_t *raw_page; /*disk page (shared) */ uint8_t *native; /*array of keys in native format */ - H5B_key_t *key; /*2k+1 key entries */ + void **nkey; /*2k+1 key entries */ haddr_t *child; /*2k child pointers */ }; diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h index 1f7a8eb..4cf558a 100644 --- a/src/H5Bprivate.h +++ b/src/H5Bprivate.h @@ -84,6 +84,7 @@ typedef struct H5B_class_t { H5B_subid_t id; /*id as found in file*/ size_t sizeof_nkey; /*size of native (memory) key*/ size_t (*get_sizeof_rkey)(H5F_t*, const void*); /*raw key size */ + void * (*get_page)(H5F_t*, const void*); /*raw disk page for node */ herr_t (*new_node)(H5F_t*, hid_t, H5B_ins_t, void*, void*, void*, haddr_t*); int (*cmp2)(H5F_t*, hid_t, void*, void*, void*); /*compare 2 keys */ int (*cmp3)(H5F_t*, hid_t, void*, void*, void*); /*compare 3 keys */ @@ -111,6 +112,8 @@ typedef struct H5B_class_t { /* * Library prototypes. */ +H5_DLL size_t H5B_nodesize(const H5F_t *f, const H5B_class_t *type, + size_t *total_nkey_size, size_t sizeof_rkey); H5_DLL herr_t H5B_create (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata, haddr_t *addr_p/*out*/); H5_DLL herr_t H5B_find (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, diff --git a/src/H5Distore.c b/src/H5Distore.c index 36e3cb7..0bab89d 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -157,6 +157,7 @@ static int H5D_istore_prune_extent(H5F_t *f, hid_t dxpl_id, void *_lt_key, haddr /* B-tree callbacks */ static size_t H5D_istore_sizeof_rkey(H5F_t *f, const void *_udata); +static void *H5D_istore_get_page(H5F_t *f, const void *_udata); static herr_t H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t, void *_lt_key, void *_udata, void *_rt_key, haddr_t *addr_p /*out*/); @@ -187,6 +188,7 @@ H5B_class_t H5B_ISTORE[1] = {{ H5B_ISTORE_ID, /*id */ sizeof(H5D_istore_key_t), /*sizeof_nkey */ H5D_istore_sizeof_rkey, /*get_sizeof_rkey */ + H5D_istore_get_page, /*get_page */ H5D_istore_new_node, /*new */ H5D_istore_cmp2, /*cmp2 */ H5D_istore_cmp3, /*cmp3 */ @@ -209,6 +211,9 @@ H5FL_SEQ_DEFINE_STATIC(H5D_rdcc_ent_ptr_t); /* Declare a free list to manage the chunk sequence information */ H5FL_BLK_DEFINE_STATIC(chunk); +/* Declare a free list to manage the raw page information */ +H5FL_BLK_DEFINE_STATIC(chunk_page); + /*------------------------------------------------------------------------- * Function: H5D_istore_sizeof_rkey @@ -249,6 +254,37 @@ H5D_istore_sizeof_rkey(H5F_t UNUSED *f, const void *_udata) /*------------------------------------------------------------------------- + * Function: H5D_istore_get_page + * + * Purpose: Returns the raw data page for the specified UDATA. + * + * Return: Success: Pointer to the raw B-tree page for this dataset + * + * Failure: Can't fail + * + * Programmer: Quincey Koziol + * Monday, July 5, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5D_istore_get_page(H5F_t UNUSED *f, const void *_udata) +{ + const H5D_istore_ud1_t *udata = (const H5D_istore_ud1_t *) _udata; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_get_page); + + assert(udata); + assert(udata->mesg); + assert(udata->mesg->u.chunk.raw_page); + + FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.raw_page); +} /* end H5D_istore_get_page() */ + + +/*------------------------------------------------------------------------- * Function: H5D_istore_decode_key * * Purpose: Decodes a raw key into a native key for the B-tree @@ -643,7 +679,7 @@ done: */ static H5B_ins_t H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key, - hbool_t UNUSED *lt_key_changed, + hbool_t *lt_key_changed, void *_md_key, void *_udata, void *_rt_key, hbool_t UNUSED *rt_key_changed, haddr_t *new_node_p/*out*/) @@ -858,6 +894,9 @@ H5D_istore_iter_dump (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, hadd herr_t H5D_istore_init (H5F_t *f, H5D_t *dset) { + H5D_istore_ud1_t udata; + size_t sizeof_rkey; /* Single raw key size */ + size_t size; /* Raw B-tree node size */ H5D_rdcc_t *rdcc = &(dset->cache.chunk); herr_t ret_value=SUCCEED; /* Return value */ @@ -872,6 +911,17 @@ H5D_istore_init (H5F_t *f, H5D_t *dset) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } /* end if */ + /* Initialize "user" data for B-tree callbacks, etc. */ + udata.mesg = &dset->layout; + + /* Set up the "global" information for this dataset's chunks */ + sizeof_rkey = H5D_istore_sizeof_rkey(f, &udata); + assert(sizeof_rkey); + size = H5B_nodesize(f, H5B_ISTORE, NULL, sizeof_rkey); + assert(size); + if(NULL==(dset->layout.u.chunk.raw_page=H5FL_BLK_MALLOC(chunk_page,size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") + done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5D_istore_init() */ @@ -1150,6 +1200,7 @@ H5D_istore_dest (H5F_t *f, hid_t dxpl_id, H5D_t *dset) if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache") + /* Flush all the cached chunks */ for (ent=rdcc->head; ent; ent=next) { #ifdef H5D_ISTORE_DEBUG HDfputc('c', stderr); @@ -1165,6 +1216,9 @@ H5D_istore_dest (H5F_t *f, hid_t dxpl_id, H5D_t *dset) H5FL_SEQ_FREE (H5D_rdcc_ent_ptr_t,rdcc->slot); HDmemset (rdcc, 0, sizeof(H5D_rdcc_t)); + /* Free the raw B-tree node buffer */ + H5FL_BLK_FREE(chunk_page,dset->layout.u.chunk.raw_page); + done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5D_istore_dest() */ @@ -1919,7 +1973,9 @@ H5D_istore_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ ) assert(layout->u.chunk.dim[u] > 0); #endif + /* Initialize "user" data for B-tree callbacks, etc. */ udata.mesg = layout; + if (H5B_create(f, dxpl_id, H5B_ISTORE, &udata, &(layout->u.chunk.addr)/*out*/) < 0) HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't create B-tree"); diff --git a/src/H5F.c b/src/H5F.c index 1755e5d..86f9019 100644 --- a/src/H5F.c +++ b/src/H5F.c @@ -1490,6 +1490,10 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id) /* Create the file's "open object" information */ if(H5FO_create(f)<0) HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create open object TBBT") + + /* Create information needed for group nodes */ + if(H5G_node_init(f)<0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create group node info") } /* end else */ f->shared->nrefs++; @@ -1576,6 +1580,10 @@ H5F_dest(H5F_t *f, hid_t dxpl_id) ret_value = FAIL; /*but keep going*/ } /* end if */ f->shared->cwfs = H5MM_xfree (f->shared->cwfs); + if (H5G_node_close(f)<0) { + HERROR(H5E_FILE, H5E_CANTRELEASE, "problems closing file"); + ret_value = FAIL; /*but keep going*/ + } /* end if */ /* Destroy file creation properties */ if(H5I_GENPROP_LST != H5I_get_type(f->shared->fcpl_id)) @@ -4464,6 +4472,38 @@ done: /*------------------------------------------------------------------------- + * Function: H5F_raw_page + * + * Purpose: Replaced a macro to retrieve the raw B-tree page value + * now that the generic properties are being used to store + * the values. + * + * Return: Success: Non-void, and the raw B-tree page value + * is returned. + * + * Failure: void (should not happen) + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Jul 5 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +void *H5F_raw_page(const H5F_t *f) +{ + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_raw_page) + + assert(f); + assert(f->shared); + + FUNC_LEAVE_NOAPI(f->shared->raw_page) +} /* end H5F_raw_page() */ + + +/*------------------------------------------------------------------------- * Function: H5F_block_read * * Purpose: Reads some data from a file/server/etc into a buffer. diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 0853a89..567ea39 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -126,6 +126,7 @@ typedef struct H5F_file_t { struct H5HG_heap_t **cwfs; /* Global heap cache */ H5FO_t *open_objs; /* Open objects in file */ H5F_close_degree_t fc_degree; /* File close behavior degree */ + void *raw_page; /* Pointer to raw B-tree node buffer */ } H5F_file_t; /* A record of the mount table */ diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 6950178..aace023 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -210,6 +210,8 @@ typedef struct H5F_t H5F_t; #define H5F_RDCC_W0(F) ((F)->shared->rdcc_w0) /* Check for file driver feature enabled */ #define H5F_HAS_FEATURE(F,FL) ((F)->shared->lf->feature_flags&(FL)) +/* B-tree node raw page */ +#define H5F_RAW_PAGE(F) ((F)->shared->raw_page) #else /* H5F_PACKAGE */ #define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F)) #define H5F_SIZEOF_SIZE(F) (H5F_sizeof_size(F)) @@ -219,6 +221,7 @@ typedef struct H5F_t H5F_t; #define H5F_RDCC_NBYTES(F) (H5F_rdcc_nbytes(F)) #define H5F_RDCC_W0(F) (H5F_rdcc_w0(F)) #define H5F_HAS_FEATURE(F,FL) (H5F_has_feature(F,FL)) +#define H5F_RAW_PAGE(F) (H5F_raw_page(F)) #endif /* H5F_PACKAGE */ @@ -414,6 +417,7 @@ H5_DLL hbool_t H5F_has_feature(const H5F_t *f, unsigned feature); H5_DLL size_t H5F_rdcc_nbytes(const H5F_t *f); H5_DLL size_t H5F_rdcc_nelmts(const H5F_t *f); H5_DLL double H5F_rdcc_w0(const H5F_t *f); +H5_DLL void *H5F_raw_page(const H5F_t *f); /* Functions that operate on blocks of bytes wrt super block */ H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 629cb48..1925ee5 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -62,7 +62,7 @@ typedef struct H5G_node_key_t { #define PABLO_MASK H5G_node_mask /* PRIVATE PROTOTYPES */ -static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, uint8_t *buf); +static herr_t H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf); static size_t H5G_node_size(H5F_t *f); /* Metadata cache callbacks */ @@ -76,6 +76,7 @@ static herr_t H5G_compute_size(H5F_t *f, H5G_node_t *sym, size_t *size_ptr); /* B-tree callbacks */ static size_t H5G_node_sizeof_rkey(H5F_t *f, const void *_udata); +static void *H5G_node_get_page(H5F_t *f, const void *_udata); static herr_t H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t op, void *_lt_key, void *_udata, void *_rt_key, haddr_t *addr_p/*out*/); @@ -116,6 +117,7 @@ H5B_class_t H5B_SNODE[1] = {{ H5B_SNODE_ID, /*id */ sizeof(H5G_node_key_t), /*sizeof_nkey */ H5G_node_sizeof_rkey, /*get_sizeof_rkey */ + H5G_node_get_page, /*get_page */ H5G_node_create, /*new */ H5G_node_cmp2, /*cmp2 */ H5G_node_cmp3, /*cmp3 */ @@ -138,6 +140,9 @@ H5FL_SEQ_DEFINE_STATIC(H5G_entry_t); /* Declare a free list to manage blocks of symbol node data */ H5FL_BLK_DEFINE_STATIC(symbol_node); +/* Declare a free list to manage the raw page information */ +H5FL_BLK_DEFINE_STATIC(grp_page); + /*------------------------------------------------------------------------- * Function: H5G_node_sizeof_rkey @@ -168,6 +173,34 @@ H5G_node_sizeof_rkey(H5F_t *f, const void UNUSED * udata) /*------------------------------------------------------------------------- + * Function: H5G_node_get_page + * + * Purpose: Returns the raw data page for the specified UDATA. + * + * Return: Success: Pointer to the raw B-tree page for this + file's groups + * + * Failure: Can't fail + * + * Programmer: Robb Matzke + * Wednesday, October 8, 1997 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static void * +H5G_node_get_page(H5F_t *f, const void UNUSED *_udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_get_page); + + assert(f); + + FUNC_LEAVE_NOAPI(H5F_RAW_PAGE(f)); +} /* end H5G_node_get_page() */ + + +/*------------------------------------------------------------------------- * Function: H5G_node_decode_key * * Purpose: Decodes a raw key into a native key. @@ -456,16 +489,15 @@ H5G_node_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5G_node_ size = H5G_node_size(f); /* Allocate temporary buffer */ - if ((buf=H5FL_BLK_CALLOC(symbol_node,size))==NULL) + if ((buf=H5FL_BLK_MALLOC(symbol_node,size))==NULL) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - if (H5G_node_serialize(f, sym, buf) < 0) + if (H5G_node_serialize(f, sym, size, buf) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTSERIALIZE, FAIL, "node serialization failed"); if (H5F_block_write(f, H5FD_MEM_BTREE, addr, size, dxpl_id, buf) < 0) HGOTO_ERROR(H5E_SYM, H5E_WRITEERROR, FAIL, "unable to write symbol table node to the file"); - if (buf) - H5FL_BLK_FREE(symbol_node,buf); + H5FL_BLK_FREE(symbol_node,buf); /* Reset the node's dirty flag */ sym->cache_info.is_dirty = FALSE; @@ -501,7 +533,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_node_serialize(H5F_t *f, H5G_node_t *sym, uint8_t *buf) +H5G_node_serialize(H5F_t *f, H5G_node_t *sym, size_t size, uint8_t *buf) { uint8_t *p; herr_t ret_value = SUCCEED; @@ -531,6 +563,7 @@ H5G_node_serialize(H5F_t *f, H5G_node_t *sym, uint8_t *buf) /* entries */ if (H5G_ent_encode_vec(f, &p, sym->entry, sym->nsyms) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTENCODE, FAIL, "can't serialize") + HDmemset(p, 0, size - (p - buf)); done: FUNC_LEAVE_NOAPI(ret_value); @@ -1672,6 +1705,76 @@ done: /*------------------------------------------------------------------------- + * Function: H5G_node_init + * + * Purpose: This function gets called during a file opening to initialize + * global information about group B-tree nodes for file. + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Quincey Koziol + * Jul 5, 2004 + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_node_init(H5F_t *f) +{ + size_t sizeof_rkey; /* Single raw key size */ + size_t size; /* Raw B-tree node size */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5G_node_init, FAIL); + + /* Check arguments. */ + assert(f); + + /* Set up the "global" information for this file's groups */ + sizeof_rkey = H5G_node_sizeof_rkey(f, NULL); + assert(sizeof_rkey); + size = H5B_nodesize(f, H5B_SNODE, NULL, sizeof_rkey); + assert(size); + if(NULL==(f->shared->raw_page=H5FL_BLK_MALLOC(grp_page,size))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page") + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5G_node_init() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_node_close + * + * Purpose: This function gets called during a file close to shutdown + * global information about group B-tree nodes for file. + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Quincey Koziol + * Jul 5, 2004 + * + * + *------------------------------------------------------------------------- + */ +herr_t +H5G_node_close(const H5F_t *f) +{ + FUNC_ENTER_NOAPI_NOFUNC(H5G_node_close) + + /* Check arguments. */ + assert(f); + + /* Free the raw B-tree node buffer */ + H5FL_BLK_FREE(grp_page,f->shared->raw_page); + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* end H5G_node_close */ + + +/*------------------------------------------------------------------------- * Function: H5G_node_debug * * Purpose: Prints debugging information about a symbol table node diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 2bf2c3f..5415e32 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -161,6 +161,8 @@ H5_DLL herr_t H5G_free_grp_name(H5G_t *grp); */ H5_DLL herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, haddr_t heap); +H5_DLL herr_t H5G_node_init(H5F_t *f); +H5_DLL herr_t H5G_node_close(const H5F_t *f); /* * These functions operate on symbol table entries. They're used primarily diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 63cac3c..b7d9b46 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -133,6 +133,7 @@ typedef struct H5O_layout_chunk_t { unsigned ndims; /* Num dimensions in chunk */ size_t dim[H5O_LAYOUT_NDIMS]; /* Size of chunk in elements */ size_t size; /* Size of chunk in bytes */ + void *raw_page; /* Buffer for raw B-tree page */ } H5O_layout_chunk_t; typedef struct H5O_layout_compact_t { -- cgit v0.12