summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5B.c426
-rw-r--r--src/H5Bpkg.h8
-rw-r--r--src/H5Bprivate.h15
-rw-r--r--src/H5Distore.c151
-rw-r--r--src/H5F.c15
-rw-r--r--src/H5Fpkg.h2
-rw-r--r--src/H5Fprivate.h6
-rw-r--r--src/H5Gnode.c90
-rw-r--r--src/H5Oprivate.h2
9 files changed, 378 insertions, 337 deletions
diff --git a/src/H5B.c b/src/H5B.c
index 4fe4e07..f6149d3 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -122,6 +122,7 @@
(H5B_SIZEOF_MAGIC + /*magic number */ \
4 + /*type, level, num entries */ \
2*H5F_SIZEOF_ADDR(F)) /*left and right sibling addresses */
+#define H5B_NKEY(b,shared,idx) ((b)->native+(shared)->nkey[(idx)])
/* Local typedefs */
@@ -134,10 +135,10 @@ static H5B_ins_t H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr,
uint8_t *rt_key,
hbool_t *rt_key_changed,
haddr_t *retval);
-static herr_t H5B_insert_child(const H5F_t *f, const H5B_class_t *type,
+static herr_t H5B_insert_child(const H5F_t *f,
H5B_t *bt, unsigned idx, haddr_t child,
H5B_ins_t anchor, const void *md_key);
-static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_t *old_bt,
+static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, 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);
@@ -167,13 +168,12 @@ static const H5AC_class_t H5AC_BT[1] = {{
/* Declare a PQ free list to manage the native block information */
H5FL_BLK_DEFINE_STATIC(native_block);
-/* 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);
+/* Declare a free list to manage the H5B_shared_t struct */
+H5FL_DEFINE(H5B_shared_t);
+
/* Declare a free list to manage the H5B_t struct */
H5FL_DEFINE_STATIC(H5B_t);
@@ -206,9 +206,7 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata,
haddr_t *addr_p/*out*/)
{
H5B_t *bt = NULL;
- size_t sizeof_rkey;
- size_t size=0;
- size_t total_native_keysize;
+ H5B_shared_t *shared=NULL; /* Pointer to shared B-tree info */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5B_create, FAIL)
@@ -223,30 +221,23 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata,
/*
* Allocate file and memory data structures.
*/
- sizeof_rkey = (type->get_sizeof_rkey) (f, udata);
- size = H5B_nodesize(f, type, &total_native_keysize, sizeof_rkey);
- 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_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->level = 0;
bt->left = HADDR_UNDEF;
bt->right = HADDR_UNDEF;
bt->nchildren = 0;
- if((bt->rc_page=(type->get_page)(f, udata))==NULL)
+ if((bt->rc_shared=(type->get_shared)(f, udata))==NULL)
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer")
- bt->raw_page=H5RC_GET_OBJ(bt->rc_page);
- 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->nkey=H5FL_SEQ_MALLOC(voidp,(size_t)(2*H5F_KVALUE(f,type)+1))))
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)) ||
+ NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,shared->type)))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree root node")
+ if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->sizeof_rnode)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for B-tree root node")
/*
* Cache the new B-tree node.
@@ -254,14 +245,14 @@ H5B_create(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata,
if (H5AC_set(f, dxpl_id, H5AC_BT, *addr_p, bt) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "can't add B-tree root node to cache")
#ifdef H5B_DEBUG
- H5B_assert(f, dxpl_id, *addr_p, type, udata);
+ H5B_assert(f, dxpl_id, *addr_p, shared->type, udata);
#endif
done:
if (ret_value<0) {
- if(size>0) {
- H5_CHECK_OVERFLOW(size,size_t,hsize_t);
- (void)H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, *addr_p, (hsize_t)size);
+ if(shared && shared->sizeof_rnode>0) {
+ H5_CHECK_OVERFLOW(shared->sizeof_rnode,size_t,hsize_t);
+ (void)H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, *addr_p, (hsize_t)shared->sizeof_rnode);
} /* end if */
if (bt)
(void)H5B_dest(f,bt);
@@ -297,9 +288,8 @@ static H5B_t *
H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
{
const H5B_class_t *type = (const H5B_class_t *) _type;
- size_t total_nkey_size;
- size_t size;
H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
uint8_t *p; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native keys */
unsigned u; /* Local index variable */
@@ -311,27 +301,23 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
assert(f);
assert(H5F_addr_defined(addr));
assert(type);
- assert(type->get_sizeof_rkey);
+ assert(type->get_shared);
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;
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))) ||
+ if((bt->rc_shared=(type->get_shared)(f, udata))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)) ||
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((bt->rc_page=(type->get_page)(f, udata))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer")
- bt->raw_page=H5RC_GET_OBJ(bt->rc_page);
- if (H5F_block_read(f, H5FD_MEM_BTREE, addr, size, dxpl_id, bt->raw_page)<0)
+ if (H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page)<0)
HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node")
- p = bt->raw_page;
+ p = shared->page;
/* magic number */
if (HDmemcmp(p, H5B_MAGIC, H5B_SIZEOF_MAGIC))
@@ -356,8 +342,7 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
/* 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;
+ p += shared->sizeof_rkey;
native += type->sizeof_nkey;
/* Decode address value */
@@ -369,7 +354,6 @@ H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
/* 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 */
/* Set return value */
@@ -402,6 +386,7 @@ done:
static herr_t
H5B_serialize(H5F_t *f, H5B_t *bt)
{
+ H5B_shared_t *shared=NULL; /* Pointer to shared B-tree info */
unsigned u;
uint8_t *p; /* Pointer into raw data buffer */
uint8_t *native; /* Pointer to native keys */
@@ -412,17 +397,18 @@ H5B_serialize(H5F_t *f, H5B_t *bt)
/* check arguments */
assert(f);
assert(bt);
- assert(bt->raw_page);
- assert(bt->type);
+ assert(bt->rc_shared);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
- p = bt->raw_page;
+ p = shared->page;
/* magic number */
HDmemcpy(p, H5B_MAGIC, H5B_SIZEOF_MAGIC);
p += 4;
/* node type and level */
- *p++ = bt->type->id;
+ *p++ = shared->type->id;
H5_CHECK_OVERFLOW(bt->level, unsigned, uint8_t);
*p++ = (uint8_t)bt->level;
@@ -437,17 +423,17 @@ H5B_serialize(H5F_t *f, H5B_t *bt)
native=bt->native;
for (u = 0; u < bt->nchildren; ++u) {
/* encode the key */
- if (bt->type->encode(f, bt, p, native) < 0)
+ if (shared->type->encode(f, bt, p, native) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
- p += bt->sizeof_rkey;
- native += bt->type->sizeof_nkey;
+ p += shared->sizeof_rkey;
+ native += shared->type->sizeof_nkey;
/* encode the child address */
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)
+ if (shared->type->encode(f, bt, p, native) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
} /* end if */
@@ -487,6 +473,7 @@ done:
static herr_t
H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt)
{
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5B_flush, FAIL)
@@ -495,8 +482,10 @@ H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt)
assert(f);
assert(H5F_addr_defined(addr));
assert(bt);
- assert(bt->type);
- assert(bt->type->encode);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ assert(shared->type);
+ assert(shared->type->encode);
if (bt->cache_info.is_dirty) {
if (H5B_serialize(f, bt) < 0)
@@ -507,7 +496,7 @@ H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt)
* 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->raw_page) < 0)
+ if (H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk")
bt->cache_info.is_dirty = FALSE;
@@ -552,9 +541,8 @@ 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(voidp,bt->nkey);
H5FL_BLK_FREE(native_block,bt->native);
- H5RC_DEC(bt->rc_page);
+ H5RC_DEC(bt->rc_shared);
H5FL_FREE(H5B_t,bt);
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -619,18 +607,22 @@ done:
static herr_t
H5B_compute_size(H5F_t *f, H5B_t *bt, size_t *size_ptr)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
size_t size;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B_compute_size)
/* check arguments */
HDassert(f);
HDassert(bt);
- HDassert(bt->type);
+ HDassert(bt->rc_shared);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ HDassert(shared->type);
HDassert(size_ptr);
- size = H5B_nodesize(f, bt->type, NULL, bt->sizeof_rkey);
+ size = H5B_nodesize(f, shared->type, NULL, shared->sizeof_rkey);
if ( size == 0 ) {
@@ -680,6 +672,7 @@ herr_t
H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *udata)
{
H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
unsigned idx=0, lt = 0, rt; /* Final, left & right key indices */
int cmp = 1; /* Key comparison value */
int ret_value = SUCCEED; /* Return value */
@@ -702,13 +695,15 @@ H5B_find(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *u
*/
if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
rt = bt->nchildren;
while (lt < rt && cmp) {
idx = (lt + rt) / 2;
/* compare */
- if ((cmp = (type->cmp3) (f, dxpl_id, bt->nkey[idx], udata,
- bt->nkey[idx+1])) < 0) {
+ if ((cmp = (type->cmp3) (f, dxpl_id, H5B_NKEY(bt,shared,idx), udata,
+ H5B_NKEY(bt,shared,idx+1))) < 0) {
rt = idx;
} else {
lt = idx+1;
@@ -742,7 +737,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, bt->child[idx], bt->nkey[idx], udata, bt->nkey[idx+1]) < 0)
+ if ((type->found) (f, dxpl_id, bt->child[idx], H5B_NKEY(bt,shared,idx), udata, H5B_NKEY(bt,shared,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
@@ -789,16 +784,15 @@ done:
*-------------------------------------------------------------------------
*/
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,
+H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt, haddr_t old_addr,
unsigned idx, void *udata, haddr_t *new_addr_p/*out*/)
{
H5P_genplist_t *dx_plist; /* Data transfer property list */
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
H5B_t *new_bt = NULL, *tmp_bt = NULL;
unsigned k; /* B-tree 'K' value for the maximum number of entries in node */
unsigned nleft, nright; /* Number of keys in left & right halves */
- size_t recsize = 0;
double split_ratios[3]; /* B-tree split ratios */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5B_split)
@@ -807,15 +801,16 @@ H5B_split(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_t *old_bt, haddr
* Check arguments.
*/
assert(f);
- assert(type);
+ assert(old_bt);
assert(H5F_addr_defined(old_addr));
/*
* Initialize variables.
*/
- assert(old_bt->nchildren == 2 * H5F_KVALUE(f, type));
- recsize = old_bt->sizeof_rkey + H5F_SIZEOF_ADDR(f);
- k = H5F_KVALUE(f, type);
+ shared=H5RC_GET_OBJ(old_bt->rc_shared);
+ HDassert(shared);
+ assert(old_bt->nchildren == 2 * H5F_KVALUE(f, shared->type));
+ k = H5F_KVALUE(f, shared->type);
/* Get the dataset transfer property list */
@@ -875,9 +870,9 @@ H5B_split(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_t *old_bt, haddr
/*
* Create the new B-tree node.
*/
- if (H5B_create(f, dxpl_id, type, udata, new_addr_p/*out*/) < 0)
+ if (H5B_create(f, dxpl_id, shared->type, udata, new_addr_p/*out*/) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create B-tree")
- if (NULL==(new_bt=H5AC_protect(f, dxpl_id, H5AC_BT, *new_addr_p, type, udata, H5AC_WRITE)))
+ if (NULL==(new_bt=H5AC_protect(f, dxpl_id, H5AC_BT, *new_addr_p, shared->type, udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to protect B-tree")
new_bt->level = old_bt->level;
@@ -885,18 +880,12 @@ 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->native,
- old_bt->native + nleft * type->sizeof_nkey,
- (nright+1) * type->sizeof_nkey);
-
- for (u=0; u<nright; u++) {
- /* key */
- new_bt->nkey[u] = new_bt->native + u * type->sizeof_nkey;
+ old_bt->native + nleft * shared->type->sizeof_nkey,
+ (nright+1) * shared->type->sizeof_nkey);
+ HDmemcpy(new_bt->child,
+ &old_bt->child[nleft],
+ nright*sizeof(haddr_t));
- /* child */
- new_bt->child[u] = old_bt->child[nleft+u];
- }
- /* Final key */
- new_bt->nkey[u] = new_bt->native + u * type->sizeof_nkey;
new_bt->nchildren = nright;
/*
@@ -912,7 +901,7 @@ H5B_split(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_t *old_bt, haddr
new_bt->right = old_bt->right;
if (H5F_addr_defined(old_bt->right)) {
- if (NULL == (tmp_bt = H5AC_protect(f, dxpl_id, H5AC_BT, old_bt->right, type, udata, H5AC_WRITE)))
+ if (NULL == (tmp_bt = H5AC_protect(f, dxpl_id, H5AC_BT, old_bt->right, shared->type, udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load right sibling")
tmp_bt->cache_info.is_dirty = TRUE;
@@ -977,7 +966,7 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
unsigned level;
H5B_t *bt;
H5B_t *new_bt; /* Copy of B-tree info */
- hsize_t size;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
H5B_ins_t my_ins = H5B_INS_ERROR;
herr_t ret_value = SUCCEED;
@@ -1000,13 +989,13 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
/* the current root */
if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to locate root of B-tree")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
level = bt->level;
- if (!lt_key_changed) {
- assert(bt->nkey[0]);
- HDmemcpy(lt_key, bt->nkey[0], type->sizeof_nkey);
- }
+ if (!lt_key_changed)
+ HDmemcpy(lt_key, H5B_NKEY(bt,shared,0), type->sizeof_nkey);
if (H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, FALSE) != SUCCEED)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release new child")
@@ -1017,24 +1006,21 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, child, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load new node")
- if (!rt_key_changed) {
- assert(bt->nkey[bt->nchildren]);
- HDmemcpy(rt_key, bt->nkey[bt->nchildren], type->sizeof_nkey);
- }
+ if (!rt_key_changed)
+ HDmemcpy(rt_key, H5B_NKEY(bt,shared,bt->nchildren), type->sizeof_nkey);
- /*
- * Copy the old root node to some other file location and make the new
- * root at the old root's previous address. This prevents the B-tree
- * from "moving".
- */
- size = bt->sizeof_node;
-
if (H5AC_unprotect(f, dxpl_id, H5AC_BT, child, bt, FALSE) != SUCCEED)
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release new child")
bt = NULL;
- if (HADDR_UNDEF==(old_root=H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, size)))
+ /*
+ * Copy the old root node to some other file location and make the new
+ * root at the old root's previous address. This prevents the B-tree
+ * from "moving".
+ */
+ H5_CHECK_OVERFLOW(shared->sizeof_rnode,size_t,hsize_t);
+ if (HADDR_UNDEF==(old_root=H5MF_alloc(f, H5FD_MEM_BTREE, dxpl_id, (hsize_t)shared->sizeof_rnode)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space to move root")
/* update the new child's left pointer */
@@ -1090,15 +1076,12 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
new_bt->nchildren = 2;
new_bt->child[0] = old_root;
- new_bt->nkey[0] = new_bt->native;
- HDmemcpy(new_bt->nkey[0], lt_key, type->sizeof_nkey);
+ HDmemcpy(H5B_NKEY(new_bt,shared,0), lt_key, shared->type->sizeof_nkey);
new_bt->child[1] = child;
- new_bt->nkey[1] = new_bt->native + type->sizeof_nkey;
- HDmemcpy(new_bt->nkey[1], md_key, type->sizeof_nkey);
+ HDmemcpy(H5B_NKEY(new_bt,shared,1), md_key, shared->type->sizeof_nkey);
- new_bt->nkey[2] = new_bt->native + 2 * type->sizeof_nkey;
- HDmemcpy(new_bt->nkey[2], rt_key, type->sizeof_nkey);
+ HDmemcpy(H5B_NKEY(new_bt,shared,2), rt_key, shared->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)
@@ -1132,54 +1115,36 @@ done:
*-------------------------------------------------------------------------
*/
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)
+H5B_insert_child(const H5F_t *f, H5B_t *bt, unsigned idx, haddr_t child,
+ H5B_ins_t anchor, const void *md_key)
{
- size_t recsize;
- unsigned u; /* Local index variable */
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ uint8_t *base; /* Base offset for move */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_insert_child)
assert(bt);
- assert(bt->nchildren<2*H5F_KVALUE(f, type));
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ assert(bt->nchildren<2*H5F_KVALUE(f, shared->type));
bt->cache_info.is_dirty = TRUE;
- recsize = bt->sizeof_rkey + H5F_SIZEOF_ADDR(f);
- if (H5B_INS_RIGHT == anchor) {
- /*
- * The MD_KEY is the left key of the new node.
- */
- idx++;
-
- 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->nkey[u+1] = bt->native + (u+1) * 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->native + (idx+2) * type->sizeof_nkey,
- bt->native + (idx+1) * type->sizeof_nkey,
- (bt->nchildren - idx) * type->sizeof_nkey);
+ /* Make room for the new key */
+ base=bt->native + (idx+1) * shared->type->sizeof_nkey,
+ HDmemmove(base + shared->type->sizeof_nkey, base,
+ (bt->nchildren - idx) * shared->type->sizeof_nkey);
+ HDmemcpy(base, md_key, shared->type->sizeof_nkey);
- for (u = bt->nchildren; u > idx; --u)
- bt->nkey[u+1] = bt->native + (u+1) * type->sizeof_nkey;
- bt->nkey[idx+1] = bt->native + (idx+1) * type->sizeof_nkey;
- HDmemcpy(bt->nkey[idx+1], md_key, type->sizeof_nkey);
- }
+ /* The MD_KEY is the left key of the new node */
+ if (H5B_INS_RIGHT == anchor)
+ idx++;
- HDmemmove(bt->child + idx + 1,
- bt->child + idx,
+ /* Make room for the new child address */
+ HDmemmove(bt->child + idx + 1, bt->child + idx,
(bt->nchildren - idx) * sizeof(haddr_t));
-
bt->child[idx] = child;
+
bt->nchildren += 1;
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -1240,6 +1205,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
haddr_t *new_node_p/*out*/)
{
H5B_t *bt = NULL, *twin = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
unsigned lt = 0, idx = 0, rt; /* Left, final & right index values */
int cmp = -1; /* Key comparison value */
haddr_t child_addr = HADDR_UNDEF;
@@ -1273,12 +1239,14 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
*/
if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to load node")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
rt = bt->nchildren;
while (lt < rt && cmp) {
idx = (lt + rt) / 2;
- if ((cmp = (type->cmp3) (f, dxpl_id, bt->nkey[idx], udata,
- bt->nkey[idx+1])) < 0) {
+ if ((cmp = (type->cmp3) (f, dxpl_id, H5B_NKEY(bt,shared,idx), udata,
+ H5B_NKEY(bt,shared,idx+1))) < 0) {
rt = idx;
} else {
lt = idx + 1;
@@ -1291,18 +1259,16 @@ 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->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)
+ if ((type->new_node)(f, dxpl_id, H5B_INS_FIRST, H5B_NKEY(bt,shared,0), udata,
+ H5B_NKEY(bt,shared,1), bt->child + 0/*out*/) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, H5B_INS_ERROR, "unable to create leaf node")
bt->nchildren = 1;
bt->cache_info.is_dirty = TRUE;
idx = 0;
if (type->follow_min) {
- if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx],
- lt_key_changed, md_key, udata, bt->nkey[idx+1],
+ if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt,shared,idx),
+ lt_key_changed, md_key, udata, H5B_NKEY(bt,shared,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 {
@@ -1315,8 +1281,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
* Follow the minimum branch out of this node to a subtree.
*/
if ((my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type,
- bt->nkey[idx], lt_key_changed, md_key,
- udata, bt->nkey[idx+1], rt_key_changed,
+ H5B_NKEY(bt,shared,idx), lt_key_changed, md_key,
+ udata, H5B_NKEY(bt,shared,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) {
@@ -1325,8 +1291,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 ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx],
- lt_key_changed, md_key, udata, bt->nkey[idx+1],
+ if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt,shared,idx),
+ lt_key_changed, md_key, udata, H5B_NKEY(bt,shared,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) {
@@ -1336,8 +1302,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
* node. This node is not empty (handled above).
*/
my_ins = H5B_INS_LEFT;
- HDmemcpy(md_key, bt->nkey[idx], type->sizeof_nkey);
- if ((type->new_node)(f, dxpl_id, H5B_INS_LEFT, bt->nkey[idx], udata,
+ HDmemcpy(md_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey);
+ if ((type->new_node)(f, dxpl_id, H5B_INS_LEFT, H5B_NKEY(bt,shared,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;
@@ -1349,8 +1315,8 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
*/
idx = bt->nchildren - 1;
if ((my_ins = H5B_insert_helper(f, dxpl_id, bt->child[idx], type,
- bt->nkey[idx], lt_key_changed, md_key, udata,
- bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0)
+ H5B_NKEY(bt,shared,idx), lt_key_changed, md_key, udata,
+ H5B_NKEY(bt,shared,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) {
/*
@@ -1359,8 +1325,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 ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], bt->nkey[idx],
- lt_key_changed, md_key, udata, bt->nkey[idx+1],
+ if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt,shared,idx),
+ lt_key_changed, md_key, udata, H5B_NKEY(bt,shared,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) {
@@ -1371,9 +1337,9 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
*/
idx = bt->nchildren - 1;
my_ins = H5B_INS_RIGHT;
- HDmemcpy(md_key, bt->nkey[idx+1], type->sizeof_nkey);
+ HDmemcpy(md_key, H5B_NKEY(bt,shared,idx+1), type->sizeof_nkey);
if ((type->new_node)(f, dxpl_id, H5B_INS_RIGHT, md_key, udata,
- bt->nkey[idx+1], &child_addr/*out*/) < 0)
+ H5B_NKEY(bt,shared,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;
@@ -1392,16 +1358,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->nkey[idx], lt_key_changed, md_key, udata,
- bt->nkey[idx+1], rt_key_changed, &child_addr/*out*/)) < 0)
+ H5B_NKEY(bt,shared,idx), lt_key_changed, md_key, udata,
+ H5B_NKEY(bt,shared,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->nkey[idx],
- lt_key_changed, md_key, udata, bt->nkey[idx+1],
+ if ((my_ins = (type->insert)(f, dxpl_id, bt->child[idx], H5B_NKEY(bt,shared,idx),
+ lt_key_changed, md_key, udata, H5B_NKEY(bt,shared,idx+1),
rt_key_changed, &child_addr/*out*/)) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert leaf node")
}
@@ -1415,14 +1381,14 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
if (idx > 0)
*lt_key_changed = FALSE;
else
- HDmemcpy(lt_key, bt->nkey[idx], type->sizeof_nkey);
+ HDmemcpy(lt_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey);
}
if (*rt_key_changed) {
bt->cache_info.is_dirty = TRUE;
if (idx+1 < bt->nchildren)
*rt_key_changed = FALSE;
else
- HDmemcpy(rt_key, bt->nkey[idx+1], type->sizeof_nkey);
+ HDmemcpy(rt_key, H5B_NKEY(bt,shared,idx+1), type->sizeof_nkey);
}
if (H5B_INS_CHANGE == my_ins) {
/*
@@ -1439,7 +1405,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
* If this node is full then split it before inserting the new child.
*/
if (bt->nchildren == 2 * H5F_KVALUE(f, type)) {
- if (H5B_split(f, dxpl_id, type, bt, addr, idx, udata, new_node_p/*out*/)<0)
+ if (H5B_split(f, dxpl_id, bt, addr, idx, udata, new_node_p/*out*/)<0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, H5B_INS_ERROR, "unable to split node")
if (NULL == (twin = H5AC_protect(f, dxpl_id, H5AC_BT, *new_node_p, type, udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to load node")
@@ -1454,7 +1420,7 @@ H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
}
/* Insert the child */
- if (H5B_insert_child(f, type, tmp_bt, idx, child_addr, my_ins, md_key) < 0)
+ if (H5B_insert_child(f, tmp_bt, idx, child_addr, my_ins, md_key) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, H5B_INS_ERROR, "can't insert child")
}
@@ -1463,17 +1429,15 @@ 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) {
- assert(twin->nkey[0]);
- HDmemcpy(md_key, twin->nkey[0], type->sizeof_nkey);
+ HDmemcpy(md_key, H5B_NKEY(twin,shared,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.
*/
- assert(bt->nkey[bt->nchildren]);
- cmp = (type->cmp2) (f, dxpl_id, bt->nkey[bt->nchildren], udata,
- twin->nkey[0]);
+ cmp = (type->cmp2) (f, dxpl_id, H5B_NKEY(bt,shared,bt->nchildren), udata,
+ H5B_NKEY(twin,shared,0));
assert(0 == cmp);
#endif
} else {
@@ -1519,6 +1483,7 @@ herr_t
H5B_iterate (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op, haddr_t addr, void *udata)
{
H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
haddr_t next_addr;
haddr_t cur_addr = HADDR_UNDEF;
haddr_t *child = NULL;
@@ -1527,7 +1492,6 @@ H5B_iterate (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op
unsigned u; /* Local index variable */
unsigned level;
haddr_t left_child;
- size_t total_native_keysize; /*size of native keys */
herr_t ret_value;
FUNC_ENTER_NOAPI(H5B_iterate, FAIL)
@@ -1543,9 +1507,10 @@ 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, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
level = bt->level;
- total_native_keysize=bt->total_native_keysize;
left_child = bt->child[0];
if (H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, FALSE) < 0)
@@ -1563,7 +1528,7 @@ H5B_iterate (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op
* pointer from leaf to leaf until we've processed all leaves.
*/
if (NULL==(child=H5FL_SEQ_MALLOC(haddr_t,(size_t)(2*H5F_KVALUE(f,type)))) ||
- NULL==(key=H5FL_BLK_MALLOC(native_block,total_native_keysize)))
+ NULL==(key=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
for (cur_addr=addr, ret_value=0; H5F_addr_defined(cur_addr) && !ret_value; cur_addr=next_addr) {
@@ -1576,7 +1541,7 @@ H5B_iterate (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, H5B_operator_t op
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "B-tree node")
HDmemcpy(child, bt->child, bt->nchildren*sizeof(haddr_t));
- HDmemcpy(key, bt->native, bt->total_native_keysize);
+ HDmemcpy(key, bt->native, shared->sizeof_keys);
next_addr = bt->right;
nchildren = bt->nchildren;
@@ -1642,10 +1607,10 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
uint8_t *rt_key/*out*/, hbool_t *rt_key_changed/*out*/)
{
H5B_t *bt = NULL, *sibling = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
H5B_ins_t ret_value = H5B_INS_ERROR;
unsigned idx=0, lt=0, rt; /* Final, left & right indices */
int cmp=1; /* Key comparison value */
- unsigned u; /* Local index variable */
size_t sizeof_rec;
FUNC_ENTER_NOAPI(H5B_remove_helper, H5B_INS_ERROR)
@@ -1666,11 +1631,14 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
*/
if (NULL==(bt=H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, H5B_INS_ERROR, "unable to load B-tree node")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+
rt = bt->nchildren;
while (lt<rt && cmp) {
idx = (lt+rt)/2;
- if ((cmp=(type->cmp3)(f, dxpl_id, bt->nkey[idx], udata,
- bt->nkey[idx+1]))<0) {
+ if ((cmp=(type->cmp3)(f, dxpl_id, H5B_NKEY(bt,shared,idx), udata,
+ H5B_NKEY(bt,shared,idx+1)))<0) {
rt = idx;
} else {
lt = idx+1;
@@ -1687,8 +1655,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->nkey[idx]/*out*/,
- lt_key_changed/*out*/, udata, bt->nkey[idx+1]/*out*/,
+ bt->child[idx], type, level+1, H5B_NKEY(bt,shared,idx)/*out*/,
+ lt_key_changed/*out*/, udata, H5B_NKEY(bt,shared,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) {
@@ -1698,8 +1666,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->nkey[idx], lt_key_changed, udata,
- bt->nkey[idx+1], rt_key_changed))<0)
+ bt->child[idx], H5B_NKEY(bt,shared,idx), lt_key_changed, udata,
+ H5B_NKEY(bt,shared,idx+1), rt_key_changed))<0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, H5B_INS_ERROR, "key not found in leaf node")
} else {
/*
@@ -1726,7 +1694,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
/* Don't propagate change out of this B-tree node */
*lt_key_changed = FALSE;
} else {
- HDmemcpy(lt_key, bt->nkey[idx], type->sizeof_nkey);
+ HDmemcpy(lt_key, H5B_NKEY(bt,shared,idx), type->sizeof_nkey);
}
}
if (*rt_key_changed) {
@@ -1735,7 +1703,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
/* Don't propagate change out of this B-tree node */
*rt_key_changed = FALSE;
} else {
- HDmemcpy(rt_key, bt->nkey[idx+1], type->sizeof_nkey);
+ HDmemcpy(rt_key, H5B_NKEY(bt,shared,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.
@@ -1747,8 +1715,7 @@ 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 */
- assert(sibling->nkey[0]);
- HDmemcpy(sibling->nkey[0], bt->nkey[idx+1], type->sizeof_nkey);
+ HDmemcpy(H5B_NKEY(sibling,shared,0), H5B_NKEY(bt,shared,idx+1), type->sizeof_nkey);
sibling->cache_info.is_dirty = TRUE;
if (H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, FALSE) != SUCCEED)
@@ -1764,7 +1731,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
* If the subtree returned H5B_INS_REMOVE then we should remove the
* subtree entry from the current node. There are four cases:
*/
- sizeof_rec = bt->sizeof_rkey + H5F_SIZEOF_ADDR(f);
+ sizeof_rec = shared->sizeof_rkey + H5F_SIZEOF_ADDR(f);
if (H5B_INS_REMOVE==ret_value && 1==bt->nchildren) {
/*
* The subtree is the only child of this node. Discard both
@@ -1791,9 +1758,7 @@ 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")
/* 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) */
- assert(sibling->nkey[0]);
- HDmemcpy(sibling->nkey[0], bt->nkey[0], type->sizeof_nkey);
+ HDmemcpy(H5B_NKEY(sibling,shared,0), H5B_NKEY(bt,shared,0), type->sizeof_nkey);
sibling->left = bt->left;
sibling->cache_info.is_dirty = TRUE;
@@ -1805,7 +1770,8 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
}
bt->left = HADDR_UNDEF;
bt->right = HADDR_UNDEF;
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)bt->sizeof_node)<0
+ H5_CHECK_OVERFLOW(shared->sizeof_rnode,size_t,hsize_t);
+ if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)shared->sizeof_rnode)<0
|| H5AC_unprotect(f, dxpl_id, H5AC_BT, addr, bt, TRUE)<0) {
bt = NULL;
HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, H5B_INS_ERROR, "unable to free B-tree node")
@@ -1830,10 +1796,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
HDmemmove(bt->child,
bt->child+1,
bt->nchildren * sizeof(haddr_t));
- for (u=0; u<=bt->nchildren; u++)
- bt->nkey[u] = bt->native + u*type->sizeof_nkey;
- assert(bt->nkey[0]);
- HDmemcpy(lt_key, bt->nkey[0], type->sizeof_nkey);
+ HDmemcpy(lt_key, H5B_NKEY(bt,shared,0), type->sizeof_nkey);
*lt_key_changed = TRUE;
ret_value = H5B_INS_NOOP;
@@ -1846,8 +1809,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;
- assert(bt->nkey[bt->nchildren]);
- HDmemcpy(rt_key, bt->nkey[bt->nchildren], type->sizeof_nkey);
+ HDmemcpy(rt_key, H5B_NKEY(bt,shared,bt->nchildren), type->sizeof_nkey);
*rt_key_changed = TRUE;
/* Since our right key was changed, we must check for a right
@@ -1859,9 +1821,7 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
if (NULL == (sibling = H5AC_protect(f, dxpl_id, H5AC_BT, bt->right, type, udata, H5AC_WRITE)))
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 */
- assert(sibling->nkey[0]);
- HDmemcpy(sibling->nkey[0], bt->nkey[bt->nchildren], type->sizeof_nkey);
+ HDmemcpy(H5B_NKEY(sibling,shared,0), H5B_NKEY(bt,shared,bt->nchildren), type->sizeof_nkey);
sibling->cache_info.is_dirty = TRUE;
if (H5AC_unprotect(f, dxpl_id, H5AC_BT, bt->right, sibling, FALSE) != SUCCEED)
@@ -1890,8 +1850,6 @@ H5B_remove_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type
HDmemmove(bt->child+idx,
bt->child+idx+1,
(bt->nchildren-idx) * sizeof(haddr_t));
- for (u=idx; u<=bt->nchildren; u++)
- bt->nkey[u] = bt->native + u*type->sizeof_nkey;
ret_value = H5B_INS_NOOP;
} else {
@@ -1994,6 +1952,7 @@ herr_t
H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void *udata)
{
H5B_t *bt; /* B-tree node being operated on */
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
unsigned u; /* Local index variable */
herr_t ret_value=SUCCEED; /* Return value */
@@ -2007,6 +1966,8 @@ H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void
/* Lock this B-tree node into memory for now */
if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_WRITE)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
/* Iterate over all children in tree, deleting them */
if (bt->level > 0) {
@@ -2024,15 +1985,15 @@ H5B_delete(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr, void
for (u=0; u<bt->nchildren; u++) {
/* Call user's callback for each entry */
if ((type->remove)(f, dxpl_id,
- bt->child[u], bt->nkey[u], &lt_key_changed, udata,
- bt->nkey[u+1], &rt_key_changed)<0)
+ bt->child[u], H5B_NKEY(bt,shared,u), &lt_key_changed, udata,
+ H5B_NKEY(bt,shared,u+1), &rt_key_changed)<0)
HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "can't remove B-tree node")
} /* end for */
} /* end if */
} /* end else */
/* Delete this node from disk */
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)bt->sizeof_node)<0)
+ if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)shared->sizeof_rnode)<0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to free B-tree node")
done:
@@ -2120,8 +2081,8 @@ static H5B_t *
H5B_copy(const H5F_t *f, const H5B_t *old_bt)
{
H5B_t *new_node = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
size_t nkeys;
- size_t u;
H5B_t *ret_value;
FUNC_ENTER_NOAPI(H5B_copy, NULL)
@@ -2131,6 +2092,8 @@ H5B_copy(const H5F_t *f, const H5B_t *old_bt)
*/
assert(f);
assert(old_bt);
+ shared=H5RC_GET_OBJ(old_bt->rc_shared);
+ HDassert(shared);
/* Allocate memory for the new H5B_t object */
if (NULL==(new_node = H5FL_MALLOC(H5B_t)))
@@ -2140,25 +2103,18 @@ H5B_copy(const H5F_t *f, const H5B_t *old_bt)
HDmemcpy(new_node,old_bt,sizeof(H5B_t));
/* Compute the number of keys in this node */
- nkeys=2*H5F_KVALUE(f,old_bt->type);
+ nkeys=2*H5F_KVALUE(f,shared->type);
- 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->nkey=H5FL_SEQ_MALLOC(voidp,(nkeys+1))))
+ if ( NULL==(new_node->native=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)) ||
+ NULL==(new_node->child=H5FL_SEQ_MALLOC(haddr_t,nkeys)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for B-tree root node")
/* Copy the other structures */
- HDmemcpy(new_node->native,old_bt->native,old_bt->total_native_keysize);
+ HDmemcpy(new_node->native,old_bt->native,shared->sizeof_keys);
HDmemcpy(new_node->child,old_bt->child,(size_t)(sizeof(haddr_t)*nkeys));
- /*
- * Set up native key pointers in new node.
- */
- for (u = 0; u < (nkeys+1); u++)
- new_node->nkey[u] = new_node->native + u*new_node->type->sizeof_nkey;
-
/* Increment the ref-count on the raw page */
- H5RC_INC(new_node->rc_page);
+ H5RC_INC(new_node->rc_shared);
/* Set return value */
ret_value=new_node;
@@ -2168,7 +2124,6 @@ done:
if(new_node) {
H5FL_BLK_FREE (native_block,new_node->native);
H5FL_SEQ_FREE (haddr_t,new_node->child);
- H5FL_SEQ_FREE (voidp,new_node->nkey);
H5FL_FREE (H5B_t,new_node);
} /* end if */
} /* end if */
@@ -2198,6 +2153,7 @@ H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
const H5B_class_t *type, void *udata)
{
H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
unsigned u; /* Local index variable */
herr_t ret_value=SUCCEED; /* Return value */
@@ -2218,20 +2174,22 @@ H5B_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
*/
if (NULL == (bt = H5AC_protect(f, dxpl_id, H5AC_BT, addr, type, udata, H5AC_READ)))
HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree node")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
/*
* Print the values.
*/
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Tree type ID:",
- ((bt->type->id)==H5B_SNODE_ID ? "H5B_SNODE_ID" :
- ((bt->type->id)==H5B_ISTORE_ID ? "H5B_ISTORE_ID" : "Unknown!")));
+ ((shared->type->id)==H5B_SNODE_ID ? "H5B_SNODE_ID" :
+ ((shared->type->id)==H5B_ISTORE_ID ? "H5B_ISTORE_ID" : "Unknown!")));
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of node:",
- bt->sizeof_node);
+ shared->sizeof_rnode);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
"Size of raw (disk) key:",
- bt->sizeof_rkey);
+ shared->sizeof_rkey);
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
"Dirty flag:",
bt->cache_info.is_dirty ? "True" : "False");
@@ -2264,16 +2222,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:");
- assert(bt->nkey[u]);
+ assert(H5B_NKEY(bt,shared,u));
(void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
- bt->nkey[u], udata);
+ H5B_NKEY(bt,shared,u), udata);
/* Decode the 'right' key & print it */
HDfprintf(stream, "%*s%-*s\n", indent + 3, "", MAX(0, fwidth - 3),
"Right Key:");
- assert(bt->nkey[u+1]);
+ assert(H5B_NKEY(bt,shared,u+1));
(void)(type->debug_key)(stream, f, dxpl_id, indent+6, MAX (0, fwidth-6),
- bt->nkey[u+1], udata);
+ H5B_NKEY(bt,shared,u+1), udata);
}
}
@@ -2382,8 +2340,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 */
- cmp = (type->cmp2) (f, dxpl_id, bt->nkey[i], udata,
- bt->nkey[i+1]);
+ cmp = (type->cmp2) (f, dxpl_id, H5B_NKEY(bt,i), udata,
+ H5B_NKEY(bt,i+1));
assert(cmp < 0);
}
}
diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h
index 67135cf..37047e7 100644
--- a/src/H5Bpkg.h
+++ b/src/H5Bpkg.h
@@ -47,18 +47,12 @@
struct H5B_t {
H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
/* first field in structure */
- const H5B_class_t *type; /*type of tree */
- 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 */
+ H5RC_t *rc_shared; /*ref-counted shared info */
unsigned level; /*node level */
haddr_t left; /*address of left sibling */
haddr_t right; /*address of right sibling */
unsigned nchildren; /*number of child pointers */
- H5RC_t *rc_page; /*ref-counted disk page */
- uint8_t *raw_page; /*disk page (shared) */
uint8_t *native; /*array of keys in native format */
- void **nkey; /*2k+1 key entries */
haddr_t *child; /*2k child pointers */
};
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 4cf558a..2dfd0e1 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -34,6 +34,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Fprivate.h" /* File access */
+#include "H5RCprivate.h" /* Reference counted object functions */
/*
* Feature: Define this constant if you want to check B-tree consistency
@@ -72,6 +73,18 @@ typedef int (*H5B_operator_t)(H5F_t *f, hid_t, void *_lt_key, haddr_t addr,
/* Typedef for B-tree in memory (defined in H5Bpkg.h) */
typedef struct H5B_t H5B_t;
+/* Each B-tree has certain information that can be shared across all
+ * the instances of nodes in that B-tree.
+ */
+typedef struct H5B_shared_t {
+ const struct H5B_class_t *type; /* Type of tree */
+ size_t sizeof_rkey; /* Size of raw (disk) key */
+ size_t sizeof_rnode; /* Size of raw (disk) node */
+ size_t sizeof_keys; /* Size of native (memory) key node */
+ uint8_t *page; /* Disk page */
+ size_t *nkey; /* Offsets of each native key in native key buffer */
+} H5B_shared_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. Each
@@ -84,7 +97,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 */
+ H5RC_t * (*get_shared)(H5F_t*, const void*); /*shared info 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 */
diff --git a/src/H5Distore.c b/src/H5Distore.c
index 09c025c..d9f05e4 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -146,7 +146,7 @@ static haddr_t H5D_istore_get_addr(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *
const hssize_t offset[], H5D_istore_ud1_t *_udata);
static void *H5D_istore_chunk_alloc(size_t size, const H5O_pline_t *pline);
static void *H5D_istore_chunk_xfree(void *chk, const H5O_pline_t *pline);
-static herr_t H5D_istore_page_free (void *page);
+static herr_t H5D_istore_shared_free (void *page);
/* B-tree iterator callbacks */
static int H5D_istore_iter_allocated(H5F_t *f, hid_t dxpl_id, void *left_key, haddr_t addr,
@@ -158,7 +158,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 H5RC_t *H5D_istore_get_shared(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*/);
@@ -189,7 +189,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_get_shared, /*get_shared */
H5D_istore_new_node, /*new */
H5D_istore_cmp2, /*cmp2 */
H5D_istore_cmp3, /*cmp3 */
@@ -203,6 +203,9 @@ H5B_class_t H5B_ISTORE[1] = {{
H5D_istore_debug_key, /*debug */
}};
+/* Declare a free list to manage the H5B_shared_t struct */
+H5FL_EXTERN(H5B_shared_t);
+
/* Declare a free list to manage H5F_rdcc_ent_t objects */
H5FL_DEFINE_STATIC(H5D_rdcc_ent_t);
@@ -212,6 +215,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 native key offset sequence information */
+H5FL_SEQ_DEFINE_STATIC(size_t);
+
/* Declare a free list to manage the raw page information */
H5FL_BLK_DEFINE_STATIC(chunk_page);
@@ -255,9 +261,9 @@ H5D_istore_sizeof_rkey(H5F_t UNUSED *f, const void *_udata)
/*-------------------------------------------------------------------------
- * Function: H5D_istore_get_page
+ * Function: H5D_istore_get_shared
*
- * Purpose: Returns the raw data page for the specified UDATA.
+ * Purpose: Returns the shared B-tree info for the specified UDATA.
*
* Return: Success: Pointer to the raw B-tree page for this dataset
*
@@ -270,23 +276,23 @@ H5D_istore_sizeof_rkey(H5F_t UNUSED *f, const void *_udata)
*
*-------------------------------------------------------------------------
*/
-static void *
-H5D_istore_get_page(H5F_t UNUSED *f, const void *_udata)
+static H5RC_t *
+H5D_istore_get_shared(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);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_get_shared);
assert(udata);
assert(udata->mesg);
- assert(udata->mesg->u.chunk.rc_page);
+ assert(udata->mesg->u.chunk.btree_shared);
- /* Increment reference count on B-tree node */
- H5RC_INC(udata->mesg->u.chunk.rc_page);
+ /* Increment reference count on B-tree info */
+ H5RC_INC(udata->mesg->u.chunk.btree_shared);
- /* Get the pointer to the ref-count object */
- FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.rc_page);
-} /* end H5D_istore_get_page() */
+ /* Return the pointer to the ref-count object */
+ FUNC_LEAVE_NOAPI(udata->mesg->u.chunk.btree_shared);
+} /* end H5D_istore_get_shared() */
/*-------------------------------------------------------------------------
@@ -307,23 +313,27 @@ static herr_t
H5D_istore_decode_key(H5F_t UNUSED *f, H5B_t *bt, uint8_t *raw, void *_key)
{
H5D_istore_key_t *key = (H5D_istore_key_t *) _key;
- int i;
- int ndims = H5D_ISTORE_NDIMS(bt);
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ unsigned u;
+ unsigned ndims;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_decode_key);
/* check args */
assert(f);
assert(bt);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
assert(raw);
assert(key);
- assert(ndims>0 && ndims<=H5O_LAYOUT_NDIMS);
+ ndims = H5D_ISTORE_NDIMS(shared);
+ assert(ndims<=H5O_LAYOUT_NDIMS);
/* decode */
UINT32DECODE(raw, key->nbytes);
UINT32DECODE(raw, key->filter_mask);
- for (i=0; i<ndims; i++)
- UINT64DECODE(raw, key->offset[i]);
+ for (u=0; u<ndims; u++)
+ UINT64DECODE(raw, key->offset[u]);
FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5D_istore_decode_key() */
@@ -347,23 +357,27 @@ static herr_t
H5D_istore_encode_key(H5F_t UNUSED *f, H5B_t *bt, uint8_t *raw, void *_key)
{
H5D_istore_key_t *key = (H5D_istore_key_t *) _key;
- int ndims = H5D_ISTORE_NDIMS(bt);
- int i;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ unsigned ndims;
+ unsigned u;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_encode_key);
/* check args */
assert(f);
assert(bt);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
assert(raw);
assert(key);
- assert(ndims>0 && ndims<=H5O_LAYOUT_NDIMS);
+ ndims = H5D_ISTORE_NDIMS(shared);
+ assert(ndims<=H5O_LAYOUT_NDIMS);
/* encode */
UINT32ENCODE(raw, key->nbytes);
UINT32ENCODE(raw, key->filter_mask);
- for (i=0; i<ndims; i++)
- UINT64ENCODE(raw, key->offset[i]);
+ for (u=0; u<ndims; u++)
+ UINT64ENCODE(raw, key->offset[u]);
FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5D_istore_encode_key() */
@@ -498,13 +512,31 @@ H5D_istore_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
assert(udata);
assert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
- if (H5V_vector_lt_s(udata->mesg->u.chunk.ndims, udata->key.offset,
- lt_key->offset)) {
- ret_value = -1;
- } else if (H5V_vector_ge_s(udata->mesg->u.chunk.ndims, udata->key.offset,
- rt_key->offset)) {
- ret_value = 1;
- }
+#ifdef NEW_WAY
+ /* Special case for faster checks on 1-D chunks */
+ /* (Checking for ndims==2 because last dimension is the datatype size) */
+ if(udata->mesg->u.chunk.ndims==2) {
+ if(udata->key.offset[0]>=rt_key->offset[0])
+ ret_value=1;
+ else if(udata->key.offset[0]<lt_key->offset[0])
+ ret_value=(-1);
+ } /* end if */
+ else {
+ if (H5V_vector_ge_s(udata->mesg->u.chunk.ndims, udata->key.offset,
+ rt_key->offset))
+ ret_value = 1;
+ else if (H5V_vector_lt_s(udata->mesg->u.chunk.ndims, udata->key.offset,
+ lt_key->offset))
+ ret_value = -1;
+ } /* end else */
+#else /* NEW_WAY */
+ if (H5V_vector_ge_s(udata->mesg->u.chunk.ndims, udata->key.offset,
+ rt_key->offset))
+ ret_value = 1;
+ else if (H5V_vector_lt_s(udata->mesg->u.chunk.ndims, udata->key.offset,
+ lt_key->offset))
+ ret_value = -1;
+#endif /* NEW_WAY */
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5D_istore_cmp3() */
@@ -900,10 +932,9 @@ 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 */
+ H5B_shared_t *shared; /* Shared B-tree node info */
+ size_t u; /* Local index variable */
H5D_rdcc_t *rdcc = &(dset->cache.chunk);
- void *page; /* Buffer for raw B-tree node */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_init, FAIL);
@@ -920,17 +951,28 @@ H5D_istore_init (H5F_t *f, H5D_t *dset)
/* 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==(page=H5FL_BLK_MALLOC(chunk_page,size)))
+ /* Allocate space for the shared structure */
+ if(NULL==(shared=H5FL_MALLOC(H5B_shared_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info")
+
+ /* Set up the "global" information for this file's groups */
+ shared->type= H5B_ISTORE;
+ shared->sizeof_rkey = H5D_istore_sizeof_rkey(f, &udata);
+ assert(shared->sizeof_rkey);
+ shared->sizeof_rnode = H5B_nodesize(f, H5B_ISTORE, &shared->sizeof_keys, shared->sizeof_rkey);
+ assert(shared->sizeof_rnode);
+ if(NULL==(shared->page=H5FL_BLK_MALLOC(chunk_page,shared->sizeof_rnode)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
+ if(NULL==(shared->nkey=H5FL_SEQ_MALLOC(size_t,(size_t)(2*H5F_KVALUE(f,H5B_ISTORE)+1))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
+
+ /* Initialize the offsets into the native key buffer */
+ for(u=0; u<(2*H5F_KVALUE(f,H5B_ISTORE)+1); u++)
+ shared->nkey[u]=u*H5B_ISTORE->sizeof_nkey;
- /* Make page buffer reference counted */
- if(NULL==(dset->layout.u.chunk.rc_page=H5RC_create(page,H5D_istore_page_free)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for page")
+ /* Make shared B-tree info reference counted */
+ if(NULL==(dset->layout.u.chunk.btree_shared=H5RC_create(shared,H5D_istore_shared_free)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info")
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1227,7 +1269,7 @@ H5D_istore_dest (H5F_t *f, hid_t dxpl_id, H5D_t *dset)
HDmemset (rdcc, 0, sizeof(H5D_rdcc_t));
/* Free the raw B-tree node buffer */
- if(H5RC_DEC(dset->layout.u.chunk.rc_page)<0)
+ if(H5RC_DEC(dset->layout.u.chunk.btree_shared)<0)
HGOTO_ERROR (H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page");
done:
@@ -1236,9 +1278,9 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_istore_page_free
+ * Function: H5D_istore_shared_free
*
- * Purpose: Free a B-tree node
+ * Purpose: Free B-tree shared info
*
* Return: Non-negative on success/Negative on failure
*
@@ -1250,14 +1292,23 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5D_istore_page_free (void *page)
+H5D_istore_shared_free (void *_shared)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_page_free)
+ H5B_shared_t *shared = (H5B_shared_t *)_shared;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_shared_free)
+
+ /* Free the raw B-tree node buffer */
+ H5FL_BLK_FREE(chunk_page,shared->page);
+
+ /* Free the B-tree native key offsets buffer */
+ H5FL_SEQ_FREE(size_t,shared->nkey);
- H5FL_BLK_FREE(chunk_page,page);
+ /* Free the shared B-tree info */
+ H5FL_FREE(H5B_shared_t,shared);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5D_istore_page_free() */
+} /* end H5D_istore_shared_free() */
/*-------------------------------------------------------------------------
diff --git a/src/H5F.c b/src/H5F.c
index de16b40..66d8587 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1842,7 +1842,6 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* We've just opened a fresh new file (or truncated one). We need
* to create & write the superblock.
*/
-
#ifdef H5_HAVE_FPHDF5
if (!H5FD_is_fphdf5_driver(lf) || H5FD_fphdf5_is_captain(lf)) {
#endif /* H5_HAVE_FPHDF5 */
@@ -4468,13 +4467,13 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5F_rc_page
+ * Function: H5F_grp_btree_shared
*
- * Purpose: Replaced a macro to retrieve the raw B-tree page value
+ * Purpose: Replaced a macro to retrieve the shared B-tree node info
* now that the generic properties are being used to store
* the values.
*
- * Return: Success: Non-void, and the raw B-tree page value
+ * Return: Success: Non-void, and the shared B-tree node info
* is returned.
*
* Failure: void (should not happen)
@@ -4487,16 +4486,16 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5RC_t *H5F_rc_page(const H5F_t *f)
+H5RC_t *H5F_grp_btree_shared(const H5F_t *f)
{
/* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_rc_page)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_grp_btree_shared)
assert(f);
assert(f->shared);
- FUNC_LEAVE_NOAPI(f->shared->rc_page)
-} /* end H5F_raw_page() */
+ FUNC_LEAVE_NOAPI(f->shared->grp_btree_shared)
+} /* end H5F_grp_btree_shared() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 318a8f1..24c980c 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -127,7 +127,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 */
- H5RC_t *rc_page; /* Pointer to ref-counted raw B-tree node buffer */
+ H5RC_t *grp_btree_shared; /* Ref-counted group B-tree node info */
} H5F_file_t;
/* A record of the mount table */
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 452b160..2e92415 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -211,7 +211,7 @@ typedef struct H5F_t H5F_t;
/* 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_RC_PAGE(F) ((F)->shared->rc_page)
+#define H5F_GRP_BTREE_SHARED(F) ((F)->shared->grp_btree_shared)
#else /* H5F_PACKAGE */
#define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F))
#define H5F_SIZEOF_SIZE(F) (H5F_sizeof_size(F))
@@ -221,7 +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_RC_PAGE(F) (H5F_rc_page(F))
+#define H5F_GRP_BTREE_SHARED(F) (H5F_grp_btree_shared(F))
#endif /* H5F_PACKAGE */
@@ -418,7 +418,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 struct H5RC_t *H5F_rc_page(const H5F_t *f);
+H5_DLL struct H5RC_t *H5F_grp_btree_shared(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 1710270..a879e54 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -64,7 +64,7 @@ typedef struct H5G_node_key_t {
/* PRIVATE PROTOTYPES */
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);
-static herr_t H5G_node_page_free (void *page);
+static herr_t H5G_node_shared_free(void *shared);
/* Metadata cache callbacks */
static H5G_node_t *H5G_node_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
@@ -77,7 +77,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 H5RC_t *H5G_node_get_shared(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*/);
@@ -118,7 +118,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_get_shared, /*get_shared */
H5G_node_create, /*new */
H5G_node_cmp2, /*cmp2 */
H5G_node_cmp3, /*cmp3 */
@@ -132,6 +132,9 @@ H5B_class_t H5B_SNODE[1] = {{
H5G_node_debug_key, /*debug */
}};
+/* Declare a free list to manage the H5B_shared_t struct */
+H5FL_EXTERN(H5B_shared_t);
+
/* Declare a free list to manage the H5G_node_t struct */
H5FL_DEFINE_STATIC(H5G_node_t);
@@ -141,6 +144,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 native key offset sequence information */
+H5FL_SEQ_DEFINE_STATIC(size_t);
+
/* Declare a free list to manage the raw page information */
H5FL_BLK_DEFINE_STATIC(grp_page);
@@ -174,9 +180,9 @@ H5G_node_sizeof_rkey(H5F_t *f, const void UNUSED * udata)
/*-------------------------------------------------------------------------
- * Function: H5G_node_get_page
+ * Function: H5G_node_get_shared
*
- * Purpose: Returns the raw data page for the specified UDATA.
+ * Purpose: Returns the shared B-tree info for the specified UDATA.
*
* Return: Success: Pointer to the raw B-tree page for this
file's groups
@@ -190,19 +196,22 @@ H5G_node_sizeof_rkey(H5F_t *f, const void UNUSED * udata)
*
*-------------------------------------------------------------------------
*/
-static void *
-H5G_node_get_page(H5F_t *f, const void UNUSED *_udata)
+static H5RC_t *
+H5G_node_get_shared(H5F_t *f, const void UNUSED *_udata)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_get_page);
+ H5RC_t *rc;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_get_shared);
assert(f);
- /* Increment reference count on B-tree node */
- H5RC_INC(H5F_RC_PAGE(f));
+ /* Increment reference count on shared B-tree node */
+ rc=H5F_GRP_BTREE_SHARED(f);
+ H5RC_INC(rc);
- /* Get the pointer to the ref-count object */
- FUNC_LEAVE_NOAPI(H5F_RC_PAGE(f));
-} /* end H5G_node_get_page() */
+ /* Return the pointer to the ref-count object */
+ FUNC_LEAVE_NOAPI(rc);
+} /* end H5G_node_get_shared() */
/*-------------------------------------------------------------------------
@@ -1721,15 +1730,13 @@ done:
* 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 */
- void *page; /* Buffer for raw B-tree node */
+ H5B_shared_t *shared; /* Shared B-tree node info */
+ size_t u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_node_init, FAIL);
@@ -1737,17 +1744,28 @@ H5G_node_init(H5F_t *f)
/* Check arguments. */
assert(f);
+ /* Allocate space for the shared structure */
+ if(NULL==(shared=H5FL_MALLOC(H5B_shared_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info")
+
/* 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==(page=H5FL_BLK_MALLOC(grp_page,size)))
+ shared->type= H5B_SNODE;
+ shared->sizeof_rkey = H5G_node_sizeof_rkey(f, NULL);
+ assert(shared->sizeof_rkey);
+ shared->sizeof_rnode = H5B_nodesize(f, H5B_SNODE, &shared->sizeof_keys, shared->sizeof_rkey);
+ assert(shared->sizeof_rnode);
+ if(NULL==(shared->page=H5FL_BLK_MALLOC(grp_page,shared->sizeof_rnode)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
+ if(NULL==(shared->nkey=H5FL_SEQ_MALLOC(size_t,(size_t)(2*H5F_KVALUE(f,H5B_SNODE)+1))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for B-tree page")
+
+ /* Initialize the offsets into the native key buffer */
+ for(u=0; u<(2*H5F_KVALUE(f,H5B_SNODE)+1); u++)
+ shared->nkey[u]=u*H5B_SNODE->sizeof_nkey;
- /* Make page buffer reference counted */
- if(NULL==(f->shared->rc_page=H5RC_create(page,H5G_node_page_free)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for page")
+ /* Make shared B-tree info reference counted */
+ if(NULL==(f->shared->grp_btree_shared=H5RC_create(shared,H5G_node_shared_free)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info")
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -1778,16 +1796,16 @@ H5G_node_close(const H5F_t *f)
assert(f);
/* Free the raw B-tree node buffer */
- H5RC_DEC(f->shared->rc_page);
+ H5RC_DEC(H5F_GRP_BTREE_SHARED(f));
FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5G_node_close */
/*-------------------------------------------------------------------------
- * Function: H5G_node_page_free
+ * Function: H5G_node_shared_free
*
- * Purpose: Free a B-tree node
+ * Purpose: Free B-tree shared info
*
* Return: Non-negative on success/Negative on failure
*
@@ -1799,15 +1817,23 @@ H5G_node_close(const H5F_t *f)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_node_page_free (void *page)
+H5G_node_shared_free (void *_shared)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_page_free)
+ H5B_shared_t *shared = (H5B_shared_t *)_shared;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_shared_free)
/* Free the raw B-tree node buffer */
- H5FL_BLK_FREE(grp_page,page);
+ H5FL_BLK_FREE(grp_page,shared->page);
+
+ /* Free the B-tree native key offsets buffer */
+ H5FL_SEQ_FREE(size_t,shared->nkey);
+
+ /* Free the shared B-tree info */
+ H5FL_FREE(H5B_shared_t,shared);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5G_node_page_free() */
+} /* end H5G_node_shared_free() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 26bf5d8..8de6392 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -134,7 +134,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 */
- H5RC_t *rc_page; /* Ref-counted buffer for raw B-tree page */
+ H5RC_t *btree_shared; /* Ref-counted info for B-tree nodes */
} H5O_layout_chunk_t;
typedef struct H5O_layout_compact_t {