HDFFV-10933, add a check inside H5Dint.c to ignore the filter operations when the filter is optional and the dataset has properties that makes the filter unable to apply to this dataset. These properties are Scalar or NULL SPACE or variable length datatype. An unpolished C example code h5_filter_ignore.c can be found under the examples directory.

This commit is contained in:
Muqun Yang 2019-10-22 19:51:25 -05:00
parent a27403d595
commit 200a77d8c3
4 changed files with 220 additions and 9 deletions

144
examples/h5_filter_ignore.c Normal file
View File

@ -0,0 +1,144 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the COPYING file, which can be found at the root of the source code *
* distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
* If you do not have access to either file, you may request a copy from *
* help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* This example illustrates how to create a compressed dataset.
* It is used in the HDF5 Tutorial.
*/
#include <hdf5.h>
int main()
{
unsigned int level = 9;
size_t cd_nelmts = 1;
unsigned int cd_values[1] = {level};
char const *data = "This is my {} string!";
hid_t f = H5Fcreate("foo.h5",H5F_ACC_TRUNC,H5P_DEFAULT,H5P_DEFAULT);
hid_t dcpl = H5Pcreate(H5P_DATASET_CREATE);
hid_t strtid = H5Tcreate(H5T_STRING, H5T_VARIABLE);
hid_t spid = H5Screate(H5S_SCALAR);
herr_t err = H5Pset_filter(dcpl, H5Z_FILTER_DEFLATE, H5Z_FLAG_OPTIONAL, cd_nelmts, cd_values);
hid_t dsid = H5Dcreate(f, "scalar-string", strtid, spid, H5P_DEFAULT, dcpl, H5P_DEFAULT);
H5Fclose(f);
H5close();
return 0;
}
#if 0
#include "hdf5.h"
#define FILE "cmprss.h5"
#define RANK 2
#define DIM0 100
#define DIM1 20
int main () {
hid_t file_id, dataset_id, dataspace_id; /* identifiers */
hid_t plist_id;
size_t nelmts;
unsigned flags, filter_info;
H5Z_filter_t filter_type;
herr_t status;
hsize_t dims[2];
hsize_t cdims[2];
int i,j, numfilt;
int buf[DIM0][DIM1];
int rbuf [DIM0][DIM1];
/* Uncomment these variables to use SZIP compression
unsigned szip_options_mask;
unsigned szip_pixels_per_block;
*/
/* Create a file. */
file_id = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
/* Create dataset "Compressed Data" in the group using absolute name. */
dims[0] = DIM0;
dims[1] = DIM1;
dataspace_id = H5Screate_simple (RANK, dims, NULL);
plist_id = H5Pcreate (H5P_DATASET_CREATE);
/* Dataset must be chunked for compression */
cdims[0] = 20;
cdims[1] = 20;
status = H5Pset_chunk (plist_id, 2, cdims);
/* Set ZLIB / DEFLATE Compression using compression level 6.
* To use SZIP Compression comment out these lines.
*/
status = H5Pset_deflate (plist_id, 6);
/* Uncomment these lines to set SZIP Compression
szip_options_mask = H5_SZIP_NN_OPTION_MASK;
szip_pixels_per_block = 16;
status = H5Pset_szip (plist_id, szip_options_mask, szip_pixels_per_block);
*/
dataset_id = H5Dcreate2 (file_id, "Compressed_Data", H5T_STD_I32BE,
dataspace_id, H5P_DEFAULT, plist_id, H5P_DEFAULT);
for (i = 0; i< DIM0; i++)
for (j=0; j<DIM1; j++)
buf[i][j] = i+j;
status = H5Dwrite (dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf);
status = H5Sclose (dataspace_id);
status = H5Dclose (dataset_id);
status = H5Pclose (plist_id);
status = H5Fclose (file_id);
/* Now reopen the file and dataset in the file. */
file_id = H5Fopen (FILE, H5F_ACC_RDWR, H5P_DEFAULT);
dataset_id = H5Dopen2 (file_id, "Compressed_Data", H5P_DEFAULT);
/* Retrieve filter information. */
plist_id = H5Dget_create_plist (dataset_id);
numfilt = H5Pget_nfilters (plist_id);
printf ("Number of filters associated with dataset: %i\n", numfilt);
for (i=0; i<numfilt; i++) {
nelmts = 0;
filter_type = H5Pget_filter2 (plist_id, 0, &flags, &nelmts, NULL, 0, NULL,
&filter_info);
printf ("Filter Type: ");
switch (filter_type) {
case H5Z_FILTER_DEFLATE:
printf ("H5Z_FILTER_DEFLATE\n");
break;
case H5Z_FILTER_SZIP:
printf ("H5Z_FILTER_SZIP\n");
break;
default:
printf ("Other filter type included.\n");
}
}
status = H5Dread (dataset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
H5P_DEFAULT, rbuf);
status = H5Dclose (dataset_id);
status = H5Pclose (plist_id);
status = H5Fclose (file_id);
}
#endif

