summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRaymond Lu <songyulu@hdfgroup.org>2011-04-13 16:14:16 (GMT)
committerRaymond Lu <songyulu@hdfgroup.org>2011-04-13 16:14:16 (GMT)
commit2815eefb6b0ea608712e0abbc1d3db0910b4cd80 (patch)
tree94051a5190c521b35601a023cec1509867a72742 /src
parent49a607c438d7e0135be61d4cb98d5de013f73fa3 (diff)
downloadhdf5-2815eefb6b0ea608712e0abbc1d3db0910b4cd80.zip
hdf5-2815eefb6b0ea608712e0abbc1d3db0910b4cd80.tar.gz
hdf5-2815eefb6b0ea608712e0abbc1d3db0910b4cd80.tar.bz2
[svn-r20489] Bug 1386 - allow dimension size to be zero even though it isn't unlimited. I brought the changes from the trunk as below:
1. I added test cases for contiguous, compact, and chunked, and external storage datasets, and also attribute. The test includes dataspace selections. 2. I added a test case of extending dataset of zero dimension size and shrinking back to zero dimension size. 3. I updated the Makefile to include the new data file to be cleaned up. 4. The dataspace code has another bug - when the maximal dimension isn't passed in for H5Sset_extent_simple, it is supposed to be same as the dimension. The current library sets NULL to it. I corrected it and added a test case to it. 5. I corrected the tests of Fortran and C++ for the problem in point 3. Tested on jam, heiwa, and amani.
Diffstat (limited to 'src')
-rw-r--r--src/H5Aint.c5
-rw-r--r--src/H5Dchunk.c12
-rw-r--r--src/H5Dint.c27
-rw-r--r--src/H5Oefl.c6
-rw-r--r--src/H5Pdcpl.c7
-rw-r--r--src/H5S.c55
-rw-r--r--src/H5Spoint.c4
7 files changed, 73 insertions, 43 deletions
diff --git a/src/H5Aint.c b/src/H5Aint.c
index e48873c..10b7257 100644
--- a/src/H5Aint.c
+++ b/src/H5Aint.c
@@ -888,8 +888,9 @@ H5A_attr_copy_file(const H5A_t *attr_src, H5F_t *file_dst, hbool_t *recompute_si
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to reset datatype sharing")
} /* end else */
- /* Copy the dataspace for the attribute */
- attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, FALSE);
+ /* Copy the dataspace for the attribute. Make sure the maximal dimension is also copied.
+ * Otherwise the comparison in the test may complain about it. SLU 2011/4/12 */
+ attr_dst->shared->ds = H5S_copy(attr_src->shared->ds, FALSE, TRUE);
HDassert(attr_dst->shared->ds);
/* Reset the dataspace's sharing in the source file before trying to share
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c
index ab1a975..39613f5 100644
--- a/src/H5Dchunk.c
+++ b/src/H5Dchunk.c
@@ -378,8 +378,9 @@ done:
static herr_t
H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
{
- const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
- hsize_t max_dim[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
+ const H5T_t *type = dset->shared->type; /* Convenience pointer to dataset's datatype */
+ hsize_t max_dims[H5O_LAYOUT_NDIMS]; /* Maximum size of data in elements */
+ hsize_t dims[H5O_LAYOUT_NDIMS]; /* Dimension size of data in elements */
uint64_t chunk_size; /* Size of chunk in bytes */
int ndims; /* Rank of dataspace */
unsigned u; /* Local index variable */
@@ -413,7 +414,7 @@ H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
dset->shared->layout.u.chunk.dim[dset->shared->layout.u.chunk.ndims - 1] = (uint32_t)H5T_GET_SIZE(type);
/* Get local copy of dataset dimensions (for sanity checking) */
- if(H5S_get_simple_extent_dims(dset->shared->space, NULL, max_dim) < 0)
+ if(H5S_get_simple_extent_dims(dset->shared->space, dims, max_dims) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to query maximum dimensions")
/* Sanity check dimensions */
@@ -424,9 +425,10 @@ H5D_chunk_construct(H5F_t UNUSED *f, H5D_t *dset)
/*
* The chunk size of a dimension with a fixed size cannot exceed
- * the maximum dimension size
+ * the maximum dimension size. If any dimension size is zero, there
+ * will be no such restriction.
*/
- if(max_dim[u] != H5S_UNLIMITED && max_dim[u] < dset->shared->layout.u.chunk.dim[u])
+ if(dims[u] && max_dims[u] != H5S_UNLIMITED && max_dims[u] < dset->shared->layout.u.chunk.dim[u])
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "chunk size must be <= maximum dimension size for fixed-sized dimensions")
} /* end for */
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 3821b78..0b4392e 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -1628,16 +1628,23 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al
case H5D_COMPACT:
/* Check if space is already allocated */
if(NULL == layout->storage.u.compact.buf) {
- /* Reserve space in layout header message for the entire array. */
- HDassert(layout->storage.u.compact.size > 0);
- if(NULL == (layout->storage.u.compact.buf = H5MM_malloc(layout->storage.u.compact.size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for compact dataset")
- if(!full_overwrite)
- HDmemset(layout->storage.u.compact.buf, 0, layout->storage.u.compact.size);
- layout->storage.u.compact.dirty = TRUE;
-
- /* Indicate that we should initialize storage space */
- must_init_space = TRUE;
+ /* Reserve space in layout header message for the entire array.
+ * Starting from the 1.8.7 release, we allow dataspace to have
+ * zero dimension size. So the storage size can be zero.
+ * SLU 2011/4/4 */
+ if(layout->storage.u.compact.size > 0) {
+ if(NULL == (layout->storage.u.compact.buf = H5MM_malloc(layout->storage.u.compact.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory for compact dataset")
+ if(!full_overwrite)
+ HDmemset(layout->storage.u.compact.buf, 0, layout->storage.u.compact.size);
+ layout->storage.u.compact.dirty = TRUE;
+
+ /* Indicate that we should initialize storage space */
+ must_init_space = TRUE;
+ } else {
+ layout->storage.u.compact.dirty = FALSE;
+ must_init_space = FALSE;
+ }
} /* end if */
break;
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 25cac88..db25e82 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -81,6 +81,11 @@ const H5O_msg_class_t H5O_MSG_EFL[1] = {{
* Programmer: Robb Matzke
* Tuesday, November 25, 1997
*
+ * Modification:
+ * Raymond Lu
+ * 11 April 2011
+ * We allow zero dimension size starting from the 1.8.7 release.
+ * The dataset size of external storage can be zero.
*-------------------------------------------------------------------------
*/
static void *
@@ -156,7 +161,6 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, H5O_t UNUSED *open_oh,
/* Size */
H5F_DECODE_LENGTH (f, p, mesg->slot[u].size);
- HDassert(mesg->slot[u].size > 0);
} /* end for */
if(H5HL_unprotect(heap) < 0)
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index a06304c..8680edb 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -966,6 +966,11 @@ done:
* Changed the way to check parameter and set property for
* generic property list.
*
+ * Raymond Lu
+ * 7 April 2011
+ * Starting from the 1.8.7 release, we allow dataspace to have
+ * zero dimension size. So the external storage size for
+ * dataset can be zero.
*-------------------------------------------------------------------------
*/
herr_t
@@ -985,8 +990,6 @@ H5Pset_external(hid_t plist_id, const char *name, off_t offset, hsize_t size)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name given")
if (offset<0)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "negative external file offset")
- if (size<=0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "zero size")
/* Get the plist structure */
if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_CREATE)))
diff --git a/src/H5S.c b/src/H5S.c
index e7cac9d..f002500 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1160,14 +1160,22 @@ H5Sis_simple(hid_t space_id)
Christian Chilan 01/17/2007
Verifies that each element of DIMS is not equal to H5S_UNLIMITED.
+ Raymond Lu 03/30/2011
+ We allow 0-dimension for non-unlimited dimension starting from 1.8.7
+ release.
+
+ Raymond Lu 04/11/2011
+ I added a condition check to make sure the new size won't exceed the
+ current maximal size when this function is called to change the
+ dimension size of an existent dataspace.
--------------------------------------------------------------------------*/
herr_t
H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
const hsize_t max[/*rank*/])
{
H5S_t *space; /* dataspace to modify */
- int u; /* local counting variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ int u; /* local counting variable */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Sset_extent_simple, FAIL)
H5TRACE4("e", "iIs*[a1]h*[a1]h", space_id, rank, dims, max);
@@ -1183,8 +1191,6 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
for (u=0; u<rank; u++) {
if (H5S_UNLIMITED==dims[u])
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "current dimension must have a specific size, not H5S_UNLIMITED")
- if (((max!=NULL && max[u]!=H5S_UNLIMITED) || max==NULL) && dims[u]==0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dimension size")
}
}
if (max!=NULL) {
@@ -1196,6 +1202,14 @@ H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
}
}
+ /* Check through all the dimensions to see if the new dimension size exceeds the current
+ * size or if the new maximal size exceeds the current maximal size */
+ for(u = 0; u < space->extent.rank; u++) {
+ if(space->extent.max && H5S_UNLIMITED!=space->extent.max[u] &&
+ (space->extent.max[u]<dims[u] || (max && space->extent.max[u]<max[u])))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "new size exceeds current maximal size")
+ } /* end for */
+
/* Do it */
if (H5S_set_extent_simple(space, (unsigned)rank, dims, max)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set simple extent")
@@ -1258,13 +1272,15 @@ H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims,
} /* end for */
space->extent.nelem = nelem;
- /* Copy the maximum dimensions if specified */
+ /* Copy the maximum dimensions if specified. Otherwise, the maximal dimensions are the
+ * same as the dimension */
+ space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
if(max != NULL) {
- space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
HDmemcpy(space->extent.max, max, sizeof(hsize_t) * rank);
- } /* end if */
- else
- space->extent.max = NULL;
+ } else {
+ for(u = 0; u < space->extent.rank; u++)
+ space->extent.max[u] = dims[u];
+ }
} /* end else */
/* Selection related cleanup */
@@ -1303,6 +1319,11 @@ done:
* Programmer: Quincey Koziol
* Tuesday, January 27, 1998
*
+ * Modification:
+ * Raymond Lu 03/30/2011
+ * We allow 0-dimension for non-unlimited dimension starting
+ * from 1.8.7 release.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -1332,17 +1353,9 @@ H5Screate_simple(int rank, const hsize_t dims[/*rank*/],
for(i = 0; i < rank; i++) {
if(H5S_UNLIMITED == dims[i])
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "current dimension must have a specific size, not H5S_UNLIMITED")
- if(maxdims) {
- if(H5S_UNLIMITED != maxdims[i] && maxdims[i]<dims[i])
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "maxdims is smaller than dims")
- if(H5S_UNLIMITED != maxdims[i] && dims[i] == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero sized dimension for non-unlimited dimension")
- } /* end if */
- else {
- if(dims[i] == 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "zero sized dimension for non-unlimited dimension")
- } /* end else */
- } /* end else */
+ if(maxdims && H5S_UNLIMITED != maxdims[i] && maxdims[i]<dims[i])
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "maxdims is smaller than dims")
+ } /* end for */
/* Create the space and set the extent */
if(NULL == (space = H5S_create_simple((unsigned)rank,dims,maxdims)))
@@ -1906,7 +1919,7 @@ H5S_set_extent_real(H5S_t *space, const hsize_t *size)
/* Change the dataspace size & re-compute the number of elements in the extent */
for(u = 0, nelem = 1; u < space->extent.rank; u++ ) {
space->extent.size[u] = size[u];
- nelem *= space->extent.size[u];
+ nelem *= size[u];
} /* end for */
space->extent.nelem = nelem;
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index cb7e98f..e544371 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -1551,8 +1551,8 @@ herr_t
H5Sselect_elements(hid_t spaceid, H5S_seloper_t op, size_t num_elem,
const hsize_t *coord)
{
- H5S_t *space; /* Dataspace to modify selection of */
- herr_t ret_value; /* Return value */
+ H5S_t *space; /* Dataspace to modify selection of */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_API(H5Sselect_elements, FAIL)
H5TRACE4("e", "iSsz*h", spaceid, op, num_elem, coord);