diff options
author | Raymond Lu <songyulu@hdfgroup.org> | 2011-04-13 16:14:16 (GMT) |
---|---|---|
committer | Raymond Lu <songyulu@hdfgroup.org> | 2011-04-13 16:14:16 (GMT) |
commit | 2815eefb6b0ea608712e0abbc1d3db0910b4cd80 (patch) | |
tree | 94051a5190c521b35601a023cec1509867a72742 /src | |
parent | 49a607c438d7e0135be61d4cb98d5de013f73fa3 (diff) | |
download | hdf5-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.c | 5 | ||||
-rw-r--r-- | src/H5Dchunk.c | 12 | ||||
-rw-r--r-- | src/H5Dint.c | 27 | ||||
-rw-r--r-- | src/H5Oefl.c | 6 | ||||
-rw-r--r-- | src/H5Pdcpl.c | 7 | ||||
-rw-r--r-- | src/H5S.c | 55 | ||||
-rw-r--r-- | src/H5Spoint.c | 4 |
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))) @@ -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); |