summaryrefslogtreecommitdiffstats
path: root/src/H5Spoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Spoint.c')
-rw-r--r--src/H5Spoint.c493
1 files changed, 343 insertions, 150 deletions
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 0bdabb4..445566a 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -47,16 +47,22 @@
/* Local Typedefs */
/******************/
+/* Define alias for hsize_t, for allocating H5S_pnt_node_t + point objects */
+/* (Makes it easier to understand the alloc / free calls) */
+typedef hsize_t hcoords_t;
+
/********************/
/* Local Prototypes */
/********************/
+static herr_t H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem,
+ const hsize_t *coord);
+static H5S_pnt_list_t *H5S__copy_pnt_list(const H5S_pnt_list_t *src,
+ unsigned rank);
+static void H5S__free_pnt_list(H5S_pnt_list_t *pnt_lst);
/* Selection callbacks */
static herr_t H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection);
-static herr_t H5S__point_get_seq_list(const H5S_t *space, unsigned flags,
- H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes,
- size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);
static herr_t H5S__point_release(H5S_t *space);
static htri_t H5S__point_is_valid(const H5S_t *space);
static hssize_t H5S__point_serial_size(const H5S_t *space);
@@ -68,13 +74,14 @@ static int H5S__point_unlim_dim(const H5S_t *space);
static htri_t H5S__point_is_contiguous(const H5S_t *space);
static htri_t H5S__point_is_single(const H5S_t *space);
static htri_t H5S__point_is_regular(const H5S_t *space);
+static htri_t H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2);
static herr_t H5S__point_adjust_u(H5S_t *space, const hsize_t *offset);
static herr_t H5S__point_project_scalar(const H5S_t *space, hsize_t *offset);
static herr_t H5S__point_project_simple(const H5S_t *space, H5S_t *new_space,
hsize_t *offset);
-static herr_t H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space);
-static herr_t
- H5S__point_get_version_enc_size(const H5S_t *space, uint32_t *version, uint8_t *enc_size);
+static herr_t H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter);
+static herr_t H5S__point_get_version_enc_size(const H5S_t *space,
+ uint32_t *version, uint8_t *enc_size);
/* Selection iteration callbacks */
static herr_t H5S__point_iter_coords(const H5S_sel_iter_t *iter, hsize_t *coords);
@@ -84,6 +91,8 @@ static hsize_t H5S__point_iter_nelmts(const H5S_sel_iter_t *iter);
static htri_t H5S__point_iter_has_next_block(const H5S_sel_iter_t *iter);
static herr_t H5S__point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem);
static herr_t H5S__point_iter_next_block(H5S_sel_iter_t *sel_iter);
+static herr_t H5S__point_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq,
+ size_t maxbytes, size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len);
static herr_t H5S__point_iter_release(H5S_sel_iter_t *sel_iter);
@@ -102,7 +111,6 @@ const H5S_select_class_t H5S_sel_point[1] = {{
/* Methods on selection */
H5S__point_copy,
- H5S__point_get_seq_list,
H5S__point_release,
H5S__point_is_valid,
H5S__point_serial_size,
@@ -115,6 +123,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S__point_is_contiguous,
H5S__point_is_single,
H5S__point_is_regular,
+ H5S__point_shape_same,
H5S__point_adjust_u,
H5S__point_project_scalar,
H5S__point_project_simple,
@@ -144,11 +153,12 @@ static const H5S_sel_iter_class_t H5S_sel_iter_point[1] = {{
H5S__point_iter_has_next_block,
H5S__point_iter_next,
H5S__point_iter_next_block,
+ H5S__point_iter_get_seq_list,
H5S__point_iter_release,
}};
-/* Declare a free list to manage the H5S_pnt_node_t struct */
-H5FL_DEFINE_STATIC(H5S_pnt_node_t);
+/* Declare a free list to manage the H5S_pnt_node_t + hcoords_t array struct */
+H5FL_BARR_DEFINE_STATIC(H5S_pnt_node_t, hcoords_t, H5S_MAX_RANK);
/* Declare a free list to manage the H5S_pnt_list_t struct */
H5FL_DEFINE_STATIC(H5S_pnt_list_t);
@@ -168,7 +178,7 @@ H5FL_DEFINE_STATIC(H5S_pnt_list_t);
*-------------------------------------------------------------------------
*/
static herr_t
-H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
+H5S__point_iter_init(const H5S_t *space, H5S_sel_iter_t *iter)
{
FUNC_ENTER_STATIC_NOERR
@@ -176,11 +186,11 @@ H5S__point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space)
HDassert(space && H5S_SEL_POINTS == H5S_GET_SELECT_TYPE(space));
HDassert(iter);
- /* Initialize the number of points to iterate over */
- iter->elmt_left = space->select.num_elem;
+ /* Share point list for internal iterations */
+ iter->u.pnt.pnt_lst = space->select.sel_info.pnt_lst;
/* Start at the head of the list of points */
- iter->u.pnt.curr=space->select.sel_info.pnt_lst->head;
+ iter->u.pnt.curr = iter->u.pnt.pnt_lst->head;
/* Initialize type of selection iterator */
iter->type = H5S_sel_iter_point;
@@ -380,13 +390,11 @@ H5S__point_iter_next_block(H5S_sel_iter_t *iter)
/*--------------------------------------------------------------------------
NAME
- H5S__point_get_seq_list
+ H5S__point_iter_get_seq_list
PURPOSE
Create a list of offsets & lengths for a selection
USAGE
- herr_t H5S__point_get_seq_list(space,flags,iter,maxseq,maxelem,nseq,nelem,off,len)
- H5S_t *space; IN: Dataspace containing selection to use.
- unsigned flags; IN: Flags for extra information about operation
+ herr_t H5S__point_iter_get_seq_list(iter,maxseq,maxelem,nseq,nelem,off,len)
H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last
position of interest in selection.
size_t maxseq; IN: Maximum number of sequences to generate
@@ -410,25 +418,22 @@ H5S__point_iter_next_block(H5S_sel_iter_t *iter)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter,
- size_t maxseq, size_t maxelem, size_t *nseq, size_t *nelem,
- hsize_t *off, size_t *len)
+H5S__point_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelem,
+ size_t *nseq, size_t *nelem, hsize_t *off, size_t *len)
{
size_t io_left; /* The number of bytes left in the selection */
size_t start_io_left; /* The initial number of bytes left in the selection */
H5S_pnt_node_t *node; /* Point node */
- hsize_t dims[H5S_MAX_RANK]; /* Total size of memory buf */
- int ndims; /* Dimensionality of space*/
+ unsigned ndims; /* Dimensionality of dataspace*/
hsize_t acc; /* Coordinate accumulator */
hsize_t loc; /* Coordinate offset */
size_t curr_seq; /* Current sequence being operated on */
int i; /* Local index variable */
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_STATIC
+ FUNC_ENTER_STATIC_NOERR
/* Check args */
- HDassert(space);
HDassert(iter);
HDassert(maxseq > 0);
HDassert(maxelem > 0);
@@ -441,9 +446,8 @@ H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter
H5_CHECK_OVERFLOW(iter->elmt_left, hsize_t, size_t);
start_io_left = io_left = (size_t)MIN(iter->elmt_left, maxelem);
- /* Get the dataspace dimensions */
- if((ndims = H5S_get_simple_extent_dims (space, dims, NULL)) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve dataspace dimensions")
+ /* Get the dataspace's rank */
+ ndims = iter->rank;
/* Walk through the points in the selection, starting at the current */
/* location in the iterator */
@@ -451,15 +455,15 @@ H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter
curr_seq = 0;
while(NULL != node) {
/* Compute the offset of each selected point in the buffer */
- for(i = ndims - 1, acc = iter->elmt_size, loc = 0; i >= 0; i--) {
- loc += (hsize_t)((hssize_t)node->pnt[i] + space->select.offset[i]) * acc;
- acc *= dims[i];
+ for(i = (int)(ndims - 1), acc = iter->elmt_size, loc = 0; i >= 0; i--) {
+ loc += (hsize_t)((hssize_t)node->pnt[i] + iter->sel_off[i]) * acc;
+ acc *= iter->dims[i];
} /* end for */
/* Check if this is a later point in the selection */
if(curr_seq > 0) {
/* If a sorted sequence is requested, make certain we don't go backwards in the offset */
- if((flags&H5S_GET_SEQ_LIST_SORTED) && loc<off[curr_seq-1])
+ if((iter->flags & H5S_SEL_ITER_GET_SEQ_LIST_SORTED) && loc < off[curr_seq - 1])
break;
/* Check if this point extends the previous sequence */
@@ -511,9 +515,8 @@ H5S__point_get_seq_list(const H5S_t *space, unsigned flags, H5S_sel_iter_t *iter
/* Set the number of elements used */
*nelem = start_io_left - io_left;
-done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5S__point_get_seq_list() */
+} /* end H5S__point_iter_get_seq_list() */
/*--------------------------------------------------------------------------
@@ -580,14 +583,14 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c
HDassert(op == H5S_SELECT_SET || op == H5S_SELECT_APPEND || op == H5S_SELECT_PREPEND);
for(u = 0; u < num_elem; u++) {
+ unsigned dim; /* Counter for dimensions */
+
/* Allocate space for the new node */
- if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, space->extent.rank)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
/* Initialize fields in node */
new_node->next = NULL;
- if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(space->extent.rank * sizeof(hsize_t))))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
/* Copy over the coordinates */
H5MM_memcpy(new_node->pnt, coord + (u * space->extent.rank), (space->extent.rank * sizeof(hsize_t)));
@@ -598,6 +601,17 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c
else
curr->next = new_node;
curr = new_node;
+
+ /* Update bound box */
+ /* (Note: when op is H5S_SELECT_SET, the bound box has been reset
+ * inside H5S_select_elements, the only caller of this function.
+ * So the following bound box update procedure works correctly
+ * for the SET operation)
+ */
+ for(dim = 0; dim < space->extent.rank; dim++) {
+ space->select.sel_info.pnt_lst->low_bounds[dim] = MIN(space->select.sel_info.pnt_lst->low_bounds[dim], curr->pnt[dim]);
+ space->select.sel_info.pnt_lst->high_bounds[dim] = MAX(space->select.sel_info.pnt_lst->high_bounds[dim], curr->pnt[dim]);
+ } /* end for */
} /* end for */
new_node = NULL;
@@ -609,20 +623,22 @@ H5S__point_add(H5S_t *space, H5S_seloper_t op, size_t num_elem, const hsize_t *c
/* Put new list in point selection */
space->select.sel_info.pnt_lst->head = top;
+
+ /* Change the tail pointer if tail has not been set */
+ if(NULL == space->select.sel_info.pnt_lst->tail)
+ space->select.sel_info.pnt_lst->tail = curr;
} /* end if */
else { /* op==H5S_SELECT_APPEND */
H5S_pnt_node_t *tmp_node; /* Temporary point selection node */
tmp_node = space->select.sel_info.pnt_lst->head;
if(tmp_node != NULL) {
- while(tmp_node->next != NULL)
- tmp_node = tmp_node->next;
-
- /* Append new list to point selection */
- tmp_node->next = top;
+ HDassert(space->select.sel_info.pnt_lst->tail);
+ space->select.sel_info.pnt_lst->tail->next = top;
} /* end if */
else
space->select.sel_info.pnt_lst->head = top;
+ space->select.sel_info.pnt_lst->tail = curr;
} /* end else */
/* Set the number of elements in the new selection */
@@ -635,13 +651,12 @@ done:
if(ret_value < 0) {
/* Release possibly partially initialized new node */
if(new_node)
- new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
+ new_node = (H5S_pnt_node_t *)H5FL_ARR_FREE(hcoords_t, new_node);
/* Release possible linked list of nodes */
while(top) {
- curr = top->next;
- H5MM_xfree(top->pnt);
- top = H5FL_FREE(H5S_pnt_node_t, top);
+ curr = top->next;
+ top = (H5S_pnt_node_t *)H5FL_ARR_FREE(hcoords_t, top);
top = curr;
} /* end while */
} /* end if */
@@ -670,24 +685,16 @@ done:
static herr_t
H5S__point_release(H5S_t *space)
{
- H5S_pnt_node_t *curr, *next; /* Point selection nodes */
-
FUNC_ENTER_STATIC_NOERR
/* Check args */
HDassert(space);
- /* Delete all the nodes from the list */
- curr = space->select.sel_info.pnt_lst->head;
- while(curr != NULL) {
- next = curr->next;
- H5MM_xfree(curr->pnt);
- curr = H5FL_FREE(H5S_pnt_node_t, curr);
- curr = next;
- } /* end while */
+ /* Free the point list */
+ H5S__free_pnt_list(space->select.sel_info.pnt_lst);
- /* Free & reset the point list header */
- space->select.sel_info.pnt_lst = H5FL_FREE(H5S_pnt_list_t, space->select.sel_info.pnt_lst);
+ /* Reset the point list header */
+ space->select.sel_info.pnt_lst = NULL;
/* Reset the number of elements in the selection */
space->select.num_elem = 0;
@@ -743,10 +750,17 @@ H5S_select_elements(H5S_t *space, H5S_seloper_t op, size_t num_elem,
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release point selection")
/* Allocate space for the point selection information if necessary */
- if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS || space->select.sel_info.pnt_lst == NULL)
+ if(H5S_GET_SELECT_TYPE(space) != H5S_SEL_POINTS || space->select.sel_info.pnt_lst == NULL) {
+ hsize_t tmp = HSIZET_MAX;
+
if(NULL == (space->select.sel_info.pnt_lst = H5FL_CALLOC(H5S_pnt_list_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate element information")
+ /* Set the bound box to the default value */
+ H5VM_array_fill(space->select.sel_info.pnt_lst->low_bounds, &tmp, sizeof(hsize_t), space->extent.rank);
+ HDmemset(space->select.sel_info.pnt_lst->high_bounds, 0, sizeof(hsize_t) * space->extent.rank);
+ } /* end if */
+
/* Add points to selection */
if(H5S__point_add(space, op, num_elem, coord) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't insert elements")
@@ -761,58 +775,56 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5S__point_copy
+ H5S__copy_pnt_list
PURPOSE
- Copy a selection from one dataspace to another
+ Copy a point selection list
USAGE
- herr_t H5S__point_copy(dst, src, share_selection)
- H5S_t *dst; OUT: Pointer to the destination dataspace
- H5S_t *src; IN: Pointer to the source dataspace
- hbool_t share_selection; IN: Whether to share the selection between the dataspaces
+ H5S_pnt_list_t *H5S__copy_pnt_list(src)
+ const H5S_pnt_list_t *src; IN: Pointer to the source point list
+ unsigned rank; IN: # of dimensions for points
RETURNS
- Non-negative on success/Negative on failure
+ Non-NULL pointer to new point list on success / NULL on failure
DESCRIPTION
- Copies all the point selection information from the source
- dataspace to the destination dataspace.
+ Copies point selection information from the source point list to newly
+ created point list.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-static herr_t
-H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selection)
+static H5S_pnt_list_t *
+H5S__copy_pnt_list(const H5S_pnt_list_t *src, unsigned rank)
{
- H5S_pnt_node_t *curr, *new_node, *new_tail; /* Point information nodes */
- herr_t ret_value = SUCCEED; /* Return value */
+ H5S_pnt_list_t *dst = NULL; /* New point list */
+ H5S_pnt_node_t *curr, *new_tail; /* Point information nodes */
+ H5S_pnt_list_t *ret_value = NULL; /* Return value */
FUNC_ENTER_STATIC
/* Sanity checks */
HDassert(src);
- HDassert(dst);
+ HDassert(rank > 0);
/* Allocate room for the head of the point list */
- if(NULL == (dst->select.sel_info.pnt_lst = H5FL_MALLOC(H5S_pnt_list_t)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point list node")
+ if(NULL == (dst = H5FL_MALLOC(H5S_pnt_list_t)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate point list node")
- curr = src->select.sel_info.pnt_lst->head;
+ curr = src->head;
new_tail = NULL;
while(curr) {
+ H5S_pnt_node_t *new_node; /* New point information node */
+
/* Create new point */
- if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
+ if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, rank)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate point node")
new_node->next = NULL;
- if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(src->extent.rank * sizeof(hsize_t)))) {
- new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
- } /* end if */
/* Copy over the point's coordinates */
- H5MM_memcpy(new_node->pnt, curr->pnt, (src->extent.rank * sizeof(hsize_t)));
+ H5MM_memcpy(new_node->pnt, curr->pnt, (rank * sizeof(hsize_t)));
/* Keep the order the same when copying */
if(NULL == new_tail)
- new_tail = dst->select.sel_info.pnt_lst->head = new_node;
+ new_tail = dst->head = new_node;
else {
new_tail->next = new_node;
new_tail = new_node;
@@ -820,22 +832,101 @@ H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selec
curr = curr->next;
} /* end while */
+ dst->tail = new_tail;
+
+ /* Copy the selection bounds */
+ H5MM_memcpy(dst->high_bounds, src->high_bounds, (rank * sizeof(hsize_t)));
+ H5MM_memcpy(dst->low_bounds, src->low_bounds, (rank * sizeof(hsize_t)));
+
+ /* Set return value */
+ ret_value = dst;
done:
- if(ret_value < 0 && dst->select.sel_info.pnt_lst) {
- /* Traverse the (incomplete?) dst list, freeing all memory */
- curr = dst->select.sel_info.pnt_lst->head;
- while(curr) {
- H5S_pnt_node_t *tmp_node = curr;
-
- curr->pnt = (hsize_t *)H5MM_xfree(curr->pnt);
- curr = curr->next;
- tmp_node = H5FL_FREE(H5S_pnt_node_t, tmp_node);
- } /* end while */
+ if(NULL == ret_value && dst)
+ H5S__free_pnt_list(dst);
- dst->select.sel_info.pnt_lst = H5FL_FREE(H5S_pnt_list_t, dst->select.sel_info.pnt_lst);
- } /* end if */
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S__copy_pnt_list() */
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__free_pnt_list
+ PURPOSE
+ Free a point selection list
+ USAGE
+ void H5S__free_pnt_list(pnt_lst)
+ H5S_pnt_list_t *pnt_lst; IN: Pointer to the point list to free
+ RETURNS
+ None
+ DESCRIPTION
+ Frees point selection information from the point list
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static void
+H5S__free_pnt_list(H5S_pnt_list_t *pnt_lst)
+{
+ H5S_pnt_node_t *curr; /* Point information nodes */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Sanity checks */
+ HDassert(pnt_lst);
+
+ /* Traverse the list, freeing all memory */
+ curr = pnt_lst->head;
+ while(curr) {
+ H5S_pnt_node_t *tmp_node = curr;
+
+ curr = curr->next;
+ tmp_node = (H5S_pnt_node_t *)H5FL_ARR_FREE(hcoords_t, tmp_node);
+ } /* end while */
+
+ H5FL_FREE(H5S_pnt_list_t, pnt_lst);
+
+ FUNC_LEAVE_NOAPI_VOID
+} /* end H5S__free_pnt_list() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S__point_copy
+ PURPOSE
+ Copy a selection from one dataspace to another
+ USAGE
+ herr_t H5S__point_copy(dst, src, share_selection)
+ H5S_t *dst; OUT: Pointer to the destination dataspace
+ H5S_t *src; IN: Pointer to the source dataspace
+ hbool_t share_selection; IN: Whether to share the selection between the dataspaces
+ RETURNS
+ Non-negative on success/Negative on failure
+ DESCRIPTION
+ Copies all the point selection information from the source
+ dataspace to the destination dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S__point_copy(H5S_t *dst, const H5S_t *src, hbool_t H5_ATTR_UNUSED share_selection)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(src);
+ HDassert(dst);
+
+ /* Allocate room for the head of the point list */
+ if(NULL == (dst->select.sel_info.pnt_lst = H5S__copy_pnt_list(src->select.sel_info.pnt_lst, src->extent.rank)))
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy point list")
+
+done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5S__point_copy() */
@@ -863,7 +954,6 @@ done:
static htri_t
H5S__point_is_valid(const H5S_t *space)
{
- H5S_pnt_node_t *curr; /* Point information nodes */
unsigned u; /* Counter */
htri_t ret_value = TRUE; /* Return value */
@@ -871,20 +961,14 @@ H5S__point_is_valid(const H5S_t *space)
HDassert(space);
- /* Check each point to determine whether selection+offset is within extent */
- curr = space->select.sel_info.pnt_lst->head;
- while(curr != NULL) {
- /* Check each dimension */
- for(u = 0; u < space->extent.rank; u++) {
- /* Check if an offset has been defined */
- /* Bounds check the selected point + offset against the extent */
- if(((curr->pnt[u] + (hsize_t)space->select.offset[u]) > space->extent.size[u])
- || (((hssize_t)curr->pnt[u] + space->select.offset[u]) < 0))
- HGOTO_DONE(FALSE)
- } /* end for */
-
- curr = curr->next;
- } /* end while */
+ /* Check each dimension */
+ for(u = 0; u < space->extent.rank; u++) {
+ /* Bounds check the selected point + offset against the extent */
+ if((space->select.sel_info.pnt_lst->high_bounds[u] + (hsize_t)space->select.offset[u]) > space->extent.size[u])
+ HGOTO_DONE(FALSE)
+ if(((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] + space->select.offset[u]) < 0)
+ HGOTO_DONE(FALSE)
+ } /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -929,6 +1013,7 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Sget_select_elem_npoints() */
+
/*--------------------------------------------------------------------------
NAME
H5S__point_get_version_enc_size
@@ -982,13 +1067,12 @@ H5S__point_get_version_enc_size(const H5S_t *space, uint32_t *version, uint8_t *
/* Determine whether number of points or high bounds exceeds (2^32 - 1) */
if(space->select.num_elem > H5S_UINT32_MAX)
count_up_version = TRUE;
- else {
+ else
for(u = 0; u < space->extent.rank; u++)
if(bounds_end[u] > H5S_UINT32_MAX) {
bound_up_version = TRUE;
break;
- }
- }
+ } /* end if */
/* If exceed (2^32 -1) */
if(count_up_version || bound_up_version)
@@ -1011,7 +1095,7 @@ H5S__point_get_version_enc_size(const H5S_t *space, uint32_t *version, uint8_t *
HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "The end of bounding box in point selection exceeds 2^32")
else
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "Dataspace point selection version out of bounds")
- }
+ } /* end if */
/* Set the version to return */
*version = tmp_version;
@@ -1540,8 +1624,6 @@ done:
static herr_t
H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
- H5S_pnt_node_t *node; /* Point node */
- unsigned rank; /* Dataspace rank */
unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
@@ -1552,30 +1634,19 @@ H5S__point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
HDassert(start);
HDassert(end);
- /* Get the dataspace extent rank */
- rank = space->extent.rank;
-
- /* Set the start and end arrays up */
- for(u = 0; u < rank; u++) {
- start[u] = HSIZET_MAX;
- end[u] = 0;
- } /* end for */
+ /* Loop over dimensions */
+ for(u = 0; u < space->extent.rank; u++) {
+ /* Sanity check */
+ HDassert(space->select.sel_info.pnt_lst->low_bounds[u] <= space->select.sel_info.pnt_lst->high_bounds[u]);
- /* Iterate through the node, checking the bounds on each element */
- node = space->select.sel_info.pnt_lst->head;
- while(node != NULL) {
- for(u = 0; u < rank; u++) {
- /* Check for offset moving selection negative */
- if(((hssize_t)node->pnt[u] + space->select.offset[u]) < 0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+ /* Check for offset moving selection negative */
+ if(((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] + space->select.offset[u]) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
- if(start[u] > (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u]))
- start[u] = (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u]);
- if(end[u] < (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u]))
- end[u] = (hsize_t)((hssize_t)node->pnt[u] + space->select.offset[u]);
- } /* end for */
- node = node->next;
- } /* end while */
+ /* Set the low & high bounds in this dimension */
+ start[u] = (hsize_t)((hssize_t)space->select.sel_info.pnt_lst->low_bounds[u] + space->select.offset[u]);
+ end[u] = (hsize_t)((hssize_t)space->select.sel_info.pnt_lst->high_bounds[u] + space->select.offset[u]);
+ } /* end for */
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -1795,6 +1866,114 @@ H5S__point_is_regular(const H5S_t *space)
/*--------------------------------------------------------------------------
NAME
+ H5S__point_shape_same
+ PURPOSE
+ Check if a two "point" selections are the same shape
+ USAGE
+ htri_t H5S__point_shape_same(space1, space2)
+ const H5S_t *space1; IN: First dataspace to check
+ const H5S_t *space2; IN: Second dataspace to check
+ RETURNS
+ TRUE / FALSE / FAIL
+ DESCRIPTION
+ Checks to see if the current selection in each dataspace are the same
+ shape.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static htri_t
+H5S__point_shape_same(const H5S_t *space1, const H5S_t *space2)
+{
+ H5S_pnt_node_t *pnt1, *pnt2; /* Point information nodes */
+ hssize_t offset[H5S_MAX_RANK]; /* Offset between the selections */
+ unsigned space1_rank; /* Number of dimensions of first dataspace */
+ unsigned space2_rank; /* Number of dimensions of second dataspace */
+ int space1_dim; /* Current dimension in first dataspace */
+ int space2_dim; /* Current dimension in second dataspace */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_STATIC_NOERR
+
+ /* Check args */
+ HDassert(space1);
+ HDassert(space2);
+
+ /* Get dataspace ranks */
+ space1_rank = space1->extent.rank;
+ space2_rank = space2->extent.rank;
+
+ /* Sanity check */
+ HDassert(space1_rank >= space2_rank);
+ HDassert(space2_rank > 0);
+
+ /* Initialize dimensions */
+ space1_dim = (int)space1_rank - 1;
+ space2_dim = (int)space2_rank - 1;
+
+ /* Look at first point in each selection to compute the offset for common
+ * dimensions.
+ */
+ pnt1 = space1->select.sel_info.pnt_lst->head;
+ pnt2 = space2->select.sel_info.pnt_lst->head;
+ while(space2_dim >= 0) {
+ /* Set the relative locations of the selections */
+ offset[space1_dim] = (hssize_t)pnt2->pnt[space2_dim] - (hssize_t)pnt1->pnt[space1_dim];
+
+ space1_dim--;
+ space2_dim--;
+ } /* end while */
+
+ /* For dimensions that appear only in space1: */
+ while(space1_dim >= 0) {
+ /* Set the absolute offset of the remaining dimensions */
+ offset[space1_dim] = (hssize_t)pnt1->pnt[space1_dim];
+
+ space1_dim--;
+ } /* end while */
+
+ /* Advance to next point */
+ pnt1 = pnt1->next;
+ pnt2 = pnt2->next;
+
+ /* Loop over remaining points */
+ while(pnt1 && pnt2) {
+ /* Initialize dimensions */
+ space1_dim = (int)space1_rank - 1;
+ space2_dim = (int)space2_rank - 1;
+
+ /* Compare locations in common dimensions, including relative offset */
+ while(space2_dim >= 0) {
+ if((hsize_t)((hssize_t)pnt1->pnt[space1_dim] + offset[space1_dim]) != pnt2->pnt[space2_dim])
+ HGOTO_DONE(FALSE)
+
+ space1_dim--;
+ space2_dim--;
+ } /* end while */
+
+ /* For dimensions that appear only in space1: */
+ while(space1_dim >= 0) {
+ /* Compare the absolute offset in the remaining dimensions */
+ if((hssize_t)pnt1->pnt[space1_dim] != offset[space1_dim])
+ HGOTO_DONE(FALSE)
+
+ space1_dim--;
+ } /* end while */
+
+
+ /* Advance to next point */
+ pnt1 = pnt1->next;
+ pnt2 = pnt2->next;
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S__point_shape_same() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S__point_adjust_u
PURPOSE
Adjust a "point" selection by subtracting an offset
@@ -1816,6 +1995,7 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset)
{
H5S_pnt_node_t *node; /* Point node */
unsigned rank; /* Dataspace rank */
+ unsigned u; /* Local index variable */
FUNC_ENTER_STATIC_NOERR
@@ -1826,8 +2006,6 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset)
node = space->select.sel_info.pnt_lst->head;
rank = space->extent.rank;
while(node) {
- unsigned u; /* Local index variable */
-
/* Adjust each coordinate for point node */
for(u = 0; u < rank; u++) {
/* Check for offset moving selection negative */
@@ -1841,6 +2019,12 @@ H5S__point_adjust_u(H5S_t *space, const hsize_t *offset)
node = node->next;
} /* end while */
+ /* update the bound box of the selection */
+ for(u = 0; u < rank; u++) {
+ space->select.sel_info.pnt_lst->low_bounds[u] -= offset[u];
+ space->select.sel_info.pnt_lst->high_bounds[u] -= offset[u];
+ } /* end for */
+
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5S__point_adjust_u() */
@@ -1905,6 +2089,7 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of
H5S_pnt_node_t *new_node; /* Point node in new space */
H5S_pnt_node_t *prev_node; /* Previous point node in new space */
unsigned rank_diff; /* Difference in ranks between spaces */
+ unsigned u; /* Local index variable */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -1939,13 +2124,9 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of
prev_node = NULL;
while(base_node) {
/* Create new point */
- if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
new_node->next = NULL;
- if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) {
- new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
- } /* end if */
/* Copy over the point's coordinates */
H5MM_memcpy(new_node->pnt, &base_node->pnt[rank_diff], (new_space->extent.rank * sizeof(hsize_t)));
@@ -1961,6 +2142,12 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of
/* Advance to next node */
base_node = base_node->next;
} /* end while */
+
+ /* Update the bounding box */
+ for(u = 0; u < new_space->extent.rank; u++) {
+ new_space->select.sel_info.pnt_lst->low_bounds[u] = base_space->select.sel_info.pnt_lst->low_bounds[u + rank_diff];
+ new_space->select.sel_info.pnt_lst->high_bounds[u] = base_space->select.sel_info.pnt_lst->high_bounds[u + rank_diff];
+ } /* end for */
} /* end if */
else {
HDassert(new_space->extent.rank > base_space->extent.rank);
@@ -1976,13 +2163,9 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of
prev_node = NULL;
while(base_node) {
/* Create new point */
- if(NULL == (new_node = H5FL_MALLOC(H5S_pnt_node_t)))
+ if(NULL == (new_node = (H5S_pnt_node_t *)H5FL_ARR_MALLOC(hcoords_t, new_space->extent.rank)))
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate point node")
new_node->next = NULL;
- if(NULL == (new_node->pnt = (hsize_t *)H5MM_malloc(new_space->extent.rank * sizeof(hsize_t)))) {
- new_node = H5FL_FREE(H5S_pnt_node_t, new_node);
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate coordinate information")
- } /* end if */
/* Copy over the point's coordinates */
HDmemset(new_node->pnt, 0, sizeof(hsize_t) * rank_diff);
@@ -1999,6 +2182,16 @@ H5S__point_project_simple(const H5S_t *base_space, H5S_t *new_space, hsize_t *of
/* Advance to next node */
base_node = base_node->next;
} /* end while */
+
+ /* Update the bounding box */
+ for(u = 0; u < rank_diff; u++) {
+ new_space->select.sel_info.pnt_lst->low_bounds[u] = 0;
+ new_space->select.sel_info.pnt_lst->high_bounds[u] = 0;
+ } /* end for */
+ for(; u < new_space->extent.rank; u++) {
+ new_space->select.sel_info.pnt_lst->low_bounds[u] = base_space->select.sel_info.pnt_lst->low_bounds[u - rank_diff];
+ new_space->select.sel_info.pnt_lst->high_bounds[u] = base_space->select.sel_info.pnt_lst->high_bounds[u - rank_diff];
+ } /* end for */
} /* end else */
/* Number of elements selected will be the same */