summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2010-06-15 21:21:03 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2010-06-15 21:21:03 (GMT)
commit686d856802341c3e6389532ee2b3617b74f6c0ce (patch)
tree6a42a36d02b4c087627b2d5bcfb4e115be37ee9e /src
parent60ecd356b2e24f125a5fd7abbdb57569af76f3ba (diff)
downloadhdf5-686d856802341c3e6389532ee2b3617b74f6c0ce.zip
hdf5-686d856802341c3e6389532ee2b3617b74f6c0ce.tar.gz
hdf5-686d856802341c3e6389532ee2b3617b74f6c0ce.tar.bz2
[svn-r19006] Purpose: Improve performance of the the chunk cache
Description: Previously, the chunk cache would, when looking for a chunk, alwaylook for the chunk in the b-tree before checking the cache. Reworked the functions that look up chunks to always check the cache first and avoid the b-tree lookup if the chunk is in cache. Tested: jam, linew, amani (h5committest)
Diffstat (limited to 'src')
-rw-r--r--src/H5Dchunk.c377
-rw-r--r--src/H5Dmpio.c22
-rw-r--r--src/H5Dpkg.h9
3 files changed, 183 insertions, 225 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index e1d6c1b..a28bce9 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -1607,53 +1607,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_in_cache
- *
- * Purpose: Check if a chunk is in the cache.
- *
- * Return: TRUE or FALSE
- *
- * Programmer: Quincey Koziol
- * 1 April 2008
- *
- *-------------------------------------------------------------------------
- */
-static hbool_t
-H5D_chunk_in_cache(const H5D_t *dset, const hsize_t *chunk_offset,
- hsize_t chunk_idx)
-{
- H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk);/*raw data chunk cache*/
- hbool_t found = FALSE; /*already in cache? */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_chunk_in_cache)
-
- /* Sanity checks */
- HDassert(dset);
- HDassert(chunk_offset);
-
- /* Check if the chunk is in the cache (but hasn't been written to disk yet) */
- if(rdcc->nslots > 0) {
- unsigned idx = H5D_CHUNK_HASH(dset->shared, chunk_idx); /* Cache entry index */
- H5D_rdcc_ent_t *ent = rdcc->slot[idx]; /* Cache entry */
-
- /* Potential match... */
- if(ent) {
- size_t u; /* Local index variable */
-
- for(u = 0, found = TRUE; u < dset->shared->layout.u.chunk.ndims; u++) {
- if(chunk_offset[u] != ent->offset[u]) {
- found = FALSE;
- break;
- } /* end if */
- } /* end for */
- } /* end if */
- } /* end if */
-
- FUNC_LEAVE_NOAPI(found)
-} /* end H5D_chunk_in_cache() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_chunk_read
*
* Purpose: Read from a chunked dataset.
@@ -1679,7 +1632,6 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
uint32_t src_accessed_bytes = 0; /* Total accessed size in a chunk */
hbool_t skip_missing_chunks = FALSE; /* Whether to skip missing chunks */
- unsigned idx_hint = 0; /* Cache index hint */
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_read)
@@ -1739,11 +1691,12 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
chunk_info = H5D_CHUNK_GET_NODE_INFO(fm, chunk_node);
/* Get the info for the chunk in the file */
- if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ if(H5D_chunk_lookup(io_info->dset, io_info->dxpl_id,
+ chunk_info->coords, chunk_info->index, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* Check for non-existant chunk & skip it if appropriate */
- if(H5F_addr_defined(udata.addr) || H5D_chunk_in_cache(io_info->dset, chunk_info->coords, chunk_info->index)
+ if(H5F_addr_defined(udata.addr) || UINT_MAX != udata.idx_hint
|| !skip_missing_chunks) {
/* Load the chunk into cache and lock it. */
if((cacheable = H5D_chunk_cacheable(io_info, udata.addr, FALSE)) < 0)
@@ -1758,7 +1711,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
src_accessed_bytes = chunk_info->chunk_points * (uint32_t)type_info->src_type_size;
/* Lock the chunk into the cache */
- if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, FALSE, &idx_hint)))
+ if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, FALSE)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@@ -1791,7 +1744,7 @@ H5D_chunk_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked read failed")
/* Release the cache lock on the chunk. */
- if(chunk && H5D_chunk_unlock(io_info, &udata, FALSE, idx_hint, chunk, src_accessed_bytes) < 0)
+ if(chunk && H5D_chunk_unlock(io_info, &udata, FALSE, chunk, src_accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
@@ -1834,7 +1787,6 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
H5D_storage_t cpt_store; /* Chunk storage information as compact dataset */
hbool_t cpt_dirty; /* Temporary placeholder for compact storage "dirty" flag */
uint32_t dst_accessed_bytes = 0; /* Total accessed size in a chunk */
- unsigned idx_hint = 0; /* Cache index hint */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_write)
@@ -1875,7 +1827,8 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
/* Load the chunk into cache. But if the whole chunk is written,
* simply allocate space instead of load the chunk. */
- if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ if(H5D_chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords,
+ chunk_info->index, &udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
if((cacheable = H5D_chunk_cacheable(io_info, udata.addr, TRUE)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't tell if chunk is cacheable")
@@ -1896,7 +1849,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
entire_chunk = FALSE;
/* Lock the chunk into the cache */
- if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk, &idx_hint)))
+ if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@@ -1948,7 +1901,7 @@ H5D_chunk_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "chunked write failed")
/* Release the cache lock on the chunk. */
- if(chunk && H5D_chunk_unlock(io_info, &udata, TRUE, idx_hint, chunk, dst_accessed_bytes) < 0)
+ if(chunk && H5D_chunk_unlock(io_info, &udata, TRUE, chunk, dst_accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
/* Advance to next chunk in list */
@@ -2262,11 +2215,10 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_chunk_get_info
+ * Function: H5D_chunk_lookup
*
- * Purpose: Get the info about a chunk if file space has been
- * assigned. Save the retrieved information in the udata
- * supplied.
+ * Purpose: Loops up a chunk in cache and on disk, and retrieves
+ * information about that chunk.
*
* Return: Non-negative on success/Negative on failure
*
@@ -2276,12 +2228,15 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
- H5D_chunk_ud_t *udata)
+H5D_chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset,
+ hsize_t chunk_idx, H5D_chunk_ud_t *udata)
{
+ H5D_rdcc_ent_t *ent = NULL; /* Cache entry */
+ hbool_t found = FALSE; /* In cache? */
+ unsigned u; /* Counter */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_get_info)
+ FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_lookup)
HDassert(dset);
HDassert(dset->shared->layout.u.chunk.ndims > 0);
@@ -2298,28 +2253,49 @@ H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset
udata->filter_mask = 0;
udata->addr = HADDR_UNDEF;
- /* Check for cached information */
- if(!H5D_chunk_cinfo_cache_found(&dset->shared->cache.chunk.last, udata)) {
- H5D_chk_idx_info_t idx_info; /* Chunked index info */
+ /* Check for chunk in cache */
+ if(dset->shared->cache.chunk.nslots > 0) {
+ udata->idx_hint = H5D_CHUNK_HASH(dset->shared, chunk_idx);
+ ent = dset->shared->cache.chunk.slot[udata->idx_hint];
- /* Compose chunked index info struct */
- idx_info.f = dset->oloc.file;
- idx_info.dxpl_id = dxpl_id;
- idx_info.pline = &dset->shared->dcpl_cache.pline;
- idx_info.layout = &dset->shared->layout.u.chunk;
- idx_info.storage = &dset->shared->layout.storage.u.chunk;
+ if(ent)
+ for(u = 0, found = TRUE; u < dset->shared->layout.u.chunk.ndims; u++)
+ if(chunk_offset[u] != ent->offset[u]) {
+ found = FALSE;
+ break;
+ } /* end if */
+ } /* end if */
+
+ /* Find chunk addr */
+ if(found)
+ udata->addr = ent->chunk_addr;
+ else {
+ /* Invalidate idx_hint, to signal that the chunk is not in cache */
+ udata->idx_hint = UINT_MAX;
- /* Go get the chunk information */
- if((dset->shared->layout.storage.u.chunk.ops->get_addr)(&idx_info, udata) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query chunk address")
+ /* Check for cached information */
+ if(!H5D_chunk_cinfo_cache_found(&dset->shared->cache.chunk.last, udata)) {
+ H5D_chk_idx_info_t idx_info; /* Chunked index info */
- /* Cache the information retrieved */
- H5D_chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, udata);
- } /* end if */
+ /* Compose chunked index info struct */
+ idx_info.f = dset->oloc.file;
+ idx_info.dxpl_id = dxpl_id;
+ idx_info.pline = &dset->shared->dcpl_cache.pline;
+ idx_info.layout = &dset->shared->layout.u.chunk;
+ idx_info.storage = &dset->shared->layout.storage.u.chunk;
+
+ /* Go get the chunk information */
+ if((dset->shared->layout.storage.u.chunk.ops->get_addr)(&idx_info, udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't query chunk address")
+
+ /* Cache the information retrieved */
+ H5D_chunk_cinfo_cache_update(&dset->shared->cache.chunk.last, udata);
+ } /* end if */
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5D_chunk_get_info() */
+} /* H5D_chunk_lookup() */
/*-------------------------------------------------------------------------
@@ -2679,7 +2655,7 @@ done:
*/
void *
H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
- hbool_t relax, unsigned *idx_hint/*in,out*/)
+ hbool_t relax)
{
H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
const H5O_pline_t *pline = &(dset->shared->dcpl_cache.pline); /* I/O pipeline info */
@@ -2689,7 +2665,6 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
hbool_t fb_info_init = FALSE; /* Whether the fill value buffer has been initialized */
H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache*/
H5D_rdcc_ent_t *ent = NULL; /*cache entry */
- unsigned idx = 0; /*hash index number */
hbool_t found = FALSE; /*already in cache? */
haddr_t chunk_addr = HADDR_UNDEF; /* Address of chunk on disk */
size_t chunk_size; /*size of a chunk */
@@ -2710,20 +2685,21 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
HDassert(layout->u.chunk.size > 0);
H5_ASSIGN_OVERFLOW(chunk_size, layout->u.chunk.size, uint32_t, size_t);
- /* Search for the chunk in the cache */
- if(rdcc->nslots > 0) {
- idx = H5D_CHUNK_HASH(dset->shared, io_info->store->chunk.index);
- ent = rdcc->slot[idx];
+ /* Check if the chunk is in the cache */
+ if(UINT_MAX != udata->idx_hint) {
+ /* Sanity check */
+ HDassert(udata->idx_hint < rdcc->nslots);
+ HDassert(rdcc->slot[udata->idx_hint]);
- if(ent)
- for(u = 0, found = TRUE; u < layout->u.chunk.ndims; u++)
- if(io_info->store->chunk.offset[u] != ent->offset[u]) {
- found = FALSE;
- break;
- } /* end if */
- } /* end if */
+ /* Get the entry */
+ ent = rdcc->slot[udata->idx_hint];
+
+#ifndef NDEBUG
+ /* Make sure this is the right chunk */
+ for(u = 0; u < layout->u.chunk.ndims; u++)
+ HDassert(io_info->store->chunk.offset[u] == ent->offset[u]);
+#endif /* NDEBUG */
- if(found) {
/*
* Already in the cache. Count a hit.
*/
@@ -2823,63 +2799,7 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
} /* end else */
HDassert(found || chunk_size > 0);
- if(!found && rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max &&
- (!ent || !ent->locked)) {
- /*
- * Add the chunk to the cache only if the slot is not already locked.
- * Preempt enough things from the cache to make room.
- */
- if(ent) {
- if(H5D_chunk_cache_evict(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, ent, TRUE) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk from cache")
- } /* end if */
- if(H5D_chunk_cache_prune(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, chunk_size) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache")
-
- /* Create a new entry */
- if(NULL == (ent = H5FL_MALLOC(H5D_rdcc_ent_t)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate raw data chunk entry")
-
- ent->locked = 0;
- ent->dirty = FALSE;
- ent->deleted = FALSE;
- ent->chunk_addr = chunk_addr;
- for(u = 0; u < layout->u.chunk.ndims; u++)
- ent->offset[u] = io_info->store->chunk.offset[u];
- H5_ASSIGN_OVERFLOW(ent->rd_count, chunk_size, size_t, uint32_t);
- H5_ASSIGN_OVERFLOW(ent->wr_count, chunk_size, size_t, uint32_t);
- ent->chunk = (uint8_t *)chunk;
-
- /* Add it to the cache */
- HDassert(NULL == rdcc->slot[idx]);
- rdcc->slot[idx] = ent;
- ent->idx = idx;
- rdcc->nbytes_used += chunk_size;
- rdcc->nused++;
-
- /* Add it to the linked list */
- ent->next = NULL;
- if(rdcc->tail) {
- rdcc->tail->next = ent;
- ent->prev = rdcc->tail;
- rdcc->tail = ent;
- } /* end if */
- else {
- rdcc->head = rdcc->tail = ent;
- ent->prev = NULL;
- } /* end else */
-
- /* Indicate that the chunk is in the cache now */
- found = TRUE;
- } else if(!found) {
- /*
- * The chunk is larger than the entire cache so we don't cache it.
- * This is the reason all those arguments have to be repeated for the
- * unlock function.
- */
- ent = NULL;
- idx = UINT_MAX;
- } else {
+ if(ent) {
/*
* The chunk is not at the beginning of the cache; move it backward
* by one slot. This is how we implement the LRU preemption
@@ -2900,8 +2820,68 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
ent->next = ent->next->next;
ent->prev->next = ent;
} /* end if */
+ } /* end if */
+ else if(rdcc->nslots > 0 && chunk_size <= rdcc->nbytes_max) {
+ /* Calculate the index */
+ udata->idx_hint = H5D_CHUNK_HASH(dset->shared, io_info->store->chunk.index);
+
+ /* Add the chunk to the cache only if the slot is not already locked */
+ ent = rdcc->slot[udata->idx_hint];
+ if(!ent || !ent->locked) {
+ /* Preempt enough things from the cache to make room */
+ if(ent) {
+ if(H5D_chunk_cache_evict(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, ent, TRUE) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk from cache")
+ } /* end if */
+ if(H5D_chunk_cache_prune(io_info->dset, io_info->dxpl_id, io_info->dxpl_cache, chunk_size) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to preempt chunk(s) from cache")
+
+ /* Create a new entry */
+ if(NULL == (ent = H5FL_MALLOC(H5D_rdcc_ent_t)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate raw data chunk entry")
+
+ ent->locked = 0;
+ ent->dirty = FALSE;
+ ent->deleted = FALSE;
+ ent->chunk_addr = chunk_addr;
+ for(u = 0; u < layout->u.chunk.ndims; u++)
+ ent->offset[u] = io_info->store->chunk.offset[u];
+ H5_ASSIGN_OVERFLOW(ent->rd_count, chunk_size, size_t, uint32_t);
+ H5_ASSIGN_OVERFLOW(ent->wr_count, chunk_size, size_t, uint32_t);
+ ent->chunk = (uint8_t *)chunk;
+
+ /* Add it to the cache */
+ HDassert(NULL == rdcc->slot[udata->idx_hint]);
+ rdcc->slot[udata->idx_hint] = ent;
+ ent->idx = udata->idx_hint;
+ rdcc->nbytes_used += chunk_size;
+ rdcc->nused++;
+
+ /* Add it to the linked list */
+ ent->next = NULL;
+ if(rdcc->tail) {
+ rdcc->tail->next = ent;
+ ent->prev = rdcc->tail;
+ rdcc->tail = ent;
+ } /* end if */
+ else {
+ rdcc->head = rdcc->tail = ent;
+ ent->prev = NULL;
+ } /* end else */
+ } /* end if */
+ else
+ /* We did not add the chunk to cache */
+ ent = NULL;
} /* end else */
+ if(!ent)
+ /*
+ * The chunk cannot be placed in cache so we don't cache it. This is the
+ * reason all those arguments have to be repeated for the unlock
+ * function.
+ */
+ udata->idx_hint = UINT_MAX;
+
/* Lock the chunk into the cache */
if(ent) {
HDassert(!ent->locked);
@@ -2909,9 +2889,6 @@ H5D_chunk_lock(const H5D_io_info_t *io_info, H5D_chunk_ud_t *udata,
chunk = ent->chunk;
} /* end if */
- if(idx_hint)
- *idx_hint = idx;
-
/* Set return value */
ret_value = chunk;
@@ -2953,7 +2930,7 @@ done:
*/
herr_t
H5D_chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
- hbool_t dirty, unsigned idx_hint, void *chunk, uint32_t naccessed)
+ hbool_t dirty, void *chunk, uint32_t naccessed)
{
const H5O_layout_t *layout = &(io_info->dset->shared->layout); /* Dataset layout */
const H5D_rdcc_t *rdcc = &(io_info->dset->shared->cache.chunk);
@@ -2964,7 +2941,7 @@ H5D_chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
HDassert(io_info);
HDassert(udata);
- if(UINT_MAX == idx_hint) {
+ if(UINT_MAX == udata->idx_hint) {
/*
* It's not in the cache, probably because it's too big. If it's
* dirty then flush it to disk. In any case, free the chunk.
@@ -2993,14 +2970,14 @@ H5D_chunk_unlock(const H5D_io_info_t *io_info, const H5D_chunk_ud_t *udata,
H5D_rdcc_ent_t *ent; /* Chunk's entry in the cache */
/* Sanity check */
- HDassert(idx_hint < rdcc->nslots);
- HDassert(rdcc->slot[idx_hint]);
- HDassert(rdcc->slot[idx_hint]->chunk == chunk);
+ HDassert(udata->idx_hint < rdcc->nslots);
+ HDassert(rdcc->slot[udata->idx_hint]);
+ HDassert(rdcc->slot[udata->idx_hint]->chunk == chunk);
/*
* It's in the cache so unlock it.
*/
- ent = rdcc->slot[idx_hint];
+ ent = rdcc->slot[udata->idx_hint];
HDassert(ent->locked);
if(dirty) {
ent->dirty = TRUE;
@@ -3308,9 +3285,21 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite,
#ifndef NDEBUG
/* None of the chunks should be allocated */
- if(H5D_chunk_get_info(dset, dxpl_id, chunk_offset, &udata) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
- HDassert(!H5F_addr_defined(udata.addr));
+ {
+ hsize_t chunk_idx;
+
+ /* Calculate the index of this chunk */
+ if(H5V_chunk_index((unsigned)space_ndims, chunk_offset,
+ layout->u.chunk.dim, layout->u.chunk.down_chunks,
+ &chunk_idx) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't get chunk index")
+
+ if(H5D_chunk_lookup(dset, dxpl_id, chunk_offset, chunk_idx,
+ &udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
+
+ HDassert(!H5F_addr_defined(udata.addr));
+ } /* end block */
/* Make sure the chunk is really in the dataset and outside the
* original dimensions */
@@ -3478,7 +3467,6 @@ H5D_chunk_prune_fill(H5D_chunk_it_ud1_t *udata)
hssize_t sel_nelmts; /* Number of elements in selection */
hsize_t count[H5O_LAYOUT_NDIMS]; /* Element count of hyperslab */
void *chunk; /* The file chunk */
- unsigned idx_hint; /* Which chunk we're dealing with */
H5D_chunk_ud_t chk_udata; /* User data for locking chunk */
uint32_t bytes_accessed; /* Bytes accessed in chunk */
unsigned u; /* Local index variable */
@@ -3487,14 +3475,13 @@ H5D_chunk_prune_fill(H5D_chunk_it_ud1_t *udata)
FUNC_ENTER_NOAPI_NOINIT(H5D_chunk_prune_fill)
/* Get the info for the chunk in the file */
- if(H5D_chunk_get_info(dset, io_info->dxpl_id, chunk_offset, &chk_udata) < 0)
+ if(H5D_chunk_lookup(dset, io_info->dxpl_id, chunk_offset,
+ io_info->store->chunk.index, &chk_udata) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
/* If this chunk does not exist in cache or on disk, no need to do anything
*/
- if(!H5F_addr_defined(chk_udata.addr)
- && !H5D_chunk_in_cache(dset, chunk_offset,
- io_info->store->chunk.index))
+ if(!H5F_addr_defined(chk_udata.addr) && UINT_MAX == chk_udata.idx_hint)
HGOTO_DONE(SUCCEED)
/* Initialize the fill value buffer, if necessary */
@@ -3524,8 +3511,7 @@ H5D_chunk_prune_fill(H5D_chunk_it_ud1_t *udata)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSELECT, FAIL, "unable to select hyperslab")
/* Lock the chunk into the cache, to get a pointer to the chunk buffer */
- if(NULL == (chunk = (void *)H5D_chunk_lock(io_info, &chk_udata, FALSE,
- &idx_hint)))
+ if(NULL == (chunk = (void *)H5D_chunk_lock(io_info, &chk_udata, FALSE)))
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to lock raw data chunk")
@@ -3566,7 +3552,7 @@ H5D_chunk_prune_fill(H5D_chunk_it_ud1_t *udata)
bytes_accessed = (uint32_t)sel_nelmts * layout->u.chunk.dim[rank];
/* Release lock on chunk */
- if(H5D_chunk_unlock(io_info, &chk_udata, TRUE, idx_hint, chunk, bytes_accessed) < 0)
+ if(H5D_chunk_unlock(io_info, &chk_udata, TRUE, chunk, bytes_accessed) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to unlock raw data chunk")
done:
@@ -3699,7 +3685,6 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
const H5O_layout_t *layout = &(dset->shared->layout); /* Dataset's layout */
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
H5D_rdcc_ent_t *ent = NULL; /* Cache entry */
- unsigned idx = 0; /* Hash index number */
int space_ndims; /* Dataset's space rank */
hsize_t space_dim[H5O_LAYOUT_NDIMS]; /* Current dataspace dimensions */
int op_dim; /* Current operationg dimension */
@@ -3713,7 +3698,6 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
hsize_t chunk_offset[H5O_LAYOUT_NDIMS]; /* Offset of current chunk */
hsize_t hyper_start[H5O_LAYOUT_NDIMS]; /* Starting location of hyperslab */
uint32_t elmts_per_chunk; /* Elements in chunk */
- hbool_t chk_on_disk; /* Whether a chunk exists on disk */
hbool_t carry; /* Flag to indicate that chunk increment carrys to higher dimension (sorta) */
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3892,8 +3876,6 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write fill value")
} /* end if */
else {
- chk_on_disk = FALSE;
-
#ifndef NDEBUG
/* Make sure this chunk is really outside the new dimensions */
{
@@ -3908,48 +3890,21 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim)
} /* end block */
#endif /* NDEBUG */
- /* Search for the chunk in the cache */
- if(rdcc->nslots > 0) {
- idx = H5D_CHUNK_HASH(dset->shared,
- chk_io_info.store->chunk.index);
- ent = rdcc->slot[idx];
-
- if(ent)
- for(i=0; i<space_ndims; i++)
- if(chunk_offset[i]
- != ent->offset[i]) {
- ent = NULL;
- break;
- } /* end if */
- } /* end if */
+ /* Check if the chunk exists in cache or on disk */
+ if(H5D_chunk_lookup(dset, dxpl_id, chunk_offset,
+ chk_io_info.store->chunk.index, &chk_udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk")
- /* Evict the entry from the cache, but do not flush it to disk
- */
- if(ent) {
- /* Determine if the chunk is allocated on disk, and
- * therefore needs to be removed from disk */
- chk_on_disk = H5F_addr_defined(ent->chunk_addr);
-
- /* Remove the chunk from cache */
- if(H5D_chunk_cache_evict(dset, dxpl_id, dxpl_cache, ent,
- FALSE) < 0)
+ /* Evict the entry from the cache if present, but do not flush
+ * it to disk */
+ if(UINT_MAX != chk_udata.idx_hint) {
+ if(H5D_chunk_cache_evict(dset, dxpl_id, dxpl_cache,
+ rdcc->slot[chk_udata.idx_hint], FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "unable to evict chunk")
-
- ent = NULL;
} /* end if */
- else {
- /* Determine if the chunk is allocated on disk, and
- * therefore needs to be removed from disk */
- /* Get the info for the chunk in the file */
- if(H5D_chunk_get_info(dset, dxpl_id, chunk_offset,
- &chk_udata) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "error looking up chunk address")
-
- chk_on_disk = H5F_addr_defined(chk_udata.addr);
- } /* end else */
/* Remove the chunk from disk, if present */
- if(chk_on_disk) {
+ if(H5F_addr_defined(chk_udata.addr)) {
/* Update the offset in idx_udata */
idx_udata.offset = chunk_offset;
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index fb0c1f4..ad9b737 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -861,7 +861,8 @@ H5D_link_chunk_collective_io(H5D_io_info_t *io_info, const H5D_type_info_t *type
HDmemset(coords, 0, sizeof(coords));
/* Look up address of chunk */
- if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, coords, &udata) < 0)
+ if(H5D_chunk_lookup(io_info->dset, io_info->dxpl_id, coords,
+ io_info->store->chunk.index, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
ctg_store.contig.dset_addr = udata.addr;
@@ -1212,7 +1213,6 @@ if(H5DEBUG(D))
H5D_chunk_ud_t udata; /* B-tree pass-through */
void *chunk; /* Pointer to the data chunk in cache */
uint32_t accessed_bytes; /* Total accessed size in a chunk */
- unsigned idx_hint = 0; /* Cache index hint */
htri_t cacheable; /* Whether the chunk is cacheable */
/* Switch to independent I/O */
@@ -1225,7 +1225,8 @@ if(H5DEBUG(D))
/* Load the chunk into cache. But if the whole chunk is written,
* simply allocate space instead of load the chunk.
*/
- if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ if(H5D_chunk_lookup(io_info->dset, io_info->dxpl_id,
+ chunk_info->coords, chunk_info->index, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
/* Load the chunk into cache and lock it. */
@@ -1244,7 +1245,7 @@ if(H5DEBUG(D))
entire_chunk = FALSE;
/* Lock the chunk into the cache */
- if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk, &idx_hint)))
+ if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@@ -1276,7 +1277,7 @@ if(H5DEBUG(D))
} /* end else */
/* Release the cache lock on the chunk. */
- if(chunk && H5D_chunk_unlock(io_info, &udata, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
+ if(chunk && H5D_chunk_unlock(io_info, &udata, (io_info->op_type == H5D_IO_OP_WRITE), chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
#else /* !defined(H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS) || !defined(H5_MPI_SPECIAL_COLLECTIVE_IO_WORKS) */
@@ -1441,7 +1442,8 @@ if(H5DEBUG(D)) {
#endif /* H5_MPI_COMPLEX_DERIVED_DATATYPE_WORKS */
/* Retrieve the chunk's address */
- if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ if(H5D_chunk_lookup(io_info->dset, io_info->dxpl_id, chunk_info->coords,
+ chunk_info->index, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
/* Independent I/O */
@@ -1449,7 +1451,6 @@ if(H5DEBUG(D)) {
void *chunk; /* Pointer to the data chunk in cache */
H5D_io_info_t *chk_io_info; /* Pointer to I/O info object for this chunk */
uint32_t accessed_bytes = 0; /* Total accessed size in a chunk */
- unsigned idx_hint = 0; /* Cache index hint */
htri_t cacheable; /* Whether the chunk is cacheable */
/* Switch to independent I/O */
@@ -1472,7 +1473,7 @@ if(H5DEBUG(D)) {
entire_chunk = FALSE;
/* Lock the chunk into the cache */
- if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk, &idx_hint)))
+ if(NULL == (chunk = H5D_chunk_lock(io_info, &udata, entire_chunk)))
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk")
/* Set up the storage buffer information for this chunk */
@@ -1505,7 +1506,7 @@ if(H5DEBUG(D)) {
/* Release the cache lock on the chunk. */
if(chunk)
- if(H5D_chunk_unlock(io_info, &udata, (io_info->op_type == H5D_IO_OP_WRITE), idx_hint, chunk, accessed_bytes) < 0)
+ if(H5D_chunk_unlock(io_info, &udata, (io_info->op_type == H5D_IO_OP_WRITE), chunk, accessed_bytes) < 0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to unlock raw data chunk")
} /* end if */
else { /*collective I/O */
@@ -1755,7 +1756,8 @@ if(H5DEBUG(D))
H5D_chunk_ud_t udata; /* User data for querying chunk info */
/* Get address of chunk */
- if(H5D_chunk_get_info(io_info->dset, io_info->dxpl_id, chunk_info->coords, &udata) < 0)
+ if(H5D_chunk_lookup(io_info->dset, io_info->dxpl_id,
+ chunk_info->coords, chunk_info->index, &udata) < 0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTGET, FAIL, "couldn't get chunk info from skipped list")
chunk_addr = udata.addr;
} /* end if */
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 0dc9a9f..34bf1da 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -260,6 +260,7 @@ typedef struct H5D_chunk_ud_t {
H5D_chunk_common_ud_t common; /* Common info for B-tree user data (must be first) */
/* Upward */
+ unsigned idx_hint; /*index of chunk in cache, if present */
uint32_t nbytes; /*size of stored data */
unsigned filter_mask; /*excluded filters */
haddr_t addr; /*file address of chunk */
@@ -601,12 +602,12 @@ H5_DLL herr_t H5D_chunk_set_info(const H5D_t *dset);
H5_DLL herr_t H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset,
hid_t dapl_id);
H5_DLL hbool_t H5D_chunk_is_space_alloc(const H5O_storage_t *storage);
-H5_DLL herr_t H5D_chunk_get_info(const H5D_t *dset, hid_t dxpl_id,
- const hsize_t *chunk_offset, H5D_chunk_ud_t *udata);
+H5_DLL herr_t H5D_chunk_lookup(const H5D_t *dset, hid_t dxpl_id,
+ const hsize_t *chunk_offset, hsize_t chunk_idx, H5D_chunk_ud_t *udata);
H5_DLL void *H5D_chunk_lock(const H5D_io_info_t *io_info,
- H5D_chunk_ud_t *udata, hbool_t relax, unsigned *idx_hint/*in,out*/);
+ H5D_chunk_ud_t *udata, hbool_t relax);
H5_DLL herr_t H5D_chunk_unlock(const H5D_io_info_t *io_info,
- const H5D_chunk_ud_t *udata, hbool_t dirty, unsigned idx_hint, void *chunk,
+ const H5D_chunk_ud_t *udata, hbool_t dirty, void *chunk,
uint32_t naccessed);
H5_DLL herr_t H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes);
H5_DLL herr_t H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id,