summaryrefslogtreecommitdiffstats
path: root/src/H5B.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5B.c')
-rw-r--r--src/H5B.c146
1 files changed, 112 insertions, 34 deletions
diff --git a/src/H5B.c b/src/H5B.c
index 23ee342..899cedd 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -126,6 +126,7 @@ static herr_t H5B_split(H5F_t *f, const H5B_class_t *type, H5B_t *old_bt,
haddr_t old_addr, intn idx,
const float split_ratios[], void *udata,
haddr_t *new_addr/*out*/);
+static H5B_t * H5B_copy(H5F_t *f, const H5B_t *old_bt);
#ifdef H5B_DEBUG
static herr_t H5B_assert(H5F_t *f, haddr_t addr, const H5B_class_t *type,
void *udata);
@@ -880,7 +881,6 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
intn level;
H5B_t *bt;
size_t size;
- uint8_t *buf = NULL;
H5B_ins_t my_ins = H5B_INS_ERROR;
herr_t ret_value = FAIL;
@@ -938,55 +938,57 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
* from "moving".
*/
size = H5B_nodesize(f, type, NULL, bt->sizeof_rkey);
- if (NULL==(buf = H5MM_malloc(size))) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "memory allocation failed");
- }
if (HADDR_UNDEF==(old_root=H5MF_alloc(f, H5FD_MEM_BTREE, size))) {
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"unable to allocate file space to move root");
}
- if (H5AC_flush(f, H5AC_BT, addr, FALSE) < 0) {
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL,
- "unable to flush B-tree root node");
- }
- if (H5F_block_read(f, addr, (hsize_t)size, H5P_DEFAULT, buf)<0) {
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, FAIL,
- "unable to read B-tree root node");
- }
- if (H5F_block_write(f, old_root, (hsize_t)size, H5P_DEFAULT, buf)<0) {
- HGOTO_ERROR(H5E_BTREE, H5E_WRITEERROR, FAIL,
- "unable to move B-tree root node");
- }
- if (H5AC_rename(f, H5AC_BT, addr, old_root) < 0) {
- HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL,
- "unable to move B-tree root node");
- }
/* update the new child's left pointer */
if (NULL == (bt = H5AC_find(f, H5AC_BT, child, type, udata))) {
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL,
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL,
"unable to load new child");
}
bt->dirty = TRUE;
bt->left = old_root;
- /* clear the old root at the old address (we already copied it) */
+ /*
+ * Move the node to the new location by checking it out & checking it in
+ * at the new location -QAK
+ */
+ /* Bring the old root into the cache if it's not already */
if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) {
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL,
- "unable to clear old root location");
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL,
+ "unable to load new child");
}
+
+ /* Make certain the old root info is marked as dirty before moving it, */
+ /* so it is certain to be written out at the new location */
bt->dirty = TRUE;
- bt->ndirty = 0;
- bt->left = HADDR_UNDEF;
- bt->right = HADDR_UNDEF;
- bt->nchildren = 0;
- /* the new root */
- if (NULL == (bt = H5AC_find(f, H5AC_BT, addr, type, udata))) {
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL, "unable to load new root");
+ /* Make a copy of the old root information */
+ if (NULL == (bt = H5B_copy(f, bt))) {
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, FAIL,
+ "unable to copy old root");
+ }
+
+ /* Move the location on the disk */
+ if (H5AC_rename(f, H5AC_BT, addr, old_root) < 0) {
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTSPLIT, FAIL,
+ "unable to move B-tree root node");
+ }
+
+ /* Insert the copy of the old root into the file again */
+ if (H5AC_set(f, H5AC_BT, addr, bt) < 0) {
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL,
+ "unable to flush old B-tree root node");
}
+
+ /* clear the old root info at the old address (we already copied it) */
bt->dirty = TRUE;
+ bt->left = HADDR_UNDEF;
+ bt->right = HADDR_UNDEF;
+
+ /* Set the new information for the copy */
bt->ndirty = 2;
bt->level = level + 1;
bt->nchildren = 2;
@@ -1011,7 +1013,6 @@ H5B_insert(H5F_t *f, const H5B_class_t *type, haddr_t addr,
ret_value = SUCCEED;
done:
- buf = H5MM_xfree(buf);
FUNC_LEAVE(ret_value);
}
@@ -2023,6 +2024,83 @@ H5B_nodesize(H5F_t *f, const H5B_class_t *type,
FUNC_LEAVE(size);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_copy
+ *
+ * Purpose: Deep copies an existing H5B_t node.
+ *
+ * Return: Success: Pointer to H5B_t object.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Apr 18 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5B_t *
+H5B_copy(H5F_t *f, const H5B_t *old_bt)
+{
+ H5B_t *ret_value = NULL;
+ size_t size, total_native_keysize;
+ uintn nkeys;
+ uintn u;
+
+ FUNC_ENTER(H5B_copy, NULL);
+
+ /*
+ * Check arguments.
+ */
+ assert(f);
+ assert(old_bt);
+
+ /*
+ * Get correct sizes
+ */
+ size = H5B_nodesize(f, old_bt->type, &total_native_keysize, old_bt->sizeof_rkey);
+
+ /* Allocate memory for the new H5B_t object */
+ if (NULL==(ret_value = H5FL_ALLOC(H5B_t,0))) {
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for B-tree root node");
+ }
+
+ /* Copy the main structure */
+ HDmemcpy(ret_value,old_bt,sizeof(H5B_t));
+
+ /* Compute the number of keys in this node */
+ nkeys=2*H5B_K(f,old_bt->type);
+
+ if (NULL==(ret_value->page=H5FL_BLK_ALLOC(page,size,0)) ||
+ NULL==(ret_value->native=H5FL_BLK_ALLOC(native_block,total_native_keysize,0)) ||
+ NULL==(ret_value->child=H5FL_ARR_ALLOC(haddr_t,nkeys,0)) ||
+ NULL==(ret_value->key=H5FL_ARR_ALLOC(H5B_key_t,(nkeys+1),0))) {
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed for B-tree root node");
+ }
+
+ /* Copy the other structures */
+ HDmemcpy(ret_value->page,old_bt->page,size);
+ HDmemcpy(ret_value->native,old_bt->native,total_native_keysize);
+ HDmemcpy(ret_value->child,old_bt->child,sizeof(haddr_t)*nkeys);
+ HDmemcpy(ret_value->key,old_bt->key,sizeof(H5B_key_t)*(nkeys+1));
+
+ /*
+ * Translate the keys from pointers into the old 'page' buffer into
+ * pointers into the new 'page' buffer.
+ */
+ for (u = 0; u < nkeys; u++)
+ ret_value->key[u].rkey = (old_bt->key[u].rkey - old_bt->page) + ret_value->page;
+
+done:
+ FUNC_LEAVE(ret_value);
+} /* H5B_copy */
+
/*-------------------------------------------------------------------------
* Function: H5B_debug