summaryrefslogtreecommitdiffstats
path: root/src/H5Shyper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r--src/H5Shyper.c548
1 files changed, 428 insertions, 120 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 04cecf6..4be5952 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -86,7 +86,7 @@ H5S_hyper_print_spans(const struct H5S_hyper_span_info_t *span_lst)
/*-------------------------------------------------------------------------
- * Function: H5S_hyper_init
+ * Function: H5S_hyper_iter_init
*
* Purpose: Initializes iteration information for hyperslab span tree selection.
*
@@ -100,7 +100,7 @@ H5S_hyper_print_spans(const struct H5S_hyper_span_info_t *span_lst)
*-------------------------------------------------------------------------
*/
herr_t
-H5S_hyper_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_iter)
+H5S_hyper_iter_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_iter)
{
unsigned cont_dim; /* Maximum contiguous dimension */
const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */
@@ -108,7 +108,7 @@ H5S_hyper_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_iter)
unsigned u; /* Index variable */
int i; /* Index variable */
- FUNC_ENTER_NOAPI(H5S_hyper_init, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_iter_init, FAIL);
/* Check args */
assert(space && H5S_SEL_HYPERSLABS==space->select.type);
@@ -230,30 +230,56 @@ H5S_hyper_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *sel_iter)
} /* end else */
FUNC_LEAVE (SUCCEED);
-} /* H5S_hyper_init() */
+} /* H5S_hyper_iter_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_iter_nelmts
+ *
+ * Purpose: Return number of elements left to process in iterator
+ *
+ * Return: non-negative number of elements on success, zero on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 16, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5S_hyper_iter_nelmts (const H5S_sel_iter_t *sel_iter)
+{
+ FUNC_ENTER_NOAPI(H5S_hyper_iter_nelmts, 0);
+
+ /* Check args */
+ assert (sel_iter);
+
+ FUNC_LEAVE (sel_iter->hyp.elmt_left);
+} /* H5S_hyper_iter_nelmts() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_sel_iter_release
+ H5S_hyper_iter_release
PURPOSE
- Release "new" hyperslab selection iterator information for a dataspace
+ Release hyperslab selection iterator information for a dataspace
USAGE
- herr_t H5S_hyper_sel_iter_release(sel_iter)
+ herr_t H5S_hyper_iter_release(sel_iter)
H5S_sel_iter_t *sel_iter; IN: Pointer to selection iterator
RETURNS
Non-negative on success/Negative on failure
DESCRIPTION
- Releases all information for a dataspace "new" hyperslab selection iterator
+ Releases all information for a dataspace hyperslab selection iterator
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_sel_iter_release (H5S_sel_iter_t *sel_iter)
+H5S_hyper_iter_release (H5S_sel_iter_t *sel_iter)
{
- FUNC_ENTER_NOAPI(H5S_hyper_sel_iter_release, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_iter_release, FAIL);
/* Check args */
assert (sel_iter);
@@ -285,35 +311,7 @@ H5S_hyper_sel_iter_release (H5S_sel_iter_t *sel_iter)
H5FL_ARR_FREE(H5S_hyper_span_t,sel_iter->hyp.span);
FUNC_LEAVE (SUCCEED);
-} /* H5S_hyper_sel_iter_release() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5S_hyper_favail
- *
- * Purpose: Figure out the optimal number of elements to transfer to/from the file
- *
- * Return: non-negative number of elements on success, zero on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, June 16, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hsize_t
-H5S_hyper_favail (const H5S_t * UNUSED space,
- const H5S_sel_iter_t *sel_iter, hsize_t max)
-{
- FUNC_ENTER_NOAPI(H5S_hyper_favail, 0);
-
- /* Check args */
- assert (space && H5S_SEL_HYPERSLABS==space->select.type);
- assert (sel_iter);
-
- FUNC_LEAVE (MIN(sel_iter->hyp.elmt_left,max));
-} /* H5S_hyper_favail() */
+} /* H5S_hyper_iter_release() */
/*-------------------------------------------------------------------------
@@ -1068,12 +1066,12 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_valid_helper
+ H5S_hyper_is_valid_helper
PURPOSE
Check whether the selection fits within the extent, with the current
offset defined.
USAGE
- htri_t H5S_hyper_select_valid_helper(spans, offset, rank);
+ 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
@@ -1090,13 +1088,13 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static htri_t
-H5S_hyper_select_valid_helper (const H5S_hyper_span_info_t *spans, const hssize_t *offset, const hsize_t *size, hsize_t rank)
+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_NOINIT(H5S_hyper_select_valid_helper);
+ FUNC_ENTER_NOINIT(H5S_hyper_is_valid_helper);
assert(spans);
assert(offset);
@@ -1118,7 +1116,7 @@ H5S_hyper_select_valid_helper (const H5S_hyper_span_info_t *spans, const hssize_
/* Recurse if this node has down spans */
if(curr->down!=NULL) {
- if((tmp=H5S_hyper_select_valid_helper(curr->down,offset,size,rank+1))!=TRUE) {
+ if((tmp=H5S_hyper_is_valid_helper(curr->down,offset,size,rank+1))!=TRUE) {
ret_value=tmp;
break;
} /* end if */
@@ -1129,17 +1127,17 @@ H5S_hyper_select_valid_helper (const H5S_hyper_span_info_t *spans, const hssize_
} /* end while */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_valid_helper() */
+} /* end H5S_hyper_is_valid_helper() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_valid
+ H5S_hyper_is_valid
PURPOSE
Check whether the selection fits within the extent, with the current
offset defined.
USAGE
- htri_t H5S_hyper_select_valid(space);
+ htri_t H5S_hyper_is_valid(space);
H5S_t *space; IN: Dataspace pointer to query
RETURNS
TRUE if the selection fits within the extent, FALSE if it does not and
@@ -1153,12 +1151,12 @@ H5S_hyper_select_valid_helper (const H5S_hyper_span_info_t *spans, const hssize_
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_hyper_select_valid (const H5S_t *space)
+H5S_hyper_is_valid (const H5S_t *space)
{
unsigned u; /* Counter */
htri_t ret_value=TRUE; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_valid, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_is_valid, FAIL);
assert(space);
@@ -1192,11 +1190,11 @@ H5S_hyper_select_valid (const H5S_t *space)
} /* end if */
else {
/* Call the recursive routine to validate the span tree */
- ret_value=H5S_hyper_select_valid_helper(space->select.sel_info.hslab.span_lst,space->select.offset,space->extent.u.simple.size,(hsize_t)0);
+ ret_value=H5S_hyper_is_valid_helper(space->select.sel_info.hslab.span_lst,space->select.offset,space->extent.u.simple.size,(hsize_t)0);
} /* end else */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_valid() */
+} /* end H5S_hyper_is_valid() */
/*--------------------------------------------------------------------------
@@ -1216,13 +1214,13 @@ H5S_hyper_select_valid (const H5S_t *space)
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-hssize_t
+static hssize_t
H5S_hyper_span_nblocks (H5S_hyper_span_info_t *spans)
{
H5S_hyper_span_t *span; /* Hyperslab span */
hssize_t ret_value=FAIL;
- FUNC_ENTER_NOAPI(H5S_hyper_span_nblocks, FAIL);
+ FUNC_ENTER_NOINIT(H5S_hyper_span_nblocks);
/* Count the number of elements in the span tree */
if(spans==NULL)
@@ -1252,12 +1250,90 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_serial_size
+ H5S_get_select_hyper_nblocks
+ PURPOSE
+ Get the number of hyperslab blocks in current hyperslab selection
+ USAGE
+ hssize_t H5S_get_select_hyper_nblocks(space)
+ H5S_t *space; IN: Dataspace ptr of selection to query
+ RETURNS
+ The number of hyperslab blocks in selection on success, negative on failure
+ DESCRIPTION
+ Returns the number of hyperslab blocks in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static hssize_t
+H5S_get_select_hyper_nblocks(H5S_t *space)
+{
+ hssize_t ret_value=FAIL; /* return value */
+ unsigned u; /* Counter */
+
+ FUNC_ENTER_NOINIT(H5S_get_select_hyper_nblocks);
+
+ assert(space);
+
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab.diminfo != NULL) {
+ /* Check each dimension */
+ for(ret_value=1,u=0; u<space->extent.u.simple.rank; u++)
+ ret_value*=space->select.sel_info.hslab.app_diminfo[u].count;
+ } /* end if */
+ else
+ ret_value = H5S_hyper_span_nblocks(space->select.sel_info.hslab.span_lst);
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_get_select_hyper_nblocks() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sget_select_hyper_nblocks
+ PURPOSE
+ Get the number of hyperslab blocks in current hyperslab selection
+ USAGE
+ hssize_t H5Sget_select_hyper_nblocks(dsid)
+ hid_t dsid; IN: Dataspace ID of selection to query
+ RETURNS
+ The number of hyperslab blocks in selection on success, negative on failure
+ DESCRIPTION
+ Returns the number of hyperslab blocks in current selection for dataspace.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hssize_t
+H5Sget_select_hyper_nblocks(hid_t spaceid)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ hssize_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER_API(H5Sget_select_hyper_nblocks, FAIL);
+ H5TRACE1("Hs","i",spaceid);
+
+ /* Check args */
+ if (H5I_DATASPACE != H5I_get_type(spaceid) || NULL == (space=H5I_object(spaceid)))
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ if(space->select.type!=H5S_SEL_HYPERSLABS)
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection");
+
+ ret_value = H5S_get_select_hyper_nblocks(space);
+
+ FUNC_LEAVE (ret_value);
+} /* H5Sget_select_hyper_nblocks() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_serial_size
PURPOSE
Determine the number of bytes needed to store the serialized hyperslab
selection information.
USAGE
- hssize_t H5S_hyper_select_serial_size(space)
+ hssize_t H5S_hyper_serial_size(space)
H5S_t *space; IN: Dataspace pointer to query
RETURNS
The number of bytes required on success, negative on an error.
@@ -1270,17 +1346,17 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
hssize_t
-H5S_hyper_select_serial_size (const H5S_t *space)
+H5S_hyper_serial_size (const H5S_t *space)
{
unsigned u; /* Counter */
hssize_t block_count; /* block counter for regular hyperslabs */
hssize_t ret_value=FAIL; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_serial_size, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_serial_size, FAIL);
assert(space);
- /* Basic number of bytes required to serialize point selection:
+ /* Basic number of bytes required to serialize hyperslab selection:
* <type (4 bytes)> + <version (4 bytes)> + <padding (4 bytes)> +
* <length (4 bytes)> + <rank (4 bytes)> + <# of blocks (4 bytes)> = 24 bytes
*/
@@ -1300,16 +1376,16 @@ H5S_hyper_select_serial_size (const H5S_t *space)
} /* end else */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_serial_size() */
+} /* end H5S_hyper_serial_size() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_serialize_helper
+ H5S_hyper_serialize_helper
PURPOSE
Serialize the current selection into a user-provided buffer.
USAGE
- herr_t H5S_hyper_select_serialize_helper(spans, start, end, rank, buf)
+ herr_t H5S_hyper_serialize_helper(spans, start, end, rank, buf)
H5S_hyper_span_info_t *spans; IN: Hyperslab span tree to serialize
hssize_t start[]; IN/OUT: Accumulated start points
hssize_t end[]; IN/OUT: Accumulated end points
@@ -1326,13 +1402,13 @@ H5S_hyper_select_serial_size (const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_select_serialize_helper (const H5S_hyper_span_info_t *spans, hssize_t *start, hssize_t *end, hsize_t rank, uint8_t **buf)
+H5S_hyper_serialize_helper (const H5S_hyper_span_info_t *spans, hssize_t *start, hssize_t *end, hsize_t rank, uint8_t **buf)
{
H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
hsize_t u; /* Index variable */
herr_t ret_value=SUCCEED; /* return value */
- FUNC_ENTER_NOINIT(H5S_hyper_select_serialize_helper);
+ FUNC_ENTER_NOINIT(H5S_hyper_serialize_helper);
/* Sanity checks */
assert(spans);
@@ -1351,7 +1427,7 @@ H5S_hyper_select_serialize_helper (const H5S_hyper_span_info_t *spans, hssize_t
end[rank]=curr->high;
/* Recurse down to the next dimension */
- if(H5S_hyper_select_serialize_helper(curr->down,start,end,rank+1,buf)<0)
+ if(H5S_hyper_serialize_helper(curr->down,start,end,rank+1,buf)<0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release hyperslab spans");
} /* end if */
else {
@@ -1378,16 +1454,16 @@ H5S_hyper_select_serialize_helper (const H5S_hyper_span_info_t *spans, hssize_t
done:
FUNC_LEAVE (ret_value);
-} /* H5S_hyper_select_serialize_helper() */
+} /* H5S_hyper_serialize_helper() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_serialize
+ H5S_hyper_serialize
PURPOSE
Serialize the current selection into a user-provided buffer.
USAGE
- herr_t H5S_hyper_select_serialize(space, buf)
+ herr_t H5S_hyper_serialize(space, buf)
H5S_t *space; IN: Dataspace pointer of selection to serialize
uint8 *buf; OUT: Buffer to put serialized selection into
RETURNS
@@ -1401,7 +1477,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf)
+H5S_hyper_serialize (const H5S_t *space, uint8_t *buf)
{
H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
@@ -1419,7 +1495,7 @@ H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf)
int done; /* Whether we are done with the iteration */
herr_t ret_value=FAIL; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_serialize, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_serialize, FAIL);
assert(space);
@@ -1530,7 +1606,7 @@ H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf)
len+=(size_t)(8*space->extent.u.simple.rank*block_count);
/* Encode each hyperslab in selection */
- H5S_hyper_select_serialize_helper(space->select.sel_info.hslab.span_lst,start,end,(hsize_t)0,&buf);
+ H5S_hyper_serialize_helper(space->select.sel_info.hslab.span_lst,start,end,(hsize_t)0,&buf);
} /* end else */
/* Encode length */
@@ -1540,16 +1616,16 @@ H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf)
ret_value=SUCCEED;
FUNC_LEAVE (ret_value);
-} /* H5S_hyper_select_serialize() */
+} /* H5S_hyper_serialize() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_deserialize
+ H5S_hyper_deserialize
PURPOSE
Deserialize the current selection from a user-provided buffer.
USAGE
- herr_t H5S_hyper_select_deserialize(space, buf)
+ herr_t H5S_hyper_deserialize(space, buf)
H5S_t *space; IN/OUT: Dataspace pointer to place selection into
uint8 *buf; IN: Buffer to retrieve serialized selection from
RETURNS
@@ -1563,7 +1639,7 @@ H5S_hyper_select_serialize (const H5S_t *space, uint8_t *buf)
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_select_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 */
@@ -1578,7 +1654,7 @@ H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf)
unsigned i,j; /* local counting variables */
herr_t ret_value=FAIL; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_deserialize, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_deserialize, FAIL);
/* Check args */
assert(space);
@@ -1632,7 +1708,7 @@ H5S_hyper_select_deserialize (H5S_t *space, const uint8_t *buf)
done:
FUNC_LEAVE (ret_value);
-} /* H5S_hyper_select_deserialize() */
+} /* H5S_hyper_deserialize() */
/*--------------------------------------------------------------------------
@@ -1668,7 +1744,7 @@ done:
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
-herr_t
+static herr_t
H5S_hyper_span_blocklist(H5S_hyper_span_info_t *spans, hssize_t start[], hssize_t end[], hsize_t rank, hsize_t *startblock, hsize_t *numblocks, hsize_t **buf)
{
H5S_hyper_span_t *curr; /* Pointer to current hyperslab span */
@@ -1741,6 +1817,205 @@ done:
/*--------------------------------------------------------------------------
NAME
+ H5S_get_select_hyper_blocklist
+ PURPOSE
+ Get the list of hyperslab blocks currently selected
+ USAGE
+ herr_t H5S_get_select_hyper_blocklist(space, startblock, numblocks, buf)
+ H5S_t *space; IN: Dataspace pointer of selection to query
+ hsize_t startblock; IN: Hyperslab block to start with
+ hsize_t numblocks; IN: Number of hyperslab blocks to get
+ hsize_t *buf; OUT: List of hyperslab blocks selected
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Puts a list of the hyperslab blocks into the user's buffer. The blocks
+ start with the 'startblock'th block in the list of blocks and put
+ 'numblocks' number of blocks into the user's buffer (or until the end of
+ the list of blocks, whichever happens first)
+ The block coordinates have the same dimensionality (rank) as the
+ dataspace they are located within. The list of blocks is formatted as
+ follows: <"start" coordinate> immediately followed by <"opposite" corner
+ coordinate>, followed by the next "start" and "opposite" coordinate, etc.
+ until all the block information requested has been put into the user's
+ buffer.
+ No guarantee of any order of the blocks is implied.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5S_get_select_hyper_blocklist(H5S_t *space, hsize_t startblock, hsize_t numblocks, hsize_t *buf)
+{
+ H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */
+ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */
+ hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */
+ hssize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */
+ hssize_t end[H5O_LAYOUT_NDIMS]; /* Location of end of hyperslab */
+ hssize_t temp_off; /* Offset in a given dimension */
+ int i; /* Counter */
+ int fast_dim; /* Rank of the fastest changing dimension for the dataspace */
+ int temp_dim; /* Temporary rank holder */
+ int ndims; /* Rank of the dataspace */
+ int done; /* Whether we are done with the iteration */
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER_NOINIT(H5S_get_select_hyper_blocklist);
+
+ assert(space);
+ assert(buf);
+
+ /* Check for a "regular" hyperslab selection */
+ if(space->select.sel_info.hslab.diminfo != NULL) {
+ /* Set some convienence values */
+ ndims=space->extent.u.simple.rank;
+ fast_dim=ndims-1;
+ /*
+ * Use the "application dimension information" to pass back to the user
+ * the blocks they set, not the optimized, internal information.
+ */
+ diminfo=space->select.sel_info.hslab.app_diminfo;
+
+ /* Build the tables of count sizes as well as the initial offset */
+ for(i=0; i<ndims; i++) {
+ tmp_count[i]=diminfo[i].count;
+ offset[i]=diminfo[i].start;
+ } /* end for */
+
+ /* We're not done with the iteration */
+ done=0;
+
+ /* Go iterate over the hyperslabs */
+ while(done==0 && numblocks>0) {
+ /* Iterate over the blocks in the fastest dimension */
+ while(tmp_count[fast_dim]>0 && numblocks>0) {
+
+ /* Check if we should copy this block information */
+ if(startblock==0) {
+ /* Copy the starting location */
+ HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
+ buf+=ndims;
+
+ /* Compute the ending location */
+ HDmemcpy(buf,offset,sizeof(hsize_t)*ndims);
+ for(i=0; i<ndims; i++)
+ buf[i]+=(diminfo[i].block-1);
+ buf+=ndims;
+
+ /* Decrement the number of blocks to retrieve */
+ numblocks--;
+ } /* end if */
+ else
+ startblock--;
+
+ /* Move the offset to the next sequence to start */
+ offset[fast_dim]+=diminfo[fast_dim].stride;
+
+ /* Decrement the block count */
+ tmp_count[fast_dim]--;
+ } /* end while */
+
+ /* Work on other dimensions if necessary */
+ if(fast_dim>0 && numblocks>0) {
+ /* Reset the block counts */
+ tmp_count[fast_dim]=diminfo[fast_dim].count;
+
+ /* Bubble up the decrement to the slower changing dimensions */
+ temp_dim=fast_dim-1;
+ while(temp_dim>=0 && done==0) {
+ /* Decrement the block count */
+ tmp_count[temp_dim]--;
+
+ /* Check if we have more blocks left */
+ if(tmp_count[temp_dim]>0)
+ break;
+
+ /* Check for getting out of iterator */
+ if(temp_dim==0)
+ done=1;
+
+ /* Reset the block count in this dimension */
+ tmp_count[temp_dim]=diminfo[temp_dim].count;
+
+ /* Wrapped a dimension, go up to next dimension */
+ temp_dim--;
+ } /* end while */
+ } /* end if */
+
+ /* Re-compute offset array */
+ for(i=0; i<ndims; i++) {
+ temp_off=diminfo[i].start+diminfo[i].stride*(diminfo[i].count-tmp_count[i]);
+ offset[i]=temp_off;
+ } /* end for */
+ } /* end while */
+ } /* end if */
+ else
+ ret_value=H5S_hyper_span_blocklist(space->select.sel_info.hslab.span_lst,start,end,(hsize_t)0,&startblock,&numblocks,&buf);
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_get_select_hyper_blocklist() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5Sget_select_hyper_blocklist
+ PURPOSE
+ Get the list of hyperslab blocks currently selected
+ USAGE
+ herr_t H5Sget_select_hyper_blocklist(dsid, startblock, numblocks, buf)
+ hid_t dsid; IN: Dataspace ID of selection to query
+ hsize_t startblock; IN: Hyperslab block to start with
+ hsize_t numblocks; IN: Number of hyperslab blocks to get
+ hsize_t *buf; OUT: List of hyperslab blocks selected
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Puts a list of the hyperslab blocks into the user's buffer. The blocks
+ start with the 'startblock'th block in the list of blocks and put
+ 'numblocks' number of blocks into the user's buffer (or until the end of
+ the list of blocks, whichever happen first)
+ The block coordinates have the same dimensionality (rank) as the
+ dataspace they are located within. The list of blocks is formatted as
+ follows: <"start" coordinate> immediately followed by <"opposite" corner
+ coordinate>, followed by the next "start" and "opposite" coordinate, etc.
+ until all the block information requested has been put into the user's
+ buffer.
+ No guarantee of any order of the blocks is implied.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5Sget_select_hyper_blocklist(hid_t spaceid, hsize_t startblock, hsize_t numblocks, hsize_t *buf)
+{
+ H5S_t *space = NULL; /* Dataspace to modify selection of */
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER_API(H5Sget_select_hyper_blocklist, FAIL);
+ H5TRACE4("e","ihh*h",spaceid,startblock,numblocks,buf);
+
+ /* Check args */
+ if(buf==NULL)
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer");
+ if (H5I_DATASPACE != H5I_get_type(spaceid) || NULL == (space=H5I_object(spaceid)))
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space");
+ if(space->select.type!=H5S_SEL_HYPERSLABS)
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a hyperslab selection");
+
+ /* Go get the correct number of blocks */
+ if(numblocks>0)
+ ret_value = H5S_get_select_hyper_blocklist(space,startblock,numblocks,buf);
+ else
+ ret_value=SUCCEED; /* Successfully got 0 blocks... */
+
+ FUNC_LEAVE (ret_value);
+} /* H5Sget_select_hyper_blocklist() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5S_hyper_bounds_helper
PURPOSE
Gets the bounding box containing the selection.
@@ -1833,9 +2108,11 @@ H5S_hyper_bounds_helper (const H5S_hyper_span_info_t *spans, const hssize_t *off
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
+H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
{
- herr_t ret_value=SUCCEED; /* return value */
+ int rank; /* Dataspace rank */
+ int i; /* index variable */
+ herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5S_hyper_bounds, FAIL);
@@ -1843,14 +2120,16 @@ H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
assert(start);
assert(end);
+ /* Set the start and end arrays up */
+ rank=space->extent.u.simple.rank;
+ for(i=0; i<rank; i++) {
+ start[i]=UINT_MAX;
+ end[i]=0;
+ } /* end for */
+
/* Check for a "regular" hyperslab selection */
if(space->select.sel_info.hslab.diminfo!=NULL) {
const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab.diminfo; /* local alias for diminfo */
- int rank; /* Dataspace rank */
- int i; /* index variable */
-
- /* Get the dataspace extent rank */
- rank=space->extent.u.simple.rank;
/* Check each dimension */
for(i=0; i<rank; i++) {
@@ -1872,11 +2151,11 @@ H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_contiguous
+ H5S_hyper_is_contiguous
PURPOSE
Check if a hyperslab selection is contiguous within the dataspace extent.
USAGE
- htri_t H5S_select_contiguous(space)
+ htri_t H5S_hyper_is_contiguous(space)
H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
@@ -1889,7 +2168,7 @@ H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_hyper_select_contiguous(const H5S_t *space)
+H5S_hyper_is_contiguous(const H5S_t *space)
{
H5S_hyper_span_info_t *spans; /* Hyperslab span info node */
H5S_hyper_span_t *span; /* Hyperslab span node */
@@ -1898,7 +2177,7 @@ H5S_hyper_select_contiguous(const H5S_t *space)
large_contiguous; /* Flag for large contiguous block */
htri_t ret_value=FALSE; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_contiguous, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_is_contiguous, FAIL);
assert(space);
@@ -2049,16 +2328,16 @@ H5S_hyper_select_contiguous(const H5S_t *space)
} /* end else */
FUNC_LEAVE (ret_value);
-} /* H5S_hyper_select_contiguous() */
+} /* H5S_hyper_is_contiguous() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_single
+ H5S_hyper_is_single
PURPOSE
Check if a hyperslab selection is a single block within the dataspace extent.
USAGE
- htri_t H5S_select_single(space)
+ htri_t H5S_hyper_is_single(space)
H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
@@ -2071,14 +2350,14 @@ H5S_hyper_select_contiguous(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_hyper_select_single(const H5S_t *space)
+H5S_hyper_is_single(const H5S_t *space)
{
H5S_hyper_span_info_t *spans; /* Hyperslab span info node */
H5S_hyper_span_t *span; /* Hyperslab span node */
unsigned u; /* index variable */
htri_t ret_value=FALSE; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_single, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_is_single, FAIL);
assert(space);
@@ -2127,16 +2406,16 @@ H5S_hyper_select_single(const H5S_t *space)
} /* end else */
FUNC_LEAVE (ret_value);
-} /* H5S_hyper_select_single() */
+} /* H5S_hyper_is_single() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_regular
+ H5S_hyper_is_regular
PURPOSE
Check if a hyperslab selection is "regular"
USAGE
- htri_t H5S_hyper_select_regular(space)
+ htri_t H5S_hyper_is_regular(space)
const H5S_t *space; IN: Dataspace pointer to check
RETURNS
TRUE/FALSE/FAIL
@@ -2151,11 +2430,11 @@ H5S_hyper_select_single(const H5S_t *space)
REVISION LOG
--------------------------------------------------------------------------*/
htri_t
-H5S_hyper_select_regular(const H5S_t *space)
+H5S_hyper_is_regular(const H5S_t *space)
{
htri_t ret_value=FAIL; /* return value */
- FUNC_ENTER_NOAPI(H5S_hyper_select_regular, FAIL);
+ FUNC_ENTER_NOAPI(H5S_hyper_is_regular, FAIL);
/* Check args */
assert(space);
@@ -2167,7 +2446,7 @@ H5S_hyper_select_regular(const H5S_t *space)
ret_value=FALSE;
FUNC_LEAVE (ret_value);
-} /* H5S_hyper_select_regular() */
+} /* H5S_hyper_is_regular() */
/*--------------------------------------------------------------------------
@@ -3778,7 +4057,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
} /* end for */
/* If we are setting a new selection, remove current selection first */
- if(H5S_select_release(space)<0)
+ if((*space->select.release)(space)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab");
/* Copy all the application per-dimension selection info into the space descriptor */
@@ -3845,6 +4124,21 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
/* Set selection type */
space->select.type=H5S_SEL_HYPERSLABS;
+ /* Set selection methods */
+ space->select.get_seq_list=H5S_hyper_get_seq_list;
+ space->select.get_npoints=H5S_hyper_npoints;
+ space->select.release=H5S_hyper_release;
+ space->select.iter_init=H5S_hyper_iter_init;
+ space->select.iter_nelmts=H5S_hyper_iter_nelmts;
+ space->select.iter_release=H5S_hyper_iter_release;
+ space->select.is_valid=H5S_hyper_is_valid;
+ space->select.serial_size=H5S_hyper_serial_size;
+ space->select.serialize=H5S_hyper_serialize;
+ space->select.bounds=H5S_hyper_bounds;
+ space->select.is_contiguous=H5S_hyper_is_contiguous;
+ space->select.is_single=H5S_hyper_is_single;
+ space->select.is_regular=H5S_hyper_is_regular;
+
ret_value=SUCCEED;
done:
@@ -3941,7 +4235,7 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper
assert(op>H5S_SELECT_NOOP && op<H5S_SELECT_INVALID);
/* Free the current selection for the result space */
- if(H5S_select_release(result)<0)
+ if((*result->select.release)(result)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release result selection");
/* Just copy the selection from spans2 if we are setting the selection */
@@ -4065,6 +4359,20 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper
/* Set selection type */
result->select.type=H5S_SEL_HYPERSLABS;
+ /* Set selection methods */
+ space->select.get_seq_list=H5S_hyper_get_seq_list;
+ space->select.get_npoints=H5S_hyper_npoints;
+ space->select.release=H5S_hyper_release;
+ space->select.iter_init=H5S_hyper_iter_init;
+ space->select.iter_nelmts=H5S_hyper_iter_nelmts;
+ space->select.iter_release=H5S_hyper_iter_release;
+ space->select.is_valid=H5S_hyper_is_valid;
+ space->select.serial_size=H5S_hyper_serial_size;
+ space->select.serialize=H5S_hyper_serialize;
+ space->select.bounds=H5S_hyper_bounds;
+ space->select.is_contiguous=H5S_hyper_is_contiguous;
+ space->select.is_single=H5S_hyper_is_single;
+
/* Set the return value */
ret_value=SUCCEED;
@@ -4307,7 +4615,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op,
} /* end for */
/* If we are setting a new selection, remove current selection first */
- if(H5S_select_release(space)<0)
+ if((*space->select.release)(space)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab");
/* Copy all the application per-dimension selection info into the space descriptor */
@@ -4734,11 +5042,11 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_get_seq_list_gen
+ H5S_hyper_get_seq_list_gen
PURPOSE
Create a list of offsets & lengths for a selection
USAGE
- herr_t H5S_hyper_select_get_file_list_gen(space,iter,maxseq,nseq,off,len)
+ herr_t H5S_select_hyper_get_file_list_gen(space,iter,maxseq,nseq,off,len)
H5S_t *space; IN: Dataspace containing selection to use.
H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last
position of interest in selection.
@@ -4764,7 +5072,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_select_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 elem_size, size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes,
hsize_t *off, size_t *len)
{
@@ -4786,7 +5094,7 @@ H5S_hyper_select_get_seq_list_gen(const H5S_t *space,H5S_sel_iter_t *iter,
int i; /* Index variable */
herr_t ret_value=SUCCEED; /* return value */
- FUNC_ENTER_NOINIT (H5S_hyper_select_get_seq_list_gen);
+ FUNC_ENTER_NOINIT (H5S_hyper_get_seq_list_gen);
/* Check args */
assert(space);
@@ -5144,16 +5452,16 @@ partial_done: /* Yes, goto's are evil, so sue me... :-) */
done:
#endif /* LATER */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_get_seq_list_gen() */
+} /* end H5S_hyper_get_seq_list_gen() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_get_seq_list_opt
+ H5S_hyper_get_seq_list_opt
PURPOSE
Create a list of offsets & lengths for a selection
USAGE
- herr_t H5S_hyper_select_get_file_list_opt(space,iter,maxseq,nseq,off,len)
+ herr_t H5S_select_hyper_get_file_list_opt(space,iter,maxseq,nseq,off,len)
H5S_t *space; IN: Dataspace containing selection to use.
H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last
position of interest in selection.
@@ -5179,7 +5487,7 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5S_hyper_select_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
+H5S_hyper_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
size_t elmt_size, size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes,
hsize_t *off, size_t *len)
{
@@ -5219,7 +5527,7 @@ H5S_hyper_select_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
#endif /* NO_DUFFS_DEVICE */
herr_t ret_value=SUCCEED; /* return value */
- FUNC_ENTER_NOINIT (H5S_hyper_select_get_seq_list_opt);
+ FUNC_ENTER_NOINIT (H5S_hyper_get_seq_list_opt);
/* Check args */
assert(space);
@@ -5707,18 +6015,18 @@ H5S_hyper_select_get_seq_list_opt(const H5S_t *space,H5S_sel_iter_t *iter,
done:
#endif /* LATER */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_get_seq_list_opt() */
+} /* end H5S_hyper_get_seq_list_opt() */
/*--------------------------------------------------------------------------
NAME
- H5S_hyper_select_get_seq_list
+ H5S_hyper_get_seq_list
PURPOSE
Create a list of offsets & lengths for a selection
USAGE
- herr_t H5S_hyper_select_get_seq_list(flags,space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len)
- unsigned flags; IN: Flags for extra information about operation
+ herr_t H5S_hyper_get_seq_list(space,flags,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len)
H5S_t *space; IN: Dataspace containing selection to use.
+ unsigned flags; IN: Flags for extra information about operation
H5S_sel_iter_t *iter; IN/OUT: Selection iterator describing last
position of interest in selection.
size_t elem_size; IN: Size of an element
@@ -5743,13 +6051,13 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_hyper_select_get_seq_list(unsigned UNUSED flags, const H5S_t *space,H5S_sel_iter_t *iter,
+H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t *iter,
size_t elem_size, size_t maxseq, size_t maxbytes, size_t *nseq, size_t *nbytes,
hsize_t *off, size_t *len)
{
herr_t ret_value=FAIL; /* return value */
- FUNC_ENTER_NOAPI (H5S_hyper_select_get_seq_list, FAIL);
+ FUNC_ENTER_NOAPI (H5S_hyper_get_seq_list, FAIL);
/* Check args */
assert(space);
@@ -5765,14 +6073,14 @@ H5S_hyper_select_get_seq_list(unsigned UNUSED flags, const H5S_t *space,H5S_sel_
/* Check for the special case of just one H5Sselect_hyperslab call made */
if(space->select.sel_info.hslab.diminfo!=NULL)
/* Use optimized call to generate sequence list */
- ret_value=H5S_hyper_select_get_seq_list_opt(space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len);
+ ret_value=H5S_hyper_get_seq_list_opt(space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len);
else
/* Call the general sequence generator routine */
- ret_value=H5S_hyper_select_get_seq_list_gen(space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len);
+ ret_value=H5S_hyper_get_seq_list_gen(space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len);
#ifdef LATER
done:
#endif /* LATER */
FUNC_LEAVE (ret_value);
-} /* end H5S_hyper_select_get_seq_list() */
+} /* end H5S_hyper_get_seq_list() */