View File

@ -1186,6 +1186,8 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
hbool_t pline_copied = FALSE; /* Flag to indicate that pipeline message was copied */ hbool_t pline_copied = FALSE; /* Flag to indicate that pipeline message was copied */
hbool_t efl_copied = FALSE; /* Flag to indicate that external file list message was copied */ hbool_t efl_copied = FALSE; /* Flag to indicate that external file list message was copied */
H5G_loc_t dset_loc; /* Dataset location */ H5G_loc_t dset_loc; /* Dataset location */
htri_t ignore_filter = FALSE;
H5D_t *ret_value = NULL; /* Return value */ H5D_t *ret_value = NULL; /* Return value */
FUNC_ENTER_PACKAGE FUNC_ENTER_PACKAGE
@ -1239,6 +1241,17 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
/* Set the dataset's checked_filters flag to enable writing */ /* Set the dataset's checked_filters flag to enable writing */
new_dset->shared->checked_filters = TRUE; new_dset->shared->checked_filters = TRUE;
if(new_dset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
// KY: We know if the space is H5S_NULL or H5S_SCALAR and the filter is optional,
// the filter operation can be ignored.
if(H5S_NULL == H5S_GET_EXTENT_TYPE(space) || H5S_SCALAR == H5S_GET_EXTENT_TYPE(space) ||
H5T_VLEN == H5Tget_class(type_id) ||
(H5T_STRING == H5Tget_class(type_id)&&TRUE==H5Tis_variable_str(type_id))) {
if((ignore_filter = H5Z_has_optional_filter(new_dset->shared->dcpl_id))<0)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "H5Z_has_optional_filter() failed")
}
}
/* Check if the dataset has a non-default DCPL & get important values, if so */ /* Check if the dataset has a non-default DCPL & get important values, if so */
if(new_dset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT) { if(new_dset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
H5O_layout_t *layout; /* Dataset's layout information */ H5O_layout_t *layout; /* Dataset's layout information */
@ -1246,13 +1259,15 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
H5O_fill_t *fill; /* Dataset's fill value info */ H5O_fill_t *fill; /* Dataset's fill value info */
H5O_efl_t *efl; /* Dataset's external file list info */ H5O_efl_t *efl; /* Dataset's external file list info */
/* Check if the filters in the DCPL can be applied to this dataset */ if(FALSE == ignore_filter) {
if(H5Z_can_apply(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0) /* Check if the filters in the DCPL can be applied to this dataset */
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "I/O filters can't operate on this dataset") if(H5Z_can_apply(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, NULL, "I/O filters can't operate on this dataset")
/* Make the "set local" filter callbacks for this dataset */ /* Make the "set local" filter callbacks for this dataset */
if(H5Z_set_local(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0) if(H5Z_set_local(new_dset->shared->dcpl_id, new_dset->shared->type_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to set local filter parameters") HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to set local filter parameters")
}
/* Get new dataset's property list object */ /* Get new dataset's property list object */
if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(new_dset->shared->dcpl_id))) if(NULL == (dc_plist = (H5P_genplist_t *)H5I_object(new_dset->shared->dcpl_id)))
@ -1276,10 +1291,13 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't retrieve external file list") HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't retrieve external file list")
efl_copied = TRUE; efl_copied = TRUE;
/* Check that chunked layout is used if filters are enabled */
if(pline->nused > 0 && H5D_CHUNKED != layout->type)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout")
if(FALSE == ignore_filter) {
/* Check that chunked layout is used if filters are enabled */
if(pline->nused > 0 && H5D_CHUNKED != layout->type)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "filters can only be used with chunked layout")
}
/* Check if the alloc_time is the default and error out */ /* Check if the alloc_time is the default and error out */
if(fill->alloc_time == H5D_ALLOC_TIME_DEFAULT) if(fill->alloc_time == H5D_ALLOC_TIME_DEFAULT)
HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "invalid space allocation state") HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, NULL, "invalid space allocation state")

