diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2015-04-17 20:49:27 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2015-04-17 20:49:27 (GMT) |
commit | 7bf3a426e8634c851d9c550fd980f07d3e29fc1b (patch) | |
tree | 4102bab36bd666a2caf3421e05a6e3b1b350220c /src/H5Dbtree.c | |
parent | c6717e8134be832103cf777d3685d61d225b61c3 (diff) | |
download | hdf5-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.c | 68 |
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 { |