summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5Dvirtual.c137
-rw-r--r--src/H5Olayout.c1
-rw-r--r--src/H5Oprivate.h1
-rw-r--r--src/H5Pdcpl.c1
-rw-r--r--src/H5Shyper.c46
-rw-r--r--src/H5Sprivate.h3
6 files changed, 131 insertions, 58 deletions
diff --git a/src/H5Dvirtual.c b/src/H5Dvirtual.c
index 67f405f..40fe7ac 100644
--- a/src/H5Dvirtual.c
+++ b/src/H5Dvirtual.c
@@ -161,6 +161,7 @@ H5D__virtual_copy_layout(H5O_layout_t *layout)
layout->storage.u.virt.list[i].unlim_extent_virtual = orig_list[i].unlim_extent_virtual;
layout->storage.u.virt.list[i].clip_size_source = orig_list[i].clip_size_source;
layout->storage.u.virt.list[i].clip_size_virtual = orig_list[i].clip_size_virtual;
+ layout->storage.u.virt.list[i].clip_size_virtual_incl_trail = orig_list[i].clip_size_virtual_incl_trail;
layout->storage.u.virt.list[i].source_space_status = orig_list[i].source_space_status;
layout->storage.u.virt.list[i].virtual_space_status = orig_list[i].virtual_space_status;
} /* end for */
@@ -332,8 +333,10 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
{
H5O_storage_virtual_t *storage;
hsize_t new_dims[H5S_MAX_RANK];
+ hsize_t max_dims[H5S_MAX_RANK];
hsize_t curr_dims[H5S_MAX_RANK];
hsize_t clip_size;
+ hsize_t clip_size_incl_trail;
int rank;
hbool_t changed = FALSE; /* Whether the VDS extent changed */
size_t i;
@@ -350,9 +353,11 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
if((rank = H5S_GET_EXTENT_NDIMS(dset->shared->space)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions")
- /* Initialize new_dims to HSIZE_UNDEF */
- for(i = 0; i < (size_t)rank; i++)
+ /* Initialize new_dims and max_dims to HSIZE_UNDEF */
+ for(i = 0; i < (size_t)rank; i++) {
new_dims[i] = HSIZE_UNDEF;
+ max_dims[i] = HSIZE_UNDEF;
+ } /* end for */
/* Iterate over mappings */
for(i = 0; i < storage->list_nalloc; i++)
@@ -376,40 +381,78 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
if(H5S_get_simple_extent_dims(storage->list[i].source_select, curr_dims, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get source space dimensions")
- /* Check if the source extent in the unlimited dimension
- * changed since the last time the VDS extent/mapping
- * was updated */
- if(curr_dims[storage->list[i].unlim_dim_source]
- == storage->list[i].unlim_extent_source)
- /* Use cached result for clip size */
- clip_size = storage->list[i].clip_size_virtual;
- else {
- /* Get size that virtual selection would be clipped
- * to to match size of source selection */
- if(H5S_hyper_get_clip_extent(storage->list[i].virtual_select, storage->list[i].source_select, &clip_size) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size")
-
- /* If we are setting the extent by the maximum of all
- * mappings, clip virtual_select. Note that if we used the
- * cached clip_size above, the selection will already be
- * clipped to the correct size. */
- if(storage->set_extent_max)
+ /* Check if we are setting extent by maximum or minimum of
+ * mappings */
+ if(storage->set_extent_max) {
+ /* Check if the source extent in the unlimited dimension
+ * changed since the last time the VDS extent/mapping
+ * was updated */
+ if(curr_dims[storage->list[i].unlim_dim_source]
+ == storage->list[i].unlim_extent_source)
+ /* Use cached result for clip size */
+ clip_size = storage->list[i].clip_size_virtual;
+ else {
+ /* Get size that virtual selection would be clipped to
+ * to match size of source selection */
+ if(H5S_hyper_get_clip_extent(storage->list[i].virtual_select, storage->list[i].source_select, &clip_size, NULL) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size")
+
+ /* Clip virtual_select. Note that if we used the cached
+ * clip_size above, the selection will already be
+ * clipped to the correct size. */
if(H5S_hyper_clip_unlim(storage->list[i].virtual_select, clip_size))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
- /* Update cached values unlim_extent_source and
- * clip_size_virtual */
- storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source];
- storage->list[i].clip_size_virtual = clip_size;
- } /* end else */
+ /* Update cached values unlim_extent_source and
+ * clip_size_virtual */
+ storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source];
+ storage->list[i].clip_size_virtual = clip_size;
+ } /* end else */
- /* Update new_dims */
- if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF)
- || (storage->set_extent_max ? (clip_size
- > (hsize_t)new_dims[storage->list[i].unlim_dim_virtual])
- : (clip_size
- < (hsize_t)new_dims[storage->list[i].unlim_dim_virtual])))
- new_dims[storage->list[i].unlim_dim_virtual] = clip_size;
+ /* Update new_dims */
+ if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF)
+ || (clip_size
+ > (hsize_t)new_dims[storage->list[i].unlim_dim_virtual]))
+ new_dims[storage->list[i].unlim_dim_virtual] = clip_size;
+ } /* end if */
+ else {
+ /* Check if the source extent in the unlimited dimension
+ * changed since the last time the VDS extent/mapping was
+ * updated */
+ if(curr_dims[storage->list[i].unlim_dim_source]
+ == storage->list[i].unlim_extent_source) {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ /* Use cached result for clip size */
+ clip_size = storage->list[i].clip_size_virtual;
+ clip_size_incl_trail = storage->list[i].clip_size_virtual_incl_trail;
+ } //VDSINC
+ else {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ /* Get size that virtual selection would be clipped to
+ * to match size of source selection. Also get the clip
+ * size including the trailing space (gap between
+ * blocks). */
+ if(H5S_hyper_get_clip_extent(storage->list[i].virtual_select, storage->list[i].source_select, &clip_size, &clip_size_incl_trail) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size")
+
+ /* Update cached values unlim_extent_source,
+ * clip_size_virtual, and clip_size_virtual_incl_trail
+ */
+ storage->list[i].unlim_extent_source = curr_dims[storage->list[i].unlim_dim_source];
+ storage->list[i].clip_size_virtual = clip_size;
+ storage->list[i].clip_size_virtual_incl_trail = clip_size_incl_trail;
+ } /* end else */
+
+ /* Update new_dims and max_dims */
+ if((new_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF)
+ || (clip_size_incl_trail
+ < (hsize_t)new_dims[storage->list[i].unlim_dim_virtual]))
+ new_dims[storage->list[i].unlim_dim_virtual] = clip_size_incl_trail;
+ if((max_dims[storage->list[i].unlim_dim_virtual] == HSIZE_UNDEF)
+ || (clip_size
+ > (hsize_t)max_dims[storage->list[i].unlim_dim_virtual]))
+ max_dims[storage->list[i].unlim_dim_virtual] = clip_size;
+ } /* end else */
} /* end if */
} /* end if */
@@ -417,17 +460,21 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
if(H5S_get_simple_extent_dims(dset->shared->space, curr_dims, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get VDS dimensions")
- /* Calculate new extent */
+ /* Calculate new extent. Apply max_dims first, so min_dims takes precedent.
+ */
for(i = 0; i < (size_t)rank; i++) {
- if((new_dims[i] != HSIZE_UNDEF) && (new_dims[i] != curr_dims[i])) {
- changed = TRUE;
- curr_dims[i] = new_dims[i];
- } /* end if */
- if(storage->min_dims[i] > curr_dims[i]) {
+ if(new_dims[i] == HSIZE_UNDEF)
+ new_dims[i] = curr_dims[i];
+ if((max_dims[i] != HSIZE_UNDEF) && (new_dims[i] > max_dims[i])) {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ new_dims[i] = max_dims[i];
+ } //VDSINC
+ if(new_dims[i] < storage->min_dims[i]) {
HDassert(0 && "Checking code coverage..."); //VDSINC
+ new_dims[i] = storage->min_dims[i];
+ } //VDSINC
+ if(new_dims[i] != curr_dims[i])
changed = TRUE;
- curr_dims[i] = storage->min_dims[i];
- } /* end if */
} /* end for */
/* If we did not change the VDS dimensions and we are setting the extent by
@@ -435,7 +482,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
if(changed || !storage->set_extent_max) {
/* Update VDS extent */
if(changed)
- if(H5S_set_extent(dset->shared->space, curr_dims) < 0)
+ if(H5S_set_extent(dset->shared->space, new_dims) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
/* Iterate over mappings again to update source selections and virtual
@@ -449,7 +496,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
/* Update virtual mapping extent. Note this function does not
* clip the selection. */
if(changed)
- if(H5S_set_extent(storage->list[i].virtual_select, curr_dims) < 0)
+ if(H5S_set_extent(storage->list[i].virtual_select, new_dims) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to modify size of data space")
/* Check if we are setting extent by the minimum of mappings */
@@ -466,7 +513,7 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
/* Check if the virtual extent in the unlimited dimension
* changed since the last time the VDS extent/mapping was
* updated */
- if(curr_dims[storage->list[i].unlim_dim_virtual]
+ if(new_dims[storage->list[i].unlim_dim_virtual]
== storage->list[i].unlim_extent_virtual) {
HDassert(0 && "Checking code coverage..."); //VDSINC
/* Use cached result for clip size */
@@ -476,12 +523,12 @@ H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id)
HDassert(0 && "Checking code coverage..."); //VDSINC
/* Get size that source selection will be clipped to to
* match size of virtual selection */
- if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].virtual_select, &clip_size) < 0)
+ if(H5S_hyper_get_clip_extent(storage->list[i].source_select, storage->list[i].virtual_select, &clip_size, NULL) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get hyperslab clip size")
/* Update cached values unlim_extent_virtual and
* clip_size_source */
- storage->list[i].unlim_extent_virtual = curr_dims[storage->list[i].unlim_dim_virtual];
+ storage->list[i].unlim_extent_virtual = new_dims[storage->list[i].unlim_dim_virtual];
storage->list[i].clip_size_source = clip_size;
} /* end else */
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index fb9bb9c..cf5b3d2 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -309,6 +309,7 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
mesg->storage.u.virt.list[i].unlim_extent_virtual = HSIZE_UNDEF;
mesg->storage.u.virt.list[i].clip_size_source = HSIZE_UNDEF;
mesg->storage.u.virt.list[i].clip_size_virtual = HSIZE_UNDEF;
+ mesg->storage.u.virt.list[i].clip_size_virtual_incl_trail = HSIZE_UNDEF;
/* Update min_dims */
if(H5D_virtual_update_min_dims(mesg, i) < 0)
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 74cc9a4..0211093 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -433,6 +433,7 @@ typedef struct H5O_storage_virtual_ent_t {
hsize_t unlim_extent_source; /* Extent of unlimited dimension in source dset last time virtual_select was patched to match selection */
hsize_t unlim_extent_virtual; /* Extent of unlimited dimension in virtual dset last time source_select was patched to match selection */
hsize_t clip_size_virtual; /* Size selection would be clipped to in virtual selection, ignoring other mappings, when source extent == unlim_extent_source */
+ hsize_t clip_size_virtual_incl_trail; /* Like above, but includes gap after last block */
hsize_t clip_size_source; /* Size selection would be clipped to in source selection when virtual extent == unlim_extent_virtual */
H5O_virtual_space_status_t source_space_status; /* Extent patching status of source_select */
H5O_virtual_space_status_t virtual_space_status; /* Extent patching status of virtual_select */
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index 575de9c..8f400cf 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -1676,6 +1676,7 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name,
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_extent_virtual = HSIZE_UNDEF;
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_source = HSIZE_UNDEF;
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_virtual = HSIZE_UNDEF;
+ layout.storage.u.virt.list[layout.storage.u.virt.list_nused].clip_size_virtual_incl_trail = HSIZE_UNDEF;
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].source_space_status = H5O_VIRTUAL_STATUS_USER;
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_space_status = H5O_VIRTUAL_STATUS_USER;
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 81306c9..6bff292 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -9741,8 +9741,8 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_get_clip_extent(const H5S_t *clip_space,
- const H5S_t *match_space, hsize_t *clip_space_unlim_extent)
+H5S_hyper_get_clip_extent(const H5S_t *clip_space, const H5S_t *match_space,
+ hsize_t *clip_size, hsize_t *clip_size_incl_trail)
{
const H5S_hyper_sel_t *clip_hslab; /* Convenience pointer to hyperslab info */
const H5S_hyper_sel_t *match_hslab; /* Convenience pointer to hyperslab info */
@@ -9759,7 +9759,7 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space,
HDassert(match_space);
match_hslab = match_space->select.sel_info.hslab;
HDassert(match_space);
- HDassert(clip_space_unlim_extent);
+ HDassert(clip_size);
HDassert(clip_hslab->unlim_dim >= 0);
HDassert(match_hslab->unlim_dim >= 0);
HDassert(clip_hslab->num_elem_non_unlim == match_hslab->num_elem_non_unlim);
@@ -9767,17 +9767,25 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space,
/* Calculate number of slices */
num_slices = match_space->select.num_elem / match_hslab->num_elem_non_unlim;
- if(num_slices == 0)
- *clip_space_unlim_extent = 0;
+ if(num_slices == 0) {
+ *clip_size = 0;
+ if(clip_size_incl_trail) {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ *clip_size_incl_trail = clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start;
+ } //VDSINC
+ } /* end if */
else if(clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block == H5S_UNLIMITED) {
- HDassert(0 && "Checking code coverage..."); //VDSINC
/* Unlimited block, just set the extent large enough for the block size
* to match num_slices */
HDassert(clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].count == (hsize_t)1);
- *clip_space_unlim_extent =
+ *clip_size =
clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start
+ num_slices;
+ if(clip_size_incl_trail) {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ *clip_size_incl_trail = *clip_size;
+ } //VDSINC
} /* end if */
else {
/* Unlimited count, need to match extent so a block (possibly) gets cut
@@ -9793,20 +9801,34 @@ H5S_hyper_get_clip_extent(const H5S_t *clip_space,
if(rem_slices > 0) {
HDassert(0 && "Checking code coverage..."); //VDSINC
- /* Must end extent in middle of partial block */
- *clip_space_unlim_extent =
+ /* Must end extent in middle of partial block (or beginning of empty
+ * block if include_trailing_space and rem_slices == 0) */
+ *clip_size =
clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start
+ (count
* clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride)
+ rem_slices;
- } //VDSINC
- else
+ if(clip_size_incl_trail) {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ *clip_size_incl_trail = *clip_size;
+ } //VDSINC
+ } /* end if */
+ else {
/* End extent at end of last block */
- *clip_space_unlim_extent =
+ *clip_size =
clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start
+ ((count - (hsize_t)1)
* clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride)
+ clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block;
+ if(clip_size_incl_trail) {
+ HDassert(0 && "Checking code coverage..."); //VDSINC
+ /* Include gap after last block */
+ *clip_size_incl_trail =
+ clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start
+ + (count
+ * clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].stride);
+ } //VDSINC
+ } /* end else */
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index ebfa88e..2900839 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -269,7 +269,8 @@ H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_off
H5_DLL herr_t H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size);
H5_DLL herr_t H5S_hyper_clip_to_extent(H5S_t *space);
H5_DLL herr_t H5S_hyper_get_clip_extent(const H5S_t *clip_space,
- const H5S_t *match_space, hsize_t *clip_space_unlim_extent);
+ const H5S_t *match_space, hsize_t *clip_size,
+ hsize_t *clip_size_incl_trail);
/* Operations on selection iterators */
H5_DLL herr_t H5S_select_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size);