diff options
Diffstat (limited to 'src/H5Dint.c')
-rw-r--r-- | src/H5Dint.c | 173 |
1 files changed, 57 insertions, 116 deletions
diff --git a/src/H5Dint.c b/src/H5Dint.c index 6d3f4a3..cc17265 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -139,9 +139,6 @@ static const H5I_class_t H5I_DATASET_CLS[1] = {{ (H5I_free_t)H5D__close_cb /* Callback routine for closing objects of this class */ }}; -/* Flag indicating "top" of interface has been initialized */ -static hbool_t H5D_top_package_initialize_s = FALSE; - /* Prefixes of VDS and external file from the environment variables * HDF5_EXTFILE_PREFIX and HDF5_VDS_PREFIX */ static const char *H5D_prefix_ext_env = NULL; @@ -160,37 +157,10 @@ static const char *H5D_prefix_vds_env = NULL; herr_t H5D_init(void) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(FAIL) - /* FUNC_ENTER() does all the work */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_init() */ - -/*-------------------------------------------------------------------------- -NAME - H5D__init_package -- Initialize interface-specific information -USAGE - herr_t H5D__init_package() - -RETURNS - Non-negative on success/Negative on failure -DESCRIPTION - Initializes any interface-specific data or routines. -NOTES - Care must be taken when using the H5P functions, since they can cause - a deadlock in the library when the library is attempting to terminate -QAK - ---------------------------------------------------------------------------*/ -herr_t -H5D__init_package(void) -{ H5P_genplist_t *def_dcpl; /* Default Dataset Creation Property list */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_PACKAGE + FUNC_ENTER_NOAPI(FAIL) /* Initialize the ID group for the dataset IDs */ if (H5I_register_type(H5I_DATASET_CLS) < 0) @@ -220,16 +190,13 @@ H5D__init_package(void) if (H5P_get(def_dcpl, H5O_CRT_PIPELINE_NAME, &H5D_def_dset.dcpl_cache.pline) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve pipeline filter") - /* Mark "top" of interface as initialized, too */ - H5D_top_package_initialize_s = TRUE; - /* Retrieve the prefixes of VDS and external file from the environment variable */ H5D_prefix_vds_env = HDgetenv("HDF5_VDS_PREFIX"); H5D_prefix_ext_env = HDgetenv("HDF5_EXTFILE_PREFIX"); done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D__init_package() */ +} /* end H5D_init() */ /*------------------------------------------------------------------------- * Function: H5D_top_term_package @@ -248,38 +215,32 @@ H5D_top_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5D_top_package_initialize_s) { - if (H5I_nmembers(H5I_DATASET) > 0) { - /* The dataset API uses the "force" flag set to true because it - * is using the "file objects" (H5FO) API functions to track open - * objects in the file. Using the H5FO code means that dataset - * IDs can have reference counts >1, when an existing dataset is - * opened more than once. However, the H5I code does not attempt - * to close objects with reference counts>1 unless the "force" flag - * is set to true. - * - * At some point (probably after the group and datatypes use the - * the H5FO code), the H5FO code might need to be switched around - * to storing pointers to the objects being tracked (H5D_t, H5G_t, - * etc) and reference count those itself instead of relying on the - * reference counting in the H5I layer. Then, the "force" flag can - * be put back to false. - * - * Setting the "force" flag to true for all the interfaces won't - * work because the "file driver" (H5FD) APIs use the H5I reference - * counting to avoid closing a file driver out from underneath an - * open file... - * - * QAK - 5/13/03 - */ - (void)H5I_clear_type(H5I_DATASET, TRUE, FALSE); - n++; /*H5I*/ - } /* end if */ - - /* Mark closed */ - if (0 == n) - H5D_top_package_initialize_s = FALSE; - } /* end if */ + if (H5I_nmembers(H5I_DATASET) > 0) { + /* The dataset API uses the "force" flag set to true because it + * is using the "file objects" (H5FO) API functions to track open + * objects in the file. Using the H5FO code means that dataset + * IDs can have reference counts >1, when an existing dataset is + * opened more than once. However, the H5I code does not attempt + * to close objects with reference counts>1 unless the "force" flag + * is set to true. + * + * At some point (probably after the group and datatypes use the + * the H5FO code), the H5FO code might need to be switched around + * to storing pointers to the objects being tracked (H5D_t, H5G_t, + * etc) and reference count those itself instead of relying on the + * reference counting in the H5I layer. Then, the "force" flag can + * be put back to false. + * + * Setting the "force" flag to true for all the interfaces won't + * work because the "file driver" (H5FD) APIs use the H5I reference + * counting to avoid closing a file driver out from underneath an + * open file... + * + * QAK - 5/13/03 + */ + (void)H5I_clear_type(H5I_DATASET, TRUE, FALSE); + n++; /*H5I*/ + } FUNC_LEAVE_NOAPI(n) } /* end H5D_top_term_package() */ @@ -304,18 +265,11 @@ H5D_term_package(void) FUNC_ENTER_NOAPI_NOINIT_NOERR - if (H5_PKG_INIT_VAR) { - /* Sanity checks */ - HDassert(0 == H5I_nmembers(H5I_DATASET)); - HDassert(FALSE == H5D_top_package_initialize_s); - - /* Destroy the dataset object id group */ - n += (H5I_dec_type_ref(H5I_DATASET) > 0); + /* Sanity checks */ + HDassert(0 == H5I_nmembers(H5I_DATASET)); - /* Mark closed */ - if (0 == n) - H5_PKG_INIT_VAR = FALSE; - } /* end if */ + /* Destroy the dataset object id group */ + n += (H5I_dec_type_ref(H5I_DATASET) > 0); FUNC_LEAVE_NOAPI(n) } /* end H5D_term_package() */ @@ -410,7 +364,7 @@ done: * * Return: * Success: Non-negative - * Failture: Negative + * Failure: Negative *------------------------------------------------------------------------- */ herr_t @@ -424,40 +378,18 @@ H5D__get_space_status(const H5D_t *dset, H5D_space_status_t *allocation) /* Check for chunked layout */ if (dset->shared->layout.type == H5D_CHUNKED) { - hsize_t space_allocated; /* The number of bytes allocated for chunks */ - hssize_t snelmts; /* Temporary holder for number of elements in dataspace */ - hsize_t nelmts; /* Number of elements in dataspace */ - size_t dt_size; /* Size of datatype */ - hsize_t full_size; /* The number of bytes in the dataset when fully populated */ - - /* For chunked layout set the space status by the storage size */ - /* Get the dataset's dataspace */ - HDassert(dset->shared->space); - - /* Get the total number of elements in dataset's dataspace */ - if ((snelmts = H5S_GET_EXTENT_NPOINTS(dset->shared->space)) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve number of elements in dataspace") - nelmts = (hsize_t)snelmts; - - /* Get the size of the dataset's datatype */ - if (0 == (dt_size = H5T_GET_SIZE(dset->shared->type))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to retrieve size of datatype") - - /* Compute the maximum size of the dataset in bytes */ - full_size = nelmts * dt_size; - - /* Check for overflow during multiplication */ - if (nelmts != (full_size / dt_size)) - HGOTO_ERROR(H5E_DATASET, H5E_OVERFLOW, FAIL, "size of dataset's storage overflowed") - - /* Difficult to error check, since the error value is 0 and 0 is a valid value... :-/ */ - if (H5D__get_storage_size(dset, &space_allocated) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get size of dataset's storage") - - /* Decide on how much of the space is allocated */ - if (space_allocated == 0) + hsize_t n_chunks_total = dset->shared->layout.u.chunk.nchunks; + hsize_t n_chunks_alloc = 0; + + if (H5D__get_num_chunks(dset, dset->shared->space, &n_chunks_alloc) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, + "unable to retrieve number of allocated chunks in dataset") + + HDassert(n_chunks_alloc <= n_chunks_total); + + if (n_chunks_alloc == 0) *allocation = H5D_SPACE_STATUS_NOT_ALLOCATED; - else if (space_allocated == full_size) + else if (n_chunks_alloc == n_chunks_total) *allocation = H5D_SPACE_STATUS_ALLOCATED; else *allocation = H5D_SPACE_STATUS_PART_ALLOCATED; @@ -757,7 +689,7 @@ H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr) H5T_t * type = NULL; H5O_fill_t *fill_prop = NULL; hbool_t use_at_least_v18 = FALSE; - const char continuation[1] = ""; /* requred for work-around */ + const char continuation[1] = ""; /* required for work-around */ size_t get_value = 0; size_t ret_value = 0; @@ -804,7 +736,7 @@ H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't get size of continuation message") ret_value += get_value; - /* Fill Value (backwards compatability) message size */ + /* Fill Value (backwards compatibility) message size */ if (fill_prop->buf && !use_at_least_v18) { H5O_fill_t old_fill_prop; /* Copy for writing "old" fill value */ @@ -893,7 +825,7 @@ H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc) if (ohdr_size == 0) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "computed header size is invalid") - /* Special allocation of space for compact datsets is handled by the call here. */ + /* Special allocation of space for compact datasets is handled by the call here. */ if (H5O_apply_ohdr(file, oh, dset->shared->dcpl_id, ohdr_size, (size_t)1, oloc) == FAIL) HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "can't apply object header to file") @@ -1347,10 +1279,19 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest indexing") } /* end if */ - /* Check if this dataset is going into a parallel file and set space allocation time */ + /* Check if the file driver would like to force early space allocation */ if (H5F_HAS_FEATURE(file, H5FD_FEAT_ALLOCATE_EARLY)) new_dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY; + /* + * Check if this dataset is going into a parallel file and set space allocation time. + * If the dataset has filters applied to it, writes to the dataset must be collective, + * so we don't need to force early space allocation. Otherwise, we force early space + * allocation to facilitate independent raw data operations. + */ + if (H5F_HAS_FEATURE(file, H5FD_FEAT_HAS_MPI) && (new_dset->shared->dcpl_cache.pline.nused == 0)) + new_dset->shared->dcpl_cache.fill.alloc_time = H5D_ALLOC_TIME_EARLY; + /* Set the dataset's I/O operations */ if (H5D__layout_set_io_ops(new_dset) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize I/O operations") |