diff options
Diffstat (limited to 'src/H5B2.c')
-rw-r--r-- | src/H5B2.c | 135 |
1 files changed, 133 insertions, 2 deletions
@@ -461,6 +461,127 @@ done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5B2_split_root */ +#ifdef LATER + +/*------------------------------------------------------------------------- + * Function: H5B2_redistribute + * + * Purpose: Redistribute records between several nodes + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Feb 8 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5B2_redistribute(H5F_t *f, hid_t dxpl_id, H5B2_t *bt2, H5RC_t *bt2_shared) +{ + H5B2_shared_t *shared; /* B-tree's shared info */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5B2_split_root) + + HDassert(f); + HDassert(bt2); + HDassert(bt2_shared); + + /* Get the pointer to the shared B-tree info */ + shared=H5RC_GET_OBJ(bt2_shared); + HDassert(shared); + + if(bt2->depth==0) { + H5B2_internal_t *new_int=NULL; /* Pointer to new internal node */ + H5B2_leaf_t *old_leaf=NULL, *new_leaf=NULL; /* Pointers to old & new leaf nodes */ + H5B2_node_ptr_t new_int_ptr; /* Node pointer to manage new internal node */ + H5B2_node_ptr_t new_leaf_ptr; /* Node pointer to manage new leaf node */ + H5B2_node_ptr_t old_leaf_ptr; /* Node pointer to manage old leaf node */ + unsigned mid_record; /* Index of "middle" record in current node */ + + /* Create new leaf node */ + new_leaf_ptr.all_nrec=new_leaf_ptr.node_nrec=0; + if(H5B2_create_leaf(f, dxpl_id, bt2, &new_leaf_ptr)<0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new leaf node") + + /* Determine "middle" record to promote to new root */ + mid_record = shared->split_leaf_nrec/2; + + /* Set "old" leaf pointer to root node */ + old_leaf_ptr = bt2->root; + + /* Protect both leafs */ + if (NULL == (old_leaf = H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, old_leaf_ptr.addr, &(old_leaf_ptr.node_nrec), bt2_shared, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree leaf node") + if (NULL == (new_leaf = H5AC_protect(f, dxpl_id, H5AC_BT2_LEAF, new_leaf_ptr.addr, &(new_leaf_ptr.node_nrec), bt2_shared, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree leaf node") + + /* Copy "upper half" of records to new leaf */ + HDmemcpy(new_leaf->leaf_native,H5B2_LEAF_NREC(old_leaf,shared,mid_record+1),shared->type->nkey_size*(shared->split_leaf_nrec-(mid_record+1))); + + /* Create new internal node */ + new_int_ptr.all_nrec=new_int_ptr.node_nrec=0; + if(H5B2_create_internal(f, dxpl_id, bt2, &new_int_ptr)<0) + HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to create new internal node") + + /* Protect new internal node */ + if (NULL == (new_int = H5AC_protect(f, dxpl_id, H5AC_BT2_INT, new_int_ptr.addr, &(new_int_ptr.node_nrec), bt2_shared, H5AC_WRITE))) + HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load B-tree internal node") + + /* Copy "middle" record to new internal node */ + HDmemcpy(new_int->int_native,H5B2_LEAF_NREC(old_leaf,shared,mid_record),shared->type->nkey_size); + + /* Update record counts in leaf nodes */ + old_leaf_ptr.all_nrec = old_leaf_ptr.node_nrec = old_leaf->nrec = mid_record; + new_leaf_ptr.all_nrec = new_leaf_ptr.node_nrec = new_leaf->nrec = shared->split_leaf_nrec-(mid_record+1); + + /* Mark leaf nodes as dirty */ + old_leaf->cache_info.is_dirty = TRUE; + new_leaf->cache_info.is_dirty = TRUE; + + /* Release leaf nodes */ + if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, old_leaf_ptr.addr, old_leaf, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree leaf node") + if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_LEAF, new_leaf_ptr.addr, new_leaf, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree leaf node") + + /* Set internal node pointers to leaf nodes */ + new_int->node_ptrs[0] = old_leaf_ptr; + new_int->node_ptrs[1] = new_leaf_ptr; + + /* Update record count in new internal node */ + new_int->nrec = 1; + + /* Mark new internal node as dirty */ + new_int->cache_info.is_dirty = TRUE; + + /* Release new internal node */ + if (H5AC_unprotect(f, dxpl_id, H5AC_BT2_INT, new_int_ptr.addr, new_int, H5AC__NO_FLAGS_SET) < 0) + HGOTO_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree internal node") + + /* Update depth of B-tree */ + bt2->depth++; + + /* Update pointer to B-tree's root node to pointer to new internal node */ + bt2->root.addr = new_int_ptr.addr; + bt2->root.node_nrec = 1; + + /* Mark B-tree header as dirty */ + bt2->cache_info.is_dirty = TRUE; + } /* end if */ + else { +HDfprintf(stderr,"%s: Need to split internal root! shared->split_int_nrec=%Zu\n",FUNC,shared->split_int_nrec); +HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split internal root node yet") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5B2_split_root */ +#endif /* LATER */ + /*------------------------------------------------------------------------- * Function: H5B2_insert @@ -572,9 +693,19 @@ H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr, /* Preemptively split/redistribute a node we will enter */ if((depth==1 && child_node_ptr->node_nrec==shared->split_leaf_nrec) || (depth>1 && child_node_ptr->node_nrec==shared->split_int_nrec)) { -HDfprintf(stderr,"%s: need to split child node!, depth=%u\n",FUNC,depth); -HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node") /* Attempt to redistribute records among children */ + if(idx==0) { +HDfprintf(stderr,"%s: left-most child\n",FUNC); + } /* end if */ + else if(idx==(internal->nrec-1)) { +HDfprintf(stderr,"%s: right-most child\n",FUNC); + } /* end if */ + else { +HDfprintf(stderr,"%s: middle child\n",FUNC); + } /* end else */ + +HDfprintf(stderr,"%s: need to split child node!, depth=%u, idx=%d\n",FUNC,depth,idx); +HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL, "unable to split child node") /* Split children, if can't redistribute */ /* Update record count info for current node to reflect new # of records (in parent) */ /* Update child_node_ptr (to reflect change in location from split/redistribution) */ |