[svn-r26962] Add support for unlimited selections to VDS code.

Not tested (except for percival-unlim example)
Fix percival-unlim example
Other bug fixes/cleanup

Tested: Fedora 64
This commit is contained in:
Neil Fortner 2015-04-28 22:22:55 -05:00
parent f3f7473161
commit a9b2e36065
16 changed files with 696 additions and 54 deletions

View File

@ -13,7 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
#define FILE "vds-percival-unlim.h5"
#define VFILE "vds-percival-unlim.h5"
#define DATASET "VDS-Percival-unlim"
#define VDSDIM0 H5S_UNLIMITED
#define VDSDIM1 10
@ -100,7 +100,7 @@ main (void)
status = H5Fclose (file);
}
file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
vfile = H5Fcreate (VFILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/* Create VDS dataspace. */
vspace = H5Screate_simple (RANK, vdsdims, vdsdims_max);
@ -147,6 +147,7 @@ main (void)
dcpl, H5P_DEFAULT);
status = H5Sclose (vspace);
status = H5Sclose (src_space);
status = H5Pclose (dcpl);
/* Let's get space of the VDS and its dimension; we should get 40x10x10 */
vspace = H5Dget_space (vdset);
H5Sget_simple_extent_dims (vspace, vdsdims_out, vdsdims_max_out);
@ -188,13 +189,12 @@ main (void)
status = H5Dwrite (dset, H5T_NATIVE_INT, mem_space, src_space, H5P_DEFAULT,
wdata);
status = H5Sclose (src_space);
status = H5Pclose (dcpl);
status = H5Dclose (dset);
status = H5Fclose (file);
}
/* Let's get space of the VDS and its dimension; we should get 80x10x10 */
vspace = H5Dget_space (dset);
vspace = H5Dget_space (vdset);
H5Sget_simple_extent_dims (vspace, vdsdims_out, vdsdims_max_out);
printf ("VDS dimensions second time \n");
printf (" Current: ");
@ -212,7 +212,7 @@ main (void)
/*
* Open file and dataset using the default properties.
*/
vfile = H5Fopen (FILE, H5F_ACC_RDONLY, H5P_DEFAULT);
vfile = H5Fopen (VFILE, H5F_ACC_RDONLY, H5P_DEFAULT);
vdset = H5Dopen (vfile, DATASET, H5P_DEFAULT);
/*

View File

@ -2346,6 +2346,8 @@ H5D__set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty")
} /* end if */
/* Make this function work with virtual layout VDSINC */
done:
FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
} /* end H5D__set_extent() */
@ -2767,6 +2769,11 @@ H5D_get_space(H5D_t *dset)
FUNC_ENTER_NOAPI_NOINIT
/* If the layout is virtual, update the extent */
if(dset->shared->layout.type == H5D_VIRTUAL)
if(H5D__virtual_set_extent_unlim(dset, H5AC_ind_dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update virtual dataset extent")
/* Read the data space message and return a data space object */
if(NULL == (space = H5S_copy(dset->shared->space, FALSE, TRUE)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get data space")

View File

@ -611,7 +611,6 @@ H5_DLL herr_t H5D__contig_copy(H5F_t *f_src, const H5O_storage_contig_t *storage
H5_DLL herr_t H5D__contig_delete(H5F_t *f, hid_t dxpl_id,
const H5O_storage_t *store);
/* Functions that operate on chunked dataset storage */
H5_DLL htri_t H5D__chunk_cacheable(const H5D_io_info_t *io_info, haddr_t caddr,
hbool_t write_op);
@ -660,6 +659,7 @@ H5_DLL herr_t H5D__compact_copy(H5F_t *f_src, H5O_storage_compact_t *storage_src
/* Functions that operate on virtual dataset storage */
H5_DLL herr_t H5D__virtual_copy_layout(H5O_layout_t *layout);
H5_DLL herr_t H5D__virtual_set_extent_unlim(const H5D_t *dset, hid_t dxpl_id);
H5_DLL herr_t H5D__virtual_reset_layout(H5O_layout_t *layout);
H5_DLL herr_t H5D__virtual_delete(H5F_t *f, hid_t dxpl_id, H5O_storage_t *storage);
H5_DLL herr_t H5D__virtual_copy(H5F_t *f_src,

View File

@ -177,6 +177,9 @@ H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id,
/* Functions that operate on chunked storage */
H5_DLL herr_t H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr);
/* Functions that operate on virtual storage */
H5_DLL herr_t H5D_virtual_update_min_dims(H5O_layout_t *layout, size_t idx);
/* Functions that operate on indexed storage */
H5_DLL herr_t H5D_btree_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream,
int indent, int fwidth, unsigned ndims);

View File

@ -155,6 +155,12 @@ H5D__virtual_copy_layout(H5O_layout_t *layout)
= H5S_copy(orig_list[i].virtual_select, FALSE, TRUE)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to copy virtual selection")
layout->storage.u.virt.list[i].source_dset = NULL;
layout->storage.u.virt.list[i].unlim_dim_source = orig_list[i].unlim_dim_source;
layout->storage.u.virt.list[i].unlim_dim_virtual = orig_list[i].unlim_dim_virtual;
layout->storage.u.virt.list[i].unlim_extent_source = orig_list[i].unlim_extent_source;
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].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 */
@ -176,15 +182,73 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__virtual_copy_layout() */
/*-------------------------------------------------------------------------
* Function: H5D_virtual_update_min_dims
*
* Purpose: Updates the virtual layout's "min_dims" field to take into
* account the "idx"th entry in the mapping list. The entry
* must be complete, though top level fields list_nused does
* (and of course min_dims) do not need to take it into
* account.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Neil Fortner
* February 10, 2015
*
*-------------------------------------------------------------------------
*/
herr_t
H5D_virtual_update_min_dims(H5O_layout_t *layout, size_t idx)
{
H5S_sel_type sel_type;
int rank;
hsize_t bounds_start[H5S_MAX_RANK];
hsize_t bounds_end[H5S_MAX_RANK];
int i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
HDassert(layout);
HDassert(layout->type == H5D_VIRTUAL);
HDassert(idx < layout->storage.u.virt.list_nalloc);
/* Get type of selection */
if(H5S_SEL_ERROR == (sel_type = H5S_GET_SELECT_TYPE(layout->storage.u.virt.list[idx].virtual_select)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection type")
/* Do not update min_dims for "all" or "none" selections */
if((sel_type == H5S_SEL_ALL) || (sel_type == H5S_SEL_NONE))
HGOTO_DONE(SUCCEED)
/* Get rank of vspace */
if((rank = H5S_GET_EXTENT_NDIMS(layout->storage.u.virt.list[idx].virtual_select)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get number of dimensions")
/* Get selection bounds */
if(H5S_SELECT_BOUNDS(layout->storage.u.virt.list[idx].virtual_select, bounds_start, bounds_end) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get selection bounds")
/* Update min_dims */
for(i = 0; i < rank; i++)
/* Don't check unlimited dimensions in the selection */
if((i != layout->storage.u.virt.list[idx].unlim_dim_virtual)
&& (bounds_end[i] > layout->storage.u.virt.min_dims[i]))
layout->storage.u.virt.min_dims[i] = bounds_end[i];
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_virtual_update_min_dims() */
/*-------------------------------------------------------------------------
* Function: H5D__virtual_open_source_dset
*
* Purpose: Attempts to open a source dataset.
*
* Return: TRUE: Source dataset opened
* FALSE: Source dataset not opened
* Negative: Error
* Return: Non-negative on success/Negative on failure
*
* Programmer: Neil Fortner
* March 6, 2015
@ -234,7 +298,7 @@ H5D__virtual_open_source_dset(const H5D_t *vdset,
/* Patch the source selection if necessary */
if(virtual_ent->source_space_status != H5O_VIRTUAL_STATUS_CORRECT) {
if(H5S_extent_copy(virtual_ent->source_select, virtual_ent->source_dset->shared->space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy virtual dataspace extent")
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent")
virtual_ent->source_space_status = H5O_VIRTUAL_STATUS_CORRECT;
} /* end if */
@ -247,6 +311,193 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__virtual_open_source_dset() */
/*-------------------------------------------------------------------------
* Function: H5D__virtual_set_extent_unlim
*
* Purpose: Sets the extent of the virtual dataset by checking the
* extents of source datasets where an unlimited selection
* matching. Dimensions that are not unlimited in any
* virtual mapping selections are not affected.
*
* Return: Non-negative on success/Negative on failure
*
* Programmer: Neil Fortner
* April 22, 2015
*
*-------------------------------------------------------------------------
*/
herr_t
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 curr_dims[H5S_MAX_RANK];
hsize_t clip_size;
int rank;
hbool_t changed = FALSE; /* Whether the VDS extent changed */
size_t i;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_PACKAGE
/* Sanity check */
HDassert(dset);
storage = &dset->shared->layout.storage.u.virt;
HDassert(dset->shared->layout.storage.type == H5D_VIRTUAL);
/* Get rank of VDS */
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++)
new_dims[i] = HSIZE_UNDEF;
/* Iterate over mappings */
for(i = 0; i < storage->list_nalloc; i++)
/* Check for unlimited dimension */
if(storage->list[i].unlim_dim_virtual >= 0) {
HDassert(storage->list[i].unlim_dim_source >= 0);
/* Open source dataset */
if(!storage->list[i].source_dset)
if(H5D__virtual_open_source_dset(dset, &storage->list[i], dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open source dataset")
/* Check if source dataset is open */
if(storage->list[i].source_dset) {
/* Retrieve current source dataset extent and patch mapping.
* Note this will clip the source selection to the extent. */
if(H5S_extent_copy(storage->list[i].source_select, storage->list[i].source_dset->shared->space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy source dataspace extent")
/* Get source space dimenstions */
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)
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 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;
} /* end if */
} /* end if */
/* Get current VDS dimensions */
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 */
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]) {
HDassert(0 && "Checking code coverage..."); //VDSINC
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
* maximum, there is nothing more to update */
if(changed || !storage->set_extent_max) {
/* Update VDS extent */
if(changed)
if(H5S_set_extent(dset->shared->space, curr_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
* mapping extents */
for(i = 0; i < storage->list_nalloc; i++)
/* Check for unlimited dimension */
if((storage->list[i].unlim_dim_source >= 0)
&& (storage->list[i].source_dset)) {
HDassert(storage->list[i].unlim_dim_virtual >= 0);
/* 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)
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 */
if(!storage->set_extent_max) {
/* Clip virtual selection to extent (only necessary if the
* extent changed, otherwise it will already be clipped to
* the extent) */
if(changed) {
HDassert(0 && "Checking code coverage..."); //VDSINC
if(H5S_hyper_clip_to_extent(storage->list[i].virtual_select))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
} //VDSINC
/* 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]
== storage->list[i].unlim_extent_virtual) {
HDassert(0 && "Checking code coverage..."); //VDSINC
/* Use cached result for clip size */
clip_size = storage->list[i].clip_size_source;
} //VDSINC
else {
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)
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].clip_size_source = clip_size;
} /* end else */
/* Clip source_select */
if(H5S_hyper_clip_unlim(storage->list[i].source_select, clip_size))
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
} /* end if */
} /* end if */
} /* end if */
/* Call H5D__mark so dataspace is updated on disk? VDSINC */
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D__virtual_set_extent_unlim() */
/*-------------------------------------------------------------------------
* Function: H5D__virtual_reset_layout
@ -462,6 +713,11 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
storage = &io_info->dset->shared->layout.storage.u.virt;
/* Update VDS extent due to unlimited selections */
/* Don't call if there is no unlimited selection? VDSINC */
if(H5D__virtual_set_extent_unlim(io_info->dset, io_info->dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update virtual dataset extent")
/* Iterate over mappings */
for(i = 0; i < storage->list_nused; i++) {
/* Sanity check that the virtual space has been patched by now */
@ -515,7 +771,7 @@ H5D__virtual_read(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
} /* end for */
/* Fill unmapped part of buffer with fill value. Keep track of total number
* elements written to memory buffer and assert that it == nelmts */
* elements written to memory buffer and assert that it == nelmts VDSINC */
done:
/* Release allocated resources on failure */
@ -569,6 +825,11 @@ H5D__virtual_write(H5D_io_info_t *io_info, const H5D_type_info_t *type_info,
storage = &io_info->dset->shared->layout.storage.u.virt;
/* Update VDS extent due to unlimited selections */
/* Don't call if there is no unlimited selection? VDSINC */
if(H5D__virtual_set_extent_unlim(io_info->dset, io_info->dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update virtual dataset extent")
/* Iterate over mappings */
for(i = 0; i < storage->list_nused; i++) {
/* Sanity check that virtual space has been patched by now */

View File

@ -191,7 +191,7 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
} /* end if */
else {
/* Layout class */
mesg->type = (H5D_layout_t)*p++;
mesg->type = mesg->storage.type = (H5D_layout_t)*p++;
/* Interpret the rest of the message according to the layout class */
switch(mesg->type) {
@ -251,6 +251,7 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
mesg->storage.u.virt.list_nused = 0;
mesg->storage.u.virt.list = NULL;
mesg->storage.u.virt.list_nalloc = 0;
mesg->storage.u.virt.set_extent_max = TRUE;
/* Decode heap block if it exists */
if(mesg->storage.u.virt.serial_list_hobjid.addr != HADDR_UNDEF) {
@ -300,6 +301,18 @@ H5O_layout_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
/* Virtual selection */
if(H5S_SELECT_DESERIALIZE(f, &(mesg->storage.u.virt.list[i].virtual_select), &heap_block_p) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "can't decode virtual space selection")
/* unlim_dim fields */
mesg->storage.u.virt.list[i].unlim_dim_source = H5S_get_select_unlim_dim(mesg->storage.u.virt.list[i].source_select);
mesg->storage.u.virt.list[i].unlim_dim_virtual = H5S_get_select_unlim_dim(mesg->storage.u.virt.list[i].virtual_select);
mesg->storage.u.virt.list[i].unlim_extent_source = HSIZE_UNDEF;
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;
/* Update min_dims */
if(H5D_virtual_update_min_dims(mesg, i) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to update virtual dataset minimum dimensions")
} /* end for */
/* Read stored checksum */

View File

@ -428,6 +428,12 @@ typedef struct H5O_storage_virtual_ent_t {
/* Not stored */
struct H5D_t *source_dset; /* Source dataset */
int unlim_dim_source; /* Unlimited dimension in source_select */
int unlim_dim_virtual; /* Unlimited dimension in virtual_select */
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_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 */
} H5O_storage_virtual_ent_t;
@ -442,6 +448,8 @@ typedef struct H5O_storage_virtual_t {
/* Not stored */
size_t list_nalloc; /* Number of slots allocated */
hsize_t min_dims[H5S_MAX_RANK]; /* Minimum extent of VDS (maximum of all non-unlimited selection bounds) */
hbool_t set_extent_max; /* Whether we set the extent by the maximum (TRUE) or minimum (FALSE) of unlimited selections */
} H5O_storage_virtual_t;
typedef struct H5O_storage_t {

View File

@ -43,6 +43,7 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Oprivate.h" /* Object headers */
#include "H5Ppkg.h" /* Property lists */
#include "H5Sprivate.h" /* Dataspaces */
#include "H5Tprivate.h" /* Datatypes */
#include "H5Zpkg.h" /* Data filters */
@ -56,12 +57,12 @@
#define H5D_DEF_STORAGE_CONTIG_INIT {HADDR_UNDEF, (hsize_t)0}
#define H5D_DEF_STORAGE_CHUNK_INIT {H5D_CHUNK_IDX_BTREE, HADDR_UNDEF, NULL, {{HADDR_UNDEF, NULL}}}
#define H5D_DEF_LAYOUT_CHUNK_INIT {(unsigned)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, (uint32_t)0, (hsize_t)0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}
#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0}
#define H5D_DEF_STORAGE_VIRTUAL_INIT {{HADDR_UNDEF, 0}, 0, NULL, 0, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, TRUE}
#ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER
#define H5D_DEF_STORAGE_COMPACT {H5D_COMPACT, { .compact = H5D_DEF_STORAGE_COMPACT_INIT }}
#define H5D_DEF_STORAGE_CONTIG {H5D_CONTIGUOUS, { .contig = H5D_DEF_STORAGE_CONTIG_INIT }}
#define H5D_DEF_STORAGE_CHUNK {H5D_CHUNKED, { .chunk = H5D_DEF_STORAGE_CHUNK_INIT }}
#define H5D_DEF_STORAGE_VIRTUAL {H5D_CHUNKED, { .virt = H5D_DEF_STORAGE_VIRTUAL_INIT }}
#define H5D_DEF_STORAGE_VIRTUAL {H5D_VIRTUAL, { .virt = H5D_DEF_STORAGE_VIRTUAL_INIT }}
#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_COMPACT}
#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CONTIG}
#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, H5D_DEF_STORAGE_CHUNK}
@ -75,7 +76,7 @@
#define H5D_DEF_LAYOUT_COMPACT {H5D_COMPACT, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_CONTIG {H5D_CONTIGUOUS, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_CHUNK {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_VIRTUAL {H5D_CHUNKED, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#define H5D_DEF_LAYOUT_VIRTUAL {H5D_VIRTUAL, H5O_LAYOUT_VERSION_3, NULL, {H5D_DEF_LAYOUT_CHUNK_INIT}, {H5D_CONTIGUOUS, H5D_DEF_STORAGE_CONTIG_INIT}}
#endif /* H5_HAVE_C99_DESIGNATED_INITIALIZER */
/* ======== Dataset creation properties ======== */
@ -1669,8 +1670,20 @@ H5Pset_virtual(hid_t dcpl_id, hid_t vspace_id, const char *src_file_name,
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection")
if(NULL == (layout.storage.u.virt.list[layout.storage.u.virt.list_nused].virtual_select = H5S_copy(vspace, FALSE, TRUE)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection")
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_dim_source = H5S_get_select_unlim_dim(src_space);
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_dim_virtual = H5S_get_select_unlim_dim(vspace);
layout.storage.u.virt.list[layout.storage.u.virt.list_nused].unlim_extent_source = HSIZE_UNDEF;
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].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;
/* Update min_dims */
if(H5D_virtual_update_min_dims(&layout, layout.storage.u.virt.list_nused) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to update virtual dataset minimum dimensions")
/* Finish adding entry */
layout.storage.u.virt.list_nused++;
adding_entry = FALSE;
@ -1786,6 +1799,11 @@ H5Pget_virtual_vspace(hid_t dcpl_id, size_t index)
if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].virtual_select, FALSE, TRUE)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy virtual selection")
/* Clip selection to extent */
if(H5S_get_select_unlim_dim(space) >= 0)
if(H5S_hyper_clip_to_extent(space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
/* Register ID */
if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space")
@ -1844,6 +1862,11 @@ H5Pget_virtual_srcspace(hid_t dcpl_id, size_t index)
if(NULL == (space = H5S_copy(layout.storage.u.virt.list[index].source_select, FALSE, TRUE)))
HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy source selection")
/* Clip selection to extent */
if(H5S_get_select_unlim_dim(space) >= 0)
if(H5S_hyper_clip_to_extent(space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
/* Register ID */
if((ret_value = H5I_register(H5I_DATASPACE, space, TRUE)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data space")

View File

@ -522,7 +522,7 @@ H5S_extent_copy(H5S_t *dst, const H5S_t *src)
/* If the selection is 'hyper', update the selection due to changed extent
*/
if(H5S_GET_SELECT_TYPE(dst) == H5S_SEL_HYPERSLABS)
if(H5S__hyper_update_extent_offset(dst) < 0)
if(H5S_hyper_clip_to_extent(dst) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")
done:
@ -1363,7 +1363,7 @@ H5S__set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims,
/* If the selection is 'hyper', update the selection due to changed
* extent */
if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS)
if(H5S__hyper_update_extent_offset(space) < 0)
if(H5S_hyper_clip_to_extent(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")
done:
@ -1883,7 +1883,14 @@ done:
/*-------------------------------------------------------------------------
* Function: H5S_set_extent
*
* Purpose: Modify the dimensions of a dataspace. Based on H5S_extend
* Purpose: Modify the dimensions of a dataspace. Based on H5S_extend.
*
* Note that this function does *not* clip unlimited
* selections, because it is not currently necessary to do
* that anywhere this function is called. If this becomes
* necessary (if the selection could be unlimited and the
* clip size is not being handled separately), this function
* must be updated to (optionally) clip the selection.
*
* Return: Success: Non-negative
* Failure: Negative
@ -1966,6 +1973,13 @@ H5S_has_extent(const H5S_t *ds)
*
* Purpose: Modify the dimensions of a dataspace. Based on H5S_extend
*
* Note that this function does *not* clip unlimited
* selections, because it is not currently necessary to do
* that anywhere this function is called. If this becomes
* necessary (if the selection could be unlimited and the
* clip size is not being handled separately), this function
* must be updated to (optionally) clip the selection.
*
* Return: Success: Non-negative
* Failure: Negative
*
@ -1999,12 +2013,6 @@ H5S_set_extent_real(H5S_t *space, const hsize_t *size)
if(H5S_select_all(space, FALSE) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
/* If the selection is 'hyper', update the selection due to changed
* extent */
if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS)
if(H5S__hyper_update_extent_offset(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")
/* Mark the dataspace as no longer shared if it was before */
if(H5O_msg_reset_share(H5O_SDSPACE_ID, space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRESET, FAIL, "can't stop sharing dataspace")

View File

@ -45,6 +45,7 @@ static herr_t H5S_all_deserialize(const H5F_t *f, H5S_t *space,
uint32_t version, uint8_t flags, const uint8_t **p);
static herr_t H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S_all_offset(const H5S_t *space, hsize_t *off);
static int H5S_all_unlim_dim(const H5S_t *space);
static htri_t H5S_all_is_contiguous(const H5S_t *space);
static htri_t H5S_all_is_single(const H5S_t *space);
static htri_t H5S_all_is_regular(const H5S_t *space);
@ -76,6 +77,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{
H5S_all_deserialize,
H5S_all_bounds,
H5S_all_offset,
H5S_all_unlim_dim,
H5S_all_is_contiguous,
H5S_all_is_single,
H5S_all_is_regular,
@ -659,6 +661,31 @@ H5S_all_offset(const H5S_t UNUSED *space, hsize_t *offset)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5S_all_offset() */
/*--------------------------------------------------------------------------
NAME
H5S_all_unlim_dim
PURPOSE
Return unlimited dimension of selection, or -1 if none
USAGE
VDSINC
RETURNS
Unlimited dimension of selection, or -1 if none (never fails).
DESCRIPTION
VDSINC
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static int
H5S_all_unlim_dim(const H5S_t UNUSED *space)
{
FUNC_ENTER_NOAPI_NOERR
FUNC_LEAVE_NOAPI(-1)
} /* end H5S_all_unlim_dim() */
/*--------------------------------------------------------------------------
NAME

View File

@ -60,6 +60,7 @@ static herr_t H5S_hyper_deserialize(const H5F_t *f, H5S_t *space,
uint32_t version, uint8_t flags, const uint8_t **p);
static herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S_hyper_offset(const H5S_t *space, hsize_t *offset);
static int H5S_hyper_unlim_dim(const H5S_t *space);
static htri_t H5S_hyper_is_contiguous(const H5S_t *space);
static htri_t H5S_hyper_is_single(const H5S_t *space);
static htri_t H5S_hyper_is_regular(const H5S_t *space);
@ -96,6 +97,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{
H5S_hyper_deserialize,
H5S_hyper_bounds,
H5S_hyper_offset,
H5S_hyper_unlim_dim,
H5S_hyper_is_contiguous,
H5S_hyper_is_single,
H5S_hyper_is_regular,
@ -1655,6 +1657,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
dst_hslab->app_diminfo[u] = src_hslab->app_diminfo[u];
} /* end for */
} /* end for */
dst_hslab->unlim_dim_clip_size = src_hslab->unlim_dim_clip_size;
dst_hslab->num_elem_non_unlim = src_hslab->num_elem_non_unlim;
dst->select.sel_info.hslab->span_lst=src->select.sel_info.hslab->span_lst;
@ -1681,7 +1684,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
if(!extent_equal)
/* Update selection due to changed extent */
if(H5S__hyper_update_extent_offset(dst) < 0)
if(H5S_hyper_clip_to_extent(dst) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")
} /* end if */
@ -1906,7 +1909,7 @@ H5S_get_select_hyper_nblocks(H5S_t *space)
for(ret_value = 1, u = 0; u < space->extent.rank; u++) {
if(diminfo[u].block == (hsize_t)0)
HGOTO_DONE((hsize_t)0)
ret_value *= diminfo[u].count;;
ret_value *= diminfo[u].count;
} /* end for */
} /* end if */
else
@ -2977,6 +2980,31 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_hyper_offset() */
/*--------------------------------------------------------------------------
NAME
H5S_hyper_unlim_dim
PURPOSE
Return unlimited dimension of selection, or -1 if none
USAGE
VDSINC
RETURNS
Unlimited dimension of selection, or -1 if none (never fails).
DESCRIPTION
VDSINC
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static int
H5S_hyper_unlim_dim(const H5S_t *space)
{
FUNC_ENTER_NOAPI_NOERR
FUNC_LEAVE_NOAPI(space->select.sel_info.hslab->unlim_dim)
} /* end H5S_hyper_get_unlim_dim() */
/*--------------------------------------------------------------------------
NAME
@ -6683,6 +6711,10 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
/* Save unlim_dim */
space->select.sel_info.hslab->unlim_dim = unlim_dim;
/* Initialize unlim_dim_clip_size to H5S_UNLIMITED so the selection is
* clipped by H5S__hyper_clip_unlim() no matter what the extent is */
space->select.sel_info.hslab->unlim_dim_clip_size = H5S_UNLIMITED;
/* Indicate that the dimension information is valid */
space->select.sel_info.hslab->diminfo_valid = TRUE;
@ -6693,17 +6725,24 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
if(unlim_dim >= 0) {
space->select.sel_info.hslab->num_elem_non_unlim = (hsize_t)1;
for(u = 0; u < space->extent.rank; u++) {
/* Save start/stride/count/block */
space->select.sel_info.hslab->opt_unlim_diminfo[u].start = start[u];
space->select.sel_info.hslab->opt_unlim_diminfo[u].stride = opt_stride[u];
space->select.sel_info.hslab->opt_unlim_diminfo[u].count = opt_count[u];
space->select.sel_info.hslab->opt_unlim_diminfo[u].block = opt_block[u];
/* Calculate num_elem_non_unlim */
if((int)u != unlim_dim)
space->select.sel_info.hslab->num_elem_non_unlim *= (opt_count[u] * opt_block[u]);
} /* end for */
/* Initialize unlim_dim_clip_size to H5S_UNLIMITED so the selection
* is clipped by H5S__hyper_clip_to_extent() no matter what the
* extent is */
space->select.sel_info.hslab->unlim_dim_clip_size = H5S_UNLIMITED;
/* Set opt_diminfo or span tree based on extent */
if(H5S__hyper_update_extent_offset(space) < 0)
if(H5S_hyper_clip_to_extent(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't set selection based on extent")
} /* end if */
} /* end if */
@ -7133,13 +7172,19 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
/* Check for unlimited dimension */
for(u = 0; u<space->extent.rank; u++)
if((count[u] == H5S_UNLIMITED) || (block[u] == H5S_UNLIMITED)) {
if(unlim_dim >= 0)
if(unlim_dim >= 0) {
HDassert(0 && "Checking code coverage..."); //VDSINC
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot have more than one unlimited dimension in selection")
} //VDSINC
else {
if(op != H5S_SELECT_SET)
if(op != H5S_SELECT_SET) {
HDassert(0 && "Checking code coverage..."); //VDSINC
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot use unlimited selection to modify existing selection")
if(count[u] == block[u] /* == H5S_UNLIMITED */)
} //VDSINC
if(count[u] == block[u] /* == H5S_UNLIMITED */) {
HDassert(0 && "Checking code coverage..."); //VDSINC
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "count and block cannot both be unlimited")
} //VDSINC
unlim_dim = (int)u;
} /* end else */
} /* end if */
@ -7336,6 +7381,11 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
/* Save unlim_dim */
space->select.sel_info.hslab->unlim_dim = unlim_dim;
/* Initialize unlim_dim_clip_size to H5S_UNLIMITED so the selection is
* clipped by H5S__hyper_clip_to_extent() no matter what the extent is
*/
space->unlim_dim_clip_size = H5S_UNLIMITED;
/* Indicate that the dimension information is valid */
space->select.sel_info.hslab->diminfo_valid=TRUE;
@ -7356,7 +7406,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
} /* end for */
/* Set opt_diminfo or span tree based on extent */
if(H5S__hyper_update_extent_offset(space) < 0)
if(H5S__hyper_clip_to_extent(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't set selection based on extent")
} /* end if */
} /* end if */
@ -7365,8 +7415,10 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS);
/* Cannot modify unlimited selections */
if(space->select.sel_info.hslab->unlim_dim >= 0)
if(space->select.sel_info.hslab->unlim_dim >= 0) {
HDassert(0 && "Checking code coverage..."); //VDSINC
HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "cannot modify unlimited selection")
} //VDSINC
/* Check if there's no hyperslab span information currently */
if(space->select.sel_info.hslab->span_lst==NULL)
@ -9502,40 +9554,39 @@ done:
/*--------------------------------------------------------------------------
NAME
H5S__hyper_update_extent_offset
H5S_hyper_clip_unlim
PURPOSE
Updates the hyperslab selection after a change to the dataspace extent
or offset
Clips the unlimited dimension of the hyperslab selection to the
specified size
USAGE
VDSINC
RETURNS
Non-negative on success/Negative on failure.
DESCRIPTION
since unlimited selections are internally described as limited
selections with maximal size, these internal selections need to be
updated whenever the maximum size changes. This function
recaluculates the unlimited dimension (if any) of the hyperslab
selection when the extent or offset is changed.
This function recalculates the internal description of the hyperslab
to make the unlimited dimension extend to the specified extent.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
Note this function takes the offset into account.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5S__hyper_update_extent_offset(H5S_t *space)
H5S_hyper_clip_unlim(H5S_t *space, hsize_t clip_size)
{
H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */
herr_t ret_value = SUCCEED;
FUNC_ENTER_PACKAGE
FUNC_ENTER_NOAPI(FAIL)
/* Check parameters */
HDassert(space);
hslab = space->select.sel_info.hslab;
HDassert(hslab);
HDassert(hslab->unlim_dim >= 0);
/* Check for unlimited dimension */
if(hslab->unlim_dim < 0)
/* Check for no need to change size */
if(clip_size == hslab->unlim_dim_clip_size)
HGOTO_DONE(SUCCEED)
/* Free previous spans, if any */
@ -9548,10 +9599,10 @@ H5S__hyper_update_extent_offset(H5S_t *space)
/* Initialize opt_diminfo with opt_unlim_diminfo */
hslab->opt_diminfo[hslab->unlim_dim] = hslab->opt_unlim_diminfo[hslab->unlim_dim];
/* Check for selection outside extent */
/* Check for selection outside clip size */
if((hsize_t)((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start
+ space->select.offset[hslab->unlim_dim])
>= space->extent.size[hslab->unlim_dim]) {
>= clip_size) {
if(hslab->opt_diminfo[hslab->unlim_dim].block == H5S_UNLIMITED)
hslab->opt_diminfo[hslab->unlim_dim].block = 0;
else
@ -9569,11 +9620,11 @@ H5S__hyper_update_extent_offset(H5S_t *space)
if(hslab->opt_diminfo[hslab->unlim_dim].count == (hsize_t)1) {
HDassert(hslab->opt_diminfo[hslab->unlim_dim].block == H5S_UNLIMITED);
/* Calculate actual block size for this extent */
/* Calculate actual block size for this clip size */
hslab->opt_diminfo[hslab->unlim_dim].block =
(hsize_t)((hssize_t)space->extent.size[hslab->unlim_dim]
- ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start
+ space->select.offset[hslab->unlim_dim]));
- ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start)
+ space->select.offset[hslab->unlim_dim]);
/* Calculate number of elements */
space->select.num_elem = hslab->opt_diminfo[hslab->unlim_dim].block
@ -9588,7 +9639,7 @@ H5S__hyper_update_extent_offset(H5S_t *space)
/* Calculate initial count (last block may be partial) */
hslab->opt_diminfo[hslab->unlim_dim].count =
((hsize_t)((hssize_t)space->extent.size[hslab->unlim_dim]
((hsize_t)((hssize_t)clip_size
- ((hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start
+ space->select.offset[hslab->unlim_dim])
+ (hssize_t)hslab->opt_diminfo[hslab->unlim_dim].stride
@ -9605,7 +9656,7 @@ H5S__hyper_update_extent_offset(H5S_t *space)
if(((hslab->opt_diminfo[hslab->unlim_dim].stride
* (hslab->opt_diminfo[hslab->unlim_dim].count - (hsize_t)1))
+ hslab->opt_diminfo[hslab->unlim_dim].block - (hsize_t)1)
> ((hsize_t)((hssize_t)space->extent.size[hslab->unlim_dim]
> ((hsize_t)((hssize_t)clip_size
- (hssize_t)hslab->opt_diminfo[hslab->unlim_dim].start
+ space->select.offset[hslab->unlim_dim]))) {
/* Last block is partial, need to construct compound selection */
@ -9616,9 +9667,150 @@ H5S__hyper_update_extent_offset(H5S_t *space)
hslab->diminfo_valid = TRUE;
} /* end else */
/* Save clip size */
hslab->unlim_dim_clip_size = clip_size;
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S__hyper_update_extent_offset() */
} /* end H5S_hyper_clip_unlim() */
/*--------------------------------------------------------------------------
NAME
H5S_hyper_clip_to_extent
PURPOSE
Updates the hyperslab selection after a change to the dataspace extent
or offset
USAGE
VDSINC
RETURNS
Non-negative on success/Negative on failure.
DESCRIPTION
Since unlimited selections are internally described as limited
selections with maximal size, these internal selections need to be
updated whenever the maximum size changes. This function
recaluculates the unlimited dimension (if any) of the hyperslab
selection when the extent or offset is changed.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
Note this function takes the offset into account.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
H5S_hyper_clip_to_extent(H5S_t *space)
{
H5S_hyper_sel_t *hslab; /* Convenience pointer to hyperslab info */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
/* Check parameters */
HDassert(space);
hslab = space->select.sel_info.hslab;
HDassert(hslab);
/* Check for unlimited dimension */
if(hslab->unlim_dim < 0)
HGOTO_DONE(SUCCEED)
/* Clip unlimited selection to extent */
if(H5S_hyper_clip_unlim(space, space->extent.size[hslab->unlim_dim]) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "failed to clip unlimited selection")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S_hyper_clip_to_extent() */
/*--------------------------------------------------------------------------
NAME
H5S_hyper_get_clip_extent
PURPOSE
VDSINC
USAGE
VDSINC
RETURNS
Non-negative on success/Negative on failure.
DESCRIPTION
VDSINC
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
Note this assumes the offset has been normalized.
EXAMPLES
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)
{
const H5S_hyper_sel_t *clip_hslab; /* Convenience pointer to hyperslab info */
const H5S_hyper_sel_t *match_hslab; /* Convenience pointer to hyperslab info */
hsize_t num_slices;
hsize_t count;
hsize_t rem_slices;
FUNC_ENTER_NOAPI_NOERR
/* Check parameters */
HDassert(clip_space);
clip_hslab = clip_space->select.sel_info.hslab;
HDassert(clip_hslab);
HDassert(match_space);
match_hslab = match_space->select.sel_info.hslab;
HDassert(match_space);
HDassert(clip_space_unlim_extent);
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);
/* 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;
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_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].start
+ num_slices;
} /* end if */
else {
/* Unlimited count, need to match extent so a block (possibly) gets cut
* off so the number of slices matches num_slices */
HDassert(clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].count == H5S_UNLIMITED);
/* Calculate number of complete blocks in clip_space */
count = num_slices / clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block;
/* Calculate slices remaining */
rem_slices = num_slices - (count
* clip_hslab->opt_unlim_diminfo[clip_hslab->unlim_dim].block);
if(rem_slices > 0) {
HDassert(0 && "Checking code coverage..."); //VDSINC
/* Must end extent in middle of partial block */
*clip_space_unlim_extent =
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
/* End extent at end of last block */
*clip_space_unlim_extent =
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;
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S_hyper_get_clip_extent() */
/*--------------------------------------------------------------------------

View File

@ -46,6 +46,7 @@ static herr_t H5S_none_deserialize(const H5F_t *f, H5S_t *space,
uint32_t version, uint8_t flags, const uint8_t **p);
static herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S_none_offset(const H5S_t *space, hsize_t *off);
static int H5S_none_unlim_dim(const H5S_t *space);
static htri_t H5S_none_is_contiguous(const H5S_t *space);
static htri_t H5S_none_is_single(const H5S_t *space);
static htri_t H5S_none_is_regular(const H5S_t *space);
@ -77,6 +78,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{
H5S_none_deserialize,
H5S_none_bounds,
H5S_none_offset,
H5S_none_unlim_dim,
H5S_none_is_contiguous,
H5S_none_is_single,
H5S_none_is_regular,
@ -610,6 +612,31 @@ H5S_none_offset(const H5S_t UNUSED *space, hsize_t UNUSED *offset)
FUNC_LEAVE_NOAPI(FAIL)
} /* H5S_none_offset() */
/*--------------------------------------------------------------------------
NAME
H5S_none_unlim_dim
PURPOSE
Return unlimited dimension of selection, or -1 if none
USAGE
VDSINC
RETURNS
Unlimited dimension of selection, or -1 if none (never fails).
DESCRIPTION
VDSINC
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static int
H5S_none_unlim_dim(const H5S_t UNUSED *space)
{
FUNC_ENTER_NOAPI_NOERR
FUNC_LEAVE_NOAPI(-1)
} /* end H5S_none_unlim_dim() */
/*--------------------------------------------------------------------------
NAME

View File

@ -124,6 +124,7 @@ typedef struct {
* contains H5S_UNLIMITED in the count or block of the unlimited
* dimension (if any). */
int unlim_dim; /* Dimension where selection is unlimited, or -1 if none */
hsize_t unlim_dim_clip_size; /* Size to which the selection is clipped in unlimited dimension */
hsize_t num_elem_non_unlim; /* # of elements in a "slice" excluding the unlimited dimension */
H5S_hyper_span_info_t *span_lst; /* List of hyperslab span information */
} H5S_hyper_sel_t;
@ -151,6 +152,8 @@ typedef herr_t (*H5S_sel_deserialize_func_t)(const H5F_t *f, H5S_t *space,
typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end);
/* Method to determine linear offset of initial element in selection within dataspace */
typedef herr_t (*H5S_sel_offset_func_t)(const H5S_t *space, hsize_t *offset);
/* Method to get unlimited dimension of selection (or -1 for none) */
typedef int (*H5S_sel_unlim_dim_func_t)(const H5S_t *space);
/* Method to determine if current selection is contiguous */
typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space);
/* Method to determine if current selection is a single block */
@ -180,6 +183,7 @@ typedef struct {
H5S_sel_deserialize_func_t deserialize; /* Method to store create selection from "serialized" form (a byte sequence suitable for storing on disk) */
H5S_sel_bounds_func_t bounds; /* Method to determine to smallest n-D bounding box containing the current selection */
H5S_sel_offset_func_t offset; /* Method to determine linear offset of initial element in selection within dataspace */
H5S_sel_unlim_dim_func_t unlim_dim; /* Method to get unlimited dimension of selection (or -1 for none) */
H5S_sel_is_contiguous_func_t is_contiguous; /* Method to determine if current selection is contiguous */
H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */
H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */
@ -268,7 +272,6 @@ H5_DLL herr_t H5S_extent_copy_real(H5S_extent_t *dst, const H5S_extent_t *src,
H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space,
const H5S_t *dst_space, const H5S_t *src_intersect_space,
H5S_t *proj_space);
H5_DLL herr_t H5S__hyper_update_extent_offset(H5S_t *space);
/* Testing functions */
#ifdef H5S_TESTING

View File

@ -47,6 +47,7 @@ static herr_t H5S_point_deserialize(const H5F_t *f, H5S_t *space,
uint32_t version, uint8_t flags, const uint8_t **p);
static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
static herr_t H5S_point_offset(const H5S_t *space, hsize_t *off);
static int H5S_point_unlim_dim(const H5S_t *space);
static htri_t H5S_point_is_contiguous(const H5S_t *space);
static htri_t H5S_point_is_single(const H5S_t *space);
static htri_t H5S_point_is_regular(const H5S_t *space);
@ -78,6 +79,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S_point_deserialize,
H5S_point_bounds,
H5S_point_offset,
H5S_point_unlim_dim,
H5S_point_is_contiguous,
H5S_point_is_single,
H5S_point_is_regular,
@ -1186,6 +1188,31 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_point_offset() */
/*--------------------------------------------------------------------------
NAME
H5S_point_unlim_dim
PURPOSE
Return unlimited dimension of selection, or -1 if none
USAGE
VDSINC
RETURNS
Unlimited dimension of selection, or -1 if none (never fails).
DESCRIPTION
VDSINC
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static int
H5S_point_unlim_dim(const H5S_t UNUSED *space)
{
FUNC_ENTER_NOAPI_NOERR
FUNC_LEAVE_NOAPI(-1)
} /* end H5S_point_unlim_dim() */
/*--------------------------------------------------------------------------
NAME

View File

@ -218,6 +218,7 @@ H5_DLL htri_t H5S_select_valid(const H5S_t *space);
H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space);
H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
H5_DLL herr_t H5S_get_select_offset(const H5S_t *space, hsize_t *offset);
H5_DLL int H5S_get_select_unlim_dim(const H5S_t *space);
H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset);
H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2);
@ -265,6 +266,10 @@ H5_DLL htri_t H5S_hyper_intersect_block (H5S_t *space, hsize_t *start, hsize_t *
H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset);
H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset);
H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset);
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);
/* 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);

View File

@ -81,7 +81,7 @@ H5S_select_offset(H5S_t *space, const hssize_t *offset)
/* If the selection is 'hyper', update the selection due to changed offset
*/
if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS)
if(H5S__hyper_update_extent_offset(space) < 0)
if(H5S_hyper_clip_to_extent(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't update hyperslab")
done:
@ -696,6 +696,44 @@ H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_get_select_offset() */
/*--------------------------------------------------------------------------
NAME
H5S_get_select_unlim_dim
PURPOSE
Gets the unlimited dimension in the selection, or -1 if there is no
unlimited dimension.
USAGE
int H5S_get_select_unlim_dim(space)
const H5S_t *space; IN: Dataspace pointer of selection to query
RETURNS
Unlimited dimension in the selection, or -1 if there is no unlimited
dimension (never fails)
DESCRIPTION
Gets the unlimited dimension in the selection, or -1 if there is no
unlimited dimension.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
Currently only implemented for hyperslab selections, all others
simply return -1.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
int
H5S_get_select_unlim_dim(const H5S_t *space)
{
herr_t ret_value; /* return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
HDassert(space);
ret_value = (*space->select.type->unlim_dim)(space);
FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_get_select_unlim_dim() */
/*--------------------------------------------------------------------------
NAME