summaryrefslogtreecommitdiffstats
path: root/src/H5Dbtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Dbtree.c')
-rw-r--r--src/H5Dbtree.c386
1 files changed, 364 insertions, 22 deletions
diff --git a/src/H5Dbtree.c b/src/H5Dbtree.c
index e61811d..f511d90 100644
--- a/src/H5Dbtree.c
+++ b/src/H5Dbtree.c
@@ -124,6 +124,10 @@ static herr_t H5D_btree_encode_key(const H5B_shared_t *shared, uint8_t *raw,
const void *_key);
static herr_t H5D_btree_debug_key(FILE *stream, int indent, int fwidth,
const void *key, const void *udata);
+static herr_t H5D_btree_create_flush_dep(void *_key, void *_udata,
+ void *parent);
+static herr_t H5D_btree_update_flush_dep(void *_key, void *_udata,
+ void *old_parent, void *new_parent);
/* Chunked layout indexing callbacks */
static herr_t H5D_btree_idx_init(const H5D_chk_idx_info_t *idx_info,
@@ -146,6 +150,10 @@ static herr_t H5D_btree_idx_copy_shutdown(H5O_storage_chunk_t *storage_src,
static herr_t H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info,
hsize_t *size);
static herr_t H5D_btree_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr);
+static herr_t H5D_btree_idx_support(const H5D_chk_idx_info_t *idx_info,
+ H5D_chunk_ud_t *udata, H5AC_info_t *child_entry);
+static herr_t H5D_btree_idx_unsupport(const H5D_chk_idx_info_t *idx_info,
+ H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry);
static herr_t H5D_btree_idx_dump(const H5O_storage_chunk_t *storage,
FILE *stream);
static herr_t H5D_btree_idx_dest(const H5D_chk_idx_info_t *idx_info);
@@ -157,7 +165,7 @@ static herr_t H5D_btree_idx_dest(const H5D_chk_idx_info_t *idx_info);
/* v1 B-tree indexed chunk I/O ops */
const H5D_chunk_ops_t H5D_COPS_BTREE[1] = {{
- FALSE, /* v1 B-tree indices don't support SWMR access */
+ TRUE, /* v1 B-tree indices do support SWMR access */
H5D_btree_idx_init,
H5D_btree_idx_create,
H5D_btree_idx_is_space_alloc,
@@ -171,8 +179,8 @@ const H5D_chunk_ops_t H5D_COPS_BTREE[1] = {{
H5D_btree_idx_copy_shutdown,
H5D_btree_idx_size,
H5D_btree_idx_reset,
- NULL,
- NULL,
+ H5D_btree_idx_support,
+ H5D_btree_idx_unsupport,
H5D_btree_idx_dump,
H5D_btree_idx_dest
}};
@@ -199,6 +207,8 @@ H5B_class_t H5B_BTREE[1] = {{
H5D_btree_decode_key, /*decode */
H5D_btree_encode_key, /*encode */
H5D_btree_debug_key, /*debug */
+ H5D_btree_create_flush_dep, /*create_flush_dep */
+ H5D_btree_update_flush_dep, /*update_flush_dep */
}};
@@ -561,13 +571,20 @@ H5D_btree_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
* QAK - 11/19/2002
*/
#ifdef OLD_WAY
+ /* Note that this does not take SWMR writes into account! Fix this
+ * if we ever want to go back to this code. -NAF 8/2/11 */
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")
+ /* Only free the old location if not doing SWMR writes - otherwise
+ * we must keep the old chunk around in case a reader has an
+ * outdated version of the b-tree node */
+ if(!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE)) {
+ 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")
+ } /* end if */
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")
@@ -644,9 +661,11 @@ H5D_btree_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key /*in,out *
FUNC_ENTER_NOAPI_NOINIT(H5D_btree_remove)
/* Remove raw data chunk from file */
- 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")
+ if(!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE)) {
+ 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")
+ } /* end if */
/* Mark keys as unchanged */
*lt_key_changed = FALSE;
@@ -801,7 +820,7 @@ H5D_btree_shared_create(const H5F_t *f, H5O_storage_chunk_t *store, unsigned ndi
/* Set up the "local" information for this dataset's chunks */
/* <none> */
-
+HDassert(!store->u.btree.shared);
/* Make shared B-tree info reference counted */
if(NULL == (store->u.btree.shared = H5RC_create(shared, H5B_shared_free)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't create ref-count wrapper for shared B-tree info")
@@ -812,6 +831,91 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_btree_create_flush_dep
+ *
+ * Purpose: Creates a flush dependency between the specified chunk
+ * (child) and parent.
+ *
+ * Return: Success: 0
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, September 21, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_create_flush_dep(void *_key, void *_udata, void *parent)
+{
+ H5D_btree_key_t *key = (H5D_btree_key_t *)_key;
+ H5D_chunk_common_ud_t *udata = (H5D_chunk_common_ud_t *) _udata;
+ int ret_value;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_create_flush_dep)
+
+ HDassert(key);
+ HDassert(udata);
+ HDassert(udata->layout->ndims > 0 && udata->layout->ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(parent);
+
+ /* If there is no rdcc, then there are no cached chunks to create
+ * dependencies on. This should only happen when copying */
+ if(udata->rdcc)
+ /* Delegate to chunk routine */
+ if(H5D_chunk_create_flush_dep(udata->rdcc, udata->layout, key->offset,
+ parent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_btree_create_flush_dep() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_update_flush_dep
+ *
+ * Purpose: Updates the flush dependency of the specified chunk from
+ * old_parent to new_parent, but only if the current parent
+ * is cached. If the chunk is not cached, does nothing.
+ *
+ * Return: Success: 0
+ * Failure: FAIL
+ *
+ * Programmer: Neil Fortner
+ * Tuesday, August 31, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_update_flush_dep(void *_key, void *_udata, void *old_parent,
+ void *new_parent)
+{
+ H5D_btree_key_t *key = (H5D_btree_key_t *)_key;
+ H5D_chunk_common_ud_t *udata = (H5D_chunk_common_ud_t *) _udata;
+ int ret_value;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_update_flush_dep)
+
+ HDassert(key);
+ HDassert(udata);
+ HDassert(udata->layout->ndims > 0 && udata->layout->ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(old_parent);
+ HDassert(new_parent);
+
+ /* If there is no rdcc, then there are no cached chunks to update
+ * dependencies. This should only happen when copying */
+ if(udata->rdcc)
+ /* Delegate to chunk routine */
+ if(H5D_chunk_update_flush_dep(udata->rdcc, udata->layout, key->offset,
+ old_parent, new_parent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to update flush dependency")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_btree_update_flush_dep() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_btree_idx_init
*
* Purpose: Initialize the indexing information for a dataset.
@@ -871,7 +975,9 @@ done:
static herr_t
H5D_btree_idx_create(const H5D_chk_idx_info_t *idx_info)
{
- H5D_chunk_common_ud_t udata; /* User data for B-tree callback */
+ H5D_chunk_common_ud_t udata; /* User data for B-tree callback */
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_create)
@@ -888,11 +994,26 @@ H5D_btree_idx_create(const H5D_chk_idx_info_t *idx_info)
udata.layout = idx_info->layout;
udata.storage = idx_info->storage;
+ /* Check for SWMR writes to the file */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/* Create the v1 B-tree for the chunk index */
- if(H5B_create(idx_info->f, idx_info->dxpl_id, H5B_BTREE, &udata, &(idx_info->storage->idx_addr)/*out*/) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create B-tree")
+ if(H5B_create(idx_info->f, idx_info->dxpl_id, H5B_BTREE, &udata, oh, &(idx_info->storage->idx_addr)/*out*/) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't create B-tree")
done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_btree_idx_create() */
@@ -942,7 +1063,9 @@ H5D_btree_idx_is_space_alloc(const H5O_storage_chunk_t *storage)
static herr_t
H5D_btree_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_insert)
@@ -954,14 +1077,30 @@ H5D_btree_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(udata);
+ /* Check for SWMR writes to the file. If so we must pin the dataset object
+ * header so it can be set as a flush dependency parent. */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/*
* Create the chunk it if it doesn't exist, or reallocate the chunk if
* its size changed.
*/
- if(H5B_insert(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
+ if(H5B_insert(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata, oh) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_btree_idx_insert() */
@@ -983,6 +1122,8 @@ done:
static herr_t
H5D_btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata)
{
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_get_addr)
@@ -996,11 +1137,27 @@ H5D_btree_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata
HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(udata);
+ /* Check for SWMR writes to the file. If so we must pin the dataset object
+ * header so it can be set as a flush dependency parent. */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/* Go get the chunk information from the B-tree */
- if(H5B_find(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
+ if(H5B_find(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata, oh) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get chunk info")
done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_btree_idx_get_addr() */
@@ -1071,9 +1228,11 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info,
H5D_chunk_cb_func_t chunk_cb, void *chunk_udata)
{
H5D_btree_it_ud_t udata; /* User data for B-tree iterator callback */
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT_NOERR(H5D_btree_idx_iterate)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_iterate)
HDassert(idx_info);
HDassert(idx_info->f);
@@ -1084,6 +1243,19 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info,
HDassert(chunk_cb);
HDassert(chunk_udata);
+ /* Check for SWMR writes to the file. If so we must pin the dataset object
+ * header so it can be set as a flush dependency parent. */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/* Initialize userdata */
HDmemset(&udata, 0, sizeof udata);
udata.common.layout = idx_info->layout;
@@ -1092,9 +1264,13 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info,
udata.udata = chunk_udata;
/* Iterate over existing chunks */
- if((ret_value = H5B_iterate(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, H5D_btree_idx_iterate_cb, &udata)) < 0)
+ if((ret_value = H5B_iterate(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, H5D_btree_idx_iterate_cb, &udata, oh)) < 0)
HERROR(H5E_DATASET, H5E_BADITER, "unable to iterate over chunk B-tree");
+done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_btree_idx_iterate() */
@@ -1114,6 +1290,8 @@ H5D_btree_idx_iterate(const H5D_chk_idx_info_t *idx_info,
static herr_t
H5D_btree_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata)
{
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_remove)
@@ -1126,13 +1304,29 @@ H5D_btree_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *
HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
HDassert(udata);
+ /* Check for SWMR writes to the file. If so we must pin the dataset object
+ * header so it can be set as a flush dependency parent. */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/* Remove the chunk from the v1 B-tree index and release the space for the
* chunk (in the B-tree callback).
*/
- if(H5B_remove(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata) < 0)
+ if(H5B_remove(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, udata, oh) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to remove chunk entry")
done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* H5D_btree_idx_remove() */
@@ -1154,7 +1348,9 @@ done:
static herr_t
H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_delete)
@@ -1170,6 +1366,19 @@ H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info)
H5O_storage_chunk_t tmp_storage; /* Local copy of storage info */
H5D_chunk_common_ud_t udata; /* User data for B-tree operations */
+ /* Check for SWMR writes to the file. If so we must pin the dataset object
+ * header so it can be set as a flush dependency parent. */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/* Set up temporary chunked storage info */
tmp_storage = *idx_info->storage;
@@ -1183,7 +1392,7 @@ H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info)
udata.storage = &tmp_storage;
/* Delete entire B-tree */
- if(H5B_delete(idx_info->f, idx_info->dxpl_id, H5B_BTREE, tmp_storage.idx_addr, &udata) < 0)
+ if(H5B_delete(idx_info->f, idx_info->dxpl_id, H5B_BTREE, tmp_storage.idx_addr, &udata, oh) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "unable to delete chunk B-tree")
/* Release the shared B-tree page */
@@ -1194,6 +1403,9 @@ H5D_btree_idx_delete(const H5D_chk_idx_info_t *idx_info)
} /* end if */
done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_btree_idx_delete() */
@@ -1300,6 +1512,8 @@ H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
H5D_chunk_common_ud_t udata; /* User-data for loading B-tree nodes */
H5B_info_t bt_info; /* B-tree info */
hbool_t shared_init = FALSE; /* Whether shared B-tree info is initialized */
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_btree_idx_size, FAIL)
@@ -1312,6 +1526,19 @@ H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
HDassert(idx_info->storage);
HDassert(index_size);
+ /* Check for SWMR writes to the file. If so we must pin the dataset object
+ * header so it can be set as a flush dependency parent. */
+ if(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE) {
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+ } /* end if */
+
/* Initialize the shared info for the B-tree traversal */
if(H5D_btree_shared_create(idx_info->f, idx_info->storage, idx_info->layout->ndims) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
@@ -1323,13 +1550,16 @@ H5D_btree_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size)
udata.storage = idx_info->storage;
/* Get metadata information for B-tree */
- if(H5B_get_info(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, &bt_info, NULL, &udata) < 0)
+ if(H5B_get_info(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr, &bt_info, NULL, &udata, oh) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "unable to iterate over chunk B-tree")
/* Set the size of the B-tree */
*index_size = bt_info.size;
done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
if(shared_init) {
if(NULL == idx_info->storage->u.btree.shared)
HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "ref-counted page nil")
@@ -1370,6 +1600,118 @@ H5D_btree_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr)
/*-------------------------------------------------------------------------
+ * Function: H5D_btree_idx_support
+ *
+ * Purpose: Create a dependency between a chunk [proxy] and the index
+ * metadata that contains the record for the chunk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Friday, Jun 24, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5D_btree_idx_support(const H5D_chk_idx_info_t *idx_info,
+ H5D_chunk_ud_t *udata, H5AC_info_t *child_entry)
+{
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_support)
+
+ /* Check args */
+ HDassert(idx_info);
+ HDassert(idx_info->f);
+ HDassert(idx_info->pline);
+ HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
+ HDassert(udata);
+ HDassert(child_entry);
+ HDassert(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE);
+
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+
+ /* Add the flush dependency on the chunk */
+ if((ret_value = H5B_support(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr,
+ udata, oh, child_entry)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTDEPEND, FAIL, "unable to create flush dependency on b-tree array metadata")
+
+done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_btree_idx_support() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_btree_idx_unsupport
+ *
+ * Purpose: Destroy a dependency between a chunk [proxy] and the index
+ * metadata that contains the record for the chunk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Neil Fortner
+ * Wednesday, Jul 6, 2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D_btree_idx_unsupport(const H5D_chk_idx_info_t *idx_info,
+ H5D_chunk_common_ud_t *udata, H5AC_info_t *child_entry)
+{
+ H5O_loc_t oloc; /* Temporary object header location for dataset */
+ H5O_t *oh = NULL; /* Dataset's object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_btree_idx_unsupport)
+
+ /* Check args */
+ HDassert(idx_info);
+ HDassert(idx_info->f);
+ HDassert(idx_info->pline);
+ HDassert(idx_info->layout);
+ HDassert(idx_info->storage);
+ HDassert(H5F_addr_defined(idx_info->storage->idx_addr));
+ HDassert(udata);
+ HDassert(child_entry);
+ HDassert(H5F_INTENT(idx_info->f) & H5F_ACC_SWMR_WRITE);
+
+ /* Set up object header location for dataset */
+ H5O_loc_reset(&oloc);
+ oloc.file = idx_info->f;
+ oloc.addr = idx_info->storage->u.btree.dset_ohdr_addr;
+
+ /* Pin the dataset's object header */
+ if(NULL == (oh = H5O_pin(&oloc, idx_info->dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+
+ /* Add the flush dependency on the chunk */
+ if((ret_value = H5B_unsupport(idx_info->f, idx_info->dxpl_id, H5B_BTREE, idx_info->storage->idx_addr,
+ udata, oh, child_entry)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTUNDEPEND, FAIL, "unable to destroy flush dependency on b-tree array metadata")
+
+done:
+ if(oh && H5O_unpin(oh) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTUNPIN, FAIL, "unable to unpin dataset object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_btree_idx_unsupport() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_btree_idx_dump
*
* Purpose: Dump indexing information to a stream.