summaryrefslogtreecommitdiffstats
path: root/src/H5Dbtree.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2015-04-17 20:49:27 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2015-04-17 20:49:27 (GMT)
commit7bf3a426e8634c851d9c550fd980f07d3e29fc1b (patch)
tree4102bab36bd666a2caf3421e05a6e3b1b350220c /src/H5Dbtree.c
parentc6717e8134be832103cf777d3685d61d225b61c3 (diff)
downloadhdf5-7bf3a426e8634c851d9c550fd980f07d3e29fc1b.zip
hdf5-7bf3a426e8634c851d9c550fd980f07d3e29fc1b.tar.gz
hdf5-7bf3a426e8634c851d9c550fd980f07d3e29fc1b.tar.bz2
[svn-r26837] Description:
Separate allocating chunk on disk from inserting the chunk record into the index. This allows a "SWMR-safe" insert/update of chunks (the chunk is always allocated -> written -> inserted/updated in the index). Tested on: Mac OSX/64 10.10.2 (amazon) w/parallel & serial Linux/32 2.6.18 (jam) w/serial & parallel
Diffstat (limited to 'src/H5Dbtree.c')
-rw-r--r--src/H5Dbtree.c68
1 files changed, 21 insertions, 47 deletions
diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c
index 75080f7..d05de03 100644
--- a/src/H5Dbtree.c
+++ b/src/H5Dbtree.c
@@ -74,8 +74,8 @@
* The chunk's file address is part of the B-tree and not part of the key.
*/
typedef struct H5D_btree_key_t {
- uint32_t nbytes; /*size of stored data */
hsize_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/
+ uint32_t nbytes; /*size of stored data */
unsigned filter_mask; /*excluded filters */
} H5D_btree_key_t;
@@ -255,7 +255,7 @@ H5D__btree_get_shared(const H5F_t UNUSED *f, const void *_udata)
*-------------------------------------------------------------------------
*/
static herr_t
-H5D__btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
+H5D__btree_new_node(H5F_t *f, hid_t UNUSED dxpl_id, H5B_ins_t op,
void *_lt_key, void *_udata, void *_rt_key,
haddr_t *addr_p/*out*/)
{
@@ -265,7 +265,7 @@ H5D__btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
unsigned u;
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* check args */
HDassert(f);
@@ -275,18 +275,16 @@ H5D__btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
HDassert(udata->common.layout->ndims > 0 && udata->common.layout->ndims < H5O_LAYOUT_NDIMS);
HDassert(addr_p);
- /* Allocate new storage */
- HDassert(udata->nbytes > 0);
- H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t);
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage")
- udata->addr = *addr_p;
+ /* Set address */
+ HDassert(H5F_addr_defined(udata->chunk_block.offset));
+ HDassert(udata->chunk_block.length > 0);
+ *addr_p = udata->chunk_block.offset;
/*
* The left key describes the storage of the UDATA chunk being
* inserted into the tree.
*/
- lt_key->nbytes = udata->nbytes;
+ H5_ASSIGN_OVERFLOW(lt_key->nbytes, udata->chunk_block.length, hsize_t, uint32_t);
lt_key->filter_mask = udata->filter_mask;
for(u = 0; u < udata->common.layout->ndims; u++)
lt_key->offset[u] = udata->common.offset[u];
@@ -305,7 +303,6 @@ H5D__btree_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
} /* end if */
} /* end if */
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__btree_new_node() */
@@ -468,8 +465,8 @@ H5D__btree_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void
/* Initialize return values */
HDassert(lt_key->nbytes > 0);
- udata->addr = addr;
- udata->nbytes = lt_key->nbytes;
+ udata->chunk_block.offset = addr;
+ udata->chunk_block.length = lt_key->nbytes;
udata->filter_mask = lt_key->filter_mask;
done:
@@ -507,7 +504,7 @@ done:
*/
/* ARGSUSED */
static H5B_ins_t
-H5D__btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
+H5D__btree_insert(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t addr, void *_lt_key,
hbool_t *lt_key_changed,
void *_md_key, void *_udata, void *_rt_key,
hbool_t UNUSED *rt_key_changed,
@@ -547,35 +544,17 @@ H5D__btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
* Already exists. If the new size is not the same as the old size
* then we should reallocate storage.
*/
- if(lt_key->nbytes != udata->nbytes) {
-/* Currently, the old chunk data is "thrown away" after the space is reallocated,
- * so avoid data copy in H5MF_realloc() call by just free'ing the space and
- * allocating new space.
- *
- * This should keep the file smaller also, by freeing the space and then
- * allocating new space, instead of vice versa (in H5MF_realloc).
- *
- * QAK - 11/19/2002
- */
-#ifdef OLD_WAY
- if(HADDR_UNDEF == (*new_node_p = H5MF_realloc(f, H5FD_MEM_DRAW, addr,
- (hsize_t)lt_key->nbytes, (hsize_t)udata->nbytes)))
- HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk storage")
-#else /* OLD_WAY */
- H5_CHECK_OVERFLOW(lt_key->nbytes, uint32_t, hsize_t);
- if(H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes) < 0)
- HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, H5B_INS_ERROR, "unable to free chunk")
- H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t);
- if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
- HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk")
-#endif /* OLD_WAY */
- lt_key->nbytes = udata->nbytes;
+ if(lt_key->nbytes != udata->chunk_block.length) {
+ /* Set node's address (already re-allocated by main chunk routines) */
+ HDassert(H5F_addr_defined(udata->chunk_block.offset));
+ *new_node_p = udata->chunk_block.offset;
+ H5_ASSIGN_OVERFLOW(lt_key->nbytes, udata->chunk_block.length, hsize_t, uint32_t);
lt_key->filter_mask = udata->filter_mask;
*lt_key_changed = TRUE;
- udata->addr = *new_node_p;
ret_value = H5B_INS_CHANGE;
} else {
- udata->addr = addr;
+ /* Already have address in udata, from main chunk routines */
+ HDassert(H5F_addr_defined(udata->chunk_block.offset));
ret_value = H5B_INS_NOOP;
}
@@ -589,20 +568,15 @@ H5D__btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
* Split this node, inserting the new new node to the right of the
* current node. The MD_KEY is where the split occurs.
*/
- md_key->nbytes = udata->nbytes;
+ H5_ASSIGN_OVERFLOW(md_key->nbytes, udata->chunk_block.length, hsize_t, uint32_t);
md_key->filter_mask = udata->filter_mask;
for(u = 0; u < udata->common.layout->ndims; u++) {
HDassert(0 == udata->common.offset[u] % udata->common.layout->dim[u]);
md_key->offset[u] = udata->common.offset[u];
} /* end for */
- /*
- * Allocate storage for the new chunk
- */
- H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t);
- if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->nbytes)))
- HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "file allocation failed")
- udata->addr = *new_node_p;
+ HDassert(H5F_addr_defined(udata->chunk_block.offset));
+ *new_node_p = udata->chunk_block.offset;
ret_value = H5B_INS_RIGHT;
} else {