View File

@ -874,6 +874,53 @@ done:
FUNC_LEAVE_NOAPI(ret_value) FUNC_LEAVE_NOAPI(ret_value)
} /* end H5Z_prepare_prelude_callback_dcpl() */ } /* end H5Z_prepare_prelude_callback_dcpl() */
/*-------------------------------------------------------------------------
* Function: H5Z_has_optional_filter
*
* Purpose: If one filter optional, this filter can be ignored.
*
* Return: Non-negative(TRUE/FALSE) on success
* 0
* Negative on failure
*
*-------------------------------------------------------------------------
*/
htri_t
H5Z_has_optional_filter(hid_t dcpl_id)
/*H5Z_can_ignore(hid_t dcpl_id, hid_t type_id) */
/*H5Z_can_ignore(hid_t dcpl_id, hid_t type_id,const H5S_t *space) */
{
htri_t ret_value = FALSE; /* Return value */
H5P_genplist_t *dc_plist; /* Dataset creation property list object */
H5O_pline_t dcpl_pline; /* Object's I/O pipeline information */
FUNC_ENTER_NOAPI(FAIL)
if (NULL == (dc_plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
/* Get I/O pipeline information */
if (H5P_peek(dc_plist, H5O_CRT_PIPELINE_NAME, &dcpl_pline) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter")
if (dcpl_pline.nused > 0) {
size_t u;
for ( u = 0; u<dcpl_pline.nused;u++) {
if(dcpl_pline.filter[u].flags & H5Z_FLAG_OPTIONAL) {
ret_value = TRUE;
break;
}
}
}
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5Z_can_apply() */
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
* Function: H5Z_can_apply * Function: H5Z_can_apply

View File

@ -85,6 +85,8 @@ H5_DLL herr_t H5Z_pipeline(const struct H5O_pline_t *pline,
size_t *nbytes/*in,out*/, size_t *buf_size/*in,out*/, size_t *nbytes/*in,out*/, size_t *buf_size/*in,out*/,
void **buf/*in,out*/); void **buf/*in,out*/);
H5_DLL H5Z_class2_t *H5Z_find(H5Z_filter_t id); H5_DLL H5Z_class2_t *H5Z_find(H5Z_filter_t id);
//H5_DLL htri_t H5Z_can_ignore(hid_t dcpl_id);
H5_DLL htri_t H5Z_has_optional_filter(hid_t dcpl_id);
H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id); H5_DLL herr_t H5Z_can_apply(hid_t dcpl_id, hid_t type_id);
H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id); H5_DLL herr_t H5Z_set_local(hid_t dcpl_id, hid_t type_id);
H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline); H5_DLL herr_t H5Z_can_apply_direct(const struct H5O_pline_t *pline);