summaryrefslogtreecommitdiffstats
path: root/src/H5Shyper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r--src/H5Shyper.c3996
1 files changed, 1761 insertions, 2235 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 889291f..c97c9b6 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -17,7 +17,7 @@
* Programmer: Quincey Koziol <koziol@ncsa.uiuc.edu>
* Thursday, June 18, 1998
*
- * Purpose: Hyperslab selection dataspace I/O functions.
+ * Purpose: Hyperslab selection data space I/O functions.
*/
#define H5S_PACKAGE /*suppress error about including H5Spkg */
@@ -30,86 +30,21 @@
#include "H5Spkg.h" /* Dataspace functions */
#include "H5VMprivate.h" /* Vector functions */
-/* Local Macros */
-
-/* Flags for which hyperslab fragments to compute */
-#define H5S_HYPER_COMPUTE_B_NOT_A 0x01
-#define H5S_HYPER_COMPUTE_A_AND_B 0x02
-#define H5S_HYPER_COMPUTE_A_NOT_B 0x04
-
-/* Macro to advance a span, possibly recycling it first */
-#define H5S_HYPER_ADVANCE_SPAN(recover, curr_span, next_span) \
- do { \
- /* Check if the span should be recovered */ \
- if(recover) { \
- H5S_hyper_free_span(curr_span); \
- recover = FALSE; \
- } /* end if */ \
- \
- /* Set the current span to next span */ \
- curr_span = next_span; \
- } while(0)
-
-
/* Local datatypes */
/* Static function prototypes */
-static H5S_hyper_span_t *H5S_hyper_new_span(hsize_t low, hsize_t high,
- H5S_hyper_span_info_t *down, H5S_hyper_span_t *next);
-static herr_t H5S_hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size);
-static void H5S_hyper_span_scratch(H5S_hyper_span_info_t *spans, void *scr_value);
-static H5S_hyper_span_info_t *H5S_hyper_copy_span(H5S_hyper_span_info_t *spans);
-static htri_t H5S_hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1,
- const H5S_hyper_span_info_t *span_info2);
static herr_t H5S_hyper_free_span_info(H5S_hyper_span_info_t *span_info);
static herr_t H5S_hyper_free_span(H5S_hyper_span_t *span);
-static herr_t H5S_hyper_span_blocklist(const H5S_hyper_span_info_t *spans,
- hsize_t start[], hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks,
- hsize_t **buf);
-static herr_t H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal,
- hsize_t startblock, hsize_t numblocks, hsize_t *buf);
-static H5S_hyper_span_t *H5S_hyper_coord_to_span(unsigned rank, const hsize_t *coords);
-static herr_t H5S_hyper_append_span(H5S_hyper_span_t **prev_span,
- H5S_hyper_span_info_t **span_tree, hsize_t low, hsize_t high,
- H5S_hyper_span_info_t *down, H5S_hyper_span_t *next);
-static herr_t H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans,
- H5S_hyper_span_info_t *b_spans, unsigned int selector,
- unsigned cur_dim, unsigned dim_size, const hsize_t *span_a_b_bounds[4],
- hsize_t *all_clips_bounds, H5S_hyper_span_info_t **a_not_b,
- H5S_hyper_span_info_t **a_and_b, H5S_hyper_span_info_t **b_not_a);
-static herr_t H5S_hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans);
-static hsize_t H5S_hyper_spans_nelem(const H5S_hyper_span_info_t *spans);
-static herr_t H5S_hyper_add_disjoint_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans);
-static H5S_hyper_span_info_t *H5S_hyper_make_spans(unsigned rank,
- const hsize_t *start, const hsize_t *stride,
- const hsize_t *count, const hsize_t *block);
-static herr_t H5S_hyper_update_diminfo(H5S_t *space, H5S_seloper_t op,
- const H5S_hyper_dim_t *new_hyper_diminfo);
-static hbool_t H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span,
- H5S_hyper_dim_t span_slab_info[], unsigned rank);
-static herr_t H5S_hyper_generate_spans(H5S_t *space);
-static herr_t H5S_hyper_update_bound_box(H5S_t *space, H5S_seloper_t op,
- const hsize_t low_bounds[], const hsize_t high_bounds[]);
-static herr_t H5S_fill_in_new_space(H5S_t *space1, H5S_seloper_t op, H5S_hyper_span_info_t *space2_span_lst, const hsize_t *space2_low_bound, const hsize_t *space2_high_bound, hbool_t can_own_span2, hbool_t *span2_owned, hbool_t *updated_spans, H5S_t **result);
+static H5S_hyper_span_info_t *H5S_hyper_copy_span(H5S_hyper_span_info_t *spans);
+static void H5S_hyper_span_scratch(H5S_hyper_span_info_t *spans, void *scr_value);
+static herr_t H5S_hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size);
static herr_t H5S_generate_hyperslab(H5S_t *space, H5S_seloper_t op,
- const hsize_t start[], const hsize_t stride[], const hsize_t count[],
- const hsize_t block[]);
-static herr_t H5S_fill_in_hyperslab(H5S_t *old_space, H5S_seloper_t op,
- const hsize_t start[], const hsize_t *stride, const hsize_t count[],
- const hsize_t *block, H5S_t **new_space);
-static herr_t H5S_fill_in_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2,
- H5S_t **result);
-static H5S_t *H5S_combine_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
-static herr_t H5S_modify_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
-static herr_t H5S_hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter,
- size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off,
- size_t *len);
-static herr_t H5S_hyper_get_seq_list_opt(const H5S_t *space, H5S_sel_iter_t *iter,
- size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off,
- size_t *len);
-static herr_t H5S_hyper_get_seq_list_single(const H5S_t *space, H5S_sel_iter_t *iter,
- size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem, hsize_t *off,
- size_t *len);
+ const hsize_t start[], const hsize_t stride[], const hsize_t count[], const hsize_t block[]);
+static herr_t H5S_hyper_generate_spans(H5S_t *space);
+/* Needed for use in hyperslab code (H5Shyper.c) */
+#ifdef NEW_HYPERSLAB_API
+static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2);
+#endif /*NEW_HYPERSLAB_API*/
/* Selection callbacks */
static herr_t H5S_hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
@@ -140,6 +75,11 @@ static herr_t H5S_hyper_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
static herr_t H5S_hyper_iter_next_block(H5S_sel_iter_t *sel_iter);
static herr_t H5S_hyper_iter_release(H5S_sel_iter_t *sel_iter);
+/* Static function for optimizing hyperslab */
+static hbool_t H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span,
+ H5S_hyper_dim_t span_slab_info[], unsigned rank);
+static htri_t H5S_hyper_rebuild(H5S_t *space);
+
/* Selection properties for hyperslab selections */
const H5S_select_class_t H5S_sel_hyper[1] = {{
H5S_SEL_HYPERSLABS,
@@ -274,116 +214,6 @@ H5S_hyper_print_diminfo(FILE *f, const H5S_t *space)
FUNC_LEAVE_NOAPI(SUCCEED)
}
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_hyper_print_spans_dfs
- PURPOSE
- Output the span elements for one span list in depth-first order
- USAGE
- herr_t H5S_hyper_print_spans_dfs(f, span_lst, depth)
- FILE *f; IN: the file to output
- const H5S_hyper_span_info_t *span_lst; IN: the span list to output
- unsigned depth; IN: the level of this span list
- RETURNS
- non-negative on success, negative on failure
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5S_hyper_print_spans_dfs(FILE *f, const H5S_hyper_span_info_t *span_lst,
- unsigned depth)
-{
- H5S_hyper_span_t *actual_tail = NULL;
- H5S_hyper_span_t *cur_elem;
- unsigned num_elems = 0;
- unsigned i, elem_idx;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_print_spans_dfs)
-
- /* get the actual tail from head */
- cur_elem = span_lst->head;
- HDassert(cur_elem); /* at least 1 element */
- while(cur_elem) {
- actual_tail = cur_elem;
- cur_elem = cur_elem->next;
- num_elems++;
- } /* end while */
-
- for(i = 0; i < depth; i++)
- HDfprintf(f, "\t");
- HDfprintf(f, "DIM[%u]: ref_count=%u, #elems=%u, scratch=%p, head=%p, tail=%p, actual_tail=%p, matched=%t\n", depth,
- span_lst->count, num_elems, span_lst->scratch, span_lst->head,
- span_lst->tail, actual_tail, (span_lst->tail == actual_tail));
-
- cur_elem = span_lst->head;
- elem_idx = 0;
- while(cur_elem) {
- for(i = 0; i < depth; i++)
- HDfprintf(f, "\t");
- HDfprintf(f, "ELEM[%u]: ptr=%p, low=%Hu, high=%Hu, nelem=%Hu, pstride=%Hu, down=%p\n",
- elem_idx++, cur_elem, cur_elem->low, cur_elem->high, cur_elem->nelem,
- cur_elem->pstride, cur_elem->down);
- if(cur_elem->down)
- H5S_hyper_print_spans_dfs(f, cur_elem->down, depth + 1);
- cur_elem = cur_elem->next;
- } /* end while */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_print_spans_dfs() */
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_hyper_print_space_dfs
- PURPOSE
- Output the span elements for one hyperslab selection space in depth-first order
- USAGE
- herr_t H5S_hyper_print_space_dfs(f, space)
- FILE *f; IN: the file to output
- const H5S_t *space; IN: the selection space to output
- RETURNS
- non-negative on success, negative on failure
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5S_hyper_print_space_dfs(FILE *f, const H5S_t *space)
-{
- const H5S_hyper_sel_t *hslab = space->select.sel_info.hslab;
- const unsigned dims = space->extent.rank;
- unsigned i;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_print_space_dfs)
- HDassert(hslab);
-
- HDfprintf(f, "=======================\n");
- HDfprintf(f, "SPACE: span_lst=%p, #dims=%u, offset_changed=%d\n", hslab->span_lst, dims, space->select.offset_changed);
- HDfprintf(f, " offsets=[");
- for(i = 0; i < dims - 1; i++)
- HDfprintf(f, "%lld,", space->select.offset[i]);
- HDfprintf(f, "%lld]\n", space->select.offset[dims-1]);
- HDfprintf(f, " low_bounds=[");
- for(i = 0; i < dims-1; i++)
- HDfprintf(f, "%llu,", space->select.low_bounds[i]);
- HDfprintf(f, "%llu]\n", space->select.low_bounds[dims-1]);
- HDfprintf(f, " high_bounds=[");
- for(i = 0; i < dims - 1; i++)
- HDfprintf(f, "%llu,", space->select.high_bounds[i]);
- HDfprintf(f, "%llu]\n", space->select.high_bounds[dims-1]);
-
- /* Start print out the highest-order of dimension */
- if(hslab->span_lst)
- H5S_hyper_print_spans_dfs(f, hslab->span_lst, 0);
- HDfprintf(f, "=======================\n\n");
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_print_space_dfs() */
#endif /* H5S_HYPER_DEBUG */
@@ -426,17 +256,11 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
/* Get the rank of the dataspace */
rank = space->extent.rank;
- /* Rebuild diminfo if it is invalid and has not been confirmed to be
- * impossible */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- /* Casting away const OK -NAF */
- (void)H5S_hyper_rebuild((H5S_t *)space);
-
/* Set the temporary pointer to the dimension information */
tdiminfo = space->select.sel_info.hslab->opt_diminfo;
/* Check for the special case of just one H5Sselect_hyperslab call made */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
/* Initialize the information needed for regular hyperslab I/O */
const hsize_t *mem_size; /* Temporary pointer to dataspace extent's dimension sizes */
hsize_t acc; /* Accumulator for "flattened" dimension's sizes */
@@ -583,7 +407,7 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
iter->type = H5S_sel_iter_hyper;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_iter_init() */
+} /* H5S_hyper_iter_init() */
/*-------------------------------------------------------------------------
@@ -597,10 +421,12 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
* Programmer: Quincey Koziol
* Tuesday, April 22, 2003
*
+ * Modifications:
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords)
+H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hsize_t *coords)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -668,7 +494,7 @@ H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords)
HDmemcpy(coords, iter->u.hyp.off, sizeof(hsize_t) * iter->rank);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_iter_coords() */
+} /* H5S_hyper_iter_coords() */
/*-------------------------------------------------------------------------
@@ -685,10 +511,12 @@ H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords)
* Notes: This routine assumes that the iterator is always located at
* the beginning of a block.
*
+ * Modifications:
+ *
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_hyper_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
+H5S_hyper_iter_block (const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
{
unsigned u; /* Local index variable */
@@ -720,7 +548,7 @@ H5S_hyper_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_iter_block() */
+} /* H5S_hyper_iter_block() */
/*-------------------------------------------------------------------------
@@ -733,10 +561,12 @@ H5S_hyper_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
* Programmer: Quincey Koziol
* Tuesday, June 16, 1998
*
+ * Modifications:
+ *
*-------------------------------------------------------------------------
*/
static hsize_t
-H5S_hyper_iter_nelmts(const H5S_sel_iter_t *iter)
+H5S_hyper_iter_nelmts (const H5S_sel_iter_t *iter)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -744,7 +574,7 @@ H5S_hyper_iter_nelmts(const H5S_sel_iter_t *iter)
HDassert(iter);
FUNC_LEAVE_NOAPI(iter->elmt_left)
-} /* end H5S_hyper_iter_nelmts() */
+} /* H5S_hyper_iter_nelmts() */
/*--------------------------------------------------------------------------
@@ -800,7 +630,7 @@ H5S_hyper_iter_has_next_block(const H5S_sel_iter_t *iter)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_iter_has_next_block() */
+} /* H5S_hyper_iter_has_next_block() */
/*-------------------------------------------------------------------------
@@ -815,6 +645,10 @@ done:
* Programmer: Quincey Koziol
* Friday, September 8, 2000
*
+ * Modifications:
+ * Modified for both general and optimized hyperslab I/O
+ * Quincey Koziol, April 17, 2003
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1013,7 +847,7 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem)
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_iter_next() */
+} /* H5S_hyper_iter_next() */
/*-------------------------------------------------------------------------
@@ -1028,6 +862,8 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem)
* Programmer: Quincey Koziol
* Tuesday, June 3, 2003
*
+ * Modifications:
+ *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1196,7 +1032,7 @@ H5S_hyper_iter_next_block(H5S_sel_iter_t *iter)
} /* end else */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_iter_next() */
+} /* H5S_hyper_iter_next() */
/*--------------------------------------------------------------------------
@@ -1217,7 +1053,7 @@ H5S_hyper_iter_next_block(H5S_sel_iter_t *iter)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_iter_release(H5S_sel_iter_t *iter)
+H5S_hyper_iter_release (H5S_sel_iter_t *iter)
{
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -1230,7 +1066,7 @@ H5S_hyper_iter_release(H5S_sel_iter_t *iter)
H5S_hyper_free_span_info(iter->u.hyp.spans);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_iter_release() */
+} /* H5S_hyper_iter_release() */
/*--------------------------------------------------------------------------
@@ -1279,7 +1115,7 @@ H5S_hyper_new_span(hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_h
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_new_span() */
+} /* H5S_hyper_new_span() */
/*--------------------------------------------------------------------------
@@ -1302,17 +1138,17 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_span_precompute_helper(H5S_hyper_span_info_t *spans, size_t elmt_size)
+H5S_hyper_span_precompute_helper (H5S_hyper_span_info_t *spans, size_t elmt_size)
{
- H5S_hyper_span_t *span; /* Hyperslab span */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_hyper_span_t *span; /* Hyperslab span */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
HDassert(spans);
/* Check if we've already set this down span tree */
- if(spans->scratch != (H5S_hyper_span_info_t *)~((size_t)NULL)) {
+ if(spans->scratch!=(H5S_hyper_span_info_t *)~((size_t)NULL)) {
/* Set the tree's scratch pointer */
spans->scratch=(H5S_hyper_span_info_t *)~((size_t)NULL);
@@ -1338,7 +1174,7 @@ H5S_hyper_span_precompute_helper(H5S_hyper_span_info_t *spans, size_t elmt_size)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_span_precompute_helper() */
+} /* H5S_hyper_span_precompute_helper() */
/*--------------------------------------------------------------------------
@@ -1378,7 +1214,7 @@ H5S_hyper_span_precompute(H5S_hyper_span_info_t *spans, size_t elmt_size)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_span_precompute() */
+} /* H5S_hyper_span_precompute() */
/*--------------------------------------------------------------------------
@@ -1425,7 +1261,7 @@ H5S_hyper_span_scratch(H5S_hyper_span_info_t *spans, void *scr_value)
} /* end if */
FUNC_LEAVE_NOAPI_VOID
-} /* end H5S_hyper_span_scratch() */
+} /* H5S_hyper_span_scratch() */
/*--------------------------------------------------------------------------
@@ -1446,7 +1282,7 @@ H5S_hyper_span_scratch(H5S_hyper_span_info_t *spans, void *scr_value)
REVISION LOG
--------------------------------------------------------------------------*/
static H5S_hyper_span_info_t *
-H5S_hyper_copy_span_helper(H5S_hyper_span_info_t *spans)
+H5S_hyper_copy_span_helper (H5S_hyper_span_info_t *spans)
{
H5S_hyper_span_t *span; /* Hyperslab span */
H5S_hyper_span_t *new_span; /* Temporary hyperslab span */
@@ -1468,11 +1304,13 @@ H5S_hyper_copy_span_helper(H5S_hyper_span_info_t *spans)
} /* end if */
else {
/* Allocate a new span_info node */
- if(NULL == (ret_value = H5FL_CALLOC(H5S_hyper_span_info_t)))
+ if(NULL == (ret_value = H5FL_MALLOC(H5S_hyper_span_info_t)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span info")
- /* Set the non-zero span_info information */
+ /* Copy the span_info information */
ret_value->count = 1;
+ ret_value->scratch = NULL;
+ ret_value->head = NULL;
/* Set the scratch pointer in the node being copied to the newly allocated node */
spans->scratch = ret_value;
@@ -1507,14 +1345,11 @@ H5S_hyper_copy_span_helper(H5S_hyper_span_info_t *spans)
/* Advance to next span */
span = span->next;
} /* end while */
-
- /* Retain a pointer to the last span */
- ret_value->tail = prev_span;
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_copy_span_helper() */
+} /* H5S_hyper_copy_span_helper() */
/*--------------------------------------------------------------------------
@@ -1554,7 +1389,7 @@ H5S_hyper_copy_span(H5S_hyper_span_info_t *spans)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_copy_span() */
+} /* H5S_hyper_copy_span() */
/*--------------------------------------------------------------------------
@@ -1577,20 +1412,19 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S_hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_span_info_t *span_info2)
+H5S_hyper_cmp_spans (H5S_hyper_span_info_t *span_info1, H5S_hyper_span_info_t *span_info2)
{
- htri_t ret_value = FAIL; /* Return value */
+ H5S_hyper_span_t *span1;
+ H5S_hyper_span_t *span2;
+ htri_t nest=FAIL;
+ htri_t ret_value=FAIL;
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check for redundant comparison */
- if(span_info1 == span_info2)
- ret_value = TRUE;
+ if(span_info1==span_info2)
+ ret_value=TRUE;
else {
- const H5S_hyper_span_t *span1;
- const H5S_hyper_span_t *span2;
- htri_t nest = FAIL;
-
/* Check for both spans being NULL */
if(span_info1==NULL && span_info2==NULL)
ret_value=TRUE;
@@ -1658,7 +1492,7 @@ H5S_hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_spa
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_cmp_spans() */
+} /* H5S_hyper_cmp_spans() */
/*--------------------------------------------------------------------------
@@ -1681,7 +1515,7 @@ H5S_hyper_cmp_spans(const H5S_hyper_span_info_t *span_info1, const H5S_hyper_spa
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_free_span_info(H5S_hyper_span_info_t *span_info)
+H5S_hyper_free_span_info (H5S_hyper_span_info_t *span_info)
{
H5S_hyper_span_t *span, *next_span;
herr_t ret_value=SUCCEED; /* Return value */
@@ -1711,7 +1545,7 @@ H5S_hyper_free_span_info(H5S_hyper_span_info_t *span_info)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_free_span_info() */
+} /* H5S_hyper_free_span_info() */
/*--------------------------------------------------------------------------
@@ -1734,7 +1568,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_free_span(H5S_hyper_span_t *span)
+H5S_hyper_free_span (H5S_hyper_span_t *span)
{
herr_t ret_value=SUCCEED;
@@ -1753,7 +1587,7 @@ H5S_hyper_free_span(H5S_hyper_span_t *span)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_free_span() */
+} /* H5S_hyper_free_span() */
/*--------------------------------------------------------------------------
@@ -1781,15 +1615,14 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection)
+H5S_hyper_copy (H5S_t *dst, const H5S_t *src, hbool_t share_selection)
{
H5S_hyper_sel_t *dst_hslab; /* Pointer to destination hyperslab info */
const H5S_hyper_sel_t *src_hslab; /* Pointer to source hyperslab info */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value=SUCCEED; /* return value */
FUNC_ENTER_NOAPI(FAIL)
- /* Sanity check */
HDassert(src);
HDassert(dst);
@@ -1798,21 +1631,24 @@ H5S_hyper_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
/* Set temporary pointers */
- dst_hslab = dst->select.sel_info.hslab;
- src_hslab = src->select.sel_info.hslab;
+ dst_hslab=dst->select.sel_info.hslab;
+ src_hslab=src->select.sel_info.hslab;
/* Copy the hyperslab information */
- dst_hslab->diminfo_valid = src_hslab->diminfo_valid;
- if(src_hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
- HDmemcpy(dst_hslab->opt_diminfo, src_hslab->opt_diminfo, sizeof(H5S_hyper_dim_t) * src->extent.rank);
- HDmemcpy(dst_hslab->app_diminfo, src_hslab->app_diminfo, sizeof(H5S_hyper_dim_t) * src->extent.rank);
- } /* end if */
+ dst_hslab->diminfo_valid=src_hslab->diminfo_valid;
+ if(src_hslab->diminfo_valid) {
+ size_t u; /* Local index variable */
- dst->select.sel_info.hslab->span_lst = src->select.sel_info.hslab->span_lst;
+ for(u=0; u<src->extent.rank; u++) {
+ dst_hslab->opt_diminfo[u]=src_hslab->opt_diminfo[u];
+ dst_hslab->app_diminfo[u]=src_hslab->app_diminfo[u];
+ } /* end for */
+ } /* end if */
+ dst->select.sel_info.hslab->span_lst=src->select.sel_info.hslab->span_lst;
/* Check if there is hyperslab span information to copy */
/* (Regular hyperslab information is copied with the selection structure) */
- if(src->select.sel_info.hslab->span_lst != NULL) {
+ if(src->select.sel_info.hslab->span_lst!=NULL) {
if(share_selection) {
/* Share the source's span tree by incrementing the reference count on it */
dst->select.sel_info.hslab->span_lst->count++;
@@ -1829,6 +1665,72 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_hyper_is_valid_helper
+ PURPOSE
+ Check whether the selection fits within the extent, with the current
+ offset defined.
+ USAGE
+ htri_t H5S_hyper_is_valid_helper(spans, offset, rank);
+ const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree
+ const hssize_t *offset; IN: Pointer to offset array
+ const hsize_t *size; IN: Pointer to size array
+ hsize_t rank; IN: Current rank looking at
+ RETURNS
+ TRUE if the selection fits within the extent, FALSE if it does not and
+ Negative on an error.
+ DESCRIPTION
+ Determines if the current selection at the current offet fits within the
+ extent for the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static htri_t
+H5S_hyper_is_valid_helper (const H5S_hyper_span_info_t *spans, const hssize_t *offset, const hsize_t *size, hsize_t rank)
+{
+ H5S_hyper_span_t *curr; /* Hyperslab information nodes */
+ htri_t tmp; /* temporary return value */
+ htri_t ret_value=TRUE; /* return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(spans);
+ HDassert(offset);
+ HDassert(size);
+ HDassert(rank < H5O_LAYOUT_NDIMS);
+
+ /* Check each point to determine whether selection+offset is within extent */
+ curr=spans->head;
+ while(curr!=NULL && ret_value==TRUE) {
+ /* Check if an offset has been defined */
+ /* Bounds check the selected point + offset against the extent */
+ if((((hssize_t)curr->low+offset[rank])>=(hssize_t)size[rank])
+ || (((hssize_t)curr->low+offset[rank])<0)
+ || (((hssize_t)curr->high+offset[rank])>=(hssize_t)size[rank])
+ || (((hssize_t)curr->high+offset[rank])<0)) {
+ ret_value=FALSE;
+ break;
+ } /* end if */
+
+ /* Recurse if this node has down spans */
+ if(curr->down!=NULL) {
+ if((tmp=H5S_hyper_is_valid_helper(curr->down,offset,size,rank+1))!=TRUE) {
+ ret_value=tmp;
+ break;
+ } /* end if */
+ } /* end if */
+
+ /* Advance to next node */
+ curr=curr->next;
+ } /* end while */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_hyper_is_valid_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_hyper_is_valid
PURPOSE
Check whether the selection fits within the extent, with the current
@@ -1848,23 +1750,43 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S_hyper_is_valid(const H5S_t *space)
+H5S_hyper_is_valid (const H5S_t *space)
{
- unsigned u; /* Counter */
- htri_t ret_value = TRUE; /* Return value */
+ unsigned u; /* Counter */
+ htri_t ret_value=TRUE; /* return value */
FUNC_ENTER_NOAPI_NOERR
HDassert(space);
- /* Check each dimension */
- for(u = 0; u < space->extent.rank; u++) {
- /* Bounds check the selected point + offset against the extent */
- if(((hssize_t)space->select.low_bounds[u] + space->select.offset[u]) < 0)
- HGOTO_DONE(FALSE)
- if((space->select.high_bounds[u] + (hsize_t)space->select.offset[u]) >= space->extent.size[u])
- HGOTO_DONE(FALSE)
- } /* end for */
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab->diminfo_valid) {
+ const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */
+ hssize_t end; /* The high bound of a region in a dimension */
+
+ /* Check each dimension */
+ for(u=0; u<space->extent.rank; u++) {
+ /* if block or count is zero, then can skip the test since */
+ /* no data point is chosen */
+ if (diminfo[u].count && diminfo[u].block) {
+ /* Bounds check the start point in this dimension */
+ if(((hssize_t)diminfo[u].start+space->select.offset[u])<0 ||
+ ((hssize_t)diminfo[u].start+space->select.offset[u])>=(hssize_t)space->extent.size[u])
+ HGOTO_DONE(FALSE)
+
+ /* Compute the largest location in this dimension */
+ end=(hssize_t)(diminfo[u].start+diminfo[u].stride*(diminfo[u].count-1)+(diminfo[u].block-1))+space->select.offset[u];
+
+ /* Bounds check the end point in this dimension */
+ if(end<0 || end>=(hssize_t)space->extent.size[u])
+ HGOTO_DONE(FALSE)
+ } /* end if */
+ } /* end for */
+ } /* end if */
+ else {
+ /* Call the recursive routine to validate the span tree */
+ ret_value=H5S_hyper_is_valid_helper(space->select.sel_info.hslab->span_lst,space->select.offset,space->extent.size,(hsize_t)0);
+ } /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1913,7 +1835,7 @@ H5S_hyper_span_nblocks(H5S_hyper_span_info_t *spans)
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_span_nblocks() */
+} /* H5S_hyper_span_nblocks() */
/*--------------------------------------------------------------------------
@@ -1936,15 +1858,14 @@ H5S_hyper_span_nblocks(H5S_hyper_span_info_t *spans)
static hsize_t
H5S_get_select_hyper_nblocks(H5S_t *space)
{
- hsize_t ret_value; /* Return value */
+ hsize_t ret_value; /* return value */
FUNC_ENTER_NOAPI_NOINIT_NOERR
HDassert(space);
/* Check for a "regular" hyperslab selection */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
unsigned u; /* Local index variable */
/* Check each dimension */
@@ -1955,7 +1876,7 @@ H5S_get_select_hyper_nblocks(H5S_t *space)
ret_value = H5S_hyper_span_nblocks(space->select.sel_info.hslab->span_lst);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_get_select_hyper_nblocks() */
+} /* H5S_get_select_hyper_nblocks() */
/*--------------------------------------------------------------------------
@@ -1986,7 +1907,7 @@ H5Sget_select_hyper_nblocks(hid_t spaceid)
/* Check args */
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_HYPERSLABS)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection")
@@ -1994,7 +1915,7 @@ H5Sget_select_hyper_nblocks(hid_t spaceid)
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Sget_select_hyper_nblocks() */
+} /* H5Sget_select_hyper_nblocks() */
/*--------------------------------------------------------------------------
@@ -2034,10 +1955,7 @@ H5S_hyper_serial_size(const H5S_t *space)
ret_value = 24;
/* Check for a "regular" hyperslab selection */
- /* (It would be useful to rebuild the regular hyperslab selection, if we
- * encoded it efficiently, which we aren't currently. *sigh* -QAK)
- */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
/* Check each dimension */
for(block_count = 1, u = 0; u < space->extent.rank; u++)
block_count *= space->select.sel_info.hslab->opt_diminfo[u].count;
@@ -2076,7 +1994,7 @@ H5S_hyper_serial_size(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_serialize_helper(const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **buf)
+H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end, hsize_t rank, uint8_t **buf)
{
H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
hsize_t u; /* Index variable */
@@ -2128,7 +2046,7 @@ H5S_hyper_serialize_helper(const H5S_hyper_span_info_t *spans, hsize_t *start, h
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_serialize_helper() */
+} /* H5S_hyper_serialize_helper() */
/*--------------------------------------------------------------------------
@@ -2151,7 +2069,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_serialize(const H5S_t *space, uint8_t *buf)
+H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
{
const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
@@ -2182,16 +2100,13 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t *buf)
len += 4;
/* Check for a "regular" hyperslab selection */
- /* (It would be useful to rebuild the regular hyperslab selection, if we
- * encoded it efficiently, which we aren't currently. *sigh* -QAK)
- */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
unsigned u; /* Local counting variable */
- /* Set some convenience values */
+ /* Set some convienence values */
ndims = space->extent.rank;
fast_dim = ndims - 1;
- diminfo = space->select.sel_info.hslab->opt_diminfo;
+ diminfo=space->select.sel_info.hslab->opt_diminfo;
/* Check each dimension */
for(block_count = 1, u = 0; u < ndims; u++)
@@ -2282,7 +2197,7 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t *buf)
/* Add 8 bytes times the rank for each hyperslab selected */
H5_CHECK_OVERFLOW((8 * space->extent.rank * block_count), hsize_t, size_t);
- len += (uint32_t)(8 * space->extent.rank * block_count);
+ len += (size_t)(8 * space->extent.rank * block_count);
/* Encode each hyperslab in selection */
H5S_hyper_serialize_helper(space->select.sel_info.hslab->span_lst, start, end, (hsize_t)0, &buf);
@@ -2292,7 +2207,7 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t *buf)
UINT32ENCODE(lenp, (uint32_t)len); /* Store the length of the extra information */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_serialize() */
+} /* H5S_hyper_serialize() */
/*--------------------------------------------------------------------------
@@ -2315,7 +2230,7 @@ H5S_hyper_serialize(const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_deserialize(H5S_t *space, const uint8_t *buf)
+H5S_hyper_deserialize (H5S_t *space, const uint8_t *buf)
{
uint32_t rank; /* rank of points */
size_t num_elem=0; /* number of elements in selection */
@@ -2372,7 +2287,7 @@ H5S_hyper_deserialize(H5S_t *space, const uint8_t *buf)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_deserialize() */
+} /* H5S_hyper_deserialize() */
/*--------------------------------------------------------------------------
@@ -2409,11 +2324,9 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[],
- hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks,
- hsize_t **buf)
+H5S_hyper_span_blocklist(H5S_hyper_span_info_t *spans, hsize_t start[], hsize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, hsize_t **buf)
{
- const H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
+ H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
hsize_t u; /* Index variable */
herr_t ret_value = SUCCEED; /* return value */
@@ -2478,7 +2391,7 @@ H5S_hyper_span_blocklist(const H5S_hyper_span_info_t *spans, hsize_t start[],
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_span_blocklist() */
+} /* H5S_hyper_span_blocklist() */
/*--------------------------------------------------------------------------
@@ -2521,13 +2434,8 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
HDassert(space);
HDassert(buf);
- /* Rebuild diminfo if it is invalid and has not been confirmed to be
- * impossible */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- (void)H5S_hyper_rebuild(space);
-
/* Check for a "regular" hyperslab selection */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
hsize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */
@@ -2639,7 +2547,7 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_get_select_hyper_blocklist() */
+} /* H5S_get_select_hyper_blocklist() */
/*--------------------------------------------------------------------------
@@ -2686,7 +2594,7 @@ H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
if(buf == NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
if(H5S_GET_SELECT_TYPE(space)!=H5S_SEL_HYPERSLABS)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection")
@@ -2698,7 +2606,77 @@ H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock,
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Sget_select_hyper_blocklist() */
+} /* H5Sget_select_hyper_blocklist() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_bounds_helper
+ PURPOSE
+ Gets the bounding box containing the selection.
+ USAGE
+ htri_t H5S_hyper_bounds_helper(spans, offset, rank);
+ const H5S_hyper_span_info_t *spans; IN: Pointer to current hyperslab span tree
+ const hssize_t *offset; IN: Pointer to offset array
+ hsize_t rank; IN: Current rank looking at
+ hsize_t *start; OUT: Start array bounds
+ hsize_t *end; OUT: End array bounds
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the bounding box containing the current selection and places
+ it into the user's buffers. The start and end buffers must be large
+ enough to hold the dataspace rank number of coordinates. The bounding box
+ exactly contains the selection, ie. if a 2-D element selection is currently
+ defined with the following points: (4,5), (6,8) (10,7), the bounding box
+ with be (4, 5), (10, 8).
+ The bounding box calculations _does_ include the current offset of the
+ selection within the dataspace extent.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_bounds_helper(const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end)
+{
+ H5S_hyper_span_t *curr; /* Hyperslab information nodes */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(spans);
+ HDassert(offset);
+ HDassert(rank < H5O_LAYOUT_NDIMS);
+ HDassert(start);
+ HDassert(end);
+
+ /* Check each point to determine whether selection+offset is within extent */
+ curr=spans->head;
+ while(curr!=NULL) {
+ /* Check for offset moving selection negative */
+ if(((hssize_t)curr->low + offset[rank]) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+
+ /* Check if the current span extends the bounding box */
+ if((curr->low + (hsize_t)offset[rank]) < start[rank])
+ start[rank] = curr->low + (hsize_t)offset[rank];
+ if((curr->high + (hsize_t)offset[rank]) > end[rank])
+ end[rank] = curr->high + (hsize_t)offset[rank];
+
+ /* Recurse if this node has down spans */
+ if(curr->down != NULL) {
+ if(H5S_hyper_bounds_helper(curr->down, offset, (rank + 1), start, end) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "failure in lower dimension")
+ } /* end if */
+
+ /* Advance to next node */
+ curr = curr->next;
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_hyper_bounds_helper() */
/*--------------------------------------------------------------------------
@@ -2730,33 +2708,48 @@ done:
static herr_t
H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
- unsigned u; /* Local index variable */
+ unsigned rank; /* Dataspace rank */
+ unsigned i; /* index variable */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_NOAPI(FAIL)
- /* Sanity check */
HDassert(space);
HDassert(start);
HDassert(end);
- /* Loop over dimensions */
- for(u = 0; u < space->extent.rank; u++) {
- /* Sanity check */
- HDassert(space->select.low_bounds[u] <= space->select.high_bounds[u]);
+ /* Set the start and end arrays up */
+ rank = space->extent.rank;
+ for(i = 0; i < rank; i++) {
+ start[i] = HSIZET_MAX;
+ end[i] = 0;
+ } /* end for */
- /* Check for offset moving selection negative */
- if(((hssize_t)space->select.low_bounds[u] + space->select.offset[u]) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab->diminfo_valid) {
+ const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */
- /* Set the low & high bounds in this dimension */
- start[u] = (hsize_t)((hssize_t)space->select.low_bounds[u] + space->select.offset[u]);
- end[u] = (hsize_t)((hssize_t)space->select.high_bounds[u] + space->select.offset[u]);
- } /* end for */
+ /* Check each dimension */
+ for(i = 0; i < rank; i++) {
+ /* Check for offset moving selection negative */
+ if((space->select.offset[i] + (hssize_t)diminfo[i].start) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+
+ /* Compute the smallest location in this dimension */
+ start[i] = diminfo[i].start + (hsize_t)space->select.offset[i];
+
+ /* Compute the largest location in this dimension */
+ end[i] = diminfo[i].start + diminfo[i].stride * (diminfo[i].count - 1) + (diminfo[i].block - 1) + (hsize_t)space->select.offset[i];
+ } /* end for */
+ } /* end if */
+ else {
+ /* Call the recursive routine to get the bounds for the span tree */
+ ret_value = H5S_hyper_bounds_helper(space->select.sel_info.hslab->span_lst, space->select.offset, (hsize_t)0, start, end);
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_bounds() */
+} /* H5S_hyper_bounds() */
/*--------------------------------------------------------------------------
@@ -2803,8 +2796,7 @@ H5S_hyper_offset(const H5S_t *space, hsize_t *offset)
dim_size = space->extent.size;
/* Check for a "regular" hyperslab selection */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Local alias for diminfo */
/* Loop through starting coordinates, calculating the linear offset */
@@ -2865,7 +2857,7 @@ H5S_hyper_offset(const H5S_t *space, hsize_t *offset)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_offset() */
+} /* H5S_hyper_offset() */
/*--------------------------------------------------------------------------
@@ -2899,8 +2891,7 @@ H5S_hyper_is_contiguous(const H5S_t *space)
HDassert(space);
/* Check for a "regular" hyperslab selection */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab->opt_diminfo; /* local alias for diminfo */
/*
@@ -3051,7 +3042,7 @@ H5S_hyper_is_contiguous(const H5S_t *space)
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_is_contiguous() */
+} /* H5S_hyper_is_contiguous() */
/*--------------------------------------------------------------------------
@@ -3085,8 +3076,7 @@ H5S_hyper_is_single(const H5S_t *space)
HDassert(space);
/* Check for a "single" hyperslab selection */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
/*
* For a regular hyperslab to be single, it must have only one
* block (i.e. count==1 in all dimensions)
@@ -3120,7 +3110,7 @@ H5S_hyper_is_single(const H5S_t *space)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_is_single() */
+} /* H5S_hyper_is_single() */
/*--------------------------------------------------------------------------
@@ -3153,20 +3143,14 @@ H5S_hyper_is_regular(const H5S_t *space)
/* Check args */
HDassert(space);
- /* Rebuild diminfo if it is invalid and has not been confirmed to be
- * impossible */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- /* Casting away const OK -NAF */
- (void)H5S_hyper_rebuild((H5S_t *)space);
-
/* Only simple check for regular hyperslabs for now... */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES)
- ret_value = TRUE;
+ if(space->select.sel_info.hslab->diminfo_valid)
+ ret_value=TRUE;
else
- ret_value = FALSE;
+ ret_value=FALSE;
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_is_regular() */
+} /* H5S_hyper_is_regular() */
/*--------------------------------------------------------------------------
@@ -3188,8 +3172,8 @@ H5S_hyper_is_regular(const H5S_t *space)
* Robb Matzke, 1998-08-25
* The fields which are freed are set to NULL to prevent them from being
* freed again later. This fixes some allocation problems where
- * changing the hyperslab selection of one dataspace causes a core dump
- * when closing some other dataspace.
+ * changing the hyperslab selection of one data space causes a core dump
+ * when closing some other data space.
--------------------------------------------------------------------------*/
static herr_t
H5S_hyper_release(H5S_t *space)
@@ -3215,7 +3199,48 @@ H5S_hyper_release(H5S_t *space)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_release() */
+} /* H5S_hyper_release() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_recover_span
+ PURPOSE
+ Recover a generated span, if appropriate
+ USAGE
+ herr_t H5S_hyper_recover_span(recover, curr_span, next_span)
+ unsigned *recover; IN/OUT: Pointer recover flag
+ H5S_hyper_span_t **curr_span; IN/OUT: Pointer to current span in list
+ H5S_hyper_span_t *next_span; IN: Pointer to next span
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Check if the current span needs to be recovered and free it if so.
+ Set the current span to the next span in any case.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_hyper_recover_span (unsigned *recover, H5S_hyper_span_t **curr_span, H5S_hyper_span_t *next_span)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ HDassert(recover);
+ HDassert(curr_span);
+
+ /* Check if the span should be recovered */
+ if(*recover) {
+ H5S_hyper_free_span(*curr_span);
+ *recover=0;
+ } /* end if */
+
+ /* Set the current span to next span */
+ *curr_span=next_span;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5S_hyper_recover_span() */
/*--------------------------------------------------------------------------
@@ -3237,11 +3262,11 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static H5S_hyper_span_t *
-H5S_hyper_coord_to_span(unsigned rank, const hsize_t *coords)
+H5S_hyper_coord_to_span(unsigned rank, hsize_t *coords)
{
H5S_hyper_span_t *new_span; /* Pointer to new span tree for coordinate */
- H5S_hyper_span_info_t *down = NULL; /* Pointer to new span tree for next level down */
- H5S_hyper_span_t *ret_value = NULL; /* Return value */
+ H5S_hyper_span_info_t *down=NULL; /* Pointer to new span tree for next level down */
+ H5S_hyper_span_t *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -3249,32 +3274,37 @@ H5S_hyper_coord_to_span(unsigned rank, const hsize_t *coords)
HDassert(coords);
/* Search for location to insert new element in tree */
- if(rank > 1) {
+ if(rank>1) {
/* Allocate a span info node */
- if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t)))
+ if((down = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
+ /* Set the reference count */
+ down->count=0;
+
+ /* Reset the scratch pad space */
+ down->scratch=0;
+
/* Build span tree for coordinates below this one */
- if(NULL == (down->head = H5S_hyper_coord_to_span(rank - 1, &coords[1])))
+ if((down->head=H5S_hyper_coord_to_span(rank-1,&coords[1]))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
-
- /* Update the tail pointer of the down dimension, and it's a single span element */
- down->tail = down->head;
} /* end if */
/* Build span for this coordinate */
- if(NULL == (new_span = H5S_hyper_new_span(coords[0], coords[0], down, NULL)))
+ if((new_span = H5S_hyper_new_span(coords[0],coords[0],down,NULL))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Set return value */
- ret_value = new_span;
+ ret_value=new_span;
done:
- if(ret_value == NULL && down!=NULL)
- H5S_hyper_free_span_info(down);
+ if(ret_value==NULL) {
+ if(down!=NULL)
+ H5S_hyper_free_span_info(down);
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_coord_to_span() */
+} /* H5S_hyper_coord_to_span() */
/*--------------------------------------------------------------------------
@@ -3294,29 +3324,18 @@ done:
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
Assumes that the element is not already covered by the span tree
-
- NOTE: There's an assumption about the context of this function call.
- This function is only called is only being called from
- H5D_chunk_mem_cb in src/H5Dchunk, when the library is
- iterating over a memory selection, so the coordinates passed
- to H5S_hyper_add_span_element will always be in increasing
- order (according to a row-major (i.e. C, not FORTRAN) scan
- over the dataset. Therefore, for every input of coordinates,
- only the last span element (i.e., the tail pointer) in one
- dimension is checked against the input.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree,
- unsigned rank, const hsize_t *coords)
+H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree, unsigned rank, hsize_t *coords)
{
H5S_hyper_span_info_t *tspan_info; /* Temporary pointer to span info */
H5S_hyper_span_info_t *prev_span_info; /* Pointer to span info for level above current position */
- H5S_hyper_span_t *tail_span; /* Pointer to the tail span of one dimension */
+ H5S_hyper_span_t *tmp_span; /* Temporary pointer to a span */
H5S_hyper_span_t *tmp2_span; /* Another temporary pointer to a span */
H5S_hyper_span_t *new_span; /* New span created for element */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -3325,26 +3344,38 @@ H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree,
HDassert(coords);
/* Get pointer to last span in span tree */
- tail_span = span_tree->tail;
+ tspan_info=span_tree;
+ if(span_tree->scratch)
+ tmp_span=(H5S_hyper_span_t *)span_tree->scratch;
+ else {
+ tmp_span=span_tree->head;
+ HDassert(tmp_span);
+ span_tree->scratch=(H5S_hyper_span_info_t *)tmp_span;
+ } /* end else */
/* Find last span tree which includes a portion of the coordinate */
- tspan_info = span_tree;
- prev_span_info = NULL;
- while(coords[0] >= tail_span->low && coords[0] <= tail_span->high) {
+ prev_span_info=NULL;
+ while(coords[0]>=tmp_span->low && coords[0]<=tmp_span->high) {
/* Move rank & coordinate offset down a dimension */
rank--;
coords++;
/* Remember the span tree we are descending into */
- prev_span_info = tspan_info;
- tspan_info = tail_span->down;
- HDassert(tspan_info);
- tail_span = tspan_info->tail;
+ prev_span_info=tspan_info;
+ tspan_info=tmp_span->down;
+
+ /* Get the last span in this span's 'down' tree */
+ if(tspan_info->scratch)
+ tmp_span=(H5S_hyper_span_t *)tspan_info->scratch;
+ else {
+ tmp_span=tspan_info->head;
+ HDassert(tmp_span);
+ tspan_info->scratch=(H5S_hyper_span_info_t *)tmp_span;
+ } /* end else */
} /* end while */
- HDassert(rank > 0);
/* Check if we made it all the way to the bottom span in the tree */
- if(rank > 1) {
+ if(rank>1) {
/* Before we create another span at this level in the tree, check if
* the last span's "down tree" was equal to any other spans in this
* list of spans in the span tree.
@@ -3353,31 +3384,31 @@ H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree,
* previous span (if possible), or at least share their "down tree"
* information.
*/
- tmp2_span = tspan_info->head;
- while(tmp2_span != tail_span) {
- if(TRUE == H5S_hyper_cmp_spans(tmp2_span->down, tail_span->down)) {
+ tmp2_span=tspan_info->head;
+ while(tmp2_span!=tmp_span) {
+ if(H5S_hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) {
/* Check for merging into previous span */
- if(tmp2_span->high + 1 == tail_span->low) {
+ if(tmp2_span->high+1==tmp_span->low) {
/* Release last span created */
- H5S_hyper_free_span(tail_span);
+ H5S_hyper_free_span(tmp_span);
/* Increase size of previous span */
tmp2_span->high++;
tmp2_span->nelem++;
/* Reset the 'tmp_span' for the rest of this block's algorithm */
- tail_span = tmp2_span;
+ tmp_span=tmp2_span;
} /* end if */
/* Span is disjoint, but has the same "down tree" selection */
else {
/* Release "down tree" information */
- H5S_hyper_free_span_info(tail_span->down);
+ H5S_hyper_free_span_info(tmp_span->down);
/* Point at earlier span's "down tree" */
- tail_span->down = tmp2_span->down;
+ tmp_span->down=tmp2_span->down;
/* Increment reference count on shared "down tree" */
- tail_span->down->count++;
+ tmp_span->down->count++;
} /* end else */
/* Found span to merge into, break out now */
@@ -3385,30 +3416,32 @@ H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree,
} /* end if */
/* Advance to next span to check */
- tmp2_span = tmp2_span->next;
+ tmp2_span=tmp2_span->next;
} /* end while */
/* Make span tree for current coordinates */
- if(NULL == (new_span = H5S_hyper_coord_to_span(rank, coords)))
+ if((new_span=H5S_hyper_coord_to_span(rank,coords))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Add new span tree as span */
- HDassert(tail_span);
- tail_span->next = new_span;
+ HDassert(tmp_span);
+ tmp_span->next=new_span;
+
+ /* Make scratch pointer point to last span in list */
HDassert(tspan_info);
- tspan_info->tail = new_span;
+ tspan_info->scratch=(H5S_hyper_span_info_t *)new_span;
/* Set the proper 'pstride' for new span */
- new_span->pstride = new_span->low - tail_span->low;
+ new_span->pstride=new_span->low-tmp_span->low;
} /* end if */
else {
/* Does new node adjoin existing node? */
- if(tail_span->high + 1 == coords[0]) {
- tail_span->high++;
- tail_span->nelem++;
+ if(tmp_span->high+1==coords[0]) {
+ tmp_span->high++;
+ tmp_span->nelem++;
/* Check if this span tree should now be merged with a level higher in the tree */
- if(prev_span_info != NULL) {
+ if(prev_span_info!=NULL) {
/* Before we create another span at this level in the tree, check if
* the last span's "down tree" was equal to any other spans in this
* list of spans in the span tree.
@@ -3417,33 +3450,33 @@ H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree,
* previous span (if possible), or at least share their "down tree"
* information.
*/
- tmp2_span = prev_span_info->head;
- tail_span = prev_span_info->tail;
- while(tmp2_span != tail_span) {
- if(TRUE == H5S_hyper_cmp_spans(tmp2_span->down, tail_span->down)) {
+ tmp2_span=prev_span_info->head;
+ tmp_span=(H5S_hyper_span_t *)prev_span_info->scratch;
+ while(tmp2_span!=tmp_span) {
+ if(H5S_hyper_cmp_spans(tmp2_span->down,tmp_span->down)==TRUE) {
/* Check for merging into previous span */
- if(tmp2_span->high + 1 == tail_span->low) {
+ if(tmp2_span->high+1==tmp_span->low) {
/* Release last span created */
- H5S_hyper_free_span(tail_span);
+ H5S_hyper_free_span(tmp_span);
/* Increase size of previous span */
tmp2_span->high++;
tmp2_span->nelem++;
/* Update pointers */
- tmp2_span->next = NULL;
- prev_span_info->tail = tmp2_span;
+ tmp2_span->next=NULL;
+ prev_span_info->scratch=(H5S_hyper_span_info_t *)tmp2_span;
} /* end if */
/* Span is disjoint, but has the same "down tree" selection */
else {
/* Release "down tree" information */
- H5S_hyper_free_span_info(tail_span->down);
+ H5S_hyper_free_span_info(tmp_span->down);
/* Point at earlier span's "down tree" */
- tail_span->down = tmp2_span->down;
+ tmp_span->down=tmp2_span->down;
/* Increment reference count on shared "down tree" */
- tail_span->down->count++;
+ tmp_span->down->count++;
} /* end else */
/* Found span to merge into, break out now */
@@ -3451,27 +3484,29 @@ H5S_hyper_add_span_element_helper(H5S_hyper_span_info_t *span_tree,
} /* end if */
/* Advance to next span to check */
- tmp2_span = tmp2_span->next;
+ tmp2_span=tmp2_span->next;
} /* end while */
} /* end if */
} /* end if */
else {
- if(NULL == (new_span = H5S_hyper_new_span(coords[0], coords[0], NULL, NULL)))
+ if((new_span = H5S_hyper_new_span(coords[0],coords[0],NULL,NULL))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Add new span tree as span */
- HDassert(tail_span);
- tail_span->next = new_span;
- tspan_info->tail = new_span;
+ HDassert(tmp_span);
+ tmp_span->next=new_span;
+
+ /* Make scratch pointer point to last span in list */
+ tspan_info->scratch=(H5S_hyper_span_info_t *)new_span;
/* Set the proper 'pstride' for new span */
- new_span->pstride = new_span->low - tail_span->low;
+ new_span->pstride=new_span->low-tmp_span->low;
} /* end else */
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_add_span_element_helper() */
+} /* H5S_hyper_add_span_element_helper() */
/*--------------------------------------------------------------------------
@@ -3495,7 +3530,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords)
+H5S_hyper_add_span_element(H5S_t *space, unsigned rank, hsize_t *coords)
{
H5S_hyper_span_info_t *head = NULL; /* Pointer to new head of span tree */
herr_t ret_value = SUCCEED; /* Return value */
@@ -3505,24 +3540,23 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords)
HDassert(space);
HDassert(rank > 0);
HDassert(coords);
- HDassert(space->extent.rank == rank);
/* Check if this is the first element in the selection */
if(NULL == space->select.sel_info.hslab) {
/* Allocate a span info node */
- if(NULL == (head = H5FL_CALLOC(H5S_hyper_span_info_t)))
+ if(NULL == (head = H5FL_MALLOC(H5S_hyper_span_info_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Set the reference count */
head->count = 1;
+ /* Reset the scratch pad space */
+ head->scratch = 0;
+
/* Build span tree for this coordinate */
if(NULL == (head->head = H5S_hyper_coord_to_span(rank, coords)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
- /* Update the tail pointer of this newly created span in dimension "rank" */
- head->tail = head->head;
-
/* Allocate selection info */
if(NULL == (space->select.sel_info.hslab = H5FL_MALLOC(H5S_hyper_sel_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
@@ -3534,7 +3568,7 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, const hsize_t *coords)
space->select.type = H5S_sel_hyper;
/* Reset "regular" hyperslab flag */
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
+ space->select.sel_info.hslab->diminfo_valid = FALSE;
/* Set # of elements in selection */
space->select.num_elem = 1;
@@ -3553,7 +3587,7 @@ done:
H5S_hyper_free_span_info(head);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_add_span_element() */
+} /* H5S_hyper_add_span_element() */
/*--------------------------------------------------------------------------
@@ -3587,7 +3621,7 @@ H5S_hyper_reset_scratch(H5S_t *space)
H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_reset_scratch() */
+} /* H5S_hyper_reset_scratch() */
/*--------------------------------------------------------------------------
@@ -3657,7 +3691,126 @@ H5S_hyper_convert(H5S_t *space)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_convert() */
+} /* H5S_hyper_convert() */
+
+#ifdef LATER
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_intersect_helper
+ PURPOSE
+ Helper routine to detect intersections in span trees
+ USAGE
+ htri_t H5S_hyper_intersect_helper(spans1, spans2)
+ H5S_hyper_span_info_t *spans1; IN: First span tree to operate with
+ H5S_hyper_span_info_t *spans2; IN: Second span tree to operate with
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Quickly detect intersections between two span trees
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static htri_t
+H5S_hyper_intersect_helper (H5S_hyper_span_info_t *spans1, H5S_hyper_span_info_t *spans2)
+{
+ H5S_hyper_span_t *curr1; /* Pointer to current span in 1st span tree */
+ H5S_hyper_span_t *curr2; /* Pointer to current span in 2nd span tree */
+ htri_t status; /* Status from recursive call */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity check */
+ HDassert((spans1 && spans2) || (spans1 == NULL && spans2 == NULL));
+
+ /* "NULL" span trees compare as overlapping */
+ if(spans1==NULL && spans2==NULL)
+ HGOTO_DONE(TRUE);
+
+ /* Get the span lists for each span in this tree */
+ curr1=spans1->head;
+ curr2=spans2->head;
+
+ /* Iterate over the spans in each tree */
+ while(curr1!=NULL && curr2!=NULL) {
+ /* Check for 1st span entirely before 2nd span */
+ if(curr1->high<curr2->low)
+ curr1=curr1->next;
+ /* Check for 2nd span entirely before 1st span */
+ else if(curr2->high<curr1->low)
+ curr2=curr2->next;
+ /* Spans must overlap */
+ else {
+ /* Recursively check spans in next dimension down */
+ if((status=H5S_hyper_intersect_helper(curr1->down,curr2->down))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check")
+
+ /* If there is a span intersection in the down dimensions, the span trees overlap */
+ if(status==TRUE)
+ HGOTO_DONE(TRUE);
+
+ /* No intersection in down dimensions, advance to next span */
+ if(curr1->high<curr2->high)
+ curr1=curr1->next;
+ else
+ curr2=curr2->next;
+ } /* end else */
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_hyper_intersect_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_intersect
+ PURPOSE
+ Detect intersections in span trees
+ USAGE
+ htri_t H5S_hyper_intersect(space1, space2)
+ H5S_t *space1; IN: First dataspace to operate on span tree
+ H5S_t *space2; IN: Second dataspace to operate on span tree
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Quickly detect intersections between two span trees
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5S_hyper_intersect (H5S_t *space1, H5S_t *space2)
+{
+ htri_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Sanity check */
+ HDassert(space1);
+ HDassert(space2);
+
+ /* Check that the space selections both have span trees */
+ if(space1->select.sel_info.hslab->span_lst==NULL ||
+ space2->select.sel_info.hslab->span_lst==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
+
+ /* Check that the dataspaces are both the same rank */
+ if(space1->extent.rank!=space2->extent.rank)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "dataspace ranks don't match")
+
+ /* Perform the span-by-span intersection check */
+ if((ret_value=H5S_hyper_intersect_helper(space1->select.sel_info.hslab->span_lst,space2->select.sel_info.hslab->span_lst))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_hyper_intersect() */
+#endif /* LATER */
/*--------------------------------------------------------------------------
@@ -3681,8 +3834,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S_hyper_intersect_block_helper(const H5S_hyper_span_info_t *spans,
- const hsize_t *start, const hsize_t *end)
+H5S_hyper_intersect_block_helper (const H5S_hyper_span_info_t *spans, hsize_t *start, hsize_t *end)
{
H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */
htri_t status; /* Status from recursive call */
@@ -3728,7 +3880,7 @@ H5S_hyper_intersect_block_helper(const H5S_hyper_span_info_t *spans,
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_intersect_block_helper() */
+} /* H5S_hyper_intersect_block_helper() */
/*--------------------------------------------------------------------------
@@ -3751,9 +3903,9 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end)
+H5S_hyper_intersect_block (H5S_t *space, hsize_t *start, hsize_t *end)
{
- htri_t ret_value = FAIL; /* Return value */
+ htri_t ret_value=FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -3764,30 +3916,30 @@ H5S_hyper_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end
/* Check for 'all' selection, instead of a hyperslab selection */
/* (Technically, this shouldn't be in the "hyperslab" routines...) */
- if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL)
+ if(H5S_GET_SELECT_TYPE(space)==H5S_SEL_ALL)
HGOTO_DONE(TRUE);
/* Check that the space selection has a span tree */
- if(space->select.sel_info.hslab->span_lst == NULL)
- if(H5S_hyper_generate_spans(space) < 0)
+ if(space->select.sel_info.hslab->span_lst==NULL)
+ if(H5S_hyper_generate_spans(space)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
/* Perform the span-by-span intersection check */
- if((ret_value = H5S_hyper_intersect_block_helper(space->select.sel_info.hslab->span_lst, start, end)) < 0)
+ if((ret_value=H5S_hyper_intersect_block_helper(space->select.sel_info.hslab->span_lst,start,end))<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_intersect_block() */
+} /* H5S_hyper_intersect_block() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_adjust_u_helper
+ H5S_hyper_adjust_helper_u
PURPOSE
Helper routine to adjust offsets in span trees
USAGE
- herr_t H5S_hyper_adjust_u_helper(spans, offset)
+ herr_t H5S_hyper_adjust_helper_u(spans, offset)
H5S_hyper_span_info_t *spans; IN: Span tree to operate with
const hsize_t *offset; IN: Offset to subtract
RETURNS
@@ -3800,7 +3952,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, const hsize_t *offset)
+H5S_hyper_adjust_helper_u (H5S_hyper_span_info_t *spans, const hsize_t *offset)
{
H5S_hyper_span_t *span; /* Pointer to current span in span tree */
@@ -3827,7 +3979,7 @@ H5S_hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, const hsize_t *offset)
/* Recursively adjust spans in next dimension down */
if(span->down!=NULL)
- H5S_hyper_adjust_u_helper(span->down,offset+1);
+ H5S_hyper_adjust_helper_u(span->down,offset+1);
/* Advance to next span in this dimension */
span=span->next;
@@ -3835,7 +3987,7 @@ H5S_hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, const hsize_t *offset)
} /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_adjust_u_helper() */
+} /* H5S_hyper_adjust_helper_u() */
/*--------------------------------------------------------------------------
@@ -3859,9 +4011,8 @@ H5S_hyper_adjust_u_helper(H5S_hyper_span_info_t *spans, const hsize_t *offset)
static herr_t
H5S_hyper_adjust_u(H5S_t *space, const hsize_t *offset)
{
- hbool_t update_bound = FALSE; /* Indicate whether to update bound */
unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -3869,39 +4020,25 @@ H5S_hyper_adjust_u(H5S_t *space, const hsize_t *offset)
HDassert(offset);
/* Subtract the offset from the "regular" coordinates, if they exist */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
- for(u = 0; u < space->extent.rank; u++) {
- HDassert(space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]);
- space->select.sel_info.hslab->opt_diminfo[u].start -= offset[u];
+ if(space->select.sel_info.hslab->diminfo_valid) {
+ for(u=0; u<space->extent.rank; u++) {
+ HDassert(space->select.sel_info.hslab->opt_diminfo[u].start>=offset[u]);
+ space->select.sel_info.hslab->opt_diminfo[u].start-=offset[u];
} /* end for */
-
- update_bound = TRUE;
} /* end if */
/* Subtract the offset from the span tree coordinates, if they exist */
if(space->select.sel_info.hslab->span_lst) {
- if(H5S_hyper_adjust_u_helper(space->select.sel_info.hslab->span_lst, offset) < 0)
+ if(H5S_hyper_adjust_helper_u(space->select.sel_info.hslab->span_lst,offset)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset adjustment")
/* Reset the scratch pointers for the next routine which needs them */
H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
-
- update_bound = TRUE;
- } /* end if */
-
- if(update_bound) {
- /* Update the bound box of this hyperslab */
- for(u = 0; u < space->extent.rank; u++) {
- HDassert(space->select.low_bounds[u] >= offset[u]);
- space->select.low_bounds[u] -= offset[u];
- space->select.high_bounds[u] -= offset[u];
- } /* end for */
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_adjust_u() */
+} /* H5S_hyper_adjust_u() */
/*-------------------------------------------------------------------------
@@ -3930,8 +4067,7 @@ H5S_hyper_project_scalar(const H5S_t *space, hsize_t *offset)
HDassert(offset);
/* Check for a "regular" hyperslab selection */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
const H5S_hyper_dim_t *diminfo = space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */
unsigned u; /* Counter */
@@ -3966,11 +4102,11 @@ H5S_hyper_project_scalar(const H5S_t *space, hsize_t *offset)
} /* end else */
/* Calculate offset of selection in projected buffer */
- *offset = H5VM_array_offset(space->extent.rank, space->extent.size, block);
+ *offset = H5VM_array_offset(space->extent.rank, space->extent.size, block);
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_project_scalar() */
+} /* H5S_hyper_project_scalar() */
/*-------------------------------------------------------------------------
@@ -3991,7 +4127,6 @@ H5S_hyper_project_simple_lower(const H5S_t *base_space, H5S_t *new_space)
{
H5S_hyper_span_info_t *down; /* Pointer to list of spans */
unsigned curr_dim; /* Current dimension being operated on */
- unsigned u; /* Local index variable */
FUNC_ENTER_NOAPI_NOINIT_NOERR
@@ -4013,18 +4148,12 @@ H5S_hyper_project_simple_lower(const H5S_t *base_space, H5S_t *new_space)
} /* end while */
HDassert(down);
- /* Update the bounding box */
- for(u = 0; u < new_space->extent.rank; u++) {
- new_space->select.low_bounds[u] = base_space->select.low_bounds[u + curr_dim];
- new_space->select.high_bounds[u] = base_space->select.high_bounds[u + curr_dim];
- } /* end for */
-
/* Share the underlying hyperslab span information */
new_space->select.sel_info.hslab->span_lst = down;
new_space->select.sel_info.hslab->span_lst->count++;
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_project_simple_lower() */
+} /* H5S_hyper_project_simple_lower() */
/*-------------------------------------------------------------------------
@@ -4045,7 +4174,6 @@ H5S_hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space)
{
H5S_hyper_span_t *prev_span = NULL; /* Pointer to previous list of spans */
unsigned curr_dim; /* Current dimension being operated on */
- unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -4063,7 +4191,7 @@ H5S_hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space)
H5S_hyper_span_t *new_span; /* Temporary hyperslab span */
/* Allocate a new span_info node */
- if(NULL == (new_span_info = H5FL_CALLOC(H5S_hyper_span_info_t))) {
+ if(NULL == (new_span_info = H5FL_MALLOC(H5S_hyper_span_info_t))) {
if(prev_span)
if(H5S_hyper_free_span(prev_span) < 0)
HERROR(H5E_DATASPACE, H5E_CANTFREE, "can't free hyperslab span");
@@ -4075,7 +4203,7 @@ H5S_hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space)
prev_span->down = new_span_info;
/* Allocate a new node */
- if(NULL == (new_span = H5S_hyper_new_span((hsize_t)0, (hsize_t)0, NULL, NULL))) {
+ if(NULL == (new_span = H5S_hyper_new_span(0, 0, NULL, NULL))) {
HDassert(new_span_info);
if(!prev_span)
(void)H5FL_FREE(H5S_hyper_span_info_t, new_span_info);
@@ -4084,8 +4212,8 @@ H5S_hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space)
/* Set the span_info information */
new_span_info->count = 1;
+ new_span_info->scratch = NULL;
new_span_info->head = new_span;
- new_span_info->tail = new_span;
/* Attach to new space, if top span info */
if(NULL == new_space->select.sel_info.hslab->span_lst)
@@ -4100,16 +4228,6 @@ H5S_hyper_project_simple_higher(const H5S_t *base_space, H5S_t *new_space)
HDassert(new_space->select.sel_info.hslab->span_lst);
HDassert(prev_span);
- /* Update the bounding box */
- for(u = 0; u < curr_dim; u++) {
- new_space->select.low_bounds[u] = 0;
- new_space->select.high_bounds[u] = 0;
- } /* end for */
- for(; u < new_space->extent.rank; u++) {
- new_space->select.low_bounds[u] = base_space->select.low_bounds[u - curr_dim];
- new_space->select.high_bounds[u] = base_space->select.high_bounds[u - curr_dim];
- } /* end for */
-
/* Share the underlying hyperslab span information */
prev_span->down = base_space->select.sel_info.hslab->span_lst;
prev_span->down->count++;
@@ -4125,7 +4243,7 @@ done:
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_project_simple_higher() */
+} /* H5S_hyper_project_simple_higher() */
/*-------------------------------------------------------------------------
@@ -4162,22 +4280,21 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
/* Check for a "regular" hyperslab selection */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(base_space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(base_space->select.sel_info.hslab->diminfo_valid) {
unsigned base_space_dim; /* Current dimension in the base dataspace */
unsigned new_space_dim; /* Current dimension in the new dataspace */
- unsigned u; /* Local index variable */
/* Check if the new space's rank is < or > base space's rank */
if(new_space->extent.rank < base_space->extent.rank) {
const H5S_hyper_dim_t *opt_diminfo = base_space->select.sel_info.hslab->opt_diminfo; /* Alias for dataspace's diminfo information */
hsize_t block[H5S_MAX_RANK]; /* Block selected in base dataspace */
+ unsigned u; /* Local index variable */
/* Compute the offset for the down-projection */
HDmemset(block, 0, sizeof(block));
for(u = 0; u < (base_space->extent.rank - new_space->extent.rank); u++)
block[u] = opt_diminfo[u].start;
- *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block);
+ *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block);
/* Set the correct dimensions for the base & new spaces */
base_space_dim = base_space->extent.rank - new_space->extent.rank;
@@ -4208,22 +4325,22 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off
/* Copy the diminfo */
while(base_space_dim < base_space->extent.rank) {
- new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start =
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].start =
base_space->select.sel_info.hslab->app_diminfo[base_space_dim].start;
- new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride =
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].stride =
base_space->select.sel_info.hslab->app_diminfo[base_space_dim].stride;
- new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count =
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].count =
base_space->select.sel_info.hslab->app_diminfo[base_space_dim].count;
- new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block =
+ new_space->select.sel_info.hslab->app_diminfo[new_space_dim].block =
base_space->select.sel_info.hslab->app_diminfo[base_space_dim].block;
- new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start =
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].start =
base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].start;
new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].stride =
base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].stride;
- new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count =
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].count =
base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].count;
- new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block =
+ new_space->select.sel_info.hslab->opt_diminfo[new_space_dim].block =
base_space->select.sel_info.hslab->opt_diminfo[base_space_dim].block;
/* Advance to next dimensions */
@@ -4231,14 +4348,8 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off
new_space_dim++;
} /* end for */
- /* Update the bounding box */
- for(u = 0; u < new_space->extent.rank; u++) {
- new_space->select.low_bounds[u] = new_space->select.sel_info.hslab->opt_diminfo[u].start;
- new_space->select.high_bounds[u] = new_space->select.low_bounds[u] + new_space->select.sel_info.hslab->opt_diminfo[u].stride * (new_space->select.sel_info.hslab->opt_diminfo[u].count - 1) + (new_space->select.sel_info.hslab->opt_diminfo[u].block - 1);
- } /* end for */
-
/* Indicate that the dimension information is valid */
- new_space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_YES;
+ new_space->select.sel_info.hslab->diminfo_valid = TRUE;
/* Indicate that there's no slab information */
new_space->select.sel_info.hslab->span_lst = NULL;
@@ -4266,7 +4377,7 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off
} /* end while */
/* Compute the offset for the down-projection */
- *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block);
+ *offset = H5VM_array_offset(base_space->extent.rank, base_space->extent.size, block);
/* Project the base space's selection down in less dimensions */
if(H5S_hyper_project_simple_lower(base_space, new_space) < 0)
@@ -4278,13 +4389,13 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off
/* The offset is zero when projected into higher dimensions */
*offset = 0;
- /* Project the base space's selection down in more dimensions */
+ /* Project the base space's selection down in less dimensions */
if(H5S_hyper_project_simple_higher(base_space, new_space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't project hyperslab selection into less dimensions")
} /* end else */
- /* Copy the status of the dimension information */
- new_space->select.sel_info.hslab->diminfo_valid = base_space->select.sel_info.hslab->diminfo_valid;
+ /* Indicate that the dimension information is not valid */
+ new_space->select.sel_info.hslab->diminfo_valid = FALSE;
} /* end else */
/* Number of elements selected will be the same */
@@ -4295,16 +4406,16 @@ H5S_hyper_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *off
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_project_simple() */
+} /* H5S_hyper_project_simple() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_adjust_s_helper
+ H5S_hyper_adjust_helper_s
PURPOSE
Helper routine to adjust offsets in span trees
USAGE
- herr_t H5S_hyper_adjust_s_helper(spans, offset)
+ herr_t H5S_hyper_adjust_helper_s(spans, offset)
H5S_hyper_span_info_t *spans; IN: Span tree to operate with
const hssize_t *offset; IN: Offset to subtract
RETURNS
@@ -4317,7 +4428,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, const hssize_t *offset)
+H5S_hyper_adjust_helper_s(H5S_hyper_span_info_t *spans, const hssize_t *offset)
{
H5S_hyper_span_t *span; /* Pointer to current span in span tree */
@@ -4344,7 +4455,7 @@ H5S_hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, const hssize_t *offset)
/* Recursively adjust spans in next dimension down */
if(span->down != NULL)
- H5S_hyper_adjust_s_helper(span->down, offset + 1);
+ H5S_hyper_adjust_helper_s(span->down, offset + 1);
/* Advance to next span in this dimension */
span = span->next;
@@ -4352,7 +4463,7 @@ H5S_hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, const hssize_t *offset)
} /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_adjust_s_helper() */
+} /* H5S_hyper_adjust_helper_s() */
/*--------------------------------------------------------------------------
@@ -4376,7 +4487,6 @@ H5S_hyper_adjust_s_helper(H5S_hyper_span_info_t *spans, const hssize_t *offset)
herr_t
H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset)
{
- hbool_t update_bound = FALSE; /* Indicate whether to update bound */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -4386,42 +4496,25 @@ H5S_hyper_adjust_s(H5S_t *space, const hssize_t *offset)
HDassert(offset);
/* Subtract the offset from the "regular" coordinates, if they exist */
- /* (No need to rebuild the dimension info yet -QAK) */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
for(u = 0; u < space->extent.rank; u++) {
HDassert((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start >= offset[u]);
space->select.sel_info.hslab->opt_diminfo[u].start = (hsize_t)((hssize_t)space->select.sel_info.hslab->opt_diminfo[u].start - offset[u]);
} /* end for */
-
- update_bound = TRUE;
} /* end if */
/* Subtract the offset from the span tree coordinates, if they exist */
if(space->select.sel_info.hslab->span_lst) {
- if(H5S_hyper_adjust_s_helper(space->select.sel_info.hslab->span_lst, offset) < 0)
+ if(H5S_hyper_adjust_helper_s(space->select.sel_info.hslab->span_lst, offset) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab offset adjustment")
/* Reset the scratch pointers for the next routine which needs them */
H5S_hyper_span_scratch(space->select.sel_info.hslab->span_lst, NULL);
-
- update_bound = TRUE;
- } /* end if */
-
- if(update_bound) {
- /* Update the bound box of this hyperslab */
- for(u = 0; u < space->extent.rank; u++) {
- hssize_t tmp = (hssize_t)space->select.low_bounds[u];
-
- HDassert(tmp >= offset[u]);
- space->select.low_bounds[u] = (hsize_t)(tmp - offset[u]);
- tmp = (hssize_t)space->select.high_bounds[u];
- space->select.high_bounds[u] = (hsize_t)(tmp - offset[u]);
- } /* end for */
} /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_adjust_s() */
+} /* H5S_hyper_adjust_s() */
/*--------------------------------------------------------------------------
@@ -4476,7 +4569,7 @@ H5S_hyper_normalize_offset(H5S_t *space, hssize_t *old_offset)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_normalize_offset() */
+} /* H5S_hyper_normalize_offset() */
/*--------------------------------------------------------------------------
@@ -4519,7 +4612,7 @@ H5S_hyper_denormalize_offset(H5S_t *space, const hssize_t *old_offset)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_denormalize_offset() */
+} /* H5S_hyper_denormalize_offset() */
/*--------------------------------------------------------------------------
@@ -4545,8 +4638,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_append_span(H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t **span_tree,
- hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next)
+H5S_hyper_append_span (H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t ** span_tree, hsize_t low, hsize_t high, H5S_hyper_span_info_t *down, H5S_hyper_span_t *next)
{
H5S_hyper_span_t *new_span = NULL;
herr_t ret_value = SUCCEED; /* Return value */
@@ -4557,51 +4649,51 @@ H5S_hyper_append_span(H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t **span
HDassert(span_tree);
/* Check for adding first node to merged spans */
- if(*prev_span == NULL) {
+ if(*prev_span==NULL) {
/* Allocate new span node to append to list */
- if(NULL == (new_span = H5S_hyper_new_span(low, high, down, next)))
+ if((new_span = H5S_hyper_new_span(low,high,down,next))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Make first node in span list */
/* Check that we haven't already allocated a span tree */
- HDassert(*span_tree == NULL);
+ HDassert(*span_tree==NULL);
/* Allocate a new span_info node */
- if(NULL == (*span_tree = H5FL_CALLOC(H5S_hyper_span_info_t)))
+ if((*span_tree = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Set the span tree's basic information */
- (*span_tree)->count = 1;
- (*span_tree)->head = new_span;
- (*span_tree)->tail = new_span;
+ (*span_tree)->count=1;
+ (*span_tree)->scratch=NULL;
+ (*span_tree)->head=new_span;
/* Update previous merged span */
- *prev_span = new_span;
+ *prev_span=new_span;
} /* end if */
/* Merge or append to existing merged spans list */
else {
/* Check if span can just extend the previous merged span */
- if((((*prev_span)->high + 1) == low) &&
- TRUE == H5S_hyper_cmp_spans(down, (*prev_span)->down)) {
+ if((((*prev_span)->high+1)==low) &&
+ H5S_hyper_cmp_spans(down,(*prev_span)->down)==TRUE) {
/* Extend previous merged span to include new high bound */
- (*prev_span)->high = high;
- (*prev_span)->nelem += (high - low) + 1;
+ (*prev_span)->high=high;
+ (*prev_span)->nelem+=(high-low)+1;
} /* end if */
else {
/* Allocate new span node to append to list */
- if(NULL == (new_span = H5S_hyper_new_span(low, high, down, next)))
+ if((new_span = H5S_hyper_new_span(low,high,down,next))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Check if there is actually a down span */
if(new_span->down) {
/* Check if the down spans for the new span node are the same as the previous span node */
- if(TRUE == H5S_hyper_cmp_spans(new_span->down, (*prev_span)->down)) {
+ if(H5S_hyper_cmp_spans(new_span->down,(*prev_span)->down)==TRUE) {
/* Release the down span for the new node */
H5S_hyper_free_span_info(new_span->down);
/* Point the new node's down span at the previous node's down span */
- new_span->down = (*prev_span)->down;
+ new_span->down=(*prev_span)->down;
/* Increment the reference count to the shared down span */
new_span->down->count++;
@@ -4609,23 +4701,23 @@ H5S_hyper_append_span(H5S_hyper_span_t **prev_span, H5S_hyper_span_info_t **span
} /* end if */
/* Indicate elements from previous span */
- new_span->pstride = low - (*prev_span)->low;
+ new_span->pstride=low-(*prev_span)->low;
/* Append to end of merged spans list */
- (*prev_span)->next = new_span;
- *prev_span = new_span;
-
- (*span_tree)->tail = new_span;
+ (*prev_span)->next=new_span;
+ *prev_span=new_span;
} /* end else */
} /* end else */
done:
- if(ret_value < 0)
- if(new_span && H5S_hyper_free_span(new_span) < 0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release new hyperslab span")
+ if(ret_value < 0) {
+ if(new_span)
+ if(H5S_hyper_free_span(new_span) < 0)
+ HDONE_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release new hyperslab span")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_append_span() */
+} /* H5S_hyper_append_span() */
/*--------------------------------------------------------------------------
@@ -4634,24 +4726,9 @@ done:
PURPOSE
Clip a new span tree against the current spans in the hyperslab selection
USAGE
- herr_t H5S_hyper_clip_spans(span_a, span_b, selector, cur_dim, dim_size,
- span_a_b_bounds[4], all_clips_bound,
- a_not_b, a_and_b, b_not_a)
+ herr_t H5S_hyper_clip_spans(span_a, span_b, a_not_b, a_and_b, b_not_a)
H5S_hyper_span_t *a_spans; IN: Span tree 'a' to clip with.
H5S_hyper_span_t *b_spans; IN: Span tree 'b' to clip with.
- unsigned int selector; IN: The parameter deciding which output is needed
- (only considering the last three bits ABC:
- If A is set, then a_not_b is needed;
- If B is set, then a_and_b is needed;
- If C is set, then b_not_a is needed;
- )
- unsigned int cur_dim; IN: The dimension in which this clip operation
- is performed.
- unsigned int dim_size; IN: The dimension size.
- const hsize_t *span_a_b_bounds[4]; IN: The bound box of span a and span b.
- hsize_t *all_clips_bounds; OUT: The array containing the bounds box
- of all three clipped span tree in the order
- a_not_b, a_and_b and b_not_a.
H5S_hyper_span_t **a_not_b; OUT: Span tree of 'a' hyperslab spans which
doesn't overlap with 'b' hyperslab
spans.
@@ -4674,29 +4751,21 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans,
- unsigned int selector, unsigned cur_dim, unsigned dim_size,
- const hsize_t *span_a_b_bounds[4], hsize_t *all_clips_bounds,
+H5S_hyper_clip_spans (H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans,
H5S_hyper_span_info_t **a_not_b, H5S_hyper_span_info_t **a_and_b,
H5S_hyper_span_info_t **b_not_a)
{
- H5S_hyper_span_t *span_a; /* Pointer to a node in span tree 'a' */
- H5S_hyper_span_t *span_b; /* Pointer to a node in span tree 'b' */
- const hsize_t *span_a_low_bounds; /* The low bound array for span a */
- const hsize_t *span_a_high_bounds; /* The high bound array for span a */
- const hsize_t *span_b_low_bounds; /* The low bound array for span b */
- const hsize_t *span_b_high_bounds; /* The high bound array for span b */
- hsize_t *a_not_b_low_bounds; /* The low bound array for a_not_b */
- hsize_t *a_not_b_high_bounds; /* The high bound array for a_not_b */
- hsize_t *a_and_b_low_bounds; /* The low bound array for a_and_b */
- hsize_t *a_and_b_high_bounds; /* The high bound array for a_and_b */
- hsize_t *b_not_a_low_bounds; /* The low bound array for b_not_a */
- hsize_t *b_not_a_high_bounds; /* The high bound array for b_not_a */
- hbool_t need_a_not_b = FALSE; /* Whether to generate a_not_b list */
- hbool_t need_a_and_b = FALSE; /* Whether to generate a_and_b list */
- hbool_t need_b_not_a = FALSE; /* Whether to generate b_not_a list */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_hyper_span_t *span_a; /* Pointer to a node in span tree 'a' */
+ H5S_hyper_span_t *span_b; /* Pointer to a node in span tree 'b' */
+ H5S_hyper_span_t *tmp_span; /* Temporary pointer to new span */
+ H5S_hyper_span_t *last_a_not_b; /* Pointer to previous node in span tree 'a_not_b' */
+ H5S_hyper_span_t *last_a_and_b; /* Pointer to previous node in span tree 'a_and_b' */
+ H5S_hyper_span_t *last_b_not_a; /* Pointer to previous node in span tree 'b_not_a' */
+ H5S_hyper_span_info_t *down_a_not_b; /* Temporary pointer to a_not_b span tree of down spans for overlapping nodes */
+ H5S_hyper_span_info_t *down_a_and_b; /* Temporary pointer to a_and_b span tree of down spans for overlapping nodes */
+ H5S_hyper_span_info_t *down_b_not_a; /* Temporary pointer to b_and_a span tree of down spans for overlapping nodes */
+ unsigned recover_a, recover_b; /* Flags to indicate when to recover temporary spans */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -4706,151 +4775,76 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
HDassert(a_not_b);
HDassert(a_and_b);
HDassert(b_not_a);
- HDassert(cur_dim < dim_size);
- HDassert(all_clips_bounds);
- HDassert(span_a_b_bounds);
-
- /* Set the values of bound box pointers */
- span_a_low_bounds = span_a_b_bounds[0];
- span_a_high_bounds = span_a_b_bounds[1];
- span_b_low_bounds = span_a_b_bounds[2];
- span_b_high_bounds = span_a_b_bounds[3];
- a_not_b_low_bounds = all_clips_bounds;
- a_not_b_high_bounds = all_clips_bounds + dim_size;
- a_and_b_low_bounds = all_clips_bounds + 2 * dim_size;
- a_and_b_high_bounds = all_clips_bounds + 3 * dim_size;
- b_not_a_low_bounds = all_clips_bounds + 4 * dim_size;
- b_not_a_high_bounds = all_clips_bounds + 5 * dim_size;
-
- /* Set which list(s) to be generated, based on selector */
- if(H5S_HYPER_COMPUTE_B_NOT_A == (selector & H5S_HYPER_COMPUTE_B_NOT_A))
- need_b_not_a = TRUE;
- if(H5S_HYPER_COMPUTE_A_AND_B == (selector & H5S_HYPER_COMPUTE_A_AND_B))
- need_a_and_b = TRUE;
- if(H5S_HYPER_COMPUTE_A_NOT_B == (selector & H5S_HYPER_COMPUTE_A_NOT_B))
- need_a_not_b = TRUE;
/* Check if both span trees are not defined */
- if(a_spans == NULL && b_spans == NULL) {
- *a_not_b = NULL;
- *a_and_b = NULL;
- *b_not_a = NULL;
+ if(a_spans==NULL && b_spans==NULL) {
+ *a_not_b=NULL;
+ *a_and_b=NULL;
+ *b_not_a=NULL;
} /* end if */
/* If span 'a' is not defined, but 'b' is, copy 'b' and set the other return span trees to empty */
- else if(a_spans == NULL) {
- *a_not_b = NULL;
- *a_and_b = NULL;
- if(need_b_not_a) {
- if(NULL == (*b_not_a = H5S_hyper_copy_span(b_spans)))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
-
- /* update b_not_a's bound box based on the values from span_b's bound box */
- for(u = cur_dim; u < dim_size; u++) {
- b_not_a_low_bounds[u] = MIN(b_not_a_low_bounds[u], span_b_low_bounds[u]);
- b_not_a_high_bounds[u] = MAX(b_not_a_high_bounds[u], span_b_high_bounds[u]);
- } /* end for */
- } /* end if */
- else
- *b_not_a = NULL;
+ else if(a_spans==NULL) {
+ *a_not_b=NULL;
+ *a_and_b=NULL;
+ if((*b_not_a=H5S_hyper_copy_span(b_spans))==NULL)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
} /* end if */
/* If span 'b' is not defined, but 'a' is, copy 'a' and set the other return span trees to empty */
- else if(b_spans == NULL) {
- *a_and_b = NULL;
- *b_not_a = NULL;
- if(need_a_not_b) {
- if(NULL == (*a_not_b = H5S_hyper_copy_span(a_spans)))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
-
- /* update b_not_a's bound box based on the values from span_a's bound box */
- for(u = cur_dim; u < dim_size; u++) {
- a_not_b_low_bounds[u] = MIN(a_not_b_low_bounds[u], span_a_low_bounds[u]);
- a_not_b_high_bounds[u] = MAX(a_not_b_high_bounds[u], span_a_high_bounds[u]);
- } /* end for */
- } /* end if */
- else
- *a_not_b = NULL;
+ else if(b_spans==NULL) {
+ if((*a_not_b=H5S_hyper_copy_span(a_spans))==NULL)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
+ *a_and_b=NULL;
+ *b_not_a=NULL;
} /* end if */
/* If span 'a' and 'b' are both defined, calculate the proper span trees */
else {
/* Check if both span trees completely overlap */
- if(H5S_hyper_cmp_spans(a_spans, b_spans) == TRUE) {
- *a_not_b = NULL;
- *b_not_a = NULL;
- if(need_a_and_b) {
- if(NULL == (*a_and_b = H5S_hyper_copy_span(a_spans)))
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
-
- /* update a_and_b's bound box based on the values from span_a's bound box */
- for(u = cur_dim; u < dim_size; u++) {
- a_and_b_low_bounds[u] = MIN(a_and_b_low_bounds[u], span_a_low_bounds[u]);
- a_and_b_high_bounds[u] = MAX(a_and_b_high_bounds[u], span_a_high_bounds[u]);
- } /* end for */
- } /* end if */
- else
- *a_and_b = NULL;
+ if(H5S_hyper_cmp_spans(a_spans,b_spans)==TRUE) {
+ *a_not_b=NULL;
+ if((*a_and_b=H5S_hyper_copy_span(a_spans))==NULL)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, FAIL, "can't copy hyperslab span tree")
+ *b_not_a=NULL;
} /* end if */
else {
- H5S_hyper_span_t *last_a_not_b; /* Pointer to previous node in span tree 'a_not_b' */
- H5S_hyper_span_t *last_a_and_b; /* Pointer to previous node in span tree 'a_and_b' */
- H5S_hyper_span_t *last_b_not_a; /* Pointer to previous node in span tree 'b_not_a' */
- hbool_t update_a_not_b_bounds, update_b_not_a_bounds; /* Flags to indicate that bounds should be updated */
- hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */
-
/* Get the pointers to the new and old span lists */
- span_a = a_spans->head;
- span_b = b_spans->head;
+ span_a=a_spans->head;
+ span_b=b_spans->head;
- /* Reset the pointers to the previous spans */
- last_a_not_b = last_a_and_b = last_b_not_a = NULL;
+ /* Set the pointer to the previous spans */
+ last_a_not_b=NULL;
+ last_a_and_b=NULL;
+ last_b_not_a=NULL;
/* No spans to recover yet */
- recover_a = recover_b = FALSE;
-
- /* No bounds to update yet */
- update_a_not_b_bounds = update_b_not_a_bounds = FALSE;
+ recover_a=recover_b=0;
/* Work through the list of spans in the new list */
- while(span_a != NULL && span_b != NULL) {
- H5S_hyper_span_info_t *down_a_not_b; /* Temporary pointer to a_not_b span tree of down spans for overlapping nodes */
- H5S_hyper_span_info_t *down_a_and_b; /* Temporary pointer to a_and_b span tree of down spans for overlapping nodes */
- H5S_hyper_span_info_t *down_b_not_a; /* Temporary pointer to b_and_a span tree of down spans for overlapping nodes */
- H5S_hyper_span_t *tmp_span; /* Temporary pointer to new span */
-
+ while(span_a!=NULL && span_b!=NULL) {
/* Check if span 'a' is completely before span 'b' */
/* AAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- if(span_a->high < span_b->low) {
+ if(span_a->high<span_b->low) {
/* Copy span 'a' and add to a_not_b list */
/* Merge/add span 'a' with/to a_not_b list */
- if(need_a_not_b) {
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_a->high, span_a->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Indicate that the a_not_b bounds should be updated */
- update_a_not_b_bounds = TRUE;
- } /* end if */
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,span_a->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Advance span 'a', leave span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
} /* end if */
/* Check if span 'a' overlaps only the lower bound */
/* of span 'b' , up to the upper bound of span 'b' */
/* AAAAAAAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if(span_a->low < span_b->low && (span_a->high >= span_b->low && span_a->high <= span_b->high)) {
+ else if(span_a->low<span_b->low && (span_a->high>=span_b->low && span_a->high<=span_b->high)) {
/* Split span 'a' into two parts at the low bound of span 'b' */
/* Merge/add lower part of span 'a' with/to a_not_b list */
- if(need_a_not_b) {
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_b->low - 1, span_a->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Indicate that the a_not_b bounds should be updated */
- update_a_not_b_bounds = TRUE;
- } /* end if */
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Check for overlaps between upper part of span 'a' and lower part of span 'b' */
@@ -4858,33 +4852,26 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL));
/* If there are no down spans, just add the overlapping area to the a_and_b list */
- if(span_a->down == NULL) {
+ if(span_a->down==NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(need_a_and_b)
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_a->high, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_a->high,NULL,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
} /* end if */
/* If there are down spans, check for the overlap in them and add to each appropriate list */
else {
/* NULL out the temporary pointers to clipped areas in down spans */
- down_a_not_b = NULL;
- down_a_and_b = NULL;
- down_b_not_a = NULL;
+ down_a_not_b=NULL;
+ down_a_and_b=NULL;
+ down_b_not_a=NULL;
/* Check for overlaps in the 'down spans' of span 'a' & 'b' */
- /** Note: since the bound box of remaining dimensions
- * has been updated in the following clip function (via
- * all_clips_bounds), there's no need updating the bound box
- * after each append call in the following codes */
- if(H5S_hyper_clip_spans(span_a->down, span_b->down, selector, cur_dim + 1, dim_size, span_a_b_bounds, all_clips_bounds, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0)
+ if(H5S_hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
/* Check for additions to the a_not_b list */
- if(down_a_not_b) {
- HDassert(need_a_not_b == TRUE);
-
+ if(down_a_not_b!=NULL) {
/* Merge/add overlapped part with/to a_not_b list */
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_b->low, span_a->high, down_a_not_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_a->high,down_a_not_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -4892,11 +4879,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the a_and_b list */
- if(down_a_and_b) {
- HDassert(need_a_and_b == TRUE);
-
+ if(down_a_and_b!=NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_a->high, down_a_and_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_a->high,down_a_and_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -4904,11 +4889,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the b_not_a list */
- if(down_b_not_a) {
- HDassert(need_b_not_a == TRUE);
-
+ if(down_b_not_a!=NULL) {
/* Merge/add overlapped part with/to b_not_a list */
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_b->low, span_a->high, down_b_not_a, NULL) < 0)
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->high,down_b_not_a,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -4919,23 +4902,23 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
/* Split off upper part of span 'b' at upper span of span 'a' */
/* Check if there is actually an upper part of span 'b' to split off */
- if(span_a->high < span_b->high) {
+ if(span_a->high<span_b->high) {
/* Allocate new span node for upper part of span 'b' */
- if(NULL == (tmp_span = H5S_hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next)))
+ if((tmp_span = H5S_hyper_new_span(span_a->high+1,span_b->high,span_b->down,span_b->next))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Advance span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
/* Make upper part of span 'b' into new span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span);
- recover_b = TRUE;
+ H5S_hyper_recover_span(&recover_b,&span_b,tmp_span);
+ recover_b=1;
} /* end if */
/* No upper part of span 'b' to split */
else {
/* Advance both 'a' and 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end else */
} /* end if */
/* Check if span 'a' overlaps the lower & upper bound */
@@ -4943,17 +4926,12 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
/* AAAAAAAAAAAAAAAAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if(span_a->low < span_b->low && span_a->high > span_b->high) {
+ else if(span_a->low<span_b->low && span_a->high>span_b->high) {
/* Split off lower part of span 'a' at lower span of span 'b' */
/* Merge/add lower part of span 'a' with/to a_not_b list */
- if(need_a_not_b) {
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_b->low - 1, span_a->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Indicate that the a_not_b bounds should be updated */
- update_a_not_b_bounds = TRUE;
- } /* end if */
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->low-1,span_a->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Check for overlaps between middle part of span 'a' and span 'b' */
@@ -4961,29 +4939,26 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL));
/* If there are no down spans, just add the overlapping area to the a_and_b list */
- if(span_a->down == NULL) {
+ if(span_a->down==NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(need_a_and_b)
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_b->high, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,NULL,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
} /* end if */
/* If there are down spans, check for the overlap in them and add to each appropriate list */
else {
/* NULL out the temporary pointers to clipped areas in down spans */
- down_a_not_b = NULL;
- down_a_and_b = NULL;
- down_b_not_a = NULL;
+ down_a_not_b=NULL;
+ down_a_and_b=NULL;
+ down_b_not_a=NULL;
/* Check for overlaps in the 'down spans' of span 'a' & 'b' */
- if(H5S_hyper_clip_spans(span_a->down, span_b->down, selector, cur_dim + 1, dim_size, span_a_b_bounds, all_clips_bounds, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0)
+ if(H5S_hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
/* Check for additions to the a_not_b list */
- if(down_a_not_b) {
- HDassert(need_a_not_b == TRUE);
-
+ if(down_a_not_b!=NULL) {
/* Merge/add overlapped part with/to a_not_b list */
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b,span_b->low, span_b->high, down_a_not_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_b->low,span_b->high,down_a_not_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -4991,11 +4966,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the a_and_b list */
- if(down_a_and_b) {
- HDassert(need_a_and_b == TRUE);
-
+ if(down_a_and_b!=NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_b->low, span_b->high, down_a_and_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_b->low,span_b->high,down_a_and_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5003,11 +4976,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the b_not_a list */
- if(down_b_not_a) {
- HDassert(need_b_not_a == TRUE);
-
+ if(down_b_not_a!=NULL) {
/* Merge/add overlapped part with/to b_not_a list */
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_b->low, span_b->high, down_b_not_a, NULL) < 0)
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,down_b_not_a,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5018,33 +4989,28 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
/* Split off upper part of span 'a' at upper span of span 'b' */
/* Allocate new span node for upper part of span 'a' */
- if(NULL == (tmp_span = H5S_hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next)))
+ if((tmp_span = H5S_hyper_new_span(span_b->high+1,span_a->high,span_a->down,span_a->next))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Make upper part of span 'a' the new span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span);
- recover_a = TRUE;
+ H5S_hyper_recover_span(&recover_a,&span_a,tmp_span);
+ recover_a=1;
/* Advance span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end if */
/* Check if span 'a' is entirely within span 'b' */
/* AAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if(span_a->low >= span_b->low && span_a->high <= span_b->high) {
+ else if(span_a->low>=span_b->low && span_a->high<=span_b->high) {
/* Split off lower part of span 'b' at lower span of span 'a' */
/* Check if there is actually a lower part of span 'b' to split off */
- if(span_a->low > span_b->low) {
+ if(span_a->low>span_b->low) {
/* Merge/add lower part of span 'b' with/to b_not_a list */
- if(need_b_not_a) {
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_b->low, span_a->low - 1, span_b->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Indicate that the b_not_a bounds should be updated */
- update_b_not_a_bounds = TRUE;
- } /* end if */
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
} /* end if */
else {
/* Keep going, nothing to split off */
@@ -5056,29 +5022,26 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL));
/* If there are no down spans, just add the overlapping area to the a_and_b list */
- if(span_a->down == NULL) {
+ if(span_a->down==NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(need_a_and_b)
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_a->low, span_a->high, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,NULL,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
} /* end if */
/* If there are down spans, check for the overlap in them and add to each appropriate list */
else {
/* NULL out the temporary pointers to clipped areas in down spans */
- down_a_not_b = NULL;
- down_a_and_b = NULL;
- down_b_not_a = NULL;
+ down_a_not_b=NULL;
+ down_a_and_b=NULL;
+ down_b_not_a=NULL;
/* Check for overlaps in the 'down spans' of span 'a' & 'b' */
- if(H5S_hyper_clip_spans(span_a->down, span_b->down, selector, cur_dim + 1, dim_size, span_a_b_bounds, all_clips_bounds, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0)
+ if(H5S_hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
/* Check for additions to the a_not_b list */
- if(down_a_not_b) {
- HDassert(need_a_not_b == TRUE);
-
+ if(down_a_not_b!=NULL) {
/* Merge/add overlapped part with/to a_not_b list */
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_a->high, down_a_not_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,down_a_not_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5086,11 +5049,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the a_and_b list */
- if(down_a_and_b) {
- HDassert(need_a_and_b == TRUE);
-
+ if(down_a_and_b!=NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_a->low, span_a->high, down_a_and_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_a->high,down_a_and_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5098,11 +5059,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the b_not_a list */
- if(down_b_not_a) {
- HDassert(need_b_not_a == TRUE);
-
+ if(down_b_not_a!=NULL) {
/* Merge/add overlapped part with/to b_not_a list */
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_a->low, span_a->high, down_b_not_a, NULL) < 0)
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_a->high,down_b_not_a,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5111,24 +5070,24 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end else */
/* Check if there is actually an upper part of span 'b' to split off */
- if(span_a->high < span_b->high) {
+ if(span_a->high<span_b->high) {
/* Split off upper part of span 'b' at upper span of span 'a' */
/* Allocate new span node for upper part of spans 'a' */
- if(NULL == (tmp_span = H5S_hyper_new_span(span_a->high + 1, span_b->high, span_b->down, span_b->next)))
+ if((tmp_span = H5S_hyper_new_span(span_a->high+1,span_b->high,span_b->down,span_b->next))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* And advance span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
/* Make upper part of span 'b' the new span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span);
- recover_b = TRUE;
+ H5S_hyper_recover_span(&recover_b,&span_b,tmp_span);
+ recover_b=1;
} /* end if */
else {
/* Advance both span 'a' & span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end else */
} /* end if */
/* Check if span 'a' overlaps only the upper bound */
@@ -5136,19 +5095,14 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
/* AAAAAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if((span_a->low >= span_b->low && span_a->low <= span_b->high) && span_a->high > span_b->high) {
+ else if((span_a->low>=span_b->low && span_a->low<=span_b->high) && span_a->high>span_b->high) {
/* Check if there is actually a lower part of span 'b' to split off */
- if(span_a->low > span_b->low) {
+ if(span_a->low>span_b->low) {
/* Split off lower part of span 'b' at lower span of span 'a' */
/* Merge/add lower part of span 'b' with/to b_not_a list */
- if(need_b_not_a) {
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_b->low, span_a->low - 1, span_b->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Indicate that the b_not_a bounds should be updated */
- update_b_not_a_bounds = TRUE;
- } /* end if */
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
} /* end if */
else {
/* Keep going, nothing to split off */
@@ -5160,29 +5114,26 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
HDassert((span_a->down != NULL && span_b->down != NULL) || (span_a->down == NULL && span_b->down == NULL));
/* If there are no down spans, just add the overlapping area to the a_and_b list */
- if(span_a->down == NULL) {
+ if(span_a->down==NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(need_a_and_b)
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_a->low, span_b->high, NULL, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,NULL,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
} /* end if */
/* If there are down spans, check for the overlap in them and add to each appropriate list */
else {
/* NULL out the temporary pointers to clipped areas in down spans */
- down_a_not_b = NULL;
- down_a_and_b = NULL;
- down_b_not_a = NULL;
+ down_a_not_b=NULL;
+ down_a_and_b=NULL;
+ down_b_not_a=NULL;
/* Check for overlaps in the 'down spans' of span 'a' & 'b' */
- if(H5S_hyper_clip_spans(span_a->down, span_b->down, selector, cur_dim + 1, dim_size, span_a_b_bounds, all_clips_bounds, &down_a_not_b, &down_a_and_b, &down_b_not_a) < 0)
+ if(H5S_hyper_clip_spans(span_a->down,span_b->down,&down_a_not_b,&down_a_and_b,&down_b_not_a)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
/* Check for additions to the a_not_b list */
- if(down_a_not_b) {
- HDassert(need_a_not_b == TRUE);
-
+ if(down_a_not_b!=NULL) {
/* Merge/add overlapped part with/to a_not_b list */
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_b->high, down_a_not_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_b->high,down_a_not_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5190,11 +5141,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the a_and_b list */
- if(down_a_and_b) {
- HDassert(need_a_and_b == TRUE);
-
+ if(down_a_and_b!=NULL) {
/* Merge/add overlapped part with/to a_and_b list */
- if(H5S_hyper_append_span(&last_a_and_b, a_and_b, span_a->low, span_b->high, down_a_and_b, NULL) < 0)
+ if(H5S_hyper_append_span(&last_a_and_b,a_and_b,span_a->low,span_b->high,down_a_and_b,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5202,11 +5151,9 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
} /* end if */
/* Check for additions to the b_not_a list */
- if(down_b_not_a) {
- HDassert(need_b_not_a == TRUE);
-
+ if(down_b_not_a!=NULL) {
/* Merge/add overlapped part with/to b_not_a list */
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_a->low, span_b->high, down_b_not_a, NULL) < 0)
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_a->low,span_b->high,down_b_not_a,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Release the down span tree generated */
@@ -5217,15 +5164,15 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
/* Split off upper part of span 'a' at upper span of span 'b' */
/* Allocate new span node for upper part of span 'a' */
- if(NULL == (tmp_span = H5S_hyper_new_span(span_b->high + 1, span_a->high, span_a->down, span_a->next)))
+ if((tmp_span = H5S_hyper_new_span(span_b->high+1,span_a->high,span_a->down,span_a->next))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Make upper part of span 'a' into new span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span);
- recover_a = TRUE;
+ H5S_hyper_recover_span(&recover_a,&span_a,tmp_span);
+ recover_a=1;
/* Advance span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end if */
/* span 'a' must be entirely above span 'b' */
/* AAAAA */
@@ -5235,103 +5182,46 @@ H5S_hyper_clip_spans(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_sp
/* Copy span 'b' and add to b_not_a list */
/* Merge/add span 'b' with/to b_not_a list */
- if(need_b_not_a) {
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_b->low, span_b->high, span_b->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Indicate that the b_not_a bounds should be updated */
- update_b_not_a_bounds = TRUE;
- } /* end if */
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
/* Advance span 'b', leave span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end else */
} /* end while */
/* Clean up 'a' spans which haven't been covered yet */
- if(span_a != NULL && span_b == NULL) {
- /* Check if need to merge/add 'a' spans with/to a_not_b list */
- if(need_a_not_b) {
- while(span_a != NULL) {
- /* Copy span 'a' and add to a_not_b list */
- if(H5S_hyper_append_span(&last_a_not_b, a_not_b, span_a->low, span_a->high, span_a->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
+ if(span_a!=NULL && span_b==NULL) {
+ while(span_a!=NULL) {
+ /* Copy span 'a' and add to a_not_b list */
- /* Advance to the next 'a' span */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
- } /* end while */
+ /* Merge/add span 'a' with/to a_not_b list */
+ if(H5S_hyper_append_span(&last_a_not_b,a_not_b,span_a->low,span_a->high,span_a->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
- /* Indicate that the a_not_b bounds should be updated */
- update_a_not_b_bounds = TRUE;
- } /* end if */
- else {
- /* Free the span, if it's generated */
- if(recover_a)
- H5S_hyper_free_span(span_a);
- } /* end else */
+ /* Advance to the next 'a' span */
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
+ } /* end while */
} /* end if */
/* Clean up 'b' spans which haven't been covered yet */
- else if(span_a == NULL && span_b != NULL) {
- /* Check if need to merge/add 'b' spans with/to b_not_a list */
- if(need_b_not_a) {
- while(span_b != NULL) {
- /* Copy span 'b' and add to b_not_a list */
- if(H5S_hyper_append_span(&last_b_not_a, b_not_a, span_b->low, span_b->high, span_b->down, NULL) < 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
-
- /* Advance to the next 'b' span */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
- } /* end while */
-
- /* Indicate that the b_not_a bounds should be updated */
- update_b_not_a_bounds = TRUE;
- } /* end if */
- else {
- /* Free the span, if it's generated */
- if(recover_b)
- H5S_hyper_free_span(span_b);
- } /* end else */
- } /* end if */
+ else if(span_a==NULL && span_b!=NULL) {
+ while(span_b!=NULL) {
+ /* Copy span 'b' and add to b_not_a list */
- /* Check for needing to update each set of bounds */
- if(update_a_not_b_bounds) {
- /* Update bounding box of a_not_b for remaining dimensions as a span was appended */
- for(u = cur_dim + 1; u < dim_size; u++) {
- a_not_b_low_bounds[u] = MIN(a_not_b_low_bounds[u], span_a_low_bounds[u]);
- a_not_b_high_bounds[u] = MAX(a_not_b_high_bounds[u], span_a_high_bounds[u]);
- } /* end for */
- } /* end if */
- if(update_b_not_a_bounds) {
- /* Update bounding box of b_not_a for remaining dimensions as a span was appended */
- for(u = cur_dim + 1; u < dim_size; u++) {
- b_not_a_low_bounds[u] = MIN(b_not_a_low_bounds[u], span_b_low_bounds[u]);
- b_not_a_high_bounds[u] = MAX(b_not_a_high_bounds[u], span_b_high_bounds[u]);
- } /* end for */
- } /* end if */
+ /* Merge/add span 'b' with/to b_not_a list */
+ if(H5S_hyper_append_span(&last_b_not_a,b_not_a,span_b->low,span_b->high,span_b->down,NULL)==FAIL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
- /**
- * Up to this point, the clip operation has been applied to one
- * span list in one dimension. So it's time to update the bound
- * box of the clipped span trees.
- */
- if(need_a_not_b && *a_not_b != NULL) {
- a_not_b_low_bounds[cur_dim] = MIN(a_not_b_low_bounds[cur_dim], (*a_not_b)->head->low);
- a_not_b_high_bounds[cur_dim] = MAX(a_not_b_high_bounds[cur_dim], (*a_not_b)->tail->high);
- } /* end if */
- if(need_a_and_b && *a_and_b != NULL) {
- a_and_b_low_bounds[cur_dim] = MIN(a_and_b_low_bounds[cur_dim], (*a_and_b)->head->low);
- a_and_b_high_bounds[cur_dim] = MAX(a_and_b_high_bounds[cur_dim], (*a_and_b)->tail->high);
- } /* end if */
- if(need_b_not_a && *b_not_a != NULL) {
- b_not_a_low_bounds[cur_dim] = MIN(b_not_a_low_bounds[cur_dim], (*b_not_a)->head->low);
- b_not_a_high_bounds[cur_dim] = MAX(b_not_a_high_bounds[cur_dim], (*b_not_a)->tail->high);
+ /* Advance to the next 'b' span */
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
+ } /* end while */
} /* end if */
} /* end else */
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_clip_spans() */
+} /* H5S_hyper_clip_spans() */
/*--------------------------------------------------------------------------
@@ -5356,10 +5246,16 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static H5S_hyper_span_info_t *
-H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans)
+H5S_hyper_merge_spans_helper (H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info_t *b_spans)
{
- H5S_hyper_span_info_t *merged_spans = NULL; /* Pointer to the merged span tree */
- H5S_hyper_span_info_t *ret_value; /* Return value */
+ H5S_hyper_span_info_t *merged_spans=NULL; /* Pointer to the merged span tree */
+ H5S_hyper_span_info_t *tmp_spans; /* Pointer to temporary new span tree */
+ H5S_hyper_span_t *tmp_span; /* Pointer to temporary new span */
+ H5S_hyper_span_t *span_a; /* Pointer to current span 'a' working on */
+ H5S_hyper_span_t *span_b; /* Pointer to current span 'b' working on */
+ H5S_hyper_span_t *prev_span_merge; /* Pointer to previous merged span */
+ unsigned recover_a, recover_b; /* Flags to indicate when to recover temporary spans */
+ H5S_hyper_span_info_t *ret_value;
FUNC_ENTER_NOAPI_NOINIT
@@ -5367,54 +5263,46 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HDassert((a_spans != NULL && b_spans != NULL) || (a_spans == NULL && b_spans == NULL));
/* Check if the span trees for the 'a' span and the 'b' span are the same */
- if(H5S_hyper_cmp_spans(a_spans, b_spans) == TRUE) {
- if(a_spans == NULL)
- merged_spans = NULL;
+ if(H5S_hyper_cmp_spans(a_spans,b_spans)==TRUE) {
+ if(a_spans==NULL)
+ merged_spans=NULL;
else {
/* Copy one of the span trees to return */
- if(NULL == (merged_spans = H5S_hyper_copy_span(a_spans)))
+ if((merged_spans=H5S_hyper_copy_span(a_spans))==NULL)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTCOPY, NULL, "can't copy hyperslab span tree")
} /* end else */
} /* end if */
else {
- H5S_hyper_span_t *span_a; /* Pointer to current span 'a' working on */
- H5S_hyper_span_t *span_b; /* Pointer to current span 'b' working on */
- H5S_hyper_span_t *prev_span_merge; /* Pointer to previous merged span */
- hbool_t recover_a, recover_b; /* Flags to indicate when to recover temporary spans */
-
/* Get the pointers to the 'a' and 'b' span lists */
- span_a = a_spans->head;
- span_b = b_spans->head;
+ span_a=a_spans->head;
+ span_b=b_spans->head;
/* Set the pointer to the previous spans */
- prev_span_merge = NULL;
+ prev_span_merge=NULL;
/* No spans to recover yet */
- recover_a = recover_b = FALSE;
+ recover_a=recover_b=0;
/* Work through the list of spans in the new list */
while(span_a!=NULL && span_b!=NULL) {
- H5S_hyper_span_info_t *tmp_spans; /* Pointer to temporary new span tree */
- H5S_hyper_span_t *tmp_span; /* Pointer to temporary new span */
-
/* Check if the 'a' span is completely before 'b' span */
/* AAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- if(span_a->high < span_b->low) {
+ if(span_a->high<span_b->low) {
/* Merge/add span 'a' with/to the merged spans */
if(H5S_hyper_append_span(&prev_span_merge,&merged_spans,span_a->low,span_a->high,span_a->down,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Advance span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
} /* end if */
/* Check if span 'a' overlaps only the lower bound */
/* of span 'b', up to the upper bound of span 'b' */
/* AAAAAAAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if(span_a->low < span_b->low && (span_a->high >= span_b->low && span_a->high <= span_b->high)) {
+ else if(span_a->low<span_b->low && (span_a->high>=span_b->low && span_a->high<=span_b->high)) {
/* Check if span 'a' and span 'b' down spans are equal */
if(H5S_hyper_cmp_spans(span_a->down,span_b->down)==TRUE) {
/* Merge/add copy of span 'a' with/to merged spans */
@@ -5438,7 +5326,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
} /* end else */
/* Check if there is an upper part of span 'b' */
- if(span_a->high < span_b->high) {
+ if(span_a->high<span_b->high) {
/* Copy upper part of span 'b' as new span 'b' */
/* Allocate new span node to append to list */
@@ -5446,16 +5334,16 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Advance span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
/* Set new span 'b' to tmp_span */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span);
- recover_b = TRUE;
+ H5S_hyper_recover_span(&recover_b,&span_b,tmp_span);
+ recover_b=1;
} /* end if */
else {
/* Advance both span 'a' & 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end else */
} /* end if */
/* Check if span 'a' overlaps the lower & upper bound */
@@ -5463,7 +5351,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
/* AAAAAAAAAAAAAAAAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if(span_a->low < span_b->low && span_a->high > span_b->high) {
+ else if(span_a->low<span_b->low && span_a->high>span_b->high) {
/* Check if span 'a' and span 'b' down spans are equal */
if(H5S_hyper_cmp_spans(span_a->down,span_b->down)==TRUE) {
/* Merge/add copy of lower & middle parts of span 'a' to merged spans */
@@ -5493,17 +5381,17 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Set new span 'a' to tmp_span */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span);
- recover_a = TRUE;
+ H5S_hyper_recover_span(&recover_a,&span_a,tmp_span);
+ recover_a=1;
/* Advance span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end if */
/* Check if span 'a' is entirely within span 'b' */
/* AAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if(span_a->low >= span_b->low && span_a->high <= span_b->high) {
+ else if(span_a->low>=span_b->low && span_a->high<=span_b->high) {
/* Check if span 'a' and span 'b' down spans are equal */
if(H5S_hyper_cmp_spans(span_a->down,span_b->down)==TRUE) {
/* Merge/add copy of lower & middle parts of span 'b' to merged spans */
@@ -5512,7 +5400,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
} /* end if */
else {
/* Check if there is a lower part of span 'b' */
- if(span_a->low > span_b->low) {
+ if(span_a->low>span_b->low) {
/* Merge/add lower part of span 'b' to merged spans */
if(H5S_hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
@@ -5533,7 +5421,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
} /* end else */
/* Check if there is an upper part of span 'b' */
- if(span_a->high < span_b->high) {
+ if(span_a->high<span_b->high) {
/* Copy upper part of span 'b' as new span 'b' (remember to free) */
/* Allocate new span node to append to list */
@@ -5541,16 +5429,16 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Advance span 'a' */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
/* Set new span 'b' to tmp_span */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, tmp_span);
- recover_b = TRUE;
+ H5S_hyper_recover_span(&recover_b,&span_b,tmp_span);
+ recover_b=1;
} /* end if */
else {
/* Advance both spans */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end else */
} /* end if */
/* Check if span 'a' overlaps only the upper bound */
@@ -5558,7 +5446,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
/* AAAAAAAAAA */
/* <-----------------------------------> */
/* BBBBBBBBBB */
- else if((span_a->low >= span_b->low && span_a->low <= span_b->high) && span_a->high > span_b->high) {
+ else if((span_a->low>=span_b->low && span_a->low<=span_b->high) && span_a->high>span_b->high) {
/* Check if span 'a' and span 'b' down spans are equal */
if(H5S_hyper_cmp_spans(span_a->down,span_b->down)==TRUE) {
/* Merge/add copy of span 'b' to merged spans if so */
@@ -5567,7 +5455,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
} /* end if */
else {
/* Check if there is a lower part of span 'b' */
- if(span_a->low > span_b->low) {
+ if(span_a->low>span_b->low) {
/* Merge/add lower part of span 'b' to merged spans */
if(H5S_hyper_append_span(&prev_span_merge,&merged_spans,span_b->low,span_a->low-1,span_b->down,NULL)==FAIL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
@@ -5594,11 +5482,11 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Set new span 'a' to tmp_span */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, tmp_span);
- recover_a = TRUE;
+ H5S_hyper_recover_span(&recover_a,&span_a,tmp_span);
+ recover_a=1;
/* Advance span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end if */
/* Span 'a' must be entirely above span 'b' */
/* AAAAA */
@@ -5610,7 +5498,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Advance span 'b' */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end else */
} /* end while */
@@ -5622,7 +5510,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Advance to next 'a' span, until all processed */
- H5S_HYPER_ADVANCE_SPAN(recover_a, span_a, span_a->next);
+ H5S_hyper_recover_span(&recover_a,&span_a,span_a->next);
} /* end while */
} /* end if */
@@ -5634,7 +5522,7 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
/* Advance to next 'b' span, until all processed */
- H5S_HYPER_ADVANCE_SPAN(recover_b, span_b, span_b->next);
+ H5S_hyper_recover_span(&recover_b,&span_b,span_b->next);
} /* end while */
} /* end if */
} /* end else */
@@ -5643,12 +5531,14 @@ H5S_hyper_merge_spans_helper(H5S_hyper_span_info_t *a_spans, H5S_hyper_span_info
ret_value = merged_spans;
done:
- if(ret_value == NULL)
- if(merged_spans && H5S_hyper_free_span_info(merged_spans) < 0)
- HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "failed to release merged hyperslab spans")
+ if(ret_value == NULL) {
+ if(merged_spans)
+ if(H5S_hyper_free_span_info(merged_spans) < 0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, NULL, "failed to release merged hyperslab spans")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_merge_spans_helper() */
+} /* H5S_hyper_merge_spans_helper() */
/*--------------------------------------------------------------------------
@@ -5662,6 +5552,9 @@ done:
selection.
H5S_hyper_span_t *new_spans; IN: Span tree of new spans to add to
hyperslab selection
+ hbool_t can_own; IN: Flag to indicate that it is OK to point
+ directly to the new spans, instead of
+ copying them.
RETURNS
non-negative on success, negative on failure
DESCRIPTION
@@ -5674,38 +5567,41 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_merge_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans)
+H5S_hyper_merge_spans (H5S_t *space, H5S_hyper_span_info_t *new_spans, hbool_t can_own)
{
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
HDassert(space);
HDassert(new_spans);
/* If this is the first span tree in the hyperslab selection, just use it */
- if(space->select.sel_info.hslab->span_lst == NULL)
- space->select.sel_info.hslab->span_lst = new_spans;
+ if(space->select.sel_info.hslab->span_lst==NULL) {
+ if(can_own)
+ space->select.sel_info.hslab->span_lst=new_spans;
+ else
+ space->select.sel_info.hslab->span_lst=H5S_hyper_copy_span(new_spans);
+ } /* end if */
else {
H5S_hyper_span_info_t *merged_spans;
/* Get the merged spans */
- if(NULL == (merged_spans = H5S_hyper_merge_spans_helper(space->select.sel_info.hslab->span_lst, new_spans)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTMERGE, FAIL, "can't merge hyperslab spans")
+ merged_spans=H5S_hyper_merge_spans_helper(space->select.sel_info.hslab->span_lst, new_spans);
+
+ /* Sanity checking since we started with some spans, we should still have some after the merge */
+ HDassert(merged_spans);
/* Free the previous spans */
- if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
+ H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst);
/* Point to the new merged spans */
- space->select.sel_info.hslab->span_lst = merged_spans;
+ space->select.sel_info.hslab->span_lst=merged_spans;
} /* end else */
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_merge_spans() */
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* H5S_hyper_merge_spans() */
+
/*--------------------------------------------------------------------------
NAME
H5S_hyper_spans_nelem
@@ -5724,150 +5620,34 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static hsize_t
-H5S_hyper_spans_nelem(const H5S_hyper_span_info_t *spans)
+H5S_hyper_spans_nelem (H5S_hyper_span_info_t *spans)
{
- hsize_t ret_value = 0; /* Return value */
+ H5S_hyper_span_t *span; /* Hyperslab span */
+ hsize_t ret_value;
FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Count the number of elements in the span tree */
- if(spans != NULL) {
- const H5S_hyper_span_t *span; /* Hyperslab span */
-
- span = spans->head;
- while(span != NULL) {
+ if(spans==NULL)
+ ret_value=0;
+ else {
+ span=spans->head;
+ ret_value=0;
+ while(span!=NULL) {
/* If there are down spans, multiply the size of this span by the total down span elements */
- if(span->down != NULL)
- ret_value += span->nelem * H5S_hyper_spans_nelem(span->down);
+ if(span->down!=NULL)
+ ret_value+=span->nelem*H5S_hyper_spans_nelem(span->down);
/* If there are no down spans, just count the elements in this span */
else
- ret_value += span->nelem;
+ ret_value+=span->nelem;
/* Advance to next span */
- span = span->next;
+ span=span->next;
} /* end while */
} /* end else */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_spans_nelem() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_hyper_add_disjoint_spans
- PURPOSE
- Add new hyperslab spans to existing hyperslab selection in the case the
- new hyperslab spans don't overlap or border with the existing hyperslab
- selection
- USAGE
- herr_t H5S_hyper_add_disjoint_spans(space, new_spans)
- H5S_t *space; IN: Dataspace to add new spans to hyperslab
- selection.
- H5S_hyper_span_t *new_spans; IN: Span tree of new spans to add to
- hyperslab selection
- RETURNS
- non-negative on success, negative on failure
- DESCRIPTION
- Add a set of hyperslab spans to an existing hyperslab selection. The
- new spans are required not to overlap or borderwith the existing spans
- in the dataspace's current hyperslab selection in terms of bound box.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5S_hyper_add_disjoint_spans(H5S_t *space, H5S_hyper_span_info_t *new_spans)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check args */
- HDassert(space);
- HDassert(new_spans);
-
- /* update the number of elements in the selection */
- space->select.num_elem += H5S_hyper_spans_nelem(new_spans);
-
- /* If this is the first span tree in the hyperslab selection, just use it */
- if(space->select.sel_info.hslab->span_lst == NULL)
- space->select.sel_info.hslab->span_lst = new_spans;
- else {
- H5S_hyper_span_info_t *old_spans = space->select.sel_info.hslab->span_lst;
- H5S_hyper_span_info_t *high_order_spans = NULL;
- H5S_hyper_span_info_t *low_order_spans = NULL;
-
- /* Combine the new_spans with the old_spans only in the highest-order of dimension */
- /* Example:
- * old_spans: ------------------> X
- * | (1,2)--->(1,3)--->(6,4)--->||
- * | | ^
- * | | |
- * Y | V |
- * | (5,2)------.
- * | |
- * | |
- * | V
- * | =
- * V
- * new_spans: --------------------> X
- * | (8,2)--->(12,3)--->(17,4)--->||
- * | |
- * Y | |
- * | V
- * | =
- * V
- *
- * After merging, the old_spans becomes
- *
- * old_spans: ------------------> X
- * | (1,2)--->(1,3)--->(6,4)--->||
- * | | ^
- * | | |
- * | V |
- * | (5,2)------.
- * | |
- * Y | |
- * | (8,2)--->(12,3)--->(17,4)--->||
- * | |
- * | |
- * | V
- * | =
- * V
- */
-
- /* Make sure the tail pointers are updated correctly */
- HDassert(old_spans->tail);
- HDassert(NULL == old_spans->tail->next);
- HDassert(new_spans->tail);
- HDassert(NULL == new_spans->tail->next);
-
- /* Check old_spans and new_spans to see which one is of higher order,
- * and append the higher order spans to the lower order ones.
- */
- if(new_spans->head->low > old_spans->tail->high) {
- high_order_spans = new_spans;
- low_order_spans = old_spans;
- } /* end if */
- else{
- high_order_spans = old_spans;
- low_order_spans = new_spans;
- } /* end else */
-
- /* The high_order_spans should be appended to low_order_spans */
- low_order_spans->tail->next = high_order_spans->head;
-
- /* "pstride" is only updated in IO operations, so it needs no update here */
- /*high_order_spans->head->pstride = high_order_spans->head->low - low_order_spans->tail->low;*/
- low_order_spans->tail = high_order_spans->tail;
-
- /* Fix the selection's 1st span info node */
- space->select.sel_info.hslab->span_lst = low_order_spans;
-
- /* free the memory space for "new_spans" node */
- high_order_spans = H5FL_FREE(H5S_hyper_span_info_t, high_order_spans);
- } /* end else */
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5S_hyper_add_disjoint_spans */
+} /* H5S_hyper_spans_nelem() */
/*--------------------------------------------------------------------------
@@ -5956,19 +5736,23 @@ H5S_hyper_make_spans(unsigned rank, const hsize_t *start, const hsize_t *stride,
span->down = down;
down->count++; /* Increment reference count for shared span */
} /* end if */
- else
+ else {
span->down = NULL;
+ } /* end else */
} /* end for */
/* Allocate a span info node */
- if(NULL == (down = H5FL_CALLOC(H5S_hyper_span_info_t)))
+ if(NULL == (down = H5FL_MALLOC(H5S_hyper_span_info_t)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate hyperslab span")
+ /* Set the reference count */
+ down->count = 0;
+
+ /* Reset the scratch pad space */
+ down->scratch = 0;
+
/* Keep the pointer to the next dimension down's completed list */
down->head = head;
-
- /* Keep the tail pointer to the next dimension down's completed list */
- down->tail = last_span;
} /* end for */
/* Indicate that there is a pointer to this tree */
@@ -6002,217 +5786,7 @@ done:
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_make_spans() */
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_hyper_update_diminfo
- PURPOSE
- Attempt to update optimized hyperslab information quickly. (It can be
- recovered with regular selection). If this algorithm cannot determine
- the optimized dimension info quickly, this function will simply mark it
- as invalid and unknown if it can be built (H5S_DIMINFO_VALID_NO), so
- H5S_hyper_rebuild can be run later to determine for sure.
- USAGE
- herr_t H5S_hyper_update_diminfo(space, op, new_hyper_diminfo)
- H5S_t *space; IN: Dataspace to check
- H5S_seloper_t op; IN: The operation being performed on the
- selection
- const H5S_hyper_dim_t new_hyper_diminfo; IN: The new selection that
- is being combined with
- the current
- RETURNS
- >=0 on success, <0 on failure
- DESCRIPTION
- Examine the span tree for a hyperslab selection and rebuild
- the start/stride/count/block information for the selection, if possible.
-
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- EXAMPLES
- REVISION LOG
- NF, 2014/6/6
---------------------------------------------------------------------------*/
-static herr_t
-H5S_hyper_update_diminfo(H5S_t *space, H5S_seloper_t op,
- const H5S_hyper_dim_t *new_hyper_diminfo)
-{
- H5S_hyper_dim_t tmp_diminfo[H5S_MAX_RANK]; /* Temporary dimension info */
- hbool_t found_nonidentical_dim = FALSE;
- unsigned curr_dim;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOERR
-
- /* Check args */
- HDassert(space);
- HDassert(new_hyper_diminfo);
-
- /* Check for conditions that prevent us from using the fast algorithm here
- * (and instead require H5S_hyper_rebuild) */
- if(!((op == H5S_SELECT_OR) || (op == H5S_SELECT_XOR))
- || space->select.sel_info.hslab->diminfo_valid != H5S_DIMINFO_VALID_YES
- || !space->select.sel_info.hslab->span_lst->head) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- HGOTO_DONE(SUCCEED)
- } /* end if */
-
- /* Copy current opt_diminfo values */
- for(curr_dim = 0; curr_dim < space->extent.rank; curr_dim++) {
- tmp_diminfo[curr_dim].start = space->select.sel_info.hslab->opt_diminfo[curr_dim].start;
- tmp_diminfo[curr_dim].stride = space->select.sel_info.hslab->opt_diminfo[curr_dim].stride;
- tmp_diminfo[curr_dim].count = space->select.sel_info.hslab->opt_diminfo[curr_dim].count;
- tmp_diminfo[curr_dim].block = space->select.sel_info.hslab->opt_diminfo[curr_dim].block;
- } /* end for */
-
- /* Loop over dimensions */
- for(curr_dim = 0; curr_dim < space->extent.rank; curr_dim++) {
- /* Check for this being identical */
- if((tmp_diminfo[curr_dim].start != new_hyper_diminfo[curr_dim].start)
- || (tmp_diminfo[curr_dim].stride != new_hyper_diminfo[curr_dim].stride)
- || (tmp_diminfo[curr_dim].count != new_hyper_diminfo[curr_dim].count)
- || (tmp_diminfo[curr_dim].block != new_hyper_diminfo[curr_dim].block)) {
- hsize_t high_start, high_count, high_block; /* The start, count & block values for the higher block */
-
- /* Dimension is not identical */
- /* Check if we already found a nonidentical dim - only one is
- * allowed */
- if(found_nonidentical_dim) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* Check that strides are the same, or count is 1 for one of the
- * slabs */
- if((tmp_diminfo[curr_dim].stride != new_hyper_diminfo[curr_dim].stride)
- && (tmp_diminfo[curr_dim].count > 1)
- && (new_hyper_diminfo[curr_dim].count > 1)) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* Patch tmp_diminfo.stride if its count is 1 */
- if((tmp_diminfo[curr_dim].count == 1)
- && (new_hyper_diminfo[curr_dim].count > 1))
- tmp_diminfo[curr_dim].stride = new_hyper_diminfo[curr_dim].stride;
-
- /* Determine lowest start, and set tmp_diminfo.start, count and
- * block to use the lowest, and high_start, high_count and
- * high_block to use the highest
- */
- if(tmp_diminfo[curr_dim].start < new_hyper_diminfo[curr_dim].start) {
- high_start = new_hyper_diminfo[curr_dim].start;
- high_count = new_hyper_diminfo[curr_dim].count;
- high_block = new_hyper_diminfo[curr_dim].block;
- } /* end if */
- else {
- high_start = tmp_diminfo[curr_dim].start;
- tmp_diminfo[curr_dim].start = new_hyper_diminfo[curr_dim].start;
- high_count = tmp_diminfo[curr_dim].count;
- tmp_diminfo[curr_dim].count = new_hyper_diminfo[curr_dim].count;
- high_block = tmp_diminfo[curr_dim].block;
- tmp_diminfo[curr_dim].block = new_hyper_diminfo[curr_dim].block;
- } /* end else */
-
- /* If count is 1 for both slabs, take different actions */
- if((tmp_diminfo[curr_dim].count == 1) && (high_count == 1)) {
- /* Check for overlap */
- if((tmp_diminfo[curr_dim].start + tmp_diminfo[curr_dim].block)
- > high_start) {
- /* Check operation type */
- if(op == H5S_SELECT_OR)
- /* Merge blocks */
- tmp_diminfo[curr_dim].block = ((high_start + high_block)
- >= (tmp_diminfo[curr_dim].start + tmp_diminfo[curr_dim].block))
- ? (high_start + high_block - tmp_diminfo[curr_dim].start)
- : tmp_diminfo[curr_dim].block;
- else {
- /* Block values must be the same */
- if(tmp_diminfo[curr_dim].block != high_block) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* XOR - overlap creates 2 blocks */
- tmp_diminfo[curr_dim].stride = high_block;
- tmp_diminfo[curr_dim].count = 2;
- tmp_diminfo[curr_dim].block = high_start - tmp_diminfo[curr_dim].start;
- } /* end else */
- } /* end if */
- else if((tmp_diminfo[curr_dim].start + tmp_diminfo[curr_dim].block)
- == high_start)
- /* Blocks border, merge them */
- tmp_diminfo[curr_dim].block += high_block;
- else {
- /* Distinct blocks */
- /* Block values must be the same */
- if(tmp_diminfo[curr_dim].block != high_block) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* Create strided selection */
- tmp_diminfo[curr_dim].stride = high_start - tmp_diminfo[curr_dim].start;
- tmp_diminfo[curr_dim].count = 2;
- } /* end else */
- } /* end if */
- else {
- /* Check if block values are the same */
- if(tmp_diminfo[curr_dim].block != new_hyper_diminfo[curr_dim].block) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* Check phase of strides */
- if((tmp_diminfo[curr_dim].start % tmp_diminfo[curr_dim].stride)
- != (new_hyper_diminfo[curr_dim].start % tmp_diminfo[curr_dim].stride)) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* Check operation type */
- if(op == H5S_SELECT_OR) {
- /* Make sure the slabs border or overlap */
- if(high_start > (tmp_diminfo[curr_dim].start
- + (tmp_diminfo[curr_dim].count
- * tmp_diminfo[curr_dim].stride))) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
- } /* end if */
- else
- /* XOR: Make sure the slabs border */
- if(high_start != (tmp_diminfo[curr_dim].start
- + (tmp_diminfo[curr_dim].count
- * tmp_diminfo[curr_dim].stride))) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
- break;
- } /* end if */
-
- /* Set count for combined selection */
- tmp_diminfo[curr_dim].count = ((high_start
- - tmp_diminfo[curr_dim].start)
- / tmp_diminfo[curr_dim].stride) + high_count;
- } /* end else */
-
- /* Indicate that we found a nonidentical dim */
- found_nonidentical_dim = TRUE;
- } /* end if */
- } /* end for */
-
- /* Check if we succeeded, if so, set the new diminfo values */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES)
- for(curr_dim = 0; curr_dim < space->extent.rank; curr_dim++) {
- space->select.sel_info.hslab->app_diminfo[curr_dim].start = space->select.sel_info.hslab->opt_diminfo[curr_dim].start = tmp_diminfo[curr_dim].start;
- space->select.sel_info.hslab->app_diminfo[curr_dim].stride = space->select.sel_info.hslab->opt_diminfo[curr_dim].stride = tmp_diminfo[curr_dim].stride;
- space->select.sel_info.hslab->app_diminfo[curr_dim].count = space->select.sel_info.hslab->opt_diminfo[curr_dim].count = tmp_diminfo[curr_dim].count;
- space->select.sel_info.hslab->app_diminfo[curr_dim].block = space->select.sel_info.hslab->opt_diminfo[curr_dim].block = tmp_diminfo[curr_dim].block;
- } /* end for */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_update_diminfo() */
+} /* H5S_hyper_make_spans() */
/*--------------------------------------------------------------------------
@@ -6245,22 +5819,23 @@ static hbool_t
H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab_info[],
unsigned rank)
{
- hbool_t ret_value = TRUE; /* Return value */
+ hsize_t curr_stride, next_stride;
+ hsize_t curr_block, next_block;
+ hsize_t curr_start;
+ hsize_t curr_low;
+ size_t outcount;
+ unsigned u;
+ H5S_hyper_dim_t canon_down_span_slab_info[H5S_MAX_RANK];
+ hbool_t ret_value = TRUE;
FUNC_ENTER_NOAPI_NOINIT_NOERR
if(span) {
- H5S_hyper_dim_t canon_down_span_slab_info[H5S_MAX_RANK];
- hsize_t curr_stride;
- hsize_t curr_block;
- hsize_t curr_start;
- hsize_t curr_low;
- size_t outcount; /* Number of spans encountered in this dimension */
-
/* Initialization */
curr_stride = 1;
- curr_low = 0;
+ curr_block = 0;
outcount = 0;
+ curr_low = 0;
/* Get "canonical" down span information */
if(span->down) {
@@ -6279,13 +5854,9 @@ H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab
/* Loop the span */
while(span) {
- hsize_t next_stride;
- hsize_t next_block;
-
if(outcount > 0) {
if(span->down) {
- H5S_hyper_dim_t *curr_down_span_slab_info;
- unsigned u; /* Local index variable */
+ H5S_hyper_dim_t *curr_down_span_slab_info;
HDassert(span->down->head);
@@ -6296,7 +5867,7 @@ H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab
/* Compare the slab information of the adjacent spans in the down span tree.
We have to compare all the sub-tree slab information with the canon_down_span_slab_info.*/
- for(u = 0; u < rank - 1; u++) {
+ for( u = 0; u < rank - 1; u++) {
curr_down_span_slab_info = &span_slab_info[u];
if(curr_down_span_slab_info->count > 0 && canon_down_span_slab_info[u].count > 0) {
@@ -6306,9 +5877,9 @@ H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab
|| curr_down_span_slab_info->count != canon_down_span_slab_info[u].count)
HGOTO_DONE(FALSE)
} /* end if */
- else if(!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[u].count == 0)))
+ else if (!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[u].count == 0)))
HGOTO_DONE(FALSE)
- } /* end for */
+ }
} /* end if */
} /* end if */
@@ -6370,19 +5941,22 @@ done:
EXAMPLES
REVISION LOG
+
This routine is the optimization of the old version. The previous version
can only detect a singluar selection. This version is general enough to
detect any regular selection.
KY, 2005/9/22
--------------------------------------------------------------------------*/
-htri_t
+static htri_t
H5S_hyper_rebuild(H5S_t *space)
{
H5S_hyper_dim_t top_span_slab_info[H5O_LAYOUT_NDIMS];
- unsigned rank; /* Dataspace rank */
- htri_t ret_value = TRUE; /* Return value */
+ H5S_hyper_dim_t *diminfo;
+ H5S_hyper_dim_t *app_diminfo;
+ unsigned rank, curr_dim;
+ htri_t ret_value = TRUE; /* Return value */
- FUNC_ENTER_NOAPI_NOERR
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
/* Check args */
HDassert(space);
@@ -6393,32 +5967,27 @@ H5S_hyper_rebuild(H5S_t *space)
/* Check whether the slab can be rebuilt. Only regular selection can be rebuilt. If yes, fill in correct values.*/
if(!H5S_hyper_rebuild_helper(space->select.sel_info.hslab->span_lst->head, top_span_slab_info, rank)) {
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_IMPOSSIBLE;
HGOTO_DONE(FALSE)
} /* end if */
else {
- H5S_hyper_dim_t *opt_diminfo; /* Convenience pointer to optimized dimension info */
- H5S_hyper_dim_t *app_diminfo; /* Convenience pointer to application dimension info */
- unsigned u; /* Local index variable */
+ diminfo=space->select.sel_info.hslab->opt_diminfo;
+ app_diminfo=space->select.sel_info.hslab->app_diminfo;
- /* Set the convenience pointers */
- opt_diminfo = space->select.sel_info.hslab->opt_diminfo;
- app_diminfo = space->select.sel_info.hslab->app_diminfo;
+ for(curr_dim = 0; curr_dim < rank; curr_dim++) {
+
+ app_diminfo[(rank - curr_dim) - 1].start = diminfo[(rank - curr_dim) - 1].start = top_span_slab_info[curr_dim].start;
+ app_diminfo[(rank - curr_dim) - 1].stride = diminfo[(rank - curr_dim) - 1].stride = top_span_slab_info[curr_dim].stride;
+ app_diminfo[(rank - curr_dim) - 1].count = diminfo[(rank - curr_dim) - 1].count = top_span_slab_info[curr_dim].count;
+ app_diminfo[(rank - curr_dim) - 1].block = diminfo[(rank - curr_dim) - 1].block = top_span_slab_info[curr_dim].block;
- /* Set the dimension info for the dataspace, from the rebuilt info */
- for(u = 0; u < rank; u++) {
- app_diminfo[(rank - u) - 1].start = opt_diminfo[(rank - u) - 1].start = top_span_slab_info[u].start;
- app_diminfo[(rank - u) - 1].stride = opt_diminfo[(rank - u) - 1].stride = top_span_slab_info[u].stride;
- app_diminfo[(rank - u) - 1].count = opt_diminfo[(rank - u) - 1].count = top_span_slab_info[u].count;
- app_diminfo[(rank - u) - 1].block = opt_diminfo[(rank - u) - 1].block = top_span_slab_info[u].block;
} /* end for */
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_YES;
+ space->select.sel_info.hslab->diminfo_valid = TRUE;
} /* end else */
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_rebuild() */
+} /* H5S_hyper_rebuild() */
/*--------------------------------------------------------------------------
@@ -6442,12 +6011,12 @@ done:
static herr_t
H5S_hyper_generate_spans(H5S_t *space)
{
- hsize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */
+ hsize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */
hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */
hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */
hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ unsigned u; /* Counter */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
@@ -6455,367 +6024,203 @@ H5S_hyper_generate_spans(H5S_t *space)
HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS);
/* Get the diminfo */
- for(u = 0; u < space->extent.rank; u++) {
- tmp_start[u] = space->select.sel_info.hslab->opt_diminfo[u].start;
- tmp_stride[u] = space->select.sel_info.hslab->opt_diminfo[u].stride;
- tmp_count[u] = space->select.sel_info.hslab->opt_diminfo[u].count;
- tmp_block[u] = space->select.sel_info.hslab->opt_diminfo[u].block;
+ for(u=0; u<space->extent.rank; u++) {
+ tmp_start[u]=space->select.sel_info.hslab->opt_diminfo[u].start;
+ tmp_stride[u]=space->select.sel_info.hslab->opt_diminfo[u].stride;
+ tmp_count[u]=space->select.sel_info.hslab->opt_diminfo[u].count;
+ tmp_block[u]=space->select.sel_info.hslab->opt_diminfo[u].block;
} /* end for */
/* Build the hyperslab information also */
- if(H5S_generate_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0)
+ if(H5S_generate_hyperslab (space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_generate_spans() */
+} /* H5S_hyper_generate_spans() */
-/*--------------------------------------------------------------------------
- NAME
- H5S_hyper_update_bound_box
- PURPOSE
- Update the bounding box of the hyperslab depending on the selection operator
- USAGE
- herr_t H5S_hyper_update_bound_box(space, op, low_bounds, high_bounds, overlapped)
- H5S_t *space; IN/OUT: Dataspace containing the 1st space
- H5S_seloper_t op; IN: Selection operator
- const hszie_t low_bounds; IN: The lower bounds of the 2nd space
- const hsize_t high_bounds; IN: The higher bounds of the 2nd space
- RETURNS
- Non-negative on success, negative on failure
- DESCRIPTION
- GLOBAL VARIABLES
- COMMENTS, BUGS
- ASSUMPTIONS
- This function assumes that the two bound boxes are not overlapped. If two bound
- boxes are overlapped, the "space"'s bound box should be calculated recursively,
- which has been done in H5S_fill_in_new_space function.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
+#ifndef NEW_HYPERSLAB_API
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_generate_hyperlab
+ *
+ * Purpose: Generate hyperslab information from H5S_select_hyperslab()
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol (split from HS_select_hyperslab()).
+ * Tuesday, September 12, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
static herr_t
-H5S_hyper_update_bound_box(H5S_t *space, H5S_seloper_t op,
- const hsize_t low_bounds[], const hsize_t high_bounds[])
+H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op,
+ const hsize_t start[],
+ const hsize_t stride[],
+ const hsize_t count[],
+ const hsize_t block[])
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */
+ H5S_hyper_span_info_t *a_not_b=NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */
+ H5S_hyper_span_info_t *a_and_b=NULL; /* Span tree for hyperslab spans in both old and new span trees */
+ H5S_hyper_span_info_t *b_not_a=NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
+ /* Check args */
HDassert(space);
- HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS);
+ HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
+ HDassert(start);
+ HDassert(stride);
+ HDassert(count);
+ HDassert(block);
- /* The offset of the dataspace is ignored here */
- switch(op) {
- case H5S_SELECT_OR:
- case H5S_SELECT_XOR:
- {
- unsigned u; /* Local index variable */
+ /* Generate span tree for new hyperslab information */
+ if((new_spans=H5S_hyper_make_spans(space->extent.rank,start,stride,count,block))==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information")
- for(u = 0; u < space->extent.rank; u++) {
- /* choose the smaller value for the low bound as the op is (X)OR */
- space->select.low_bounds[u] = MIN(low_bounds[u], space->select.low_bounds[u]);
+ /* Generate list of blocks to add/remove based on selection operation */
+ if(op==H5S_SELECT_SET) {
+ /* Add new spans to current selection */
+ if(H5S_hyper_merge_spans(space,new_spans,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- /* choose the larger value for the high bound as the op is (X)OR */
- space->select.high_bounds[u] = MAX(high_bounds[u], space->select.high_bounds[u]);
- } /* end for */
- }
- break;
+ /* Set the number of elements in current selection */
+ space->select.num_elem=H5S_hyper_spans_nelem(new_spans);
- case H5S_SELECT_AND:
- {
- hsize_t tmp = HSIZET_MAX;
+ /* Indicate that the new_spans are owned */
+ new_spans=NULL;
+ } /* end if */
+ else {
+ hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */
- H5VM_array_fill(space->select.low_bounds, &tmp, sizeof(hsize_t), space->extent.rank);
- HDmemset(space->select.high_bounds, 0, sizeof(hsize_t) * space->extent.rank);
- }
- break;
+ /* Generate lists of spans which overlap and don't overlap */
+ if(H5S_hyper_clip_spans(space->select.sel_info.hslab->span_lst,new_spans,&a_not_b,&a_and_b,&b_not_a)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
- case H5S_SELECT_NOTB:
- /* Since the two spaces don't overlap, the bound box needs no update */
- break;
+ switch(op) {
+ case H5S_SELECT_OR:
+ /* Add any new spans from b_not_a to current selection */
+ if(b_not_a!=NULL) {
+ if(H5S_hyper_merge_spans(space,b_not_a,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- case H5S_SELECT_NOTA:
- /* Since the two spaces don't overlap, the bound box is same with 2nd space */
- HDmemcpy(space->select.low_bounds, low_bounds, sizeof(hsize_t) * space->extent.rank);
- HDmemcpy(space->select.high_bounds, high_bounds, sizeof(hsize_t) * space->extent.rank);
- break;
+ /* Update the number of elements in current selection */
+ space->select.num_elem+=H5S_hyper_spans_nelem(b_not_a);
- case H5S_SELECT_NOOP:
- case H5S_SELECT_SET:
- case H5S_SELECT_APPEND:
- case H5S_SELECT_PREPEND:
- case H5S_SELECT_INVALID:
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
- } /* end switch(op) */
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ break;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_hyper_update_bound_box() */
+ case H5S_SELECT_AND:
+ /* Free the current selection */
+ if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
+ space->select.sel_info.hslab->span_lst=NULL;
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_fill_in_new_space
- PURPOSE
- Combine two span lists, one from an existing dataspace and the
- other from input arguments, into a new selection depending on the
- selection operator. The new selection is put into a resulting dataspace
- which could be allocated inside the function.
- USAGE
- herr_t H5S_fill_in_new_space(space1, op, space2_span_lst, space2_low_bound,
- space2_high_bound, can_own_span2,
- span2_owned, result)
- H5S_t *space1; IN: Dataspace containing the first span list
- H5S_seloper_t op; IN: Selection operation
- H5S_hyper_span_info_t *space2_span_lst; IN: Second span list
- const hsize_t *span2_low_bound; IN: The lower bound box for 2nd span list
- const hsize_t *span2_high_bound; IN: The higher bound box for 2nd span list
- hbool_t can_own_span2; IN: Indicates whether the 2nd span list could be
- owned by the result. If not, the 2nd span list
- has to be copied.
- hbool_t *span2_owned; OUT: Indicates if the 2nd span list is actually owned
- H5S_t **result; OUT: The dataspace containing the the new selection. It
- could be same with the 1st dataspace.
- RETURNS
- Non-negative on success, negative on failure
- PROGRAMMER
- Chao Mei July 8, 2011
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- The function is extracted from H5S_generate_hyperslab, and then modified
- to be general enough for hyperslab selection operations.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
-static herr_t
-H5S_fill_in_new_space(H5S_t *space1, H5S_seloper_t op,
- H5S_hyper_span_info_t *space2_span_lst, const hsize_t *space2_low_bound,
- const hsize_t *space2_high_bound, hbool_t can_own_span2, hbool_t *span2_owned,
- hbool_t *updated_spans, H5S_t **result)
-{
- H5S_hyper_span_info_t *a_not_b = NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */
- H5S_hyper_span_info_t *a_and_b = NULL; /* Span tree for hyperslab spans in both old and new span trees */
- H5S_hyper_span_info_t *b_not_a = NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */
- hsize_t *space1_low_bound = space1->select.low_bounds;
- hsize_t *space1_high_bound = space1->select.high_bounds;
- hbool_t overlapped = FALSE;
- hbool_t is_result_new = FALSE;
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ /* Reset the number of items in selection */
+ space->select.num_elem=0;
- FUNC_ENTER_NOAPI_NOINIT
+ /* Check if there are any overlapped selections */
+ if(a_and_b!=NULL) {
+ if(H5S_hyper_merge_spans(space,a_and_b,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- HDassert(space1);
- HDassert(space2_span_lst);
- HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA);
- /* The result is either a to-be-created space or an empty one */
- HDassert(*result == NULL || *result == space1);
- HDassert(space1->select.sel_info.hslab->span_lst);
- HDassert(span2_owned);
-
- /* Reset flags to return */
- *span2_owned = FALSE;
- *updated_spans = FALSE;
-
- /* The result shares the same info from space1 */
- if(*result == NULL) {
- if(NULL == ((*result) = H5S_copy(space1, TRUE, TRUE)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
- space1->select.sel_info.hslab->span_lst->count--;
- (*result)->select.sel_info.hslab->span_lst = NULL;
- is_result_new = TRUE;
- } /* end if */
+ /* Update the number of elements in current selection */
+ space->select.num_elem=H5S_hyper_spans_nelem(a_and_b);
- /* Check bound box of both spaces to see if they overlap or border */
- for(u = 0; u < space1->extent.rank; u++) {
- /*
- * Three conditions for overlapping/bordering:
- * 1. the lower bound of the new span is between the lower and
- * higher bound of the existing one. In other words, the left
- * part of new span will at least overlap or border with the
- * existing one.
- * 2. the higher bound of the new span is between the lower and
- * higher bound of the exisiting one. In other words, the right
- * part of new span will at least overlap or border with the
- * existing one.
- * 3. The new span includes the existing one where the lower bound
- * is smaller than that of the existing one, and the higher bound
- * is larger than that of the existing one.
- */
- /* condition 1 */
- if((space1_low_bound[u] >= space2_low_bound[u] &&
- space1_low_bound[u] <= (space2_high_bound[u] + 1)) ||
- /* condition 2 */
- ((space1_high_bound[u] + 1) >= space2_low_bound[u] &&
- space1_high_bound[u] <= space2_high_bound[u]) ||
- /* condition 3 */
- (space1_low_bound[u] < space2_low_bound[u] &&
- space1_high_bound[u] > space2_high_bound[u])) {
- overlapped = TRUE;
- break;
- } /* end if */
- } /* end for */
+ /* Indicate that the a_and_b spans are owned */
+ a_and_b=NULL;
- /* If two spans are disjoint in terms of bound box, then work could be much simplified. */
- if(!overlapped) {
- switch(op) {
- case H5S_SELECT_OR:
- case H5S_SELECT_XOR:
- /* Add the new disjoint spans to the space */
- /* A copy of space1's spans to *result, and another copy of space2's spans */
- if(is_result_new)
- (*result)->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(space1->select.sel_info.hslab->span_lst);
- if(!can_own_span2) {
- b_not_a = H5S_hyper_copy_span(space2_span_lst);
- if(H5S_hyper_add_disjoint_spans(*result, b_not_a) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't append hyperslabs")
-
- /* The new_spans is now owned by space, so its memory space should not be released */
- b_not_a = NULL;
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
} /* end if */
- else {
- if(H5S_hyper_add_disjoint_spans(*result, space2_span_lst) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't append hyperslabs")
- *span2_owned = TRUE;
- } /* end else */
-
- /* Indicate that the spans changed */
- *updated_spans = TRUE;
break;
- case H5S_SELECT_AND:
- /* Convert *result to "none" selection */
- if(H5S_select_none(*result) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
- HGOTO_DONE(SUCCEED);
+ case H5S_SELECT_XOR:
+ /* Free the current selection */
+ if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
+ space->select.sel_info.hslab->span_lst=NULL;
- case H5S_SELECT_NOTB:
- /* Copy space1's spans to *result */
- if(is_result_new)
- (*result)->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(space1->select.sel_info.hslab->span_lst);
+ /* Reset the number of items in selection */
+ space->select.num_elem=0;
- /* Indicate that the spans changed */
- *updated_spans = TRUE;
- break;
+ /* Check if there are any non-overlapped selections */
+ if(a_not_b!=NULL) {
+ if(H5S_hyper_merge_spans(space,a_not_b,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- case H5S_SELECT_NOTA:
- if(!is_result_new) {
- HDassert(space1 == *result);
+ /* Update the number of elements in current selection */
+ space->select.num_elem=H5S_hyper_spans_nelem(a_not_b);
- /* Free the current selection */
- if(H5S_hyper_free_span_info(space1->select.sel_info.hslab->span_lst) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
} /* end if */
+ if(b_not_a!=NULL) {
+ if(H5S_hyper_merge_spans(space,b_not_a,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- /* Copy space2's spans to *result */
- if(!can_own_span2)
- (*result)->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(space2_span_lst);
- else {
- (*result)->select.sel_info.hslab->span_lst = space2_span_lst;
- *span2_owned = TRUE;
- } /* end else */
-
- /* Reset the number of items in selection */
- (*result)->select.num_elem = H5S_hyper_spans_nelem(space2_span_lst);
+ /* Update the number of elements in current selection */
+ space->select.num_elem+=H5S_hyper_spans_nelem(b_not_a);
- /* Indicate that the spans changed */
- *updated_spans = TRUE;
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
break;
- case H5S_SELECT_NOOP:
- case H5S_SELECT_SET:
- case H5S_SELECT_APPEND:
- case H5S_SELECT_PREPEND:
- case H5S_SELECT_INVALID:
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
- } /* end switch */
-
- /* update bound box of the selection result */
- if(H5S_hyper_update_bound_box(*result, op, space2_low_bound, space2_high_bound) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't update the bound box")
- } /* end if */
- else {
- const hsize_t *span_a_b_bounds[4]; /* Pointers to space1 & space2 bound boxes */
- hsize_t bounds_array[6 * H5S_MAX_RANK]; /* Array for bounding boxes */
- hsize_t *tmp_bounds_array; /* Temp. pointer to array for bounding boxes */
- hsize_t tmp = HSIZET_MAX;
- unsigned selector = 0; /* Select which clipping spans to generate */
+ case H5S_SELECT_NOTB:
+ /* Free the current selection */
+ if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
+ space->select.sel_info.hslab->span_lst=NULL;
- /* Generate mask for clip operation depending on the op */
- switch(op) {
- case H5S_SELECT_OR:
- selector = H5S_HYPER_COMPUTE_B_NOT_A; /* a + b_not_a */
- break;
+ /* Reset the number of items in selection */
+ space->select.num_elem=0;
- case H5S_SELECT_XOR: /* a_not_b + b_not_a */
- selector = H5S_HYPER_COMPUTE_A_NOT_B | H5S_HYPER_COMPUTE_B_NOT_A;
- break;
+ /* Check if there are any non-overlapped selections */
+ if(a_not_b!=NULL) {
+ if(H5S_hyper_merge_spans(space,a_not_b,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- case H5S_SELECT_AND: /* a_and_b */
- selector = H5S_HYPER_COMPUTE_A_AND_B;
- break;
+ /* Update the number of elements in current selection */
+ space->select.num_elem=H5S_hyper_spans_nelem(a_not_b);
- case H5S_SELECT_NOTB: /* a_not_b */
- selector = H5S_HYPER_COMPUTE_A_NOT_B;
- break;
+ /* Indicate that the a_not_b are owned */
+ a_not_b=NULL;
- case H5S_SELECT_NOTA: /* b_not_a */
- selector = H5S_HYPER_COMPUTE_B_NOT_A;
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
break;
- case H5S_SELECT_NOOP:
- case H5S_SELECT_SET:
- case H5S_SELECT_APPEND:
- case H5S_SELECT_PREPEND:
- case H5S_SELECT_INVALID:
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
- } /* end switch */
+ case H5S_SELECT_NOTA:
+ /* Free the current selection */
+ if(H5S_hyper_free_span_info(space->select.sel_info.hslab->span_lst)<0)
+ HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
+ space->select.sel_info.hslab->span_lst=NULL;
- /* Initialize arrays for 3 pairs of low/high bounds to default values */
- tmp_bounds_array = bounds_array;
- for(u = 0; u < 3; u++) {
- /* set the bounds to be the default value */
- H5VM_array_fill(tmp_bounds_array, &tmp, sizeof(hsize_t), space1->extent.rank);
- tmp_bounds_array += space1->extent.rank;
- HDmemset(tmp_bounds_array, 0, sizeof(hsize_t) * space1->extent.rank);
- tmp_bounds_array += space1->extent.rank;
- } /* end for */
+ /* Reset the number of items in selection */
+ space->select.num_elem=0;
- /* Initialize array of pointers to space1 & space2's bound arrays */
- span_a_b_bounds[0] = space1->select.low_bounds;
- span_a_b_bounds[1] = space1->select.high_bounds;
- span_a_b_bounds[2] = space2_low_bound;
- span_a_b_bounds[3] = space2_high_bound;
+ /* Check if there are any non-overlapped selections */
+ if(b_not_a!=NULL) {
+ if(H5S_hyper_merge_spans(space,b_not_a,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
- /* Generate lists of spans which overlap and don't overlap */
- if(H5S_hyper_clip_spans(space1->select.sel_info.hslab->span_lst,
- space2_span_lst, selector, 0, space1->extent.rank,
- span_a_b_bounds, bounds_array, &a_not_b, &a_and_b, &b_not_a) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
- switch(op) {
- case H5S_SELECT_OR:
- if(is_result_new)
- (*result)->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(space1->select.sel_info.hslab->span_lst);
- break;
+ /* Update the number of elements in current selection */
+ space->select.num_elem=H5S_hyper_spans_nelem(b_not_a);
- case H5S_SELECT_AND:
- case H5S_SELECT_XOR:
- case H5S_SELECT_NOTB:
- case H5S_SELECT_NOTA:
- if(!is_result_new) {
- HDassert(space1 == *result);
+ /* Indicate that the b_not_a are owned */
+ b_not_a=NULL;
- /* Free the current selection */
- if(H5S_hyper_free_span_info(space1->select.sel_info.hslab->span_lst) < 0)
- HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans")
- space1->select.sel_info.hslab->span_lst = NULL;
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
} /* end if */
-
- /* Reset the number of items in selection */
- (*result)->select.num_elem = 0;
break;
case H5S_SELECT_NOOP:
@@ -6827,110 +6232,40 @@ H5S_fill_in_new_space(H5S_t *space1, H5S_seloper_t op,
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
} /* end switch */
- /* Check if there are any non-overlapped selections */
- if(a_not_b) {
- hsize_t *a_not_b_low_bounds = bounds_array;
- hsize_t *a_not_b_high_bounds = bounds_array + space1->extent.rank;
-
- /* Other than OR, the span_lst is set to NULL. And in OR, a_not_b is not needed */
- HDassert(NULL == (*result)->select.sel_info.hslab->span_lst);
-
- if(H5S_hyper_merge_spans(*result, a_not_b) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
-
- /* Update the bound box: just use a_not_b's bound box as no span tree is in result */
- HDmemcpy((*result)->select.low_bounds, a_not_b_low_bounds, sizeof(hsize_t) * space1->extent.rank);
- HDmemcpy((*result)->select.high_bounds, a_not_b_high_bounds, sizeof(hsize_t) * space1->extent.rank);
-
- /* Update the number of elements in current selection */
- (*result)->select.num_elem += H5S_hyper_spans_nelem(a_not_b);
+ /* Check if the resulting hyperslab span tree is empty */
+ if(space->select.sel_info.hslab->span_lst==NULL) {
+ H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */
- /* Indicate that the spans were updated */
- *updated_spans = TRUE;
-
- /* Indicate that the a_not_b spans are owned */
- a_not_b = NULL;
- } /* end if */
-
- if(a_and_b) {
- hsize_t *a_and_b_low_bounds = bounds_array + 2 * space1->extent.rank;
- hsize_t *a_and_b_high_bounds = bounds_array + 3 * space1->extent.rank;
-
- /**
- * 1. Other than OR, the span_lst is set to NULL. And in OR,
- * a_and_b is not needed
- * 2. a_not_b will never be computed together with a_and_b
- * because merging these two equals to a.
- */
- HDassert(NULL == (*result)->select.sel_info.hslab->span_lst);
+ /* Sanity check */
+ HDassert(space->select.num_elem == 0);
- if(H5S_hyper_merge_spans(*result, a_and_b) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+ /* Allocate a span info node */
+ if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab span")
- /* Update the bound box: just use a_not_b's bound box as no span tree is in result */
- HDmemcpy((*result)->select.low_bounds, a_and_b_low_bounds, sizeof(hsize_t) * space1->extent.rank);
- HDmemcpy((*result)->select.high_bounds, a_and_b_high_bounds, sizeof(hsize_t) * space1->extent.rank);
+ /* Set the reference count */
+ spans->count=1;
- /* Update the number of elements in current selection */
- (*result)->select.num_elem += H5S_hyper_spans_nelem(a_and_b);
+ /* Reset the scratch pad space */
+ spans->scratch=0;
- /* Indicate that the spans were updated */
- *updated_spans = TRUE;
+ /* Set to empty tree */
+ spans->head=NULL;
- /* Indicate that the a_and_b spans are owned */
- a_and_b = NULL;
+ /* Set pointer to empty span tree */
+ space->select.sel_info.hslab->span_lst=spans;
} /* end if */
-
- if(b_not_a) {
- hsize_t *b_not_a_low_bounds = bounds_array + 4 * space1->extent.rank;
- hsize_t *b_not_a_high_bounds = bounds_array + 5 * space1->extent.rank;
- hbool_t has_span_tree = (NULL != (*result)->select.sel_info.hslab->span_lst);
-
- if(H5S_hyper_merge_spans(*result, b_not_a) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
-
- /* Update the bound box */
- if(has_span_tree) {
- /* Since two span trees are merged, the update on bound box is like an OR operation */
- for(u = 0; u < space1->extent.rank; u++) {
- (*result)->select.low_bounds[u] = MIN((*result)->select.low_bounds[u], b_not_a_low_bounds[u]);
- (*result)->select.high_bounds[u] = MAX((*result)->select.high_bounds[u], b_not_a_high_bounds[u]);
- } /* end for */
+ else {
+ /* Check if we updated the spans */
+ if(updated_spans) {
+ /* Attempt to rebuild "optimized" start/stride/count/block information.
+ * from resulting hyperslab span tree
+ */
+ if(H5S_hyper_rebuild(space) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't rebuild hyperslab info")
} /* end if */
- else {
- /* Just use b_not_a's bound box as no span tree is in result */
- HDmemcpy((*result)->select.low_bounds, b_not_a_low_bounds, sizeof(hsize_t) * space1->extent.rank);
- HDmemcpy((*result)->select.high_bounds, b_not_a_high_bounds, sizeof(hsize_t) * space1->extent.rank);
- } /* end else */
-
- /* Update the number of elements in current selection */
- (*result)->select.num_elem += H5S_hyper_spans_nelem(b_not_a);
-
- /* Indicate that the spans were updated */
- *updated_spans = TRUE;
-
- /* Indicate that the b_not_a spans are owned */
- b_not_a = NULL;
- } /* end if */
- } /* end else for the case the new span overlaps with the old (i.e. space) */
-
- /* Check if the spans weren't updated, and reset selection if so */
- if(!*updated_spans) {
- /** If updated_spans remains FALSE as in this branch, it
- * means the result has been cleared in cases
- * XOR/AND/NOTB/NOTA, and the result is a copy of the
- * dataspace in the case OR.
- *
- * If two dataspaces have generated any of the three clipped
- * span trees (i.e. a_not_b, a_and_b, and b_not_a), the
- * updated_spans must be TRUE.
- */
- if(H5S_SELECT_OR != op) {
- /* Convert *result to "none" selection */
- if(H5S_select_none(*result) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
} /* end else */
- } /* end if */
+ } /* end else */
done:
/* Free resources */
@@ -6943,108 +6278,6 @@ done:
if(b_not_a)
if(H5S_hyper_free_span_info(b_not_a) < 0)
HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_fill_in_new_space() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5S_generate_hyperlab
- *
- * Purpose: Generate hyperslab information from H5S_select_hyperslab()
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, September 12, 2000
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5S_generate_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
- const hsize_t stride[], const hsize_t count[], const hsize_t block[])
-{
- H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */
- hsize_t new_spans_low_bounds[H5S_MAX_RANK]; /* The lower bound box for the new hyperslab */
- hsize_t new_spans_high_bounds[H5S_MAX_RANK]; /* The upper bound box for the new hyperslab */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT
-
- /* Check args */
- HDassert(space);
- HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
- HDassert(start);
- HDassert(stride);
- HDassert(count);
- HDassert(block);
-
- /* Generate span tree for new hyperslab information */
- if(NULL == (new_spans = H5S_hyper_make_spans(space->extent.rank, start, stride, count, block)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information")
-
- /* Generate the bound box for the new hyperslab */
- for(u = 0; u < space->extent.rank; u++) {
- new_spans_low_bounds[u] = start[u];
- new_spans_high_bounds[u] = new_spans_low_bounds[u] + stride[u] * (count[u] - 1) + (block[u] - 1);
- } /* end for */
-
- /* Generate list of blocks to add/remove based on selection operation */
- if(op == H5S_SELECT_SET) {
- H5S_hyper_span_info_t *existing_spans = space->select.sel_info.hslab->span_lst;
-
- /* Add new spans to current selection */
- if(NULL != existing_spans)
- if(H5S_hyper_free_span_info(existing_spans) < 0)
- HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release existing hyperslab spans")
-
- space->select.sel_info.hslab->span_lst = new_spans;
-
- /* Set the number of elements in current selection */
- space->select.num_elem = H5S_hyper_spans_nelem(new_spans);
-
- /* Update the bound box of this hyperslab */
- HDmemcpy(space->select.low_bounds, new_spans_low_bounds, sizeof(hsize_t) * space->extent.rank);
- HDmemcpy(space->select.high_bounds, new_spans_high_bounds, sizeof(hsize_t) * space->extent.rank);
-
- /* Indicate that the new_spans are owned */
- new_spans = NULL;
- } /* end if */
- else {
- hbool_t new_spans_owned;
- hbool_t updated_spans;
-
- /* Generate new spans for space */
- if(H5S_fill_in_new_space(space, op, new_spans, new_spans_low_bounds, new_spans_high_bounds, TRUE, &new_spans_owned, &updated_spans, &space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't generate the specified hyperslab")
-
- /* Check if the spans were updated by H5S_fill_in_new_space */
- if(updated_spans) {
- H5S_hyper_dim_t new_hyper_diminfo[H5S_MAX_RANK];
-
- /* Sanity check */
- HDassert(space->select.sel_info.hslab->span_lst->head);
-
- /* Build diminfo struct */
- for(u = 0; u <space->extent.rank; u++) {
- new_hyper_diminfo[u].start = start[u];
- new_hyper_diminfo[u].stride = stride[u];
- new_hyper_diminfo[u].count = count[u];
- new_hyper_diminfo[u].block = block[u];
- } /* end for */
-
- /* Update space's dim info */
- if(H5S_hyper_update_diminfo(space, op, new_hyper_diminfo) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't update hyperslab info")
- } /* end if */
-
- /* Indicate that the new_spans are owned, there's no need to free */
- if(new_spans_owned)
- new_spans = NULL;
- } /* end else */
-
-done:
if(new_spans)
if(H5S_hyper_free_span_info(new_spans) < 0)
HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
@@ -7066,17 +6299,20 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
- const hsize_t *stride, const hsize_t count[], const hsize_t *block)
+H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
+ const hsize_t start[],
+ const hsize_t *stride,
+ const hsize_t count[],
+ const hsize_t *block)
{
hsize_t int_stride[H5O_LAYOUT_NDIMS]; /* Internal storage for stride information */
hsize_t int_count[H5O_LAYOUT_NDIMS]; /* Internal storage for count information */
hsize_t int_block[H5O_LAYOUT_NDIMS]; /* Internal storage for block information */
- const hsize_t *opt_stride; /* Optimized stride information */
- const hsize_t *opt_count; /* Optimized count information */
- const hsize_t *opt_block; /* Optimized block information */
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ const hsize_t *opt_stride; /* Optimized stride information */
+ const hsize_t *opt_count; /* Optimized count information */
+ const hsize_t *opt_block; /* Optimized block information */
+ unsigned u; /* Counters */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(FAIL)
@@ -7109,8 +6345,8 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */
case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */
/* Convert to "none" selection */
- if(H5S_select_none(space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
+ if(H5S_select_none(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection")
HGOTO_DONE(SUCCEED);
case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */
@@ -7229,8 +6465,8 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */
/* Convert to "none" selection */
- if(H5S_select_none(space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
+ if(H5S_select_none(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection")
HGOTO_DONE(SUCCEED);
case H5S_SELECT_NOOP:
@@ -7279,21 +6515,14 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u];
space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u];
- /* update bound box of the hyperslab selection */
- space->select.low_bounds[u] = start[u];
- space->select.high_bounds[u] = space->select.low_bounds[u] + stride[u] * (count[u] - 1) + (block[u] - 1);
-
space->select.num_elem *= (opt_count[u] * opt_block[u]);
} /* end for */
/* Indicate that the dimension information is valid */
- space->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_YES;
+ space->select.sel_info.hslab->diminfo_valid = TRUE;
/* Indicate that there's no slab information */
space->select.sel_info.hslab->span_lst = NULL;
-
- /* Set selection type */
- space->select.type = H5S_sel_hyper;
} /* end if */
else if(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA) {
/* Sanity check */
@@ -7304,9 +6533,8 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
if(H5S_hyper_generate_spans(space) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
- /* Set selection type */
- /* (Could be overridden by resetting selection to 'none', below) */
- space->select.type = H5S_sel_hyper;
+ /* Indicate that the regular dimensions are no longer valid */
+ space->select.sel_info.hslab->diminfo_valid = FALSE;
/* Add in the new hyperslab information */
if(H5S_generate_hyperslab(space, op, start, opt_stride, opt_count, opt_block) < 0)
@@ -7315,9 +6543,12 @@ H5S_select_hyperslab(H5S_t *space, H5S_seloper_t op, const hsize_t start[],
else
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+ /* Set selection type */
+ space->select.type = H5S_sel_hyper;
+
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_select_hyperslab() */
+} /* end H5S_select_hyperslab() */
/*--------------------------------------------------------------------------
@@ -7348,9 +6579,10 @@ done:
--------------------------------------------------------------------------*/
herr_t
H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
- const hsize_t stride[], const hsize_t count[], const hsize_t block[])
+ const hsize_t stride[], const hsize_t count[], const hsize_t block[])
{
H5S_t *space; /* Dataspace to modify selection of */
+ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
@@ -7358,7 +6590,7 @@ H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
/* Check args */
if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
if(H5S_SCALAR == H5S_GET_EXTENT_TYPE(space))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space")
if(H5S_NULL == H5S_GET_EXTENT_TYPE(space))
@@ -7367,283 +6599,617 @@ H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified")
if(!(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID))
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
- if(stride != NULL) {
- unsigned u; /* Local index variable */
-
+ if(stride!=NULL) {
/* Check for 0-sized strides */
- for(u = 0; u < space->extent.rank; u++) {
- if(stride[u] == 0)
+ for(u=0; u<space->extent.rank; u++) {
+ if(stride[u]==0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stride==0 value")
} /* end for */
} /* end if */
- if(H5S_select_hyperslab(space, op, start, stride, count, block) < 0)
+ if (H5S_select_hyperslab(space, op, start, stride, count, block)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection")
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Sselect_hyperslab() */
+#else /* NEW_HYPERSLAB_API */ /* Works */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_operate_hyperslab
+ *
+ * Purpose: Combines two hyperslabs with an operation, putting the
+ * result into a third hyperslab selection
+ *
+ * Return: non-negative on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 30, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper_t op, H5S_hyper_span_info_t *spans2,
+ hbool_t can_own_span2, hbool_t *span2_owned)
+{
+ H5S_hyper_span_info_t *a_not_b=NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */
+ H5S_hyper_span_info_t *a_and_b=NULL; /* Span tree for hyperslab spans in both old and new span trees */
+ H5S_hyper_span_info_t *b_not_a=NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check args */
+ HDassert(result);
+ HDassert(spans2);
+ HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
+
+ /* Just copy the selection from spans2 if we are setting the selection */
+ /* ('space1' to 'result' aliasing happens at the next layer up) */
+ if(op==H5S_SELECT_SET) {
+ if(H5S_hyper_merge_spans(result,spans2,can_own_span2)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem=H5S_hyper_spans_nelem(spans2);
+
+ /* Indicate that we took ownership of span2, if allowed */
+ if(can_own_span2)
+ *span2_owned=TRUE;
+ } /* end if */
+ else {
+ hbool_t updated_spans = FALSE; /* Whether the spans in the selection were modified */
+
+ HDassert(spans1);
+
+ /* Generate lists of spans which overlap and don't overlap */
+ if(H5S_hyper_clip_spans(spans1,spans2,&a_not_b,&a_and_b,&b_not_a)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
+
+ /* Switch on the operation */
+ switch(op) {
+ case H5S_SELECT_OR:
+ /* Copy spans from spans1 to current selection */
+ if(spans1!=NULL) {
+ if(H5S_hyper_merge_spans(result,spans1,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem=H5S_hyper_spans_nelem(spans1);
+ } /* end if */
+
+ /* Add any new spans from spans2 to current selection */
+ if(b_not_a!=NULL) {
+ if(H5S_hyper_merge_spans(result,b_not_a,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem+=H5S_hyper_spans_nelem(b_not_a);
+
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ break;
+
+ case H5S_SELECT_AND:
+ /* Check if there are any overlapped selections */
+ if(a_and_b!=NULL) {
+ if(H5S_hyper_merge_spans(result,a_and_b,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem=H5S_hyper_spans_nelem(a_and_b);
+
+ /* Indicate that the result owns the a_and_b spans */
+ a_and_b=NULL;
+
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ break;
+
+ case H5S_SELECT_XOR:
+ /* Check if there are any non-overlapped selections */
+ if(a_not_b!=NULL) {
+ if(H5S_hyper_merge_spans(result,a_not_b,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem=H5S_hyper_spans_nelem(a_not_b);
+
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ if(b_not_a!=NULL) {
+ if(H5S_hyper_merge_spans(result,b_not_a,FALSE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem+=H5S_hyper_spans_nelem(b_not_a);
+
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ break;
+
+ case H5S_SELECT_NOTB:
+ /* Check if there are any non-overlapped selections */
+ if(a_not_b!=NULL) {
+ if(H5S_hyper_merge_spans(result,a_not_b,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem=H5S_hyper_spans_nelem(a_not_b);
+
+ /* Indicate that the result owns the a_not_b spans */
+ a_not_b=NULL;
+
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ break;
+
+ case H5S_SELECT_NOTA:
+ /* Check if there are any non-overlapped selections */
+ if(b_not_a!=NULL) {
+ if(H5S_hyper_merge_spans(result,b_not_a,TRUE)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert hyperslabs")
+
+ /* Update the number of elements in current selection */
+ result->select.num_elem=H5S_hyper_spans_nelem(b_not_a);
+
+ /* Indicate that the result owns the b_not_a spans */
+ b_not_a=NULL;
+
+ /* Indicate that the spans were updated */
+ updated_spans = TRUE;
+ } /* end if */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+ } /* end switch */
+
+ /* Free the hyperslab trees generated from the clipping algorithm */
+ if(a_not_b)
+ H5S_hyper_free_span_info(a_not_b);
+ if(a_and_b)
+ H5S_hyper_free_span_info(a_and_b);
+ if(b_not_a)
+ H5S_hyper_free_span_info(b_not_a);
+
+ /* Check if the resulting hyperslab span tree is empty */
+ if(result->select.sel_info.hslab->span_lst==NULL) {
+ H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */
+
+ /* Sanity check */
+ HDassert(result->select.num_elem == 0);
+
+ /* Allocate a span info node */
+ if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span")
+
+ /* Set the reference count */
+ spans->count=1;
+
+ /* Reset the scratch pad space */
+ spans->scratch=0;
+
+ /* Set to empty tree */
+ spans->head=NULL;
+
+ /* Set pointer to empty span tree */
+ result->select.sel_info.hslab->span_lst=spans;
+ } /* end if */
+ else {
+ /* Check if we updated the spans */
+ if(updated_spans) {
+ /* Attempt to rebuild "optimized" start/stride/count/block information.
+ * from resulting hyperslab span tree
+ */
+ if(H5S_hyper_rebuild(result) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't rebuild hyperslab info")
+ } /* end if */
+ } /* end else */
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_operate_hyperslab() */
-/*--------------------------------------------------------------------------
- NAME
- H5S_fill_in_hyperslab
- PURPOSE
- Specify a hyperslab to combine with the current hyperslab selection, and
- store the result in the new hyperslab selection.
- USAGE
- herr_t H5S_fill_in_hyperslab(new_space, old_space, op, start, stride, count, block)
- H5S_t old_space; IN: The old space the selection is performed on
- H5S_seloper_t op; IN: Operation to perform on current selection
- const hsize_t *start; IN: Offset of start of hyperslab
- const hsize_t *stride; IN: Hyperslab stride
- const hsize_t *count; IN: Number of blocks included in hyperslab
- const hsize_t *block; IN: Size of block in hyperslab
- H5S_t *new_space; OUT: The new dataspace to store the selection result
- RETURNS
- Non-negative on success/Negative on failure
- DESCRIPTION
- Combines a hyperslab selection with the current selection for a dataspace.
- If STRIDE or BLOCK is NULL, they are assumed to be set to all '1'.
- GLOBAL VARIABLES
- COMMENTS, BUGS, ASSUMPTIONS
- In some cases, the whole span tree in the old_space could be avoided from copying
- into the new_space. In order to deal with such cases, H5S_select_hyperslab could
- not be directly called. Otherwise, this function equals two steps:
- 1. copy the whole span tree from old_space into new_space
- 2. call H5S_select_hyperslab with the new_space.
- EXAMPLES
- REVISION LOG
---------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------
+ * Function: H5S_generate_hyperlab
+ *
+ * Purpose: Generate hyperslab information from H5S_select_hyperslab()
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol (split from HS_select_hyperslab()).
+ * Tuesday, September 12, 2000
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
static herr_t
-H5S_fill_in_hyperslab(H5S_t *old_space, H5S_seloper_t op, const hsize_t start[],
- const hsize_t *stride, const hsize_t count[], const hsize_t *block,
- H5S_t **new_space)
+H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op,
+ const hsize_t start[],
+ const hsize_t stride[],
+ const hsize_t count[],
+ const hsize_t block[])
{
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */
+ H5S_hyper_span_info_t *tmp_spans=NULL; /* Temporary copy of selection */
+ hbool_t span2_owned=FALSE; /* Flag to indicate that span2 was used in H5S_operate_hyperslab() */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/* Check args */
- HDassert(old_space);
+ HDassert(space);
+ HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
HDassert(start);
+ HDassert(stride);
HDassert(count);
- HDassert(op >= H5S_SELECT_SET && op <= H5S_SELECT_NOTA);
- HDassert(new_space);
- HDassert(*new_space == NULL);
+ HDassert(block);
+
+ /* Generate span tree for new hyperslab information */
+ if((new_spans=H5S_hyper_make_spans(space->extent.rank,start,stride,count,block))==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information")
+
+ /* Copy the original dataspace */
+ if(space->select.sel_info.hslab->span_lst!=NULL) {
+ /* Take ownership of the dataspace's hyperslab spans */
+ /* (These are freed later) */
+ tmp_spans=space->select.sel_info.hslab->span_lst;
+ space->select.sel_info.hslab->span_lst=NULL;
+
+ /* Reset the other dataspace selection information */
+ if(H5S_SELECT_RELEASE(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
+
+ /* Allocate space for the hyperslab selection information */
+ if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
+ } /* end if */
+
+ /* Combine tmp_space (really space) & new_space, with the result in space */
+ if(H5S_operate_hyperslab(space,tmp_spans,op,new_spans,TRUE,&span2_owned)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
+
+done:
+ /* Free temporary data structures */
+ if(tmp_spans!=NULL)
+ if(H5S_hyper_free_span_info(tmp_spans)<0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
+ if(new_spans!=NULL && span2_owned==FALSE)
+ if(H5S_hyper_free_span_info(new_spans)<0)
+ HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_generate_hyperslab() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_select_hyperslab
+ *
+ * Purpose: Internal version of H5Sselect_hyperslab().
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, January 10, 2001
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
+ const hsize_t start[],
+ const hsize_t *stride,
+ const hsize_t count[],
+ const hsize_t *block)
+{
+ hsize_t int_stride[H5O_LAYOUT_NDIMS]; /* Internal storage for stride information */
+ hsize_t int_count[H5O_LAYOUT_NDIMS]; /* Internal storage for count information */
+ hsize_t int_block[H5O_LAYOUT_NDIMS]; /* Internal storage for block information */
+ const hsize_t *opt_stride; /* Optimized stride information */
+ const hsize_t *opt_count; /* Optimized count information */
+ const hsize_t *opt_block; /* Optimized block information */
+ unsigned u; /* Counters */
+ herr_t ret_value=SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(space);
+ HDassert(start);
+ HDassert(count);
+ HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
/* Point to the correct stride values */
- if(stride == NULL)
+ if(stride==NULL)
stride = _ones;
/* Point to the correct block values */
- if(block == NULL)
+ if(block==NULL)
block = _ones;
- /* Check new selection. */
- for(u = 0; u < old_space->extent.rank; u++) {
+ /*
+ * Check new selection.
+ */
+ for(u=0; u<space->extent.rank; u++) {
/* Check for overlapping hyperslab blocks in new selection. */
- if(count[u] > 1 && stride[u] < block[u])
+ if(count[u]>1 && stride[u]<block[u])
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab blocks overlap")
/* Detect zero-sized hyperslabs in new selection */
if(count[u] == 0 || block[u] == 0) {
switch(op) {
+ case H5S_SELECT_SET: /* Select "set" operation */
case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */
case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */
/* Convert to "none" selection */
- /* Copy the first dataspace without sharing the list of spans */
- if(NULL == ((*new_space) = H5S_copy(old_space, TRUE, TRUE)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
- if(H5S_select_none((*new_space)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
+ if(H5S_select_none(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection")
HGOTO_DONE(SUCCEED);
case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */
case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */
case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */
- /* Copy the first dataspace with sharing the list of spans */
- if(NULL == ((*new_space) = H5S_copy(old_space, FALSE, TRUE)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
HGOTO_DONE(SUCCEED); /* Selection stays same */
- case H5S_SELECT_NOOP:
- case H5S_SELECT_SET:
- case H5S_SELECT_APPEND:
- case H5S_SELECT_PREPEND:
- case H5S_SELECT_INVALID:
default:
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
} /* end switch */
} /* end if */
} /* end for */
- if(H5S_GET_SELECT_TYPE(old_space) == H5S_SEL_HYPERSLABS) {
- hsize_t new_low_bound[H5S_MAX_RANK];
- hsize_t new_high_bound[H5S_MAX_RANK];
- hbool_t overlapped = FALSE;
-
- /* Generate bounding box for hyperslab parameters */
- for(u = 0; u < old_space->extent.rank; u++) {
- new_low_bound[u] = start[u];
- new_high_bound[u] = new_low_bound[u] + stride[u] * (count[u]-1) + (block[u]-1);
- } /* end for */
-
- /* Check bounding box to see if two are disjoint */
- for(u = 0; u < old_space->extent.rank; u++) {
- /* Note: offset of this old_space is neglected */
- hsize_t old_low_bound = old_space->select.low_bounds[u];
- hsize_t old_high_bound = old_space->select.high_bounds[u];
-
- /* The following condition tests are copied from H5S_fill_in_new_space */
- if((new_low_bound[u] >= old_low_bound && new_low_bound[u] <= old_high_bound) ||
- (new_high_bound[u] >= old_low_bound && new_high_bound[u] <= old_high_bound) ||
- (new_low_bound[u] <= old_low_bound && new_high_bound[u] >= old_high_bound)) {
- overlapped = TRUE;
- break;
+ /* Optimize hyperslab parameters to merge contiguous blocks, etc. */
+ if(stride == _ones && block == _ones) {
+ /* Point to existing arrays */
+ opt_stride = _ones;
+ opt_count = _ones;
+ opt_block = count;
+ } /* end if */
+ else {
+ /* Point to local arrays */
+ opt_stride = int_stride;
+ opt_count = int_count;
+ opt_block = int_block;
+ for(u=0; u<space->extent.rank; u++) {
+ /* contiguous hyperslabs have the block size equal to the stride */
+ if(stride[u]==block[u]) {
+ int_count[u]=1;
+ int_stride[u]=1;
+ if(block[u]==1)
+ int_block[u]=count[u];
+ else
+ int_block[u]=block[u]*count[u];
} /* end if */
+ else {
+ if(count[u]==1)
+ int_stride[u]=1;
+ else {
+ HDassert(stride[u] > block[u]);
+ int_stride[u]=stride[u];
+ } /* end else */
+ int_count[u]=count[u];
+ int_block[u]=block[u];
+ } /* end else */
} /* end for */
+ } /* end else */
- if(!overlapped) {
- H5S_hyper_span_info_t *new_spans = NULL;
- H5S_hyper_dim_t new_hyper_diminfo[H5S_MAX_RANK];
+ /* Fixup operation for non-hyperslab selections */
+ switch(H5S_GET_SELECT_TYPE(space)) {
+ case H5S_SEL_NONE: /* No elements selected in dataspace */
+ switch(op) {
+ case H5S_SELECT_SET: /* Select "set" operation */
+ /* Change "none" selection to hyperslab selection */
+ break;
- if(NULL == ((*new_space) = H5S_copy(old_space, TRUE, TRUE)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
- if(NULL != (*new_space)->select.sel_info.hslab->span_lst) {
- old_space->select.sel_info.hslab->span_lst->count--;
- (*new_space)->select.sel_info.hslab->span_lst = NULL;
- } /* end if */
+ case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */
+ case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */
+ case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */
+ op=H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */
+ break;
+
+ case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */
+ case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */
+ HGOTO_DONE(SUCCEED); /* Selection stays "none" */
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+ } /* end switch */
+ break;
- /* Generate hyperslab info for new space */
+ case H5S_SEL_ALL: /* All elements selected in dataspace */
switch(op) {
- case H5S_SELECT_OR:
- case H5S_SELECT_XOR:
- /* Add the new space to the space */
- if(NULL == (new_spans = H5S_hyper_make_spans(old_space->extent.rank, start, stride, count, block)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information")
- if(NULL != old_space->select.sel_info.hslab->span_lst)
- (*new_space)->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(old_space->select.sel_info.hslab->span_lst);
- if(H5S_hyper_add_disjoint_spans(*new_space, new_spans) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't append hyperslabs")
+ case H5S_SELECT_SET: /* Select "set" operation */
+ /* Change "all" selection to hyperslab selection */
break;
- case H5S_SELECT_AND:
- if(H5S_select_none((*new_space)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
- HGOTO_DONE(SUCCEED);
+ case H5S_SELECT_OR: /* Binary "or" operation for hyperslabs */
+ HGOTO_DONE(SUCCEED); /* Selection stays "all" */
- case H5S_SELECT_NOTB:
- if(old_space->select.sel_info.hslab->span_lst != NULL)
- (*new_space)->select.sel_info.hslab->span_lst = H5S_hyper_copy_span(old_space->select.sel_info.hslab->span_lst);
- else {
- if(H5S_select_none((*new_space)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
- HGOTO_DONE(SUCCEED);
- } /* end else */
+ case H5S_SELECT_AND: /* Binary "and" operation for hyperslabs */
+ op=H5S_SELECT_SET; /* Maps to "set" operation when applied to "none" selection */
break;
- case H5S_SELECT_NOTA:
- if(NULL == (new_spans = H5S_hyper_make_spans(old_space->extent.rank, start, stride, count, block)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information")
- (*new_space)->select.sel_info.hslab->span_lst = new_spans;
- (*new_space)->select.num_elem = H5S_hyper_spans_nelem(new_spans);
+ case H5S_SELECT_XOR: /* Binary "xor" operation for hyperslabs */
+ case H5S_SELECT_NOTB: /* Binary "A not B" operation for hyperslabs */
+ /* Convert current "all" selection to "real" hyperslab selection */
+ /* Then allow operation to proceed */
+ {
+ hsize_t tmp_start[H5O_LAYOUT_NDIMS]; /* Temporary start information */
+ hsize_t tmp_stride[H5O_LAYOUT_NDIMS]; /* Temporary stride information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary count information */
+ hsize_t tmp_block[H5O_LAYOUT_NDIMS]; /* Temporary block information */
+
+ /* Fill in temporary information for the dimensions */
+ for(u=0; u<space->extent.rank; u++) {
+ tmp_start[u]=0;
+ tmp_stride[u]=1;
+ tmp_count[u]=1;
+ tmp_block[u]=space->extent.size[u];
+ } /* end for */
+
+ /* Convert to hyperslab selection */
+ if(H5S_select_hyperslab(space,H5S_SELECT_SET,tmp_start,tmp_stride,tmp_count,tmp_block)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection")
+ } /* end case */
break;
- case H5S_SELECT_NOOP:
- case H5S_SELECT_SET:
- case H5S_SELECT_APPEND:
- case H5S_SELECT_PREPEND:
- case H5S_SELECT_INVALID:
+ case H5S_SELECT_NOTA: /* Binary "B not A" operation for hyperslabs */
+ /* Convert to "none" selection */
+ if(H5S_select_none(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't convert selection")
+ HGOTO_DONE(SUCCEED);
+
default:
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
} /* end switch */
+ break;
- /* Update bound box */
- if(H5S_hyper_update_bound_box(*new_space, op, new_low_bound, new_high_bound)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't update the bound box")
+ case H5S_SEL_HYPERSLABS:
+ /* Hyperslab operation on hyperslab selection, OK */
+ break;
- /* Build diminfo struct */
- for(u = 0; u < (*new_space)->extent.rank; u++) {
- new_hyper_diminfo[u].start = start[u];
- new_hyper_diminfo[u].stride = stride[u];
- new_hyper_diminfo[u].count = count[u];
- new_hyper_diminfo[u].block = block[u];
- } /* end for */
+ case H5S_SEL_POINTS: /* Can't combine hyperslab operations and point selections currently */
+ if(op==H5S_SELECT_SET) /* Allow only "set" operation to proceed */
+ break;
+ /* Else fall through to error */
- /* Update space's dim info */
- if(H5S_hyper_update_diminfo(*new_space, op, new_hyper_diminfo) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't update hyperslab info")
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+ } /* end switch */
- HGOTO_DONE(SUCCEED);
- } /* end if(!overlapped) */
- } /* end if the selection of old space is H5S_SEL_HYPERSLABS*/
- /* Copy the first dataspace with sharing the list of spans */
- if(NULL == ((*new_space) = H5S_copy(old_space, FALSE, TRUE)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
+ if(op==H5S_SELECT_SET) {
+ /* If we are setting a new selection, remove current selection first */
+ if(H5S_SELECT_RELEASE(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab")
- /* Note: a little overhead in calling the function as some conditions are checked again */
- if(H5S_select_hyperslab(*new_space, op, start, stride, count, block) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection")
+ /* Allocate space for the hyperslab selection information */
+ if((space->select.sel_info.hslab=H5FL_MALLOC(H5S_hyper_sel_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab info")
+
+ /* Save the diminfo */
+ space->select.num_elem=1;
+ for(u=0; u<space->extent.rank; u++) {
+ space->select.sel_info.hslab->app_diminfo[u].start = start[u];
+ space->select.sel_info.hslab->app_diminfo[u].stride = stride[u];
+ space->select.sel_info.hslab->app_diminfo[u].count = count[u];
+ space->select.sel_info.hslab->app_diminfo[u].block = block[u];
+
+ space->select.sel_info.hslab->opt_diminfo[u].start = start[u];
+ space->select.sel_info.hslab->opt_diminfo[u].stride = opt_stride[u];
+ space->select.sel_info.hslab->opt_diminfo[u].count = opt_count[u];
+ space->select.sel_info.hslab->opt_diminfo[u].block = opt_block[u];
+
+ space->select.num_elem*=(opt_count[u]*opt_block[u]);
+ } /* end for */
+
+ /* Indicate that the dimension information is valid */
+ space->select.sel_info.hslab->diminfo_valid=TRUE;
+
+ /* Indicate that there's no slab information */
+ space->select.sel_info.hslab->span_lst=NULL;
+ } /* end if */
+ else if(op>=H5S_SELECT_OR && op<=H5S_SELECT_NOTA) {
+ /* Sanity check */
+ HDassert(H5S_GET_SELECT_TYPE(space) == H5S_SEL_HYPERSLABS);
+
+ /* Check if there's no hyperslab span information currently */
+ if(space->select.sel_info.hslab->span_lst==NULL)
+ if(H5S_hyper_generate_spans(space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
+
+ /* Add in the new hyperslab information */
+ if(H5S_generate_hyperslab (space, op, start, opt_stride, opt_count, opt_block)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs")
+
+ /* Indicate that the regular dimensions are no longer valid */
+ space->select.sel_info.hslab->diminfo_valid=FALSE;
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+
+ /* Set selection type */
+ space->select.type=H5S_sel_hyper;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_fill_in_hyperslab() */
+} /* end H5S_select_hyperslab() */
-/*-------------------------------------------------------------------------
- * Function: H5S_fill_in_select
- *
- * Purpose: Combines two hyperslabs with an operation, putting the
- * result into a third hyperslab selection
- *
- * Return: non-negative on success/NULL on failure
- *
- * Programmer: Chao Mei
- * Tuesday, July 5, 2011
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5S_fill_in_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2, H5S_t **result)
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sselect_hyperslab
+ PURPOSE
+ Specify a hyperslab to combine with the current hyperslab selection
+ USAGE
+ herr_t H5Sselect_hyperslab(dsid, op, start, stride, count, block)
+ hid_t dsid; IN: Dataspace ID of selection to modify
+ H5S_seloper_t op; IN: Operation to perform on current selection
+ const hsize_t *start; IN: Offset of start of hyperslab
+ const hsize_t *stride; IN: Hyperslab stride
+ const hsize_t *count; IN: Number of blocks included in hyperslab
+ const hsize_t *block; IN: Size of block in hyperslab
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Combines a hyperslab selection with the current selection for a dataspace.
+ If the current selection is not a hyperslab, it is freed and the hyperslab
+ parameters passed in are combined with the H5S_SEL_ALL hyperslab (ie. a
+ selection composing the entire current extent). If STRIDE or BLOCK is
+ NULL, they are assumed to be set to all '1'.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Sselect_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
+ const hsize_t stride[], const hsize_t count[], const hsize_t block[])
{
- hbool_t span2_owned;
- hbool_t updated_spans;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_API(FAIL)
+ H5TRACE6("e", "iSs*h*h*h*h", space_id, op, start, stride, count, block);
- /* Sanity check */
- HDassert(space1);
- HDassert(space2);
- HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA);
- HDassert(space1->extent.rank == space2->extent.rank);
- /* The result is either a to-be-created space or an empty one */
- HDassert(NULL == *result || *result == space1);
- HDassert(space1->select.sel_info.hslab->span_lst);
- HDassert(space2->select.sel_info.hslab->span_lst);
-
- /* Note: the offset of space2 is not considered here for bounding box */
- if(H5S_fill_in_new_space(space1, op, space2->select.sel_info.hslab->span_lst, space2->select.low_bounds, space2->select.high_bounds, FALSE, &span2_owned, &updated_spans, result) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create the specified selection")
-
- /* Update diminfo if space2's diminfo was valid, otherwise just mark it as
- * invalid if the spans were updated */
- HDassert(result);
- if(updated_spans) {
- if(space2->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
- if(H5S_hyper_update_diminfo(*result, op, space2->select.sel_info.hslab->opt_diminfo) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't update hyperslab info")
- } /* end if */
- else
- (*result)->select.sel_info.hslab->diminfo_valid = H5S_DIMINFO_VALID_NO;
+ /* Check args */
+ if (NULL == (space=H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if (H5S_SCALAR==H5S_GET_EXTENT_TYPE(space))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_SCALAR space")
+ if (H5S_NULL==H5S_GET_EXTENT_TYPE(space))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "hyperslab doesn't support H5S_NULL space")
+ if(start==NULL || count==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified")
+ if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID))
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
+ if(stride!=NULL) {
+ unsigned u; /* Local index variable */
+
+ /* Check for 0-sized strides */
+ for(u=0; u<space->extent.rank; u++) {
+ if(stride[u]==0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid stride==0 value")
+ } /* end for */
} /* end if */
+ if (H5S_select_hyperslab(space, op, start, stride, count, block)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection")
+
done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_fill_in_select() */
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sselect_hyperslab() */
/*--------------------------------------------------------------------------
@@ -7677,33 +7243,38 @@ done:
--------------------------------------------------------------------------*/
hid_t
H5Scombine_hyperslab(hid_t space_id, H5S_seloper_t op, const hsize_t start[],
- const hsize_t stride[], const hsize_t count[], const hsize_t block[])
+ const hsize_t stride[], const hsize_t count[], const hsize_t block[])
{
- H5S_t *space; /* Dataspace to modify selection of */
- H5S_t *new_space = NULL; /* New dataspace created */
- hid_t ret_value; /* Return value */
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ H5S_t *new_space = NULL; /* New dataspace created */
+ hid_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE6("i", "iSs*h*h*h*h", space_id, op, start, stride, count, block);
/* Check args */
- if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- if(start == NULL || count == NULL)
+ if (NULL == (space=H5I_object_verify(space_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(start==NULL || count==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "hyperslab not specified")
- if(!(op >= H5S_SELECT_SET && op <= H5S_SELECT_NOTA))
+
+ if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID))
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
- /* Generate new space, with combination of selections */
- if(H5S_fill_in_hyperslab(space, op, start, stride, count, block, &new_space) < 0)
+ /* Copy the first dataspace */
+ if (NULL == (new_space = H5S_copy (space, TRUE, TRUE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy data space")
+
+ /* Go modify the selection in the new dataspace */
+ if (H5S_select_hyperslab(new_space, op, start, stride, count, block)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection")
/* Atomize */
- if((ret_value = H5I_register(H5I_DATASPACE, new_space, TRUE)) < 0)
+ if ((ret_value=H5I_register (H5I_DATASPACE, new_space, TRUE))<0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
- if(ret_value < 0 && new_space)
+ if (ret_value<0 && new_space)
H5S_close(new_space);
FUNC_LEAVE_API(ret_value)
@@ -7720,62 +7291,57 @@ done:
* Programmer: Quincey Koziol
* Tuesday, October 30, 2001
*
- * Chao Mei
- * Wednesday, June 29, 2011
+ * Modifications:
*
*-------------------------------------------------------------------------
*/
static H5S_t *
-H5S_combine_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2)
+H5S_combine_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2)
{
- H5S_t *new_space = NULL; /* New dataspace generated */
- H5S_t *ret_value = NULL; /* Return value */
+ H5S_t *new_space=NULL; /* New dataspace generated */
+ hbool_t span2_owned=FALSE; /* Flag to indicate that span2 was used in H5S_operate_hyperslab() */
+ H5S_t *ret_value; /* return value */
FUNC_ENTER_NOAPI_NOINIT
/* Check args */
HDassert(space1);
HDassert(space2);
- HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA);
+ HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
- /* Check that if space1 selections has span trees */
- if(NULL == space1->select.sel_info.hslab->span_lst)
- if(H5S_hyper_generate_spans(space1) < 0)
+ /* Check that the space selections both have span trees */
+ if(space1->select.sel_info.hslab->span_lst==NULL)
+ if(H5S_hyper_generate_spans(space1)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, NULL, "dataspace does not have span tree")
+ if(space2->select.sel_info.hslab->span_lst==NULL)
+ if(H5S_hyper_generate_spans(space2)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, NULL, "dataspace does not have span tree")
- if(NULL == space2->select.sel_info.hslab->span_lst) {
- hsize_t tmp_start[H5S_MAX_RANK];
- hsize_t tmp_stride[H5S_MAX_RANK];
- hsize_t tmp_count[H5S_MAX_RANK];
- hsize_t tmp_block[H5S_MAX_RANK];
- unsigned u;
-
- for(u = 0; u < space2->extent.rank; u++) {
- tmp_start[u] = space2->select.sel_info.hslab->opt_diminfo[u].start;
- tmp_stride[u] = space2->select.sel_info.hslab->opt_diminfo[u].stride;
- tmp_count[u] = space2->select.sel_info.hslab->opt_diminfo[u].count;
- tmp_block[u] = space2->select.sel_info.hslab->opt_diminfo[u].block;
- } /* end for */
+ /* Copy the first dataspace */
+ if (NULL == (new_space = H5S_copy (space1, TRUE, TRUE)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy data space")
- /* call H5S_select_hyperslab directly */
- if(H5S_fill_in_hyperslab(space1, op, tmp_start, tmp_stride, tmp_count, tmp_block, &new_space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to set hyperslab selection")
- } /* end if */
- else{
- /* Combine new_space (a copy of space 1) & space2, with the result in new_space */
- if(H5S_fill_in_select(space1, op, space2, &new_space) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, NULL, "can't clip hyperslab information")
- } /* end else */
+ /* Free the current selection for the new dataspace */
+ if(H5S_SELECT_RELEASE(new_space)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, NULL, "can't release selection")
+
+ /* Allocate space for the hyperslab selection information */
+ if((new_space->select.sel_info.hslab=H5FL_CALLOC(H5S_hyper_sel_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab info")
+
+ /* Combine space1 & space2, with the result in new_space */
+ if(H5S_operate_hyperslab(new_space,space1->select.sel_info.hslab->span_lst,op,space2->select.sel_info.hslab->span_lst,FALSE,&span2_owned)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, NULL, "can't clip hyperslab information")
/* Set return value */
- ret_value = new_space;
+ ret_value=new_space;
done:
- if(ret_value == NULL && new_space)
+ if(ret_value==NULL && new_space!=NULL)
H5S_close(new_space);
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_combine_select() */
+} /* end H5S_combine_select() */
/*--------------------------------------------------------------------------
@@ -7806,47 +7372,37 @@ H5Scombine_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id)
H5S_t *space1; /* First Dataspace */
H5S_t *space2; /* Second Dataspace */
H5S_t *new_space = NULL; /* New Dataspace */
- hid_t ret_value; /* Return value */
+ hid_t ret_value;
FUNC_ENTER_API(FAIL)
H5TRACE3("i", "iSsi", space1_id, op, space2_id);
/* Check args */
- if(NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- if(NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- if(!(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA))
+ if (NULL == (space1=H5I_object_verify(space1_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if (NULL == (space2=H5I_object_verify(space2_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID))
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
/* Check that both dataspaces have the same rank */
- if(space1->extent.rank != space2->extent.rank)
+ if(space1->extent.rank!=space2->extent.rank)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces not same rank")
- /* Note: currently, the offset of each dataspace is ignored */
-#if 0
- /* Check that both dataspaces have the same offset */
- /* Same note as in H5Smodify_select */
- for(u=0; u<space1->extent.rank; u++) {
- if(space1->select.offset[u] != space2->select.offset[u])
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces not same offset")
- } /* end for */
-#endif
-
/* Check that both dataspaces have hyperslab selections */
- if(H5S_GET_SELECT_TYPE(space1) != H5S_SEL_HYPERSLABS || H5S_GET_SELECT_TYPE(space2) != H5S_SEL_HYPERSLABS)
+ if(H5S_GET_SELECT_TYPE(space1)!=H5S_SEL_HYPERSLABS || H5S_GET_SELECT_TYPE(space2)!=H5S_SEL_HYPERSLABS)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces don't have hyperslab selections")
/* Go combine the dataspaces */
- if(NULL == (new_space = H5S_combine_select(space1, op, space2)))
+ if ((new_space=H5S_combine_select(space1, op, space2))==NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to create hyperslab selection")
/* Atomize */
- if((ret_value = H5I_register(H5I_DATASPACE, new_space, TRUE)) < 0)
+ if ((ret_value=H5I_register (H5I_DATASPACE, new_space, TRUE))<0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
- if(ret_value < 0 && new_space)
+ if (ret_value<0 && new_space)
H5S_close(new_space);
FUNC_LEAVE_API(ret_value)
@@ -7854,74 +7410,74 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5S_modify_select
+ * Function: H5S_select_select
*
- * Purpose: Internal version of H5Smodify_select().
+ * Purpose: Internal version of H5Sselect_select().
*
* Return: New dataspace on success/NULL on failure
*
* Programmer: Quincey Koziol
* Tuesday, October 30, 2001
*
- * Chao Mei
- * Wednesday, June 29, 2011
+ * Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_modify_select(H5S_t *space1, H5S_seloper_t op, H5S_t *space2)
+H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2)
{
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_hyper_span_info_t *tmp_spans=NULL; /* Temporary copy of selection */
+ hbool_t span2_owned=FALSE; /* Flag to indicate that span2 was used in H5S_operate_hyperslab() */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT
/* Check args */
HDassert(space1);
HDassert(space2);
- HDassert(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA);
+ HDassert(op > H5S_SELECT_NOOP && op < H5S_SELECT_INVALID);
/* Check that the space selections both have span trees */
- if(NULL == space1->select.sel_info.hslab->span_lst)
- if(H5S_hyper_generate_spans(space1) < 0)
+ if(space1->select.sel_info.hslab->span_lst==NULL)
+ if(H5S_hyper_generate_spans(space1)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
+ if(space2->select.sel_info.hslab->span_lst==NULL)
+ if(H5S_hyper_generate_spans(space2)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree")
- if(NULL == space2->select.sel_info.hslab->span_lst) {
- hsize_t tmp_start[H5S_MAX_RANK];
- hsize_t tmp_stride[H5S_MAX_RANK];
- hsize_t tmp_count[H5S_MAX_RANK];
- hsize_t tmp_block[H5S_MAX_RANK];
- unsigned u;
-
- for(u = 0; u < space2->extent.rank; u++) {
- tmp_start[u] = space2->select.sel_info.hslab->opt_diminfo[u].start;
- tmp_stride[u] = space2->select.sel_info.hslab->opt_diminfo[u].stride;
- tmp_count[u] = space2->select.sel_info.hslab->opt_diminfo[u].count;
- tmp_block[u] = space2->select.sel_info.hslab->opt_diminfo[u].block;
- } /* end for */
+ /* Take ownership of the dataspace's hyperslab spans */
+ /* (These are freed later) */
+ tmp_spans=space1->select.sel_info.hslab->span_lst;
+ space1->select.sel_info.hslab->span_lst=NULL;
- /* Call H5S_select_hyperslab directly */
- if(H5S_select_hyperslab(space1, op, tmp_start, tmp_stride, tmp_count, tmp_block) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set hyperslab selection")
- } /* end if */
- else {
- /* Combine spans from space1 & spans from space2, with the result in space1 */
- if(H5S_fill_in_select(space1, op, space2, &space1) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't perform operation on two selections")
- } /* end else*/
+ /* Reset the other dataspace selection information */
+ if(H5S_SELECT_RELEASE(space1)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection")
+
+ /* Allocate space for the hyperslab selection information */
+ if((space1->select.sel_info.hslab=H5FL_CALLOC(H5S_hyper_sel_t))==NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate hyperslab info")
+
+ /* Combine tmp_spans (from space1) & spans from space2, with the result in space1 */
+ if(H5S_operate_hyperslab(space1,tmp_spans,op,space2->select.sel_info.hslab->span_lst,FALSE,&span2_owned)<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't clip hyperslab information")
done:
+ if(tmp_spans!=NULL)
+ H5S_hyper_free_span_info(tmp_spans);
+
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S_modify_select() */
+} /* end H5S_select_select() */
/*--------------------------------------------------------------------------
NAME
- H5Smodify_select
+ H5Sselect_select
PURPOSE
Refine a hyperslab selection with an operation using a second hyperslab
- to modify it
+ to modify it.
USAGE
- herr_t H5Smodify_select(space1, op, space2)
+ herr_t H5Sselect_select(space1, op, space2)
hid_t space1; IN/OUT: First Dataspace ID
H5S_seloper_t op; IN: Selection operation
hid_t space2; IN: Second Dataspace ID
@@ -7937,63 +7493,39 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5Smodify_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id)
+H5Sselect_select(hid_t space1_id, H5S_seloper_t op, hid_t space2_id)
{
H5S_t *space1; /* First Dataspace */
H5S_t *space2; /* Second Dataspace */
- herr_t ret_value = SUCCEED; /* Return value */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(FAIL)
H5TRACE3("e", "iSsi", space1_id, op, space2_id);
/* Check args */
- if(NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- if(NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
- if(!(op >= H5S_SELECT_OR && op <= H5S_SELECT_NOTA))
+ if (NULL == (space1=H5I_object_verify(space1_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if (NULL == (space2=H5I_object_verify(space2_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
+ if(!(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID))
HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation")
/* Check that both dataspaces have the same rank */
- if(space1->extent.rank != space2->extent.rank)
+ if(space1->extent.rank!=space2->extent.rank)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces not same rank")
- /* Check that both dataspaces have the same offset */
- /** Note that this is a tricky part of this function. It's
- * possible that two dataspaces have different "offset". If the
- * space2 has smaller offset value than that of space1 in a
- * dimension, then the span elements of this dimension in
- * space2 could have negative "low" and "high" values relative
- * to the offset in space1. In other words, if the bounds of
- * span elements in space2 are adjusted relative to the offset
- * in space1, then every span element's bound is computed as
- * "origin_bound+offset2-offset1". Therefore, if offset2 (the
- * offset of space2) is smaller, then
- * "origin_bound+offset2-offset1" could be negative which is
- * not allowed by the bound type declaration as hsize_t!
- * As a result, if the op is an OR selection, then the final
- * result may contain span elements that have negative bound!
- * So right now, the difference in the offset is totally
- * ignored!!
- */
-#if 0
- for(u=0; u<space1->extent.rank; u++) {
- if(space1->select.offset[u] != space2->select.offset[u])
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces not same offset")
- } /* end for */
-#endif
-
/* Check that both dataspaces have hyperslab selections */
- if(H5S_GET_SELECT_TYPE(space1) != H5S_SEL_HYPERSLABS || H5S_GET_SELECT_TYPE(space2) != H5S_SEL_HYPERSLABS)
+ if(H5S_GET_SELECT_TYPE(space1)!=H5S_SEL_HYPERSLABS || H5S_GET_SELECT_TYPE(space2)!=H5S_SEL_HYPERSLABS)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspaces don't have hyperslab selections")
/* Go refine the first selection */
- if(H5S_modify_select(space1, op, space2) < 0)
+ if (H5S_select_select(space1, op, space2)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to modify hyperslab selection")
done:
FUNC_LEAVE_API(ret_value)
-} /* end H5Smodify_select() */
+} /* end H5Sselect_select() */
+#endif /* NEW_HYPERSLAB_API */ /* Works */
/*--------------------------------------------------------------------------
@@ -8027,7 +7559,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_get_seq_list_gen(const H5S_t *space, H5S_sel_iter_t *iter,
+H5S_hyper_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem,
hsize_t *off, size_t *len)
{
@@ -9199,14 +8731,8 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t
HDassert(off);
HDassert(len);
- /* Rebuild diminfo if it is invalid and has not been confirmed to be
- * impossible */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_NO)
- /* Casting away const OK -NAF */
- (void)H5S_hyper_rebuild((H5S_t *)space);
-
/* Check for the special case of just one H5Sselect_hyperslab call made */
- if(space->select.sel_info.hslab->diminfo_valid == H5S_DIMINFO_VALID_YES) {
+ if(space->select.sel_info.hslab->diminfo_valid) {
const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */
const hssize_t *sel_off; /* Selection offset in dataspace */
hsize_t *mem_size; /* Size of the source buffer */