summaryrefslogtreecommitdiffstats
path: root/src/H5Spoint.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2007-11-29 18:44:07 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2007-11-29 18:44:07 (GMT)
commit765f0159ffa71c77754583d97a2b9e494d381ebe (patch)
treeb52931bca7b603c4e73df53dca322afeefcedcfd /src/H5Spoint.c
parent44fa94541b3de90b358f4921725bab2cbe953c4d (diff)
downloadhdf5-765f0159ffa71c77754583d97a2b9e494d381ebe.zip
hdf5-765f0159ffa71c77754583d97a2b9e494d381ebe.tar.gz
hdf5-765f0159ffa71c77754583d97a2b9e494d381ebe.tar.bz2
[svn-r14307] Description:
- Extracted common code from H5D_select_read/H5D_select_write into single routine (H5D_select_io) and made H5D_select_read/H5D_select_write "gateway" routines, passing I/O buffer to operate on in "op" struct. - Create optimized pathway in H5D_select_io for I/O operations on single elements. - Make "get linear offset of first element" callback for each type of selection (used in "optimized pathway", above) Tested on: FreeBSD/32 6.2 (duty) in debug mode FreeBSD/64 6.2 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (kagiso) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/default API=1.6.x, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Mac OS X/32 10.4.10 (amazon) in debug mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in production mode
Diffstat (limited to 'src/H5Spoint.c')
-rw-r--r--src/H5Spoint.c110
1 files changed, 89 insertions, 21 deletions
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index eb37945..78c401c 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -44,6 +44,7 @@ static hssize_t H5S_point_serial_size(const H5S_t *space);
static herr_t H5S_point_serialize(const H5S_t *space, uint8_t *buf);
static herr_t H5S_point_deserialize(H5S_t *space, const uint8_t *buf);
static herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end);
+static herr_t H5S_point_offset(const H5S_t *space, hsize_t *off);
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);
@@ -72,6 +73,7 @@ const H5S_select_class_t H5S_sel_point[1] = {{
H5S_point_serialize,
H5S_point_deserialize,
H5S_point_bounds,
+ H5S_point_offset,
H5S_point_is_contiguous,
H5S_point_is_single,
H5S_point_is_regular,
@@ -1038,48 +1040,114 @@ static herr_t
H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
H5S_pnt_node_t *node; /* Point node */
- int rank; /* Dataspace rank */
- int i; /* index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ unsigned rank; /* Dataspace rank */
+ unsigned u; /* index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5S_point_bounds);
+ FUNC_ENTER_NOAPI_NOINIT(H5S_point_bounds)
- assert(space);
- assert(start);
- assert(end);
+ HDassert(space);
+ HDassert(start);
+ HDassert(end);
/* Get the dataspace extent rank */
- rank=space->extent.rank;
+ rank = space->extent.rank;
/* Set the start and end arrays up */
- for(i=0; i<rank; i++) {
- start[i]=HSIZET_MAX;
- end[i]=0;
+ for(u = 0; u < rank; u++) {
+ start[u] = HSIZET_MAX;
+ end[u] = 0;
} /* end for */
/* Iterate through the node, checking the bounds on each element */
- node=space->select.sel_info.pnt_lst->head;
- while(node!=NULL) {
- for(i=0; i<rank; i++) {
+ 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[i]+space->select.offset[i])<0)
+ if(((hssize_t)node->pnt[u] + space->select.offset[u]) < 0)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
- if(start[i]>(node->pnt[i]+space->select.offset[i]))
- start[i]=node->pnt[i]+space->select.offset[i];
- if(end[i]<(node->pnt[i]+space->select.offset[i]))
- end[i]=node->pnt[i]+space->select.offset[i];
+ if(start[u] > (node->pnt[u] + space->select.offset[u]))
+ start[u] = node->pnt[u] + space->select.offset[u];
+ if(end[u] < (node->pnt[u] + space->select.offset[u]))
+ end[u] = node->pnt[u] + space->select.offset[u];
} /* end for */
- node=node->next;
+ node = node->next;
} /* end while */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5S_point_bounds() */
/*--------------------------------------------------------------------------
NAME
+ H5S_point_offset
+ PURPOSE
+ Gets the linear offset of the first element for the selection.
+ USAGE
+ herr_t H5S_point_offset(space, offset)
+ const H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t *offset; OUT: Linear offset of first element in selection
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Retrieves the linear offset (in "units" of elements) of the first element
+ selected within the dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Calling this function on a "none" selection returns fail.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_point_offset(const H5S_t *space, hsize_t *offset)
+{
+ const hsize_t *pnt; /* Pointer to a selected point's coordinates */
+ const hssize_t *sel_offset; /* Pointer to the selection's offset */
+ const hsize_t *dim_size; /* Pointer to a dataspace's extent */
+ hsize_t accum; /* Accumulator for dimension sizes */
+ int rank; /* Dataspace rank */
+ int i; /* index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_point_offset, FAIL)
+
+ HDassert(space);
+ HDassert(offset);
+
+ /* Start at linear offset 0 */
+ *offset = 0;
+
+ /* Set up pointers to arrays of values */
+ pnt = space->select.sel_info.pnt_lst->head->pnt;
+ sel_offset = space->select.offset;
+ dim_size = space->extent.size;
+
+ /* Loop through coordinates, calculating the linear offset */
+ rank = space->extent.rank;
+ accum = 1;
+ for(i = (rank - 1); i >= 0; i--) {
+ hssize_t pnt_offset = (hssize_t)pnt[i] + sel_offset[i]; /* Point's offset in this dimension */
+
+ /* Check for offset moving selection out of the dataspace */
+ if(pnt_offset < 0 || (hsize_t)pnt_offset >= dim_size[i])
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "offset moves selection out of bounds")
+
+ /* Add the point's offset in this dimension to the total linear offset */
+ *offset += pnt_offset * accum;
+
+ /* Increase the accumulator */
+ accum *= dim_size[i];
+ } /* end for */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5S_point_offset() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_point_is_contiguous
PURPOSE
Check if a point selection is contiguous within the dataspace extent.