diff options
author | Quincey Koziol <koziol@lbl.gov> | 2019-08-04 23:38:36 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@lbl.gov> | 2019-08-04 23:38:36 (GMT) |
commit | 5fe1216a4e6af8feef0551f7bece8a0e193310a9 (patch) | |
tree | 357b147c218af566ce2cf8c6ef9c210d98b7829f /src | |
parent | ab1ce69900caa0b249e07db8992e66f95b0af1dc (diff) | |
parent | 905d40aa6f6eb603c5507e7967130760e3a2e43c (diff) | |
download | hdf5-5fe1216a4e6af8feef0551f7bece8a0e193310a9.zip hdf5-5fe1216a4e6af8feef0551f7bece8a0e193310a9.tar.gz hdf5-5fe1216a4e6af8feef0551f7bece8a0e193310a9.tar.bz2 |
Merge pull request #1819 in HDFFV/hdf5 from ~KOZIOL/hdf5:develop to develop
* commit '905d40aa6f6eb603c5507e7967130760e3a2e43c':
Fix return type for H5Sselect_intersect_block().
Updated H5TRACE macro.
Add H5Sselect_shape_same and H5Sselect_intersect_block API routines, along with tests and minor cleanups and refactorings.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dchunk.c | 10 | ||||
-rw-r--r-- | src/H5Dio.c | 4 | ||||
-rw-r--r-- | src/H5Fint.c | 2 | ||||
-rw-r--r-- | src/H5Pdcpl.c | 4 | ||||
-rw-r--r-- | src/H5Sall.c | 48 | ||||
-rw-r--r-- | src/H5Shyper.c | 114 | ||||
-rw-r--r-- | src/H5Snone.c | 51 | ||||
-rw-r--r-- | src/H5Spkg.h | 13 | ||||
-rw-r--r-- | src/H5Spoint.c | 76 | ||||
-rw-r--r-- | src/H5Sprivate.h | 14 | ||||
-rw-r--r-- | src/H5Spublic.h | 3 | ||||
-rw-r--r-- | src/H5Sselect.c | 169 | ||||
-rw-r--r-- | src/H5Stest.c | 44 |
13 files changed, 400 insertions, 152 deletions
diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 7a07225..ec8ea4d 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -1245,7 +1245,7 @@ H5D__chunk_io_init(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf } /* end else */ /* Build the memory selection for each chunk */ - if(sel_hyper_flag && H5S_select_shape_same(file_space, mem_space) == TRUE) { + if(sel_hyper_flag && H5S_SELECT_SHAPE_SAME(file_space, mem_space) == TRUE) { /* Reset chunk template information */ fm->mchunk_tmpl = NULL; @@ -1811,7 +1811,7 @@ H5D__create_chunk_file_map_hyper(H5D_chunk_map_t *fm, const H5D_io_info_t while(sel_points) { /* Check for intersection of current chunk and file selection */ /* (Casting away const OK - QAK) */ - if(TRUE == H5S_hyper_intersect_block((H5S_t *)fm->file_space, coords, end)) { + if(TRUE == H5S_SELECT_INTERSECT_BLOCK(fm->file_space, coords, end)) { H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into skip list */ hssize_t schunk_points; /* Number of elements in chunk selection */ @@ -2030,12 +2030,8 @@ H5D__create_chunk_mem_map_hyper(const H5D_chunk_map_t *fm) /* Sanity check */ HDassert(H5S_SEL_HYPERSLABS == chunk_sel_type); - /* Release the current selection */ - if(H5S_SELECT_RELEASE(chunk_info->mspace) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection") - /* Copy the file chunk's selection */ - if(H5S_select_copy(chunk_info->mspace, chunk_info->fspace, FALSE) < 0) + if(H5S_SELECT_COPY(chunk_info->mspace, chunk_info->fspace, FALSE) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy selection") /* Compute the adjustment for this chunk */ diff --git a/src/H5Dio.c b/src/H5Dio.c index 9343b80..cdb73e3 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -490,7 +490,7 @@ H5D__read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, * Note that in general, this requires us to touch up the memory buffer as * well. */ - if(TRUE == H5S_select_shape_same(mem_space, file_space) && + if(TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ @@ -725,7 +725,7 @@ H5D__write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space, * Note that in general, this requires us to touch up the memory buffer * as well. */ - if(TRUE == H5S_select_shape_same(mem_space, file_space) && + if(TRUE == H5S_SELECT_SHAPE_SAME(mem_space, file_space) && H5S_GET_EXTENT_NDIMS(mem_space) != H5S_GET_EXTENT_NDIMS(file_space)) { void *adj_buf = NULL; /* Pointer to the location in buf corresponding */ /* to the beginning of the projected mem space. */ diff --git a/src/H5Fint.c b/src/H5Fint.c index 758900b..7ed3ca8 100644 --- a/src/H5Fint.c +++ b/src/H5Fint.c @@ -868,7 +868,7 @@ H5F__is_hdf5(const char *name, hid_t fapl_id) /* The file is an hdf5 file if the hdf5 file signature can be found */ if(H5FD_locate_signature(file, &sig_addr) < 0) - HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "unable to locate file signature") + HGOTO_ERROR(H5E_FILE, H5E_NOTHDF5, FAIL, "error while trying to locate file signature") ret_value = (HADDR_UNDEF != sig_addr); done: diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 6b9edf1..721ba89 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -827,7 +827,7 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, if((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1) if(!equal) HGOTO_DONE(1) - if((equal = H5S_select_shape_same(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1) + if((equal = H5S_SELECT_SHAPE_SAME(layout1->storage.u.virt.list[u].source_dset.virtual_select, layout2->storage.u.virt.list[u].source_dset.virtual_select)) < 0) HGOTO_DONE(-1) if(!equal) HGOTO_DONE(1) @@ -847,7 +847,7 @@ H5P__dcrt_layout_cmp(const void *_layout1, const void *_layout2, if((equal = H5S_extent_equal(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1) if(!equal) HGOTO_DONE(1) - if((equal = H5S_select_shape_same(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1) + if((equal = H5S_SELECT_SHAPE_SAME(layout1->storage.u.virt.list[u].source_select, layout2->storage.u.virt.list[u].source_select)) < 0) HGOTO_DONE(-1) if(!equal) HGOTO_DONE(1) } /* end for */ diff --git a/src/H5Sall.c b/src/H5Sall.c index fbe7041..9d0a65a 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -28,11 +28,11 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Iprivate.h" /* ID Functions */ -#include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* ID Functions */ +#include "H5Spkg.h" /* Dataspace functions */ +#include "H5VMprivate.h" /* Vector functions */ /****************/ @@ -63,6 +63,8 @@ static htri_t H5S__all_is_contiguous(const H5S_t *space); static htri_t H5S__all_is_single(const H5S_t *space); static htri_t H5S__all_is_regular(const H5S_t *space); static htri_t H5S__all_shape_same(const H5S_t *space1, const H5S_t *space2); +static htri_t H5S__all_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end); static herr_t H5S__all_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__all_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__all_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); @@ -108,6 +110,7 @@ const H5S_select_class_t H5S_sel_all[1] = {{ H5S__all_is_single, H5S__all_is_regular, H5S__all_shape_same, + H5S__all_intersect_block, H5S__all_adjust_u, H5S__all_project_scalar, H5S__all_project_simple, @@ -976,6 +979,41 @@ done: /*-------------------------------------------------------------------------- NAME + H5S__all_intersect_block + PURPOSE + Detect intersections of selection with block + USAGE + htri_t H5S__all_intersect_block(space, start, end) + const H5S_t *space; IN: Dataspace with selection to use + const hsize_t *start; IN: Starting coordinate for block + const hsize_t *end; IN: Ending coordinate for block + RETURNS + Non-negative TRUE / FALSE on success, negative on failure + DESCRIPTION + Quickly detect intersections with a block + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S__all_intersect_block(const H5S_t H5_ATTR_UNUSED *space, + const hsize_t H5_ATTR_UNUSED *start, const hsize_t H5_ATTR_UNUSED *end) +{ + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(space); + HDassert(H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space)); + HDassert(start); + HDassert(end); + + FUNC_LEAVE_NOAPI(TRUE) +} /* end H5S__all_intersect_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__all_adjust_u PURPOSE Adjust an "all" selection by subtracting an offset diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 2acc135..492cd9e 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -28,30 +28,20 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* ID Functions */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* ID Functions */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Spkg.h" /* Dataspace functions */ +#include "H5VMprivate.h" /* Vector functions */ /****************/ /* Local Macros */ /****************/ -/* Macro for checking if two ranges overlap one another */ -/* - * Check for the inverse of whether the ranges are disjoint. If they are - * disjoint, then the low bound of one of the ranges must be greater than the - * high bound of the other. - */ -/* (Assumes that low & high bounds are _inclusive_) */ -#define H5S_RANGE_OVERLAP(L1, H1, L2, H2) \ - (!((L1) > (H2) || (L2) > (H1))) - /* Flags for which hyperslab fragments to compute */ #define H5S_HYPER_COMPUTE_B_NOT_A 0x01 #define H5S_HYPER_COMPUTE_A_AND_B 0x02 @@ -197,6 +187,8 @@ static htri_t H5S__hyper_is_contiguous(const H5S_t *space); static htri_t H5S__hyper_is_single(const H5S_t *space); static htri_t H5S__hyper_is_regular(const H5S_t *space); static htri_t H5S__hyper_shape_same(const H5S_t *space1, const H5S_t *space2); +static htri_t H5S__hyper_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end); static herr_t H5S__hyper_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__hyper_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__hyper_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); @@ -242,6 +234,7 @@ const H5S_select_class_t H5S_sel_hyper[1] = {{ H5S__hyper_is_single, H5S__hyper_is_regular, H5S__hyper_shape_same, + H5S__hyper_intersect_block, H5S__hyper_adjust_u, H5S__hyper_project_scalar, H5S__hyper_project_simple, @@ -4829,7 +4822,6 @@ static herr_t H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) { const hsize_t *low_bounds, *high_bounds; /* Pointers to the correct pair of low & high bounds */ - unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_STATIC @@ -4849,22 +4841,32 @@ H5S__hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) high_bounds = space->select.sel_info.hslab->span_lst->high_bounds; } /* end else */ - /* Loop over dimensions */ - for(u = 0; u < space->extent.rank; u++) { - /* Sanity check */ - HDassert(low_bounds[u] <= high_bounds[u]); + /* Check for offset set */ + if(space->select.offset_changed) { + unsigned u; /* Local index variable */ - /* Check for offset moving selection negative */ - if(((hssize_t)low_bounds[u] + space->select.offset[u]) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + /* Loop over dimensions */ + for(u = 0; u < space->extent.rank; u++) { + /* Sanity check */ + HDassert(low_bounds[u] <= high_bounds[u]); - /* Set the low & high bounds in this dimension */ - start[u] = (hsize_t)((hssize_t)low_bounds[u] + space->select.offset[u]); - if((int)u == space->select.sel_info.hslab->unlim_dim) - end[u] = H5S_UNLIMITED; - else - end[u] = (hsize_t)((hssize_t)high_bounds[u] + space->select.offset[u]); - } /* end for */ + /* Check for offset moving selection negative */ + if(((hssize_t)low_bounds[u] + space->select.offset[u]) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds") + + /* Set the low & high bounds in this dimension */ + start[u] = (hsize_t)((hssize_t)low_bounds[u] + space->select.offset[u]); + if((int)u == space->select.sel_info.hslab->unlim_dim) + end[u] = H5S_UNLIMITED; + else + end[u] = (hsize_t)((hssize_t)high_bounds[u] + space->select.offset[u]); + } /* end for */ + } /* end if */ + else { + /* Offset vector is still zeros, just copy low & high bounds */ + H5MM_memcpy(start, low_bounds, sizeof(hsize_t) * space->extent.rank); + H5MM_memcpy(end, high_bounds, sizeof(hsize_t) * space->extent.rank); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value) @@ -6240,32 +6242,31 @@ done: /*-------------------------------------------------------------------------- NAME - H5S_hyper_intersect_block + H5S__hyper_intersect_block PURPOSE - Detect intersections in span trees + Detect intersections of selection with block USAGE - htri_t H5S_hyper_intersect_block(space, start, end) - H5S_t *space; IN: First dataspace to operate on span tree - hssize_t *start; IN: Starting coordinate for block - hssize_t *end; IN: Ending coordinate for block + htri_t H5S__hyper_intersect_block(space, start, end) + const H5S_t *space; IN: Dataspace with selection to use + const hsize_t *start; IN: Starting coordinate for block + const hsize_t *end; IN: Ending coordinate for block RETURNS - Non-negative on success, negative on failure + Non-negative TRUE / FALSE on success, negative on failure DESCRIPTION - Quickly detect intersections between span tree and block + Quickly detect intersections between both regular hyperslabs and span trees + with a block GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS Does not use selection offset. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -htri_t -H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end) +static htri_t +H5S__hyper_intersect_block(const H5S_t *space, const hsize_t *start, const hsize_t *end) { - const hsize_t *low_bounds, *high_bounds; /* Pointers to the correct pair of low & high bounds */ - unsigned u; /* Local index variable */ htri_t ret_value = FAIL; /* Return value */ - FUNC_ENTER_NOAPI(FAIL) + FUNC_ENTER_STATIC /* Sanity check */ HDassert(space); @@ -6277,27 +6278,12 @@ H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end * to be impossible. */ if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO) - H5S__hyper_rebuild(space); - - /* Check which set of low & high bounds we should be using */ - if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { - low_bounds = space->select.sel_info.hslab->diminfo.low_bounds; - high_bounds = space->select.sel_info.hslab->diminfo.high_bounds; - } /* end if */ - else { - low_bounds = space->select.sel_info.hslab->span_lst->low_bounds; - high_bounds = space->select.sel_info.hslab->span_lst->high_bounds; - } /* end else */ - - /* Loop over selection bounds and block, checking for overlap */ - for(u = 0; u < space->extent.rank; u++) - /* If selection bounds & block don't overlap, can leave now */ - if(!H5S_RANGE_OVERLAP(low_bounds[u], high_bounds[u], start[u], end[u])) - HGOTO_DONE(FALSE) + H5S__hyper_rebuild((H5S_t *)space); /* Casting away const OK -QAK */ /* Check for regular hyperslab intersection */ if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) { hbool_t single_block; /* Whether the regular selection is a single block */ + unsigned u; /* Local index variable */ /* Check for a single block */ /* For a regular hyperslab to be single, it must have only one block @@ -6381,7 +6367,7 @@ H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5S_hyper_intersect_block() */ +} /* end H5S__hyper_intersect_block() */ /*-------------------------------------------------------------------------- diff --git a/src/H5Snone.c b/src/H5Snone.c index 9d64e9d..c262d18 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -28,11 +28,11 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5Iprivate.h" /* ID Functions */ -#include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* ID Functions */ +#include "H5Spkg.h" /* Dataspace functions */ +#include "H5VMprivate.h" /* Vector functions */ /****************/ @@ -63,9 +63,12 @@ static htri_t H5S__none_is_contiguous(const H5S_t *space); static htri_t H5S__none_is_single(const H5S_t *space); static htri_t H5S__none_is_regular(const H5S_t *space); static htri_t H5S__none_shape_same(const H5S_t *space1, const H5S_t *space2); +static htri_t H5S__none_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end); static herr_t H5S__none_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__none_project_scalar(const H5S_t *space, hsize_t *offset); -static herr_t H5S__none_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset); +static herr_t H5S__none_project_simple(const H5S_t *space, H5S_t *new_space, + hsize_t *offset); static herr_t H5S__none_iter_init(const H5S_t *space, H5S_sel_iter_t *iter); /* Selection iteration callbacks */ @@ -108,6 +111,7 @@ const H5S_select_class_t H5S_sel_none[1] = {{ H5S__none_is_single, H5S__none_is_regular, H5S__none_shape_same, + H5S__none_intersect_block, H5S__none_adjust_u, H5S__none_project_scalar, H5S__none_project_simple, @@ -886,6 +890,41 @@ H5S__none_shape_same(const H5S_t H5_ATTR_UNUSED *space1, /*-------------------------------------------------------------------------- NAME + H5S__none_intersect_block + PURPOSE + Detect intersections of selection with block + USAGE + htri_t H5S__none_intersect_block(space, start, end) + const H5S_t *space; IN: Dataspace with selection to use + const hsize_t *start; IN: Starting coordinate for block + const hsize_t *end; IN: Ending coordinate for block + RETURNS + Non-negative TRUE / FALSE on success, negative on failure + DESCRIPTION + Quickly detect intersections with a block + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S__none_intersect_block(const H5S_t H5_ATTR_UNUSED *space, + const hsize_t H5_ATTR_UNUSED *start, const hsize_t H5_ATTR_UNUSED *end) +{ + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(space); + HDassert(H5S_SEL_NONE == H5S_GET_SELECT_TYPE(space)); + HDassert(start); + HDassert(end); + + FUNC_LEAVE_NOAPI(FALSE) +} /* end H5S__none_intersect_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__none_adjust_u PURPOSE Adjust an "none" selection by subtracting an offset diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 4752c59..278f08d 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -91,6 +91,15 @@ * H5S_UNLIMITED) */ #define H5S_MAX_SIZE ((hsize_t)(hssize_t)(-2)) +/* Macro for checking if two ranges overlap one another */ +/* + * Check for the inverse of whether the ranges are disjoint. If they are + * disjoint, then the low bound of one of the ranges must be greater than the + * high bound of the other. + */ +/* (Assumes that low & high bounds are _inclusive_) */ +#define H5S_RANGE_OVERLAP(L1, H1, L2, H2) (!((L1) > (H2) || (L2) > (H1))) + /* * Dataspace extent information @@ -240,6 +249,8 @@ typedef htri_t (*H5S_sel_is_single_func_t)(const H5S_t *space); typedef htri_t (*H5S_sel_is_regular_func_t)(const H5S_t *space); /* Method to determine if two dataspaces' selections are the same shape */ typedef htri_t (*H5S_sel_shape_same_func_t)(const H5S_t *space1, const H5S_t *space2); +/* Method to determine if selection intersects a block */ +typedef htri_t (*H5S_sel_intersect_block_func_t)(const H5S_t *space, const hsize_t *start, const hsize_t *end); /* Method to adjust a selection by an offset */ typedef herr_t (*H5S_sel_adjust_u_func_t)(H5S_t *space, const hsize_t *offset); /* Method to construct single element projection onto scalar dataspace */ @@ -268,6 +279,7 @@ typedef struct { H5S_sel_is_single_func_t is_single; /* Method to determine if current selection is a single block */ H5S_sel_is_regular_func_t is_regular; /* Method to determine if current selection is "regular" */ H5S_sel_shape_same_func_t shape_same; /* Method to determine if two dataspaces' selections are the same shape */ + H5S_sel_intersect_block_func_t intersect_block; /* Method to determine if a dataspaces' selection intersects a block */ H5S_sel_adjust_u_func_t adjust_u; /* Method to adjust a selection by an offset */ H5S_sel_project_scalar project_scalar; /* Method to construct scalar dataspace projection */ H5S_sel_project_simple project_simple; /* Method to construct simple dataspace projection */ @@ -369,7 +381,6 @@ H5_DLL herr_t H5S__hyper_project_intersection(const H5S_t *src_space, /* Testing functions */ #ifdef H5S_TESTING -H5_DLL htri_t H5S__select_shape_same_test(hid_t sid1, hid_t sid2); H5_DLL herr_t H5S__get_rebuild_status_test(hid_t space_id, H5S_diminfo_valid_t *status1, H5S_diminfo_valid_t *status2); H5_DLL herr_t H5S__get_diminfo_status_test(hid_t space_id, diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 875c018..8e1175a 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -28,14 +28,14 @@ /***********/ /* Headers */ /***********/ -#include "H5private.h" /* Generic Functions */ -#include "H5CXprivate.h" /* API Contexts */ -#include "H5Eprivate.h" /* Error handling */ -#include "H5FLprivate.h" /* Free Lists */ -#include "H5Iprivate.h" /* ID Functions */ -#include "H5MMprivate.h" /* Memory management */ -#include "H5Spkg.h" /* Dataspace functions */ -#include "H5VMprivate.h" /* Vector functions */ +#include "H5private.h" /* Generic Functions */ +#include "H5CXprivate.h" /* API Contexts */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* ID Functions */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Spkg.h" /* Dataspace functions */ +#include "H5VMprivate.h" /* Vector functions */ /****************/ @@ -75,6 +75,8 @@ static htri_t H5S__point_is_contiguous(const H5S_t *space); static htri_t H5S__point_is_single(const H5S_t *space); static htri_t H5S__point_is_regular(const H5S_t *space); static htri_t H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2); +static htri_t H5S__point_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end); static herr_t H5S__point_adjust_u(H5S_t *space, const hsize_t *offset); static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset); static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space, @@ -124,6 +126,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{ H5S__point_is_single, H5S__point_is_regular, H5S__point_shape_same, + H5S__point_intersect_block, H5S__point_adjust_u, H5S__point_project_scalar, H5S__point_project_simple, @@ -1998,6 +2001,63 @@ done: /*-------------------------------------------------------------------------- NAME + H5S__point_intersect_block + PURPOSE + Detect intersections of selection with block + USAGE + htri_t H5S__point_intersect_block(space, start, end) + const H5S_t *space; IN: Dataspace with selection to use + const hsize_t *start; IN: Starting coordinate for block + const hsize_t *end; IN: Ending coordinate for block + RETURNS + Non-negative TRUE / FALSE on success, negative on failure + DESCRIPTION + Quickly detect intersections with a block + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5S__point_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end) +{ + H5S_pnt_node_t *pnt; /* Point information node */ + htri_t ret_value = FALSE; /* Return value */ + + FUNC_ENTER_STATIC_NOERR + + /* Sanity check */ + HDassert(space); + HDassert(H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space)); + HDassert(start); + HDassert(end); + + /* Loop over points */ + pnt = space->select.sel_info.pnt_lst->head; + while(pnt) { + unsigned u; /* Local index variable */ + + /* Verify that the point is within the block */ + for(u = 0; u < space->extent.rank; u++) + if(pnt->pnt[u] < start[u] || pnt->pnt[u] > end[u]) + break; + + /* Check if point was within block for all dimensions */ + if(u == space->extent.rank) + HGOTO_DONE(TRUE) + + /* Advance to next point */ + pnt = pnt->next; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S__point_intersect_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S__point_adjust_u PURPOSE Adjust a "point" selection by subtracting an offset diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 6646f84..0a9d2e7 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -30,15 +30,6 @@ #include "H5Pprivate.h" /* Property lists */ #include "H5Tprivate.h" /* Datatypes */ -/* Flags for H5S_find */ -#define H5S_CONV_PAR_IO_POSSIBLE 0x0001 -/* The storage options are mutually exclusive */ -/* (2-bits reserved for storage type currently) */ -#define H5S_CONV_STORAGE_COMPACT 0x0000 /* i.e. '0' */ -#define H5S_CONV_STORAGE_CONTIGUOUS 0x0002 /* i.e. '1' */ -#define H5S_CONV_STORAGE_CHUNKED 0x0004 /* i.e. '2' */ -#define H5S_CONV_STORAGE_MASK 0x0006 - /* Forward references of package typedefs */ typedef struct H5S_extent_t H5S_extent_t; typedef struct H5S_pnt_node_t H5S_pnt_node_t; @@ -192,6 +183,8 @@ typedef struct H5S_sel_iter_op_t { #endif /* H5S_MODULE */ /* Handle these callbacks in a special way, since they have prologs that need to be executed */ #define H5S_SELECT_COPY(DST,SRC,SHARE) (H5S_select_copy(DST,SRC,SHARE)) +#define H5S_SELECT_SHAPE_SAME(S1,S2) (H5S_select_shape_same(S1,S2)) +#define H5S_SELECT_INTERSECT_BLOCK(S,START,END) (H5S_select_intersect_block(S,START,END)) #define H5S_SELECT_RELEASE(S) (H5S_select_release(S)) #define H5S_SELECT_DESERIALIZE(S,BUF) (H5S_select_deserialize(S,BUF)) @@ -252,6 +245,8 @@ H5_DLL herr_t H5S_get_select_num_elem_non_unlim(const H5S_t *space, H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset); H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection); H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2); +H5_DLL htri_t H5S_select_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end); H5_DLL herr_t H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr, unsigned new_space_rank, const void *buf, void const **adj_buf_ptr, hsize_t element_size); @@ -287,7 +282,6 @@ H5_DLL herr_t H5S_combine_hyperslab(H5S_t *old_space, H5S_seloper_t op, const hsize_t *block, H5S_t **new_space); H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords); -H5_DLL htri_t H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end); H5_DLL herr_t H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset); H5_DLL htri_t H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset); H5_DLL herr_t H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index 23e6846..9e76b4b 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -145,6 +145,9 @@ H5_DLL herr_t H5Sselect_copy(hid_t dst_id, hid_t src_id); H5_DLL htri_t H5Sselect_valid(hid_t spaceid); H5_DLL herr_t H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[]); +H5_DLL htri_t H5Sselect_shape_same(hid_t space1_id, hid_t space2_id); +H5_DLL htri_t H5Sselect_intersect_block(hid_t space_id, const hsize_t *start, + const hsize_t *end); H5_DLL herr_t H5Soffset_simple(hid_t space_id, const hssize_t *offset); H5_DLL herr_t H5Sselect_all(hid_t spaceid); H5_DLL herr_t H5Sselect_none(hid_t spaceid); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index c383fed..e632b11 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -250,11 +250,15 @@ H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection) HDassert(dst); HDassert(src); + /* Release the current selection */ + if(H5S_SELECT_RELEASE(dst) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection") + /* Copy regular fields */ dst->select = src->select; /* Perform correct type of copy based on the type of selection */ - if((ret_value = (*src->select.type->copy)(dst,src,share_selection)) < 0) + if((ret_value = (*src->select.type->copy)(dst, src, share_selection)) < 0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information") done: @@ -281,7 +285,7 @@ done: herr_t H5S_select_release(H5S_t *ds) { - herr_t ret_value = FAIL; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT @@ -1689,9 +1693,12 @@ H5S_get_select_type(const H5S_t *space) DESCRIPTION Checks to see if the current selection in the dataspaces are the same dimensionality and shape. + This is primarily used for reading the entire selection in one swoop. GLOBAL VARIABLES COMMENTS, BUGS, ASSUMPTIONS + This routine participates in the "Inlining C function pointers" pattern, + don't call it directly, use the appropriate macro defined in H5Sprivate.h. EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ @@ -1945,6 +1952,164 @@ done: /*-------------------------------------------------------------------------- NAME + H5Sselect_shape_same + PURPOSE + Check if two selections are the same shape + USAGE + htri_t H5Sselect_shape_same(space1_id, space2_id) + hid_t space1_id; IN: ID of 1st Dataspace pointer to compare + hid_t space2_id; IN: ID of 2nd Dataspace pointer to compare + RETURNS + TRUE/FALSE/FAIL + DESCRIPTION + Checks to see if the current selection in the dataspaces are the same + dimensionality and shape. + This is primarily used for reading the entire selection in one swoop. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5Sselect_shape_same(hid_t space1_id, hid_t space2_id) +{ + H5S_t *space1, *space2; /* Dataspaces to compare */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE2("t", "ii", space1_id, space2_id); + + if(NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace") + if(NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace") + + if((ret_value = H5S_select_shape_same(space1, space2)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't compare selections") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Sselect_shape_same() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_select_intersect_block + PURPOSE + Check if current selection intersects with a block + USAGE + htri_t H5S_select_intersect_block(space, start, end) + const H5S_t *space; IN: Dataspace to compare + const hsize_t *start; IN: Starting coordinate of block + const hsize_t *end; IN: Opposite ("ending") coordinate of block + RETURNS + TRUE / FALSE / FAIL + DESCRIPTION + Checks to see if the current selection in the dataspace intersects with + the block given. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Assumes that start & end block bounds are _inclusive_, so start == end + value OK. + + This routine participates in the "Inlining C function pointers" pattern, + don't call it directly, use the appropriate macro defined in H5Sprivate.h. +--------------------------------------------------------------------------*/ +htri_t +H5S_select_intersect_block(const H5S_t *space, const hsize_t *start, + const hsize_t *end) +{ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_NOAPI(FAIL) + + /* Check args */ + HDassert(space); + HDassert(start); + HDassert(end); + + /* If selections aren't "none", compare their bounds */ + if(H5S_SEL_NONE != H5S_GET_SELECT_TYPE(space)) { + hsize_t low[H5S_MAX_RANK]; /* Low bound of selection in dataspace */ + hsize_t high[H5S_MAX_RANK]; /* High bound of selection in dataspace */ + unsigned u; /* Local index variable */ + + /* Get low & high bounds for dataspace selection */ + if(H5S_SELECT_BOUNDS(space, low, high) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds for dataspace") + + /* Loop over selection bounds and block, checking for overlap */ + for(u = 0; u < space->extent.rank; u++) + /* If selection bounds & block don't overlap, can leave now */ + if(!H5S_RANGE_OVERLAP(low[u], high[u], start[u], end[u])) + HGOTO_DONE(FALSE) + } /* end if */ + + /* Call selection type's intersect routine */ + if((ret_value = (*space->select.type->intersect_block)(space, start, end)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't intersect block with selection") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5S_select_intersect_block() */ + + +/*-------------------------------------------------------------------------- + NAME + H5Sselect_intersect_block + PURPOSE + Check if current selection intersects with a block + USAGE + htri_t H5Sselect_intersect_block(space_id, start, end) + hid_t space1_id; IN: ID of dataspace pointer to compare + const hsize_t *start; IN: Starting coordinate of block + const hsize_t *end; IN: Opposite ("ending") coordinate of block + RETURNS + TRUE / FALSE / FAIL + DESCRIPTION + Checks to see if the current selection in the dataspace intersects with + the block given. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + Assumes that start & end block bounds are _inclusive_, so start == end + value OK. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +htri_t +H5Sselect_intersect_block(hid_t space_id, const hsize_t *start, const hsize_t *end) +{ + H5S_t *space; /* Dataspace to query */ + unsigned u; /* Local index value */ + htri_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_API(FAIL) + H5TRACE3("t", "i*h*h", space_id, start, end); + + /* Check arguments */ + if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace") + if(NULL == start) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "block start array pointer is NULL") + if(NULL == end) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "block end array pointer is NULL") + + /* Range check start & end values */ + for(u = 0; u < space->extent.rank; u++) + if(start[u] > end[u]) + HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "block start[%u] (%llu) > end[%u] (%llu)", u, (unsigned long long)start[u], u, (unsigned long long)end[u]) + + /* Call internal routine to do comparison */ + if((ret_value = H5S_select_intersect_block(space, start, end)) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't compare selection and block") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Sselect_intersect_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_select_construct_projection PURPOSE diff --git a/src/H5Stest.c b/src/H5Stest.c index 2c42713..b61b6bf 100644 --- a/src/H5Stest.c +++ b/src/H5Stest.c @@ -66,50 +66,6 @@ /*-------------------------------------------------------------------------- NAME - H5S__select_shape_same_test - PURPOSE - Determine if two dataspace selections are the same shape - USAGE - htri_t H5S__select_shape_same_test(sid1, sid2) - hid_t sid1; IN: 1st dataspace to compare - hid_t sid2; IN: 2nd dataspace to compare - RETURNS - Non-negative TRUE/FALSE on success, negative on failure - DESCRIPTION - Checks to see if the current selection in the dataspaces are the same - dimensionality and shape. - GLOBAL VARIABLES - COMMENTS, BUGS, ASSUMPTIONS - DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING - EXAMPLES - REVISION LOG ---------------------------------------------------------------------------*/ -htri_t -H5S__select_shape_same_test(hid_t sid1, hid_t sid2) -{ - H5S_t *space1; /* Pointer to 1st dataspace */ - H5S_t *space2; /* Pointer to 2nd dataspace */ - htri_t ret_value = FAIL; /* Return value */ - - FUNC_ENTER_PACKAGE - - /* Get dataspace structures */ - if(NULL == (space1 = (H5S_t *)H5I_object_verify(sid1, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - if(NULL == (space2 = (H5S_t *)H5I_object_verify(sid2, H5I_DATASPACE))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace") - - /* Check if the dataspace selections are the same shape */ - if((ret_value = H5S_select_shape_same(space1, space2)) < 0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "unable to compare dataspace selections") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5S__select_shape_same_test() */ - - -/*-------------------------------------------------------------------------- - NAME H5S__get_rebuild_status_test PURPOSE Determine the status of the diminfo_valid field (whether we know the |