summaryrefslogtreecommitdiffstats
path: root/src/H5Z.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-04-09 02:34:21 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-04-09 02:34:21 (GMT)
commit92b6e817897817df03ad9f9b171ea4e11b901834 (patch)
tree5dc8befddaa0341a8380f80b55756ba1801ad110 /src/H5Z.c
parent099a9f4e74078691a79874638b9aeeebb3bc1996 (diff)
downloadhdf5-92b6e817897817df03ad9f9b171ea4e11b901834.zip
hdf5-92b6e817897817df03ad9f9b171ea4e11b901834.tar.gz
hdf5-92b6e817897817df03ad9f9b171ea4e11b901834.tar.bz2
[svn-r6611] Purpose:
Code cleanup/new features Description: Switch over to a new style for registering filters with the library - instead passing in an ID, a string and a callback function to H5Zregister, the client should pass in a single pointer to a H5Z_claass_t struct which contains the ID, the description string and all the function callbacks as fields. Added support for a new "can apply" callback for each filter, which is called when a dataset is created to check whether the parameters for that filter apply correctly to the combination of the datatype and the chunk size (i.e. dataspace) for the dataset. Added support for a new "set local" callback for each filter, which is called when a dataset is created (after the "can apply" filter callback) and sets filter parameters that are specific to that particular dataset. Switched the filters we ship over to use the new H5Z_class_t struct for their internal registrations and also added "set local" callbacks to the szip and shuffle filters and a "can apply" callback to the szip filter. Lots of other code cleanups, etc. also Solution: Platforms tested: FreeBSD 4.8 (sleipnir) w/szip Linux 2.4 (sleipnir) w/szip Solaris 2.7 (arabica) w/FORTRAN IRIX64 6.5 (modi4) w/szip, FORTRAN & parallel Misc. update:
Diffstat (limited to 'src/H5Z.c')
-rw-r--r--src/H5Z.c648
1 files changed, 584 insertions, 64 deletions
diff --git a/src/H5Z.c b/src/H5Z.c
index cb96be5..b4b63fd 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -12,11 +12,17 @@
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#include "H5private.h"
-#include "H5Eprivate.h"
-#include "H5MMprivate.h"
-#include "H5Oprivate.h"
-#include "H5Zprivate.h"
+#define H5Z_PACKAGE /*suppress error about including H5Zpkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Dataset functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Oprivate.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5Sprivate.h" /* Dataspace functions */
+#include "H5Zpkg.h" /* Data filters */
/* Pablo mask */
#define PABLO_MASK H5Z_mask
@@ -26,12 +32,33 @@
static int interface_initialize_g = 0;
static herr_t H5Z_init_interface (void);
+/* Local typedefs */
+#ifdef H5Z_DEBUG
+typedef struct H5Z_stats_t {
+ struct {
+ hsize_t total; /*total number of bytes processed */
+ hsize_t errors; /*bytes of total attributable to errors */
+ H5_timer_t timer; /*execution time including errors */
+ } stats[2]; /*0=output, 1=input */
+} H5Z_stats_t;
+#endif /* H5Z_DEBUG */
+
+/* Enumerated type for dataset creation prelude callbacks */
+typedef enum {
+ H5Z_PRELUDE_CAN_APPLY, /* Call "can apply" callback */
+ H5Z_PRELUDE_SET_LOCAL /* Call "set local" callback */
+} H5Z_prelude_type_t;
+
/* Local variables */
static size_t H5Z_table_alloc_g = 0;
static size_t H5Z_table_used_g = 0;
static H5Z_class_t *H5Z_table_g = NULL;
+#ifdef H5Z_DEBUG
+static H5Z_stats_t *H5Z_stat_table_g = NULL;
+#endif /* H5Z_DEBUG */
/* Local functions */
+static int H5Z_find_idx(H5Z_filter_t id);
/*-------------------------------------------------------------------------
@@ -51,22 +78,31 @@ static H5Z_class_t *H5Z_table_g = NULL;
static herr_t
H5Z_init_interface (void)
{
+ herr_t ret_value=SUCCEED; /* Return value */
+
FUNC_ENTER_NOINIT(H5Z_init_interface);
#ifdef H5_HAVE_FILTER_DEFLATE
- H5Z_register (H5Z_FILTER_DEFLATE, "deflate", H5Z_filter_deflate);
+ if (H5Z_register (H5Z_DEFLATE)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register deflate filter");
#endif /* H5_HAVE_FILTER_DEFLATE */
#ifdef H5_HAVE_FILTER_SHUFFLE
- H5Z_register (H5Z_FILTER_SHUFFLE, "shuffle", H5Z_filter_shuffle);
+ if (H5Z_register (H5Z_SHUFFLE)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register shuffle filter");
#endif /* H5_HAVE_FILTER_SHUFFLE */
#ifdef H5_HAVE_FILTER_FLETCHER32
- H5Z_register (H5Z_FILTER_FLETCHER32, "fletcher32", H5Z_filter_fletcher32);
+ if (H5Z_register (H5Z_FLETCHER32)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register fletcher32 filter");
#endif /* H5_HAVE_FILTER_FLETCHER32 */
#ifdef H5_HAVE_FILTER_SZIP
- H5Z_register (H5Z_FILTER_SZIP, "szip", H5Z_filter_szip);
+ if (H5Z_register (H5Z_SZIP)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register szip filter");
#endif /* H5_HAVE_FILTER_SZIP */
- FUNC_LEAVE_NOAPI(SUCCEED);
+#if (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP)
+done:
+#endif /* (defined H5_HAVE_FILTER_DEFLATE | defined H5_HAVE_FILTER_FLETCHER32 | defined H5_HAVE_FILTER_SHUFFLE | defined H5_HAVE_FILTER_SZIP) */
+ FUNC_LEAVE_NOAPI(ret_value);
}
@@ -98,7 +134,7 @@ H5Z_term_interface (void)
if (H5DEBUG(Z)) {
for (i=0; i<H5Z_table_used_g; i++) {
for (dir=0; dir<2; dir++) {
- if (0==H5Z_table_g[i].stats[dir].total) continue;
+ if (0==H5Z_stat_table_g[i].stats[dir].total) continue;
if (0==nprint++) {
/* Print column headers */
@@ -125,34 +161,35 @@ H5Z_term_interface (void)
* the word `Inf' if the elapsed time is zero.
*/
H5_bandwidth(bandwidth,
- (double)(H5Z_table_g[i].stats[dir].total),
- H5Z_table_g[i].stats[dir].timer.etime);
+ (double)(H5Z_stat_table_g[i].stats[dir].total),
+ H5Z_stat_table_g[i].stats[dir].timer.etime);
/* Print the statistics */
HDfprintf (H5DEBUG(Z),
" %s%-15s %10Hd %10Hd %8.2f %8.2f %8.2f "
"%10s\n", dir?"<":">", comment,
- H5Z_table_g[i].stats[dir].total,
- H5Z_table_g[i].stats[dir].errors,
- H5Z_table_g[i].stats[dir].timer.utime,
- H5Z_table_g[i].stats[dir].timer.stime,
- H5Z_table_g[i].stats[dir].timer.etime,
+ H5Z_stat_table_g[i].stats[dir].total,
+ H5Z_stat_table_g[i].stats[dir].errors,
+ H5Z_stat_table_g[i].stats[dir].timer.utime,
+ H5Z_stat_table_g[i].stats[dir].timer.stime,
+ H5Z_stat_table_g[i].stats[dir].timer.etime,
bandwidth);
}
}
}
-#endif
- /* Free the table */
- for (i=0; i<H5Z_table_used_g; i++) {
- H5MM_xfree(H5Z_table_g[i].name);
- }
+#endif /* H5Z_DEBUG */
+ /* Free the table of filters */
H5Z_table_g = H5MM_xfree(H5Z_table_g);
+#ifdef H5Z_DEBUG
+ H5Z_stat_table_g = H5MM_xfree(H5Z_stat_table_g);
+#endif /* H5Z_DEBUG */
H5Z_table_used_g = H5Z_table_alloc_g = 0;
interface_initialize_g = 0;
}
return 0;
}
+#ifdef H5_WANT_H5_V1_4_COMPAT
/*-------------------------------------------------------------------------
* Function: H5Zregister
@@ -166,13 +203,16 @@ H5Z_term_interface (void)
* Thursday, April 16, 1998
*
* Modifications:
+ * Changed to pass H5Z_class_t struct to H5Z_register
+ * Quincey Koziol, April 5, 2003
*
*-------------------------------------------------------------------------
*/
herr_t
H5Zregister(H5Z_filter_t id, const char *comment, H5Z_func_t func)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ H5Z_class_t cls; /* Filter class used to bundle parameters */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Zregister, FAIL);
H5TRACE3("e","Zfsx",id,comment,func);
@@ -185,13 +225,62 @@ H5Zregister(H5Z_filter_t id, const char *comment, H5Z_func_t func)
if (!func)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no function specified");
+ /* Build class structure */
+ cls.id=id;
+ cls.name=comment;
+ cls.can_apply=cls.set_local=NULL;
+ cls.filter=func;
+
+ /* Do it */
+ if (H5Z_register (&cls)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+}
+#else /* H5_WANT_H5_V1_4_COMPAT */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Zregister
+ *
+ * Purpose: This function registers new filter.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Thursday, April 16, 1998
+ *
+ * Modifications:
+ * Changed to pass in H5Z_class_t struct
+ * Quincey Koziol, April 5, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Zregister(const H5Z_class_t *cls)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Zregister, FAIL);
+
+ /* Check args */
+ if (cls==NULL)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter class");
+ if (cls->id<0 || cls->id>H5Z_FILTER_MAX)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number");
+ if (cls->id<H5Z_FILTER_RESERVED)
+ HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "unable to modify predefined filters");
+ if (cls->filter==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no filter function specified");
+
/* Do it */
- if (H5Z_register (id, comment, func)<0)
+ if (H5Z_register (cls)<0)
HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to register filter");
done:
FUNC_LEAVE_API(ret_value);
}
+#endif /* H5_WANT_H5_V1_4_COMPAT */
/*-------------------------------------------------------------------------
@@ -210,42 +299,54 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_register (H5Z_filter_t id, const char *comment, H5Z_func_t func)
+H5Z_register (const H5Z_class_t *cls)
{
size_t i;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_register, FAIL);
- assert (id>=0 && id<=H5Z_FILTER_MAX);
+ assert (cls);
+ assert (cls->id>=0 && cls->id<=H5Z_FILTER_MAX);
/* Is the filter already registered? */
- for (i=0; i<H5Z_table_used_g; i++) {
- if (H5Z_table_g[i].id==id) break;
- }
+ for (i=0; i<H5Z_table_used_g; i++)
+ if (H5Z_table_g[i].id==cls->id)
+ break;
+
+ /* Filter not already registered */
if (i>=H5Z_table_used_g) {
if (H5Z_table_used_g>=H5Z_table_alloc_g) {
size_t n = MAX(H5Z_MAX_NFILTERS, 2*H5Z_table_alloc_g);
H5Z_class_t *table = H5MM_realloc(H5Z_table_g,
n*sizeof(H5Z_class_t));
+#ifdef H5Z_DEBUG
+ H5Z_stats_t *stat_table = H5MM_realloc(H5Z_stat_table_g,
+ n*sizeof(H5Z_stats_t));
+#endif /* H5Z_DEBUG */
if (!table)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend filter table");
H5Z_table_g = table;
+#ifdef H5Z_DEBUG
+ if (!stat_table)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to extend filter statistics table");
+ H5Z_stat_table_g = stat_table;
+#endif /* H5Z_DEBUG */
H5Z_table_alloc_g = n;
- }
+ } /* end if */
/* Initialize */
i = H5Z_table_used_g++;
- HDmemset(H5Z_table_g+i, 0, sizeof(H5Z_class_t));
- H5Z_table_g[i].id = id;
- H5Z_table_g[i].name = H5MM_xstrdup(comment);
- H5Z_table_g[i].func = func;
- } else {
+ HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class_t));
+#ifdef H5Z_DEBUG
+ HDmemset(H5Z_stat_table_g+i, 0, sizeof(H5Z_stats_t));
+#endif /* H5Z_DEBUG */
+ } /* end if */
+ /* Filter already registered */
+ else {
/* Replace old contents */
- H5MM_xfree(H5Z_table_g[i].name);
- H5Z_table_g[i].name = H5MM_xstrdup(comment);
- H5Z_table_g[i].func = func;
- }
+ HDmemcpy(H5Z_table_g+i, cls, sizeof(H5Z_class_t));
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -310,7 +411,7 @@ H5Z_unregister (H5Z_filter_t id)
size_t i; /* Local index variable */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOINIT(H5Z_unregister);
+ FUNC_ENTER_NOAPI(H5Z_unregister,FAIL);
assert (id>=0 && id<=H5Z_FILTER_MAX);
@@ -326,6 +427,9 @@ H5Z_unregister (H5Z_filter_t id)
/* Remove filter from table */
/* Don't worry about shrinking table size (for now) */
HDmemmove(&H5Z_table_g[i],&H5Z_table_g[i+1],sizeof(H5Z_class_t)*((H5Z_table_used_g-1)-i));
+#ifdef H5Z_DEBUG
+ HDmemmove(&H5Z_stat_table_g[i],&H5Z_stat_table_g[i+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-i));
+#endif /* H5Z_DEBUG */
H5Z_table_used_g--;
done:
@@ -373,6 +477,295 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_prelude_callback
+ *
+ * Purpose: Makes a dataset creation "prelude" callback for the "can_apply"
+ * or "set_local" routines.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 4, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5Z_prelude_callback(hid_t dcpl_id, hid_t type_id, H5Z_prelude_type_t prelude_type)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5Z_prelude_callback);
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Check if the property list is non-default */
+ if(dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ H5P_genplist_t *dc_plist; /* Dataset creation property list object */
+ H5D_layout_t dcpl_layout; /* Dataset's layout information */
+
+ /* Get dataset creation property list object */
+ if (NULL == (dc_plist = H5I_object(dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list");
+
+ /* Get layout information */
+ if(H5P_get(dc_plist, H5D_CRT_LAYOUT_NAME, &dcpl_layout) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve layout");
+
+ /* Check if the dataset is chunked */
+ if(H5D_CHUNKED == dcpl_layout) {
+ H5O_pline_t dcpl_pline; /* Dataset's I/O pipeline information */
+
+ /* Get I/O pipeline information */
+ if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter");
+
+ /* Check if the chunks have filters */
+ if(dcpl_pline.nfilters > 0) {
+ int chunk_ndims; /* # of chunk dimensions */
+ hsize_t chunk_size[H5O_LAYOUT_NDIMS]; /* Size of chunk dimensions */
+ H5S_t *space; /* Dataspace describing chunk */
+ hid_t space_id; /* ID for dataspace describing chunk */
+ size_t u; /* Local index variable */
+
+ /* Get chunk information */
+ if(H5P_get(dc_plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk dimensions");
+ if(H5P_get(dc_plist, H5D_CRT_CHUNK_SIZE_NAME, chunk_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve chunk size");
+
+ /* Create a data space for a chunk & set the extent */
+ if(NULL == (space = H5S_create_simple(chunk_ndims,chunk_size,NULL)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace");
+
+ /* Get ID for dataspace to pass to filter routines */
+ if ((space_id=H5I_register (H5I_DATASPACE, space))<0) {
+ H5S_close(space);
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID");
+ } /* end if */
+
+ /* Iterate over filters */
+ for (u=0; u<dcpl_pline.nfilters; u++) {
+ H5Z_class_t *fclass; /* Individual filter information */
+
+ /* Get filter information */
+ if (NULL==(fclass=H5Z_find(dcpl_pline.filter[u].id))) {
+ /* Ignore errors from optional filters */
+ if (dcpl_pline.filter[u].flags & H5Z_FLAG_OPTIONAL)
+ H5E_clear();
+ else
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "required filter was not located");
+ } /* end if */
+ else {
+ /* Make correct callback */
+ switch(prelude_type) {
+ case H5Z_PRELUDE_CAN_APPLY:
+ /* Check if there is a "can apply" callback */
+ if(fclass->can_apply) {
+ /* Make callback to filter's "can apply" function */
+ herr_t status=(fclass->can_apply)(dcpl_id, type_id, space_id);
+
+ /* Check return value */
+ if(status<=0) {
+ /* We're leaving, so close dataspace */
+ if(H5Sclose(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace");
+
+ /* Indicate filter can't apply to this combination of parameters */
+ if(status==0) {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate");
+ } /* end if */
+ /* Indicate error during filter callback */
+ else {
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "error during user callback");
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5Z_PRELUDE_SET_LOCAL:
+ /* Check if there is a "set local" callback */
+ if(fclass->set_local) {
+ /* Make callback to filter's "set local" function */
+ if((fclass->set_local)(dcpl_id, type_id, space_id)<0) {
+ /* We're leaving, so close dataspace */
+ if(H5Sclose(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace");
+
+ /* Indicate error during filter callback */
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "error during user callback");
+ } /* end if */
+ } /* end if */
+ break;
+
+ default:
+ assert("invalid prelude type" && 0);
+ } /* end switch */
+ } /* end else */
+ } /* end for */
+
+ /* Close dataspace */
+ if(H5Sclose(space_id)<0)
+ HGOTO_ERROR (H5E_PLINE, H5E_CANTRELEASE, FAIL, "unable to close dataspace");
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_prelude_callback() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_can_apply
+ *
+ * Purpose: Checks if all the filters defined in the dataset creation
+ * property list can be applied to a particular combination of
+ * datatype and dataspace for a dataset.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, April 3, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_can_apply (hid_t dcpl_id, hid_t type_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_can_apply,FAIL);
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Make "can apply" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_CAN_APPLY)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "filter parameters not appropriate");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_can_apply() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_set_local
+ *
+ * Purpose: Makes callbacks to modify dataset creation list property
+ * settings for filters on a new dataset, based on the datatype
+ * and dataspace of that dataset (chunk).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 4, 2003
+ *
+ * Notes:
+ * The chunk dimensions are used to create a dataspace, instead
+ * of passing in the dataset's dataspace, since the chunk
+ * dimensions are what the I/O filter will actually see
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_set_local (hid_t dcpl_id, hid_t type_id)
+{
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_set_local,FAIL);
+
+ assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ assert (H5I_DATATYPE==H5I_get_type(type_id));
+
+ /* Make "set local" callbacks for filters in pipeline */
+ if(H5Z_prelude_callback(dcpl_id, type_id, H5Z_PRELUDE_SET_LOCAL)<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_SETLOCAL, FAIL, "local filter parameters not set");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_set_local() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_modify
+ *
+ * Purpose: Modify filter parameters for specified pipeline.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_modify(H5O_pline_t *pline, H5Z_filter_t filter, unsigned flags,
+ size_t cd_nelmts, const unsigned int cd_values[/*cd_nelmts*/])
+{
+ size_t idx; /* Index of filter in pipeline */
+ size_t i; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_modify, FAIL);
+
+ assert(pline);
+ assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+ assert(0==(flags & ~((unsigned)H5Z_FLAG_DEFMASK)));
+ assert(0==cd_nelmts || cd_values);
+
+ /* Locate the filter in the pipeline */
+ for(idx=0; idx<pline->nfilters; idx++)
+ if(pline->filter[idx].id==filter)
+ break;
+
+ /* Check if the filter was not already in the pipeline */
+ if(idx>pline->nfilters)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "filter not in pipeline");
+
+ /* Change parameters for filter */
+ pline->filter[idx].flags = flags;
+ pline->filter[idx].cd_nelmts = cd_nelmts;
+
+ /* Free any existing parameters */
+ if(pline->filter[idx].cd_values!=NULL)
+ H5MM_xfree(pline->filter[idx].cd_values);
+
+ /* Set parameters */
+ if (cd_nelmts>0) {
+ pline->filter[idx].cd_values = H5MM_malloc(cd_nelmts*sizeof(unsigned));
+ if (NULL==pline->filter[idx].cd_values)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for filter parameters");
+ for (i=0; i<cd_nelmts; i++)
+ pline->filter[idx].cd_values[i] = cd_values[i];
+ } /* end if */
+ else
+ pline->filter[idx].cd_values = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_modify() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_append
*
* Purpose: Append another filter to the specified pipeline.
@@ -441,38 +834,74 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Z_find_idx
+ *
+ * Purpose: Given a filter ID return the offset in the global array
+ * that holds all the registered filters.
+ *
+ * Return: Success: Non-negative index of entry in global filter table.
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5Z_find_idx(H5Z_filter_t id)
+{
+ size_t i; /* Local index variable */
+ int ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOINIT(H5Z_find_idx);
+
+ for (i=0; i<H5Z_table_used_g; i++)
+ if (H5Z_table_g[i].id == id)
+ HGOTO_DONE((int)i);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_find_idx() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Z_find
*
* Purpose: Given a filter ID return a pointer to a global struct that
* defines the filter.
*
* Return: Success: Ptr to entry in global filter table.
- *
* Failure: NULL
*
* Programmer: Robb Matzke
* Wednesday, August 5, 1998
*
* Modifications:
+ * Use H5Z_find_idx now
+ * Quincey Koziol, April 5, 2003
*
*-------------------------------------------------------------------------
*/
H5Z_class_t *
H5Z_find(H5Z_filter_t id)
{
- size_t i;
- H5Z_class_t *ret_value=NULL; /* Return value */
+ int idx; /* Filter index in global table */
+ H5Z_class_t *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI(H5Z_find, NULL);
- for (i=0; i<H5Z_table_used_g; i++) {
- if (H5Z_table_g[i].id == id)
- HGOTO_DONE(H5Z_table_g+i);
- }
+ /* Get the index in the global table */
+ if((idx=H5Z_find_idx(id))<0)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, NULL, "required filter is not registered");
+
+ /* Set return value */
+ ret_value=H5Z_table_g+idx;
done:
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* H5Z_find() */
/*-------------------------------------------------------------------------
@@ -504,23 +933,24 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
+H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
unsigned *filter_mask/*in,out*/, H5Z_EDC_t edc_read,
H5Z_cb_t cb_struct, size_t *nbytes/*in,out*/,
size_t *buf_size/*in,out*/, void **buf/*in,out*/)
{
size_t i, idx, new_nbytes;
- H5Z_class_t *fclass=NULL;
- unsigned failed = 0;
- unsigned tmp_flags;
+ int fclass_idx; /* Index of filter class in global table */
+ H5Z_class_t *fclass=NULL; /* Filter class pointer */
#ifdef H5Z_DEBUG
+ H5Z_stats_t *fstats=NULL; /* Filter stats pointer */
H5_timer_t timer;
#endif
+ unsigned failed = 0;
+ unsigned tmp_flags;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5Z_pipeline, FAIL);
- assert(f);
assert(0==(flags & ~((unsigned)H5Z_FLAG_INVMASK)));
assert(filter_mask);
assert(nbytes && *nbytes>0);
@@ -536,22 +966,24 @@ H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
failed |= (unsigned)1 << idx;
continue;/*filter excluded*/
}
- if (NULL==(fclass=H5Z_find(pline->filter[idx].id))) {
+ if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) {
failed |= (unsigned)1 << idx;
HGOTO_ERROR(H5E_PLINE, H5E_READERROR, FAIL, "required filter is not registered");
}
+ fclass=&H5Z_table_g[fclass_idx];
#ifdef H5Z_DEBUG
+ fstats=&H5Z_stat_table_g[fclass_idx];
H5_timer_begin(&timer);
#endif
tmp_flags=flags|(pline->filter[idx].flags);
tmp_flags|=(edc_read== H5Z_DISABLE_EDC) ? H5Z_FLAG_SKIP_EDC : 0;
- new_nbytes = (fclass->func)(tmp_flags, pline->filter[idx].cd_nelmts,
+ new_nbytes = (fclass->filter)(tmp_flags, pline->filter[idx].cd_nelmts,
pline->filter[idx].cd_values, *nbytes, buf_size, buf);
#ifdef H5Z_DEBUG
- H5_timer_end(&(fclass->stats[1].timer), &timer);
- fclass->stats[1].total += MAX(*nbytes, new_nbytes);
- if (0==new_nbytes) fclass->stats[1].errors += *nbytes;
+ H5_timer_end(&(fstats->stats[1].timer), &timer);
+ fstats->stats[1].total += MAX(*nbytes, new_nbytes);
+ if (0==new_nbytes) fstats->stats[1].errors += *nbytes;
#endif
if(0==new_nbytes) {
@@ -572,7 +1004,7 @@ H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
failed |= (unsigned)1 << idx;
continue; /*filter excluded*/
}
- if (NULL==(fclass=H5Z_find(pline->filter[idx].id))) {
+ if ((fclass_idx=H5Z_find_idx(pline->filter[idx].id))<0) {
failed |= (unsigned)1 << idx;
if (pline->filter[idx].flags & H5Z_FLAG_OPTIONAL) {
H5E_clear();
@@ -581,15 +1013,17 @@ H5Z_pipeline(H5F_t UNUSED *f, const H5O_pline_t *pline, unsigned flags,
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "required filter is not registered");
}
}
+ fclass=&H5Z_table_g[fclass_idx];
#ifdef H5Z_DEBUG
+ fstats=&H5Z_stat_table_g[fclass_idx];
H5_timer_begin(&timer);
#endif
- new_nbytes = (fclass->func)(flags|(pline->filter[idx].flags), pline->filter[idx].cd_nelmts,
+ new_nbytes = (fclass->filter)(flags|(pline->filter[idx].flags), pline->filter[idx].cd_nelmts,
pline->filter[idx].cd_values, *nbytes, buf_size, buf);
#ifdef H5Z_DEBUG
- H5_timer_end(&(fclass->stats[0].timer), &timer);
- fclass->stats[0].total += MAX(*nbytes, new_nbytes);
- if (0==new_nbytes) fclass->stats[0].errors += *nbytes;
+ H5_timer_end(&(fstats->stats[0].timer), &timer);
+ fstats->stats[0].total += MAX(*nbytes, new_nbytes);
+ if (0==new_nbytes) fstats->stats[0].errors += *nbytes;
#endif
if(0==new_nbytes) {
if (0==(pline->filter[idx].flags & H5Z_FLAG_OPTIONAL)) {
@@ -616,3 +1050,89 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_filter_info
+ *
+ * Purpose: Get pointer to filter info for pipeline
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Friday, April 5, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5Z_filter_info_t *
+H5Z_filter_info(H5O_pline_t *pline, H5Z_filter_t filter)
+{
+ size_t idx; /* Index of filter in pipeline */
+ H5Z_filter_info_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_filter_info, NULL);
+
+ assert(pline);
+ assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+
+ /* Locate the filter in the pipeline */
+ for(idx=0; idx<pline->nfilters; idx++)
+ if(pline->filter[idx].id==filter)
+ break;
+
+ /* Check if the filter was not already in the pipeline */
+ if(idx>pline->nfilters)
+ HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, NULL, "filter not in pipeline");
+
+ /* Set return value */
+ ret_value=&pline->filter[idx];
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_filter_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_all_filters_avail
+ *
+ * Purpose: Verify that all the filters in a pipeline are currently
+ * available (i.e. registered)
+ *
+ * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, April 8, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Z_all_filters_avail(H5O_pline_t *pline)
+{
+ size_t i,j; /* Local index variable */
+ htri_t ret_value=TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5Z_all_filters_avail, UFAIL);
+
+ /* Check args */
+ assert(pline);
+
+ /* Iterate through all the filters in pipeline */
+ for(i=0; i<pline->nfilters; i++) {
+
+ /* Look for each filter in the list of registered filters */
+ for(j=0; j<H5Z_table_used_g; j++)
+ if(H5Z_table_g[j].id==pline->filter[i].id)
+ break;
+
+ /* Check if we didn't find the filter */
+ if(j==H5Z_table_used_g)
+ HGOTO_DONE(FALSE);
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5Z_all_filters_avail() */
+