summaryrefslogtreecommitdiffstats
path: root/src/H5Z.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Z.c')
-rw-r--r--src/H5Z.c372
1 files changed, 250 insertions, 122 deletions
diff --git a/src/H5Z.c b/src/H5Z.c
index 5d68c25..d415060 100644
--- a/src/H5Z.c
+++ b/src/H5Z.c
@@ -46,15 +46,17 @@ typedef struct H5Z_stats_t {
} H5Z_stats_t;
#endif /* H5Z_DEBUG */
+typedef struct H5Z_object_t {
+ H5Z_filter_t filter_id; /* ID of the filter we're looking for */
+ htri_t found; /* Whether we find an object using the filter */
+} H5Z_object_t;
+
/* 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;
-/* Maximal number of the list of opened objects (2^16) */
-#define NUM_OBJS 65536
-
/* Local variables */
static size_t H5Z_table_alloc_g = 0;
static size_t H5Z_table_used_g = 0;
@@ -65,6 +67,9 @@ static H5Z_stats_t *H5Z_stat_table_g = NULL;
/* Local functions */
static int H5Z_find_idx(H5Z_filter_t id);
+static int H5Z__check_unregister_dset_cb(void *obj_ptr, hid_t obj_id, void *key);
+static int H5Z__check_unregister_group_cb(void *obj_ptr, hid_t obj_id, void *key);
+static int H5Z__flush_file_cb(void *obj_ptr, hid_t obj_id, void *key);
/*-------------------------------------------------------------------------
@@ -364,8 +369,6 @@ done:
* Programmer: Quincey Koziol
* Thursday, November 14, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -377,14 +380,14 @@ H5Zunregister(H5Z_filter_t id)
H5TRACE1("e", "Zf", id);
/* Check args */
- if (id<0 || id>H5Z_FILTER_MAX)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number")
- if (id<H5Z_FILTER_RESERVED)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "unable to modify predefined filters")
+ if(id < 0 || id > H5Z_FILTER_MAX)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid filter identification number")
+ if(id < H5Z_FILTER_RESERVED)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to modify predefined filters")
/* Do it */
- if (H5Z_unregister (id)<0)
- HGOTO_ERROR (H5E_PLINE, H5E_CANTINIT, FAIL, "unable to unregister filter")
+ if(H5Z_unregister(id) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTINIT, FAIL, "unable to unregister filter")
done:
FUNC_LEAVE_API(ret_value)
@@ -402,29 +405,18 @@ done:
* Programmer: Quincey Koziol
* Thursday, November 14, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5Z_unregister (H5Z_filter_t filter_id)
+H5Z_unregister(H5Z_filter_t filter_id)
{
- hid_t *file_list = NULL;
- hid_t *obj_id_list = NULL;
- size_t num_obj_id = 0;
- size_t num_file_id = 0;
- H5F_t *f = NULL; /* File to query */
- H5I_type_t id_type;
- hid_t ocpl_id;
- H5P_genplist_t *plist; /* Property list */
- size_t filter_index; /* Local index variable for filter */
- int i;
- htri_t filter_in_pline = FALSE;
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t filter_index; /* Local index variable for filter */
+ H5Z_object_t object;
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
- assert (filter_id>=0 && filter_id<=H5Z_FILTER_MAX);
+ HDassert(filter_id>=0 && filter_id<=H5Z_FILTER_MAX);
/* Is the filter already registered? */
for (filter_index=0; filter_index<H5Z_table_used_g; filter_index++)
@@ -435,107 +427,214 @@ H5Z_unregister (H5Z_filter_t filter_id)
if (filter_index>=H5Z_table_used_g)
HGOTO_ERROR(H5E_PLINE, H5E_NOTFOUND, FAIL, "filter is not registered")
- /* Count the number of opened datasets and groups among all opened files */
- if(H5F_get_obj_count(NULL, H5F_OBJ_DATASET | H5F_OBJ_GROUP, FALSE, &num_obj_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object number")
+ /* Initialize the structure object for iteration */
+ object.filter_id = filter_id;
+ object.found = FALSE;
- if(num_obj_id) {
- if(NULL == (obj_id_list = (hid_t *)H5MM_malloc(num_obj_id*sizeof(hid_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "failed to allocate space")
+ /* Iterate through all opened datasets, returns a failure if any of them uses the filter */
+ if(H5I_iterate(H5I_DATASET, H5Z__check_unregister_dset_cb, &object, FALSE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed")
- /* Find all opened objects that may use the filter (datasets and groups). Passing NULL as a pointer to
- * file structure indicates searching among all opened files */
- if(H5F_get_obj_ids(NULL, H5F_OBJ_DATASET | H5F_OBJ_GROUP, num_obj_id, obj_id_list, FALSE, &num_obj_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get object IDs")
- }
+ if(object.found)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "can't unregister filter because a dataset is still using it")
- /* Check if any opened object (dataset or group) uses the filter. If so, fail with a message */
- for(i=0; i<num_obj_id; i++) {
- if((id_type = H5I_get_type(obj_id_list[i])) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "bad object id");
+ /* Iterate through all opened groups, returns a failure if any of them uses the filter */
+ if(H5I_iterate(H5I_GROUP, H5Z__check_unregister_group_cb, &object, FALSE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed")
- switch(id_type) {
- case H5I_GROUP:
- {
- H5G_t *group = NULL;
+ if(object.found)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTRELEASE, FAIL, "can't unregister filter because a group is still using it")
- if(NULL == (group = (H5G_t *)H5I_object_verify(obj_id_list[i], H5I_GROUP)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+ /* Iterate through all opened files and flush them */
+ if(H5I_iterate(H5I_FILE, H5Z__flush_file_cb, NULL, FALSE) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADITER, FAIL, "iteration failed")
+
+ /* Remove filter from table */
+ /* Don't worry about shrinking table size (for now) */
+ HDmemmove(&H5Z_table_g[filter_index],&H5Z_table_g[filter_index+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-filter_index));
+#ifdef H5Z_DEBUG
+ HDmemmove(&H5Z_stat_table_g[filter_index],&H5Z_stat_table_g[filter_index+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-filter_index));
+#endif /* H5Z_DEBUG */
+ H5Z_table_used_g--;
- if((ocpl_id = H5G_get_create_plist(group)) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get group creation property list")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_unregister() */
- }
- break;
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z__check_unregister
+ *
+ * Purpose: Check if an object uses the filter to be unregistered.
+ *
+ * Return: TRUE if the object uses the filter.
+ * FALSE if not, NEGATIVE on error.
+ *
+ * Programmer: Quincey Koziol
+ * 11 May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5Z__check_unregister(hid_t ocpl_id, H5Z_filter_t filter_id)
+{
+ H5P_genplist_t *plist; /* Property list */
+ htri_t ret_value = FALSE; /* Return value */
- case H5I_DATASET:
- {
- H5D_t *dataset = NULL;
+ FUNC_ENTER_STATIC
- if(NULL == (dataset = (H5D_t *)H5I_object_verify(obj_id_list[i], H5I_DATASET)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+ /* Get the plist structure of object creation */
+ if(NULL == (plist = H5P_object_verify(ocpl_id, H5P_OBJECT_CREATE)))
+ HGOTO_ERROR(H5E_PLINE, H5E_BADATOM, FAIL, "can't find object for ID")
- if((ocpl_id = H5D_get_create_plist(dataset)) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get dataset creation property list")
- }
- break;
+ /* Check if the object creation property list uses the filter */
+ if((ret_value = H5P_filter_in_pline(plist, filter_id)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't check filter in pipeline")
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object")
- } /* end switch */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z__check_unregister() */
- /* Get the plist structure of object creation */
- if(NULL == (plist = H5P_object_verify(ocpl_id, H5P_OBJECT_CREATE)))
- HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z__check_unregister_group_cb
+ *
+ * Purpose: The callback function for H5Z_unregister. It iterates
+ * through all opened objects. If the object is a dataset
+ * or a group and it uses the filter to be unregistered, the
+ * function returns TRUE.
+ *
+ * Return: TRUE if the object uses the filter.
+ * FALSE otherwise.
+ *
+ * Programmer: Raymond Lu
+ * 6 May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5Z__check_unregister_group_cb(void *obj_ptr, hid_t UNUSED obj_id, void *key)
+{
+ hid_t ocpl_id = -1;
+ H5Z_object_t *object = (H5Z_object_t *)key;
+ htri_t filter_in_pline = FALSE;
+ int ret_value = FALSE; /* Return value */
- /* Check if the object creation property list uses the filter */
- if((filter_in_pline = H5P_filter_in_pline(plist, filter_id)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't check filter in pipeline")
-
- if(filter_in_pline)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't unregister filter because some object is still using it")
- }
+ FUNC_ENTER_STATIC
- /* Count the number of opened files */
- if(H5F_get_obj_count(NULL, H5F_OBJ_FILE, FALSE, &num_file_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file number")
-
- /* Get the list of IDs for all opened files */
- if(num_file_id) {
- if(NULL == (file_list = (hid_t *)H5MM_malloc(num_file_id*sizeof(hid_t))))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "failed to allocate space")
-
- if(H5F_get_obj_ids(NULL, H5F_OBJ_FILE, num_file_id, file_list, FALSE, &num_file_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL, "can't get file IDs")
- }
+ HDassert(obj_ptr);
- /* Flush all opened files in case any file uses the filter */
- for(i=0; i<num_file_id; i++) {
- if(NULL == (f = (H5F_t *)H5I_object_verify(file_list[i], H5I_FILE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
+ /* Get the group creation property */
+ if((ocpl_id = H5G_get_create_plist((H5G_t *)obj_ptr)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't get group creation property list")
- /* Call the flush routine for mounted file hierarchies. Do a global flush
- * if the file is opened for write */
- if(H5F_ACC_RDWR & H5F_INTENT(f)) {
- if(H5F_flush_mounts(f, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush file hierarchy")
- } /* end if */
- }
+ /* Check if the filter is in the group creation property list */
+ if((filter_in_pline = H5Z__check_unregister(ocpl_id, object->filter_id)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't check filter in pipeline")
- /* Remove filter from table */
- /* Don't worry about shrinking table size (for now) */
- HDmemmove(&H5Z_table_g[filter_index],&H5Z_table_g[filter_index+1],sizeof(H5Z_class2_t)*((H5Z_table_used_g-1)-filter_index));
-#ifdef H5Z_DEBUG
- HDmemmove(&H5Z_stat_table_g[filter_index],&H5Z_stat_table_g[filter_index+1],sizeof(H5Z_stats_t)*((H5Z_table_used_g-1)-filter_index));
-#endif /* H5Z_DEBUG */
- H5Z_table_used_g--;
+ /* H5I_iterate expects TRUE to stop the loop over objects. Stop the loop and
+ * let H5Z_unregister return failure.
+ */
+ if(filter_in_pline) {
+ object->found = TRUE;
+ ret_value = TRUE;
+ } /* end if */
done:
- if(file_list) H5MM_free(file_list);
- if(obj_id_list) H5MM_free(obj_id_list);
+ if(ocpl_id > 0)
+ if(H5I_dec_app_ref(ocpl_id) < 0)
+ HDONE_ERROR(H5E_PLINE, H5E_CANTDEC, FAIL, "can't release plist")
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5Z_unregister() */
+} /* end H5Z__check_unregister_group_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z__check_unregister_dset_cb
+ *
+ * Purpose: The callback function for H5Z_unregister. It iterates
+ * through all opened objects. If the object is a dataset
+ * or a group and it uses the filter to be unregistered, the
+ * function returns TRUE.
+ *
+ * Return: TRUE if the object uses the filter.
+ * FALSE otherwise.
+ *
+ * Programmer: Raymond Lu
+ * 6 May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5Z__check_unregister_dset_cb(void *obj_ptr, hid_t UNUSED obj_id, void *key)
+{
+ hid_t ocpl_id = -1;
+ H5Z_object_t *object = (H5Z_object_t *)key;
+ htri_t filter_in_pline = FALSE;
+ int ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ HDassert(obj_ptr);
+
+ /* Get the dataset creation property */
+ if((ocpl_id = H5D_get_create_plist((H5D_t *)obj_ptr)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't get dataset creation property list")
+
+ /* Check if the filter is in the dataset creation property list */
+ if((filter_in_pline = H5Z__check_unregister(ocpl_id, object->filter_id)) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "can't check filter in pipeline")
+
+ /* H5I_iterate expects TRUE to stop the loop over objects. Stop the loop and
+ * let H5Z_unregister return failure.
+ */
+ if(filter_in_pline) {
+ object->found = TRUE;
+ ret_value = TRUE;
+ } /* end if */
+
+done:
+ if(ocpl_id > 0)
+ if(H5I_dec_app_ref(ocpl_id) < 0)
+ HDONE_ERROR(H5E_PLINE, H5E_CANTDEC, FAIL, "can't release plist")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z__check_unregister_dset_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z__flush_file_cb
+ *
+ * Purpose: The callback function for H5Z_unregister. It iterates
+ * through all opened files and flush them.
+ *
+ * Return: FALSE if finishes flushing and moves on
+ * FAIL if there is an error
+ *
+ * Programmer: Raymond Lu
+ * 6 May 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5Z__flush_file_cb(void *obj_ptr, hid_t UNUSED obj_id, void UNUSED *key)
+{
+ int ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ HDassert(obj_ptr);
+
+ /* Call the flush routine for mounted file hierarchies. Do a global flush
+ * if the file is opened for write */
+ if(H5F_ACC_RDWR & H5F_INTENT((H5F_t *)obj_ptr)) {
+ if(H5F_flush_mounts((H5F_t *)obj_ptr, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTFLUSH, FAIL, "unable to flush file hierarchy")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z__flush_file_cb() */
/*-------------------------------------------------------------------------
@@ -1203,12 +1302,12 @@ H5Z_pipeline(const H5O_pline_t *pline, unsigned flags,
FUNC_ENTER_NOAPI(FAIL)
- assert(0==(flags & ~((unsigned)H5Z_FLAG_INVMASK)));
- assert(filter_mask);
- assert(nbytes && *nbytes>0);
- assert(buf_size && *buf_size>0);
- assert(buf && *buf);
- assert(!pline || pline->nused<H5Z_MAX_NFILTERS);
+ HDassert(0==(flags & ~((unsigned)H5Z_FLAG_INVMASK)));
+ HDassert(filter_mask);
+ HDassert(nbytes && *nbytes>0);
+ HDassert(buf_size && *buf_size>0);
+ HDassert(buf && *buf);
+ HDassert(!pline || pline->nused<H5Z_MAX_NFILTERS);
if (pline && (flags & H5Z_FLAG_REVERSE)) { /* Read */
for (i=pline->nused; i>0; --i) {
@@ -1358,8 +1457,8 @@ H5Z_filter_info(const H5O_pline_t *pline, H5Z_filter_t filter)
FUNC_ENTER_NOAPI(NULL)
- assert(pline);
- assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+ HDassert(pline);
+ HDassert(filter>=0 && filter<=H5Z_FILTER_MAX);
/* Locate the filter in the pipeline */
for(idx=0; idx<pline->nused; idx++)
@@ -1403,8 +1502,8 @@ H5Z_filter_in_pline(const H5O_pline_t *pline, H5Z_filter_t filter)
FUNC_ENTER_NOAPI(FAIL)
- assert(pline);
- assert(filter>=0 && filter<=H5Z_FILTER_MAX);
+ HDassert(pline);
+ HDassert(filter>=0 && filter<=H5Z_FILTER_MAX);
/* Locate the filter in the pipeline */
for(idx=0; idx<pline->nused; idx++)
@@ -1445,7 +1544,7 @@ H5Z_all_filters_avail(const H5O_pline_t *pline)
FUNC_ENTER_NOAPI(FAIL)
/* Check args */
- assert(pline);
+ HDassert(pline);
/* Iterate through all the filters in pipeline */
for(i=0; i<pline->nused; i++) {
@@ -1567,15 +1666,44 @@ done:
herr_t
H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags)
{
- H5Z_class2_t *fclass;
herr_t ret_value = SUCCEED;
FUNC_ENTER_API(FAIL)
H5TRACE2("e", "Zf*Iu", filter, filter_config_flags);
+ /* Get the filter info */
+ if(H5Z_get_filter_info(filter, filter_config_flags) < 0)
+ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "Filter info not retrieved")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Zget_filter_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Z_get_filter_info
+ *
+ * Purpose: Gets information about a pipeline data filter and stores it
+ * in filter_config_flags.
+ *
+ * Return: zero on success / negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, May 11, 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Z_get_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags)
+{
+ H5Z_class2_t *fclass;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
/* Look up the filter class info */
if(NULL == (fclass = H5Z_find(filter)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Filter not defined")
+ HGOTO_ERROR(H5E_PLINE, H5E_BADVALUE, FAIL, "Filter not defined")
/* Set the filter config flags for the application */
if(filter_config_flags != NULL) {
@@ -1588,6 +1716,6 @@ H5Zget_filter_info(H5Z_filter_t filter, unsigned int *filter_config_flags)
} /* end if */
done:
- FUNC_LEAVE_API(ret_value)
-} /* end H5Zget_filter_info() */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5Z_get_filter_info() */