summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1999-06-24 02:16:13 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1999-06-24 02:16:13 (GMT)
commitc4c6318e6ab92d8204226923e8e9302e2779aaf4 (patch)
treeeb925287f4f0ac500619d9259ffbbe8fb9342acc
parentace37763c377153217564e4dd08c2fcc385e83c4 (diff)
downloadhdf5-c4c6318e6ab92d8204226923e8e9302e2779aaf4.zip
hdf5-c4c6318e6ab92d8204226923e8e9302e2779aaf4.tar.gz
hdf5-c4c6318e6ab92d8204226923e8e9302e2779aaf4.tar.bz2
[svn-r1374] Added in code to support the H5Diterate function, which I've got to add tests
for now. Also, I revised some of the code for hyperslab I/O, which should provide a modest speedup in situations with lots of hyperslabs.
-rw-r--r--src/H5D.c89
-rw-r--r--src/H5Dpublic.h6
-rw-r--r--src/H5S.c1
-rw-r--r--src/H5Sall.c89
-rw-r--r--src/H5Shyper.c775
-rw-r--r--src/H5Snone.c42
-rw-r--r--src/H5Spoint.c77
-rw-r--r--src/H5Sprivate.h10
-rw-r--r--src/H5Sselect.c69
-rw-r--r--src/H5V.c46
-rw-r--r--src/H5Vprivate.h2
11 files changed, 917 insertions, 289 deletions
diff --git a/src/H5D.c b/src/H5D.c
index 2b432d3..4a55b64 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -2579,6 +2579,93 @@ H5D_get_storage_size(H5D_t *dset)
/*-------------------------------------------------------------------------
+ * Function: H5Diterate
+ *
+ * Purpose: This routine iterates over all the elements selected in a memory
+ * buffer. The callback function is called once for each element selected
+ * in the dataspace. The selection in the dataspace is modified so
+ * that any elements already iterated over are removed from the selection
+ * if the iteration is interrupted (by the H5D_operator_t function
+ * returning non-zero) in the "middle" of the iteration and may be
+ * re-started by the user where it left off.
+ *
+ * NOTE: Until "subtracting" elements from a selection is implemented,
+ * the selection is not modified.
+ *
+ * Parameters:
+ * void *buf; IN/OUT: Pointer to the buffer in memory containing
+ * the elements to iterate over.
+ * hid_t type_id; IN: Datatype ID for the elements stored in BUF.
+ * hid_t space_id; IN: Dataspace ID for BUF, also contains the
+ * selection to iterate over.
+ * H5D_operator_t operator; IN: Function pointer to the routine to be
+ * called for each element in BUF iterated over.
+ * void *operator_data; IN/OUT: Pointer to any user-defined data
+ * associated with the operation.
+ *
+ * Operation information:
+ * H5D_operator_t is defined as:
+ * typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id,
+ * hsize_t ndim, hssize_t *point, void *operator_data);
+ *
+ * H5D_operator_t parameters:
+ * void *elem; IN/OUT: Pointer to the element in memory containing
+ * the current point.
+ * hid_t type_id; IN: Datatype ID for the elements stored in ELEM.
+ * hsize_t ndim; IN: Number of dimensions for POINT array
+ * hssize_t *point; IN: Array containing the location of the element
+ * within the original dataspace.
+ * void *operator_data; IN/OUT: Pointer to any user-defined data
+ * associated with the operation.
+ *
+ * The return values from an operator are:
+ * Zero causes the iterator to continue, returning zero when all
+ * elements have been processed.
+ * Positive causes the iterator to immediately return that positive
+ * value, indicating short-circuit success. The iterator can be
+ * restarted at the next element.
+ * Negative causes the iterator to immediately return that value,
+ * indicating failure. The iterator can be restarted at the next
+ * element.
+ *
+ * Return: Returns the return value of the last operator if it was non-zero,
+ * or zero if all elements were processed. Otherwise returns a
+ * negative value.
+ *
+ * Programmer: Quincey Koziol
+ * Friday, June 11, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t operator,
+ void *operator_data)
+{
+ H5S_t *space = NULL;
+ herr_t ret_value=FAIL;
+
+ FUNC_ENTER(H5Diterate, FAIL);
+
+ /* Check args */
+ if (NULL==operator)
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator");
+ if (buf==NULL)
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer");
+ if (H5I_DATATYPE != H5I_get_type(type_id))
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype");
+ if (H5I_DATASPACE != H5I_get_type(space_id) ||
+ NULL == (space = H5I_object(space_id)))
+ HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace");
+
+ ret_value=H5S_select_iterate(buf,type_id,space,operator,operator_data);
+
+ FUNC_LEAVE(ret_value);
+} /* end H5Diterate() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Dvlen_reclaim
*
* Purpose: Frees the buffers allocated for storing variable-length data
@@ -2614,7 +2701,7 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
/* Call H5Diterate with args, etc. */
FUNC_LEAVE(ret_value);
-}
+} /* end H5Dvlen_reclaim() */
/*-------------------------------------------------------------------------
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 74c6549..ba0205c 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -39,6 +39,10 @@ typedef enum H5D_transfer_t {
} H5D_transfer_t;
+/* Define the operator function pointer for H5Diterate() */
+typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, hsize_t ndim,
+ hssize_t *point, void *operator_data);
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -56,6 +60,8 @@ __DLL__ herr_t H5Dread (hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
__DLL__ herr_t H5Dwrite (hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
hid_t file_space_id, hid_t plist_id, const void *buf);
__DLL__ herr_t H5Dextend (hid_t dset_id, const hsize_t *size);
+__DLL__ herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
+ H5D_operator_t operator, void *operator_data);
__DLL__ herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
__DLL__ herr_t H5Ddebug(hid_t dset_id, unsigned int flags);
diff --git a/src/H5S.c b/src/H5S.c
index 5446224..b311117 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -1818,6 +1818,7 @@ H5Soffset_simple(hid_t space_id, const hssize_t *offset)
FUNC_LEAVE(SUCCEED);
} /* end H5Soffset_simple() */
+
/*-------------------------------------------------------------------------
* Function: H5S_debug
diff --git a/src/H5Sall.c b/src/H5Sall.c
index 9ac1e5e..18d8f52 100644
--- a/src/H5Sall.c
+++ b/src/H5Sall.c
@@ -914,3 +914,92 @@ H5S_all_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
FUNC_LEAVE (ret_value);
} /* H5Sget_all_bounds() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_all_select_iterate
+ PURPOSE
+ Iterate over a "all" selection, calling a user's function for each
+ element.
+ USAGE
+ herr_t H5S_all_select_iterate(buf, type_id, space, operator, operator_data)
+ void *buf; IN/OUT: Buffer containing elements to iterate over
+ hid_t type_id; IN: Datatype ID of BUF array.
+ H5S_t *space; IN: Dataspace object containing selection to iterate over
+ H5D_operator_t operator; IN: Function pointer to the routine to be
+ called for each element in BUF iterated over.
+ void *operator_data; IN/OUT: Pointer to any user-defined data
+ associated with the operation.
+ RETURNS
+ Returns the return value of the last operator if it was non-zero, or zero
+ if all elements were processed. Otherwise returns a negative value.
+ DESCRIPTION
+ Iterates over the selected elements in a memory buffer, calling the user's
+ callback function for each element. The selection in the dataspace is
+ modified so that any elements already iterated over are removed from the
+ selection if the iteration is interrupted (by the H5D_operator_t function
+ returning non-zero) in the "middle" of the iteration and may be re-started
+ by the user where it left off.
+
+ NOTE: Until "subtracting" elements from a selection is implemented,
+ the selection is not modified.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator,
+ void *operator_data)
+{
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
+ hsize_t mem_offset[H5O_LAYOUT_NDIMS]; /* current coordinates */
+ hsize_t offset; /* offset of region in buffer */
+ hsize_t nelemts; /* Number of elements to iterate through */
+ void *tmp_buf; /* temporary location of the element in the buffer */
+ intn rank; /* Dataspace rank */
+ intn index; /* Index to increment */
+ herr_t ret_value=0; /* return value */
+
+ FUNC_ENTER (H5S_all_select_iterate, 0);
+
+ assert(buf);
+ assert(space);
+ assert(operator);
+ assert(H5I_DATATYPE != H5I_get_type(type_id));
+
+ /* Get the dataspace extent rank */
+ rank=space->extent.u.simple.rank;
+
+ /* Set up the size of the memory space */
+ HDmemcpy(mem_size, space->extent.u.simple.size, rank*sizeof(hsize_t));
+ mem_size[rank]=H5Tget_size(type_id);
+
+ /* Set the coordinates to zero */
+ HDmemset(mem_offset, 0, (rank+1)*sizeof(hsize_t));
+
+ /* Get the number of elements to iterate through */
+ nelemts=H5S_get_simple_extent_npoints(space);
+
+ /* Iterate through the entire dataset */
+ while(nelemts>0 && ret_value==0) {
+ /* Get the offset in the memory buffer */
+ offset=H5V_array_offset(rank+1,mem_size,mem_offset);
+ tmp_buf=((char *)buf+offset);
+
+ ret_value=(*operator)(tmp_buf,type_id,rank,mem_offset,operator_data);
+
+ /* Advance the coordinate (currently in C memory order) */
+ index=rank-1; /* Leave the byte offset in the element alone */
+ while(++mem_offset[index]==mem_size[index] && index>=0) {
+ mem_offset[index]=0;
+ index--;
+ } /* end while */
+
+ /* Decrement the number of elements to iterate through */
+ nelemts--;
+ } /* end while */
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_all_select_iterate() */
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 09c3b77..ecef87c 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -9,6 +9,7 @@
*/
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5Iprivate.h>
#include <H5Sprivate.h>
#include <H5Vprivate.h>
#include <H5MMprivate.h>
@@ -21,7 +22,7 @@
static intn interface_initialize_g = 0;
/* Local datatypes */
-/* Parameter block for H5S_hyper_fread & H5S_hyper_fwrite */
+/* Parameter block for H5S_hyper_fread, H5S_hyper_fwrite, H5S_hyper_mread & H5S_hyper_mwrite */
typedef struct {
H5F_t *f;
const struct H5O_layout_t *layout;
@@ -35,9 +36,27 @@ typedef struct {
const H5F_xfer_t *xfer_parms;
const void *src;
void *dst;
+ hsize_t mem_size[H5O_LAYOUT_NDIMS];
+ hssize_t offset[H5O_LAYOUT_NDIMS];
+ hsize_t hsize[H5O_LAYOUT_NDIMS];
H5S_hyper_bound_t **lo_bounds;
H5S_hyper_bound_t **hi_bounds;
-} H5S_hyper_fhyper_info_t;
+} H5S_hyper_io_info_t;
+
+/* Parameter block for H5S_hyper_select_iter_mem */
+typedef struct {
+ hid_t dt;
+ size_t elem_size;
+ const H5S_t *space;
+ H5S_sel_iter_t *iter;
+ void *src;
+ H5S_hyper_bound_t **lo_bounds;
+ H5S_hyper_bound_t **hi_bounds;
+ hsize_t mem_size[H5O_LAYOUT_NDIMS];
+ hssize_t mem_offset[H5O_LAYOUT_NDIMS];
+ H5D_operator_t op;
+ void * op_data;
+} H5S_hyper_iter_info_t;
/* Static function prototypes */
static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr,
@@ -47,9 +66,9 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
H5S_hyper_bound_t **lo_bounds,
H5S_hyper_bound_t **hi_bounds, hssize_t *pos,
hssize_t *offset);
-static size_t H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info);
+static size_t H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info);
static size_t H5S_hyper_fwrite (intn dim,
- H5S_hyper_fhyper_info_t *fhyper_info);
+ H5S_hyper_io_info_t *io_info);
static herr_t H5S_hyper_init (const struct H5O_layout_t *layout,
const H5S_t *space, H5S_sel_iter_t *iter, size_t *min_elem_out);
static size_t H5S_hyper_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
@@ -120,7 +139,6 @@ H5S_hyper_init (const struct H5O_layout_t UNUSED *layout,
FUNC_ENTER (H5S_hyper_init, FAIL);
/* Check args */
- assert (layout);
assert (space && H5S_SEL_HYPERSLABS==space->select.type);
assert (sel_iter);
@@ -275,7 +293,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
hi_bounds[0][i].bound!=reg[curr_reg].end) {
/* Enlarge array */
- H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),&reg);
+ H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)&reg);
/* Initialize with new region */
reg[num_reg].start=lo_bounds[0][i].bound+offset[0];
@@ -368,7 +386,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
(int)reg[curr_reg].end);
#endif /* QAK */
/* Enlarge array */
- H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),&reg);
+ H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)),(void **)&reg);
/* Initialize with new region */
reg[num_reg].start=node->start[next_dim]+offset[next_dim];
@@ -429,7 +447,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
*/
static herr_t
H5S_hyper_block_cache (H5S_hyper_node_t *node,
- H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read)
+ H5S_hyper_io_info_t *io_info, uintn block_read)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
@@ -438,27 +456,27 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node,
FUNC_ENTER (H5S_hyper_block_cache, SUCCEED);
assert(node);
- assert(fhyper_info);
+ assert(io_info);
/* Allocate temporary buffer of proper size */
- if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*fhyper_info->elmt_size,1,(void **)&(node->cinfo.block)))<0)
+ if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*io_info->elmt_size,1,(void **)&(node->cinfo.block)))<0)
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate hyperslab cache block");
/* Read in block, if we are read caching */
if(block_read) {
/* Copy the location of the region in the file */
- HDmemcpy(file_offset,node->start,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t)));
- file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+ HDmemcpy(file_offset,node->start,(io_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ file_offset[io_info->space->extent.u.simple.rank]=0;
/* Set the hyperslab size to read */
- for(i=0; i<fhyper_info->space->extent.u.simple.rank; i++)
+ for(i=0; i<io_info->space->extent.u.simple.rank; i++)
hsize[i]=(node->end[i]-node->start[i])+1;
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ hsize[io_info->space->extent.u.simple.rank]=io_info->elmt_size;
- if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms,
- fhyper_info->layout, fhyper_info->pline,
- fhyper_info->fill, fhyper_info->efl, hsize, hsize,
+ if (H5F_arr_read (io_info->f, io_info->xfer_parms,
+ io_info->layout, io_info->pline,
+ io_info->fill, io_info->efl, hsize, hsize,
zero, file_offset, node->cinfo.block/*out*/)<0)
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
} /* end if */
@@ -491,27 +509,25 @@ H5S_hyper_block_cache (H5S_hyper_node_t *node,
*-------------------------------------------------------------------------
*/
static herr_t
-H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, hsize_t region_size)
+H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_io_info_t *io_info, hsize_t region_size)
{
FUNC_ENTER (H5S_hyper_block_read, SUCCEED);
assert(node && node->cinfo.cached);
- assert(fhyper_info);
+ assert(io_info);
/* Copy the elements into the user's buffer */
/*
!! NOTE !! This will need to be changed for different dimension
permutations from the standard 'C' ordering!
*/
- HDmemcpy(fhyper_info->dst,
- node->cinfo.rpos,
- (size_t)(region_size*fhyper_info->elmt_size));
+ HDmemcpy(io_info->dst, node->cinfo.rpos, (size_t)(region_size*io_info->elmt_size));
/*
* Decrement the number of elements left in block to read & move the
* offset
*/
- node->cinfo.rpos+=region_size*fhyper_info->elmt_size;
+ node->cinfo.rpos+=region_size*io_info->elmt_size;
node->cinfo.rleft-=region_size;
/* If we've read in all the elements from the block, throw it away */
@@ -542,7 +558,7 @@ H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_in
*/
static herr_t
H5S_hyper_block_write (H5S_hyper_node_t *node,
- H5S_hyper_fhyper_info_t *fhyper_info,
+ H5S_hyper_io_info_t *io_info,
hsize_t region_size)
{
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
@@ -552,41 +568,36 @@ H5S_hyper_block_write (H5S_hyper_node_t *node,
FUNC_ENTER (H5S_hyper_block_write, SUCCEED);
assert(node && node->cinfo.cached);
- assert(fhyper_info);
+ assert(io_info);
/* Copy the elements into the user's buffer */
/*
!! NOTE !! This will need to be changed for different dimension
permutations from the standard 'C' ordering!
*/
- HDmemcpy(node->cinfo.wpos,
- fhyper_info->src,
- (size_t)(region_size*fhyper_info->elmt_size));
+ HDmemcpy(node->cinfo.wpos, io_info->src, (size_t)(region_size*io_info->elmt_size));
/*
* Decrement the number of elements left in block to read & move the
* offset
*/
- node->cinfo.wpos+=region_size*fhyper_info->elmt_size;
+ node->cinfo.wpos+=region_size*io_info->elmt_size;
node->cinfo.wleft-=region_size;
/* If we've read in all the elements from the block, throw it away */
if(node->cinfo.wleft==0 && (node->cinfo.rleft==0 || node->cinfo.rleft==node->cinfo.size)) {
/* Copy the location of the region in the file */
- HDmemcpy(file_offset,
- node->start,
- (fhyper_info->space->extent.u.simple.rank *
- sizeof(hssize_t)));
- file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+ HDmemcpy(file_offset, node->start, (io_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ file_offset[io_info->space->extent.u.simple.rank]=0;
/* Set the hyperslab size to write */
- for(i=0; i<fhyper_info->space->extent.u.simple.rank; i++)
+ for(i=0; i<io_info->space->extent.u.simple.rank; i++)
hsize[i]=(node->end[i]-node->start[i])+1;
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ hsize[io_info->space->extent.u.simple.rank]=io_info->elmt_size;
- if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms,
- fhyper_info->layout, fhyper_info->pline,
- fhyper_info->fill, fhyper_info->efl, hsize, hsize,
+ if (H5F_arr_write (io_info->f, io_info->xfer_parms,
+ io_info->layout, io_info->pline,
+ io_info->fill, io_info->efl, hsize, hsize,
zero, file_offset, node->cinfo.block/*out*/)<0)
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
@@ -618,10 +629,8 @@ H5S_hyper_block_write (H5S_hyper_node_t *node,
*-------------------------------------------------------------------------
*/
static size_t
-H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+H5S_hyper_fread (intn dim, H5S_hyper_io_info_t *io_info)
{
- hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
uintn parm_init=0; /* Whether one-shot parameters set up */
hid_t reg_id; /* ID of temporary region buffer */
@@ -633,7 +642,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
FUNC_ENTER (H5S_hyper_fread, 0);
- assert(fhyper_info);
+ assert(io_info);
#ifdef QAK
printf("%s: check 1.0, dim=%d\n",FUNC,dim);
@@ -642,9 +651,9 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
- fhyper_info->space->select.sel_info.hslab.hyper_lst->count,
- fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) {
+ io_info->space->select.sel_info.hslab.hyper_lst->count,
+ io_info->lo_bounds, io_info->hi_bounds,
+ io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
/* Get the pointer to the actual regions array */
regions=H5TB_buf_ptr(reg_id);
@@ -656,45 +665,40 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
*/
#ifdef QAK
printf("%s: check 2.0, rank=%d, cache_hyper=%d\n",
- FUNC,(int)fhyper_info->space->extent.u.simple.rank,
- (int)fhyper_info->xfer_parms->cache_hyper);
+ FUNC,(int)io_info->space->extent.u.simple.rank,
+ (int)io_info->xfer_parms->cache_hyper);
for(i=0; i<num_regions; i++)
printf("%s: check 2.1, region #%d: start=%d, end=%d\n",
FUNC,i,(int)regions[i].start,(int)regions[i].end);
#endif /* QAK */
- if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+ if((dim+2)==io_info->space->extent.u.simple.rank) {
/* perform I/O on data from regions */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
/* Compute the size of the region to read */
- region_size=MIN(fhyper_info->nelmts,
+ region_size=MIN(io_info->nelmts,
(regions[i].end-regions[i].start)+1);
/* Check if this hyperslab block is cached or could be cached */
if(!regions[i].node->cinfo.cached &&
- (fhyper_info->xfer_parms->cache_hyper &&
- (fhyper_info->xfer_parms->block_limit==0 ||
- fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) {
+ (io_info->xfer_parms->cache_hyper &&
+ (io_info->xfer_parms->block_limit==0 ||
+ io_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) {
/* if we aren't cached, attempt to cache the block */
- H5S_hyper_block_cache(regions[i].node,fhyper_info,1);
+ H5S_hyper_block_cache(regions[i].node,io_info,1);
} /* end if */
/* Read information from the cached block */
if(regions[i].node->cinfo.cached) {
- if(H5S_hyper_block_read(regions[i].node,fhyper_info,region_size)<0)
+ if(H5S_hyper_block_read(regions[i].node,io_info,region_size)<0)
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
}
else {
/* Set up hyperslab I/O parameters which apply to all regions */
if(!parm_init) {
/* Copy the location of the region in the file */
- HDmemcpy(file_offset,fhyper_info->iter->hyp.pos,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t)));
- file_offset[fhyper_info->space->extent.u.simple.rank]=0;
-
- /* Set the hyperslab size to copy */
- hsize[0]=1;
- H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank);
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
-
+ HDmemcpy(io_info->offset,io_info->iter->hyp.pos,(io_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ io_info->offset[io_info->space->extent.u.simple.rank]=0;
+
/* Set flag */
parm_init=1;
} /* end if */
@@ -703,45 +707,45 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
printf("%s: check 2.2, i=%d, region_size=%d\n",FUNC,(int)i,(int)region_size);
#endif /* QAK */
/* Fill in the region specific parts of the I/O request */
- hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
- file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+ io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size;
+ io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start;
/*
* Gather from file.
*/
- if (H5F_arr_read (fhyper_info->f, fhyper_info->xfer_parms,
- fhyper_info->layout, fhyper_info->pline,
- fhyper_info->fill, fhyper_info->efl,
- hsize, hsize, zero, file_offset,
- fhyper_info->dst/*out*/)<0) {
+ if (H5F_arr_read (io_info->f, io_info->xfer_parms,
+ io_info->layout, io_info->pline,
+ io_info->fill, io_info->efl,
+ io_info->hsize, io_info->hsize, zero, io_info->offset,
+ io_info->dst/*out*/)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0,
"read error");
}
#ifdef QAK
printf("%s: check 2.3, region #%d\n",FUNC,(int)i);
- for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++)
- printf("%s: %d - pos=%d\n", FUNC,j,(int)fhyper_info->iter->hyp.pos[j]);
+ for(j=0; j<io_info->space->extent.u.simple.rank; j++)
+ printf("%s: %d - pos=%d\n", FUNC,j,(int)io_info->iter->hyp.pos[j]);
#endif /* QAK */
} /* end else */
/* Advance the pointer in the buffer */
- fhyper_info->dst = ((uint8_t *)fhyper_info->dst) +
- region_size*fhyper_info->elmt_size;
+ io_info->dst = ((uint8_t *)io_info->dst) +
+ region_size*io_info->elmt_size;
/* Increment the number of elements read */
num_read+=region_size;
/* Decrement the buffer left */
- fhyper_info->nelmts-=region_size;
+ io_info->nelmts-=region_size;
/* Set the next position to start at */
if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1))
- fhyper_info->iter->hyp.pos[dim+1]=(-1);
+ io_info->iter->hyp.pos[dim+1]=(-1);
else
- fhyper_info->iter->hyp.pos[dim+1] = regions[i].start + region_size;
+ io_info->iter->hyp.pos[dim+1] = regions[i].start + region_size;
/* Decrement the iterator count */
- fhyper_info->iter->hyp.elmt_left-=region_size;
+ io_info->iter->hyp.elmt_left-=region_size;
} /* end for */
} else { /* recurse on each region to next dimension down */
#ifdef QAK
@@ -754,25 +758,25 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
dim++;
/* Step through each region in this dimension */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
/* Step through each location in each region */
- for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) {
+ for(j=regions[i].start; j<=regions[i].end && io_info->nelmts>0; j++) {
#ifdef QAK
printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j);
#endif /* QAK */
/* Set the correct position we are working on */
- fhyper_info->iter->hyp.pos[dim]=j;
+ io_info->iter->hyp.pos[dim]=j;
/* Go get the regions in the next lower dimension */
- num_read+=H5S_hyper_fread(dim, fhyper_info);
+ num_read+=H5S_hyper_fread(dim, io_info);
/* Advance to the next row if we got the whole region */
- if(fhyper_info->iter->hyp.pos[dim+1]==(-1))
- fhyper_info->iter->hyp.pos[dim]=j+1;
+ if(io_info->iter->hyp.pos[dim+1]==(-1))
+ io_info->iter->hyp.pos[dim]=j+1;
} /* end for */
- if(j>regions[i].end && fhyper_info->iter->hyp.pos[dim+1]==(-1))
- fhyper_info->iter->hyp.pos[dim]=(-1);
+ if(j>regions[i].end && io_info->iter->hyp.pos[dim+1]==(-1))
+ io_info->iter->hyp.pos[dim]=(-1);
} /* end for */
} /* end else */
@@ -817,7 +821,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
{
H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
- H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */
intn i; /*counters */
size_t num_read; /* number of elements read into buffer */
@@ -851,27 +855,33 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
} /* end for */
/* Initialize parameter block for recursive calls */
- fhyper_info.f=f;
- fhyper_info.layout=layout;
- fhyper_info.pline=pline;
- fhyper_info.fill=fill;
- fhyper_info.efl=efl;
- fhyper_info.elmt_size=elmt_size;
- fhyper_info.space=file_space;
- fhyper_info.iter=file_iter;
- fhyper_info.nelmts=nelmts;
- fhyper_info.xfer_parms=xfer_parms;
- fhyper_info.src=NULL;
- fhyper_info.dst=_buf;
- fhyper_info.lo_bounds=lo_bounds;
- fhyper_info.hi_bounds=hi_bounds;
+ io_info.f=f;
+ io_info.layout=layout;
+ io_info.pline=pline;
+ io_info.fill=fill;
+ io_info.efl=efl;
+ io_info.elmt_size=elmt_size;
+ io_info.space=file_space;
+ io_info.iter=file_iter;
+ io_info.nelmts=nelmts;
+ io_info.xfer_parms=xfer_parms;
+ io_info.src=NULL;
+ io_info.dst=_buf;
+
+ /* Set the hyperslab size to copy */
+ io_info.hsize[0]=1;
+ H5V_array_fill(io_info.hsize,io_info.hsize,sizeof(io_info.hsize[0]),file_space->extent.u.simple.rank);
+ io_info.hsize[file_space->extent.u.simple.rank]=elmt_size;
+
+ io_info.lo_bounds=lo_bounds;
+ io_info.hi_bounds=hi_bounds;
/* Recursively input the hyperslabs currently defined */
/* starting with the slowest changing dimension */
#ifdef QAK
printf("%s: check 4.0\n",FUNC);
#endif /* QAK */
- num_read=H5S_hyper_fread(-1,&fhyper_info);
+ num_read=H5S_hyper_fread(-1,&io_info);
#ifdef QAK
printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read);
#endif /* QAK */
@@ -901,10 +911,8 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
*-------------------------------------------------------------------------
*/
static size_t
-H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+H5S_hyper_fwrite (intn dim, H5S_hyper_io_info_t *io_info)
{
- hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
uintn parm_init=0; /* Whether one-shot parameters set up */
hid_t reg_id; /* ID of temporary region buffer */
@@ -916,7 +924,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
FUNC_ENTER (H5S_hyper_fwrite, 0);
- assert(fhyper_info);
+ assert(io_info);
#ifdef QAK
printf("%s: check 1.0\n", FUNC);
@@ -924,16 +932,16 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
- fhyper_info->space->select.sel_info.hslab.hyper_lst->count,
- fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) {
+ io_info->space->select.sel_info.hslab.hyper_lst->count,
+ io_info->lo_bounds, io_info->hi_bounds,
+ io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
/* Get the pointer to the actual regions array */
regions=H5TB_buf_ptr(reg_id);
#ifdef QAK
printf("%s: check 1.1, regions=%p\n", FUNC,regions);
printf("%s: check 1.2, rank=%d\n",
- FUNC,(int)fhyper_info->space->extent.u.simple.rank);
+ FUNC,(int)io_info->space->extent.u.simple.rank);
for(i=0; i<num_regions; i++)
printf("%s: check 2.1, region #%d: start=%d, end=%d\n",
FUNC,i,(int)regions[i].start,(int)regions[i].end);
@@ -942,79 +950,69 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Check if this is the second to last dimension in dataset */
/* (Which means that we've got a list of the regions in the fastest */
/* changing dimension and should input those regions) */
- if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+ if((dim+2)==io_info->space->extent.u.simple.rank) {
/* perform I/O on data from regions */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
/* Compute the size of the region to read */
- region_size=MIN(fhyper_info->nelmts, (regions[i].end-regions[i].start)+1);
+ region_size=MIN(io_info->nelmts, (regions[i].end-regions[i].start)+1);
/* Check if this hyperslab block is cached or could be cached */
- if(!regions[i].node->cinfo.cached && (fhyper_info->xfer_parms->cache_hyper && (fhyper_info->xfer_parms->block_limit==0 || fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) {
+ if(!regions[i].node->cinfo.cached && (io_info->xfer_parms->cache_hyper && (io_info->xfer_parms->block_limit==0 || io_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*io_info->elmt_size)))) {
/* if we aren't cached, attempt to cache the block */
- H5S_hyper_block_cache(regions[i].node,fhyper_info,0);
+ H5S_hyper_block_cache(regions[i].node,io_info,0);
} /* end if */
- /* Read information from the cached block */
+ /* Write information to the cached block */
if(regions[i].node->cinfo.cached) {
- if(H5S_hyper_block_write(regions[i].node,fhyper_info,region_size)<0)
+ if(H5S_hyper_block_write(regions[i].node,io_info,region_size)<0)
HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
}
else {
/* Set up hyperslab I/O parameters which apply to all regions */
if(!parm_init) {
-
/* Copy the location of the region in the file */
- HDmemcpy(file_offset, fhyper_info->iter->hyp.pos,
- (fhyper_info->space->extent.u.simple.rank *
- sizeof(hssize_t)));
- file_offset[fhyper_info->space->extent.u.simple.rank]=0;
-
- /* Set the hyperslab size to copy */
- hsize[0]=1;
- H5V_array_fill(hsize, hsize, sizeof(hsize[0]),
- fhyper_info->space->extent.u.simple.rank);
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ HDmemcpy(io_info->offset, io_info->iter->hyp.pos, (io_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ io_info->offset[io_info->space->extent.u.simple.rank]=0;
/* Set flag */
parm_init=1;
} /* end if */
- hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
- file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+ io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size;
+ io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start;
/*
* Scatter to file.
*/
- if (H5F_arr_write (fhyper_info->f, fhyper_info->xfer_parms,
- fhyper_info->layout, fhyper_info->pline,
- fhyper_info->fill, fhyper_info->efl,
- hsize, hsize, zero, file_offset,
- fhyper_info->src)<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0,
- "write error");
+ if (H5F_arr_write (io_info->f, io_info->xfer_parms,
+ io_info->layout, io_info->pline,
+ io_info->fill, io_info->efl,
+ io_info->hsize, io_info->hsize, zero, io_info->offset,
+ io_info->src)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
}
} /* end else */
/* Advance the pointer in the buffer */
- fhyper_info->src = ((const uint8_t *)fhyper_info->src) +
- region_size*fhyper_info->elmt_size;
+ io_info->src = ((const uint8_t *)io_info->src) +
+ region_size*io_info->elmt_size;
/* Increment the number of elements read */
num_written+=region_size;
/* Decrement the buffer left */
- fhyper_info->nelmts-=region_size;
+ io_info->nelmts-=region_size;
/* Set the next position to start at */
if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1))
- fhyper_info->iter->hyp.pos[dim+1]=(-1);
+ io_info->iter->hyp.pos[dim+1]=(-1);
else
- fhyper_info->iter->hyp.pos[dim+1] = regions[i].start +
+ io_info->iter->hyp.pos[dim+1] = regions[i].start +
region_size;
/* Decrement the iterator count */
- fhyper_info->iter->hyp.elmt_left-=region_size;
+ io_info->iter->hyp.elmt_left-=region_size;
} /* end for */
} else { /* recurse on each region to next dimension down */
@@ -1022,21 +1020,21 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
dim++;
/* Step through each region in this dimension */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
/* Step through each location in each region */
- for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) {
+ for(j=regions[i].start; j<=regions[i].end && io_info->nelmts>0; j++) {
/* Set the correct position we are working on */
- fhyper_info->iter->hyp.pos[dim]=j;
+ io_info->iter->hyp.pos[dim]=j;
/* Go get the regions in the next lower dimension */
- num_written+=H5S_hyper_fwrite(dim, fhyper_info);
+ num_written+=H5S_hyper_fwrite(dim, io_info);
/* Advance to the next row if we got the whole region */
- if(fhyper_info->iter->hyp.pos[dim+1]==(-1))
- fhyper_info->iter->hyp.pos[dim]=j+1;
+ if(io_info->iter->hyp.pos[dim+1]==(-1))
+ io_info->iter->hyp.pos[dim]=j+1;
} /* end for */
- if(j>regions[i].end && fhyper_info->iter->hyp.pos[dim+1]==(-1))
- fhyper_info->iter->hyp.pos[dim]=(-1);
+ if(j>regions[i].end && io_info->iter->hyp.pos[dim+1]==(-1))
+ io_info->iter->hyp.pos[dim]=(-1);
} /* end for */
} /* end else */
@@ -1079,7 +1077,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
{
H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
- H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */
intn i; /*counters */
size_t num_written; /* number of elements read into buffer */
@@ -1114,24 +1112,30 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
} /* end for */
/* Initialize parameter block for recursive calls */
- fhyper_info.f=f;
- fhyper_info.layout=layout;
- fhyper_info.pline=pline;
- fhyper_info.fill=fill;
- fhyper_info.efl=efl;
- fhyper_info.elmt_size=elmt_size;
- fhyper_info.space=file_space;
- fhyper_info.iter=file_iter;
- fhyper_info.nelmts=nelmts;
- fhyper_info.xfer_parms=xfer_parms;
- fhyper_info.src=_buf;
- fhyper_info.dst=NULL;
- fhyper_info.lo_bounds=lo_bounds;
- fhyper_info.hi_bounds=hi_bounds;
+ io_info.f=f;
+ io_info.layout=layout;
+ io_info.pline=pline;
+ io_info.fill=fill;
+ io_info.efl=efl;
+ io_info.elmt_size=elmt_size;
+ io_info.space=file_space;
+ io_info.iter=file_iter;
+ io_info.nelmts=nelmts;
+ io_info.xfer_parms=xfer_parms;
+ io_info.src=_buf;
+ io_info.dst=NULL;
+
+ /* Set the hyperslab size to copy */
+ io_info.hsize[0]=1;
+ H5V_array_fill(io_info.hsize,io_info.hsize,sizeof(io_info.hsize[0]),file_space->extent.u.simple.rank);
+ io_info.hsize[file_space->extent.u.simple.rank]=elmt_size;
+
+ io_info.lo_bounds=lo_bounds;
+ io_info.hi_bounds=hi_bounds;
/* Recursively input the hyperslabs currently defined */
/* starting with the slowest changing dimension */
- num_written=H5S_hyper_fwrite(-1,&fhyper_info);
+ num_written=H5S_hyper_fwrite(-1,&io_info);
/* Release the memory we allocated */
H5MM_xfree(lo_bounds);
@@ -1161,11 +1165,8 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
*-------------------------------------------------------------------------
*/
static size_t
-H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+H5S_hyper_mread (intn dim, H5S_hyper_io_info_t *io_info)
{
- hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*size of memory buffer*/
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in memory*/
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
@@ -1176,7 +1177,7 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
FUNC_ENTER (H5S_hyper_mread, 0);
- assert(fhyper_info);
+ assert(io_info);
#ifdef QAK
printf("%s: check 1.0, dim=%d\n",FUNC,dim);
@@ -1185,9 +1186,9 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
- fhyper_info->space->select.sel_info.hslab.hyper_lst->count,
- fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) {
+ io_info->space->select.sel_info.hslab.hyper_lst->count,
+ io_info->lo_bounds, io_info->hi_bounds,
+ io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
/* Get the pointer to the actual regions array */
regions=H5TB_buf_ptr(reg_id);
@@ -1197,40 +1198,26 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* changing dimension and should input those regions) */
#ifdef QAK
printf("%s: check 2.0, rank=%d, num_regions=%d\n",
- FUNC, (int)fhyper_info->space->extent.u.simple.rank,
+ FUNC, (int)io_info->space->extent.u.simple.rank,
(int)num_regions);
for(i=0; i<num_regions; i++)
printf("%s: check 2.1, region #%d: start=%d, end=%d\n",
FUNC,i,(int)regions[i].start,(int)regions[i].end);
#endif /* QAK */
- if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+ if((dim+2)==io_info->space->extent.u.simple.rank) {
/* Set up hyperslab I/O parameters which apply to all regions */
- /* Set up the size of the memory space */
- HDmemcpy(mem_size, fhyper_info->space->extent.u.simple.size,
- fhyper_info->space->extent.u.simple.rank*sizeof(hsize_t));
- mem_size[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
-
/* Copy the location of the region in the file */
- HDmemcpy(mem_offset, fhyper_info->iter->hyp.pos,
- (fhyper_info->space->extent.u.simple.rank *
- sizeof(hssize_t)));
- mem_offset[fhyper_info->space->extent.u.simple.rank]=0;
-
- /* Set the hyperslab size to copy */
- hsize[0]=1;
- H5V_array_fill(hsize, hsize, sizeof(hsize[0]),
- fhyper_info->space->extent.u.simple.rank);
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ HDmemcpy(io_info->offset, io_info->iter->hyp.pos, (io_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ io_info->offset[io_info->space->extent.u.simple.rank]=0;
/* perform I/O on data from regions */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
- region_size=MIN(fhyper_info->nelmts,
- (regions[i].end-regions[i].start)+1);
- hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
- mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
+ region_size=MIN(io_info->nelmts,(regions[i].end-regions[i].start)+1);
+ io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size;
+ io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start;
#ifdef QAK
printf("%s: check 2.1, i=%d, region_size=%d\n",
FUNC,(int)i,(int)region_size);
@@ -1239,32 +1226,31 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/*
* Gather from memory.
*/
- if (H5V_hyper_copy (fhyper_info->space->extent.u.simple.rank+1,
- hsize, hsize, zero, fhyper_info->dst,
- mem_size, mem_offset, fhyper_info->src)<0) {
+ if (H5V_hyper_copy (io_info->space->extent.u.simple.rank+1,
+ io_info->hsize, io_info->hsize, zero, io_info->dst,
+ io_info->mem_size, io_info->offset, io_info->src)<0) {
HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0,
"unable to gather data from memory");
}
/* Advance the pointer in the buffer */
- fhyper_info->dst = ((uint8_t *)fhyper_info->dst) +
- region_size*fhyper_info->elmt_size;
+ io_info->dst = ((uint8_t *)io_info->dst) + region_size*io_info->elmt_size;
/* Increment the number of elements read */
num_read+=region_size;
/* Decrement the buffer left */
- fhyper_info->nelmts-=region_size;
+ io_info->nelmts-=region_size;
/* Set the next position to start at */
if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1))
- fhyper_info->iter->hyp.pos[dim+1]=(-1);
+ io_info->iter->hyp.pos[dim+1]=(-1);
else
- fhyper_info->iter->hyp.pos[dim+1] =regions[i].start +
+ io_info->iter->hyp.pos[dim+1] =regions[i].start +
region_size;
/* Decrement the iterator count */
- fhyper_info->iter->hyp.elmt_left-=region_size;
+ io_info->iter->hyp.elmt_left-=region_size;
} /* end for */
} else { /* recurse on each region to next dimension down */
#ifdef QAK
@@ -1275,27 +1261,25 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
dim++;
/* Step through each region in this dimension */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
/* Step through each location in each region */
- for(j=regions[i].start;
- j<=regions[i].end && fhyper_info->nelmts>0;
- j++) {
+ for(j=regions[i].start; j<=regions[i].end && io_info->nelmts>0; j++) {
#ifdef QAK
printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j);
#endif /* QAK */
/*
- * If we are moving to a new position in this dim, reset
- * the next lower dim. location.
- */
- if(fhyper_info->iter->hyp.pos[dim]!=j)
- fhyper_info->iter->hyp.pos[dim+1]=(-1);
+ * If we are moving to a new position in this dim, reset
+ * the next lower dim. location.
+ */
+ if(io_info->iter->hyp.pos[dim]!=j)
+ io_info->iter->hyp.pos[dim+1]=(-1);
/* Set the correct position we are working on */
- fhyper_info->iter->hyp.pos[dim]=j;
+ io_info->iter->hyp.pos[dim]=j;
/* Go get the regions in the next lower dimension */
- num_read+=H5S_hyper_mread(dim, fhyper_info);
+ num_read+=H5S_hyper_mread(dim, io_info);
} /* end for */
} /* end for */
} /* end else */
@@ -1334,7 +1318,7 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size,
{
H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
- H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */
intn i;
#ifdef QAK
intn j; /* Counters */
@@ -1391,21 +1375,31 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size,
} /* end for */
/* Initialize parameter block for recursive calls */
- fhyper_info.elmt_size=elmt_size;
- fhyper_info.space=mem_space;
- fhyper_info.iter=mem_iter;
- fhyper_info.nelmts=nelmts;
- fhyper_info.src=_buf;
- fhyper_info.dst=_tconv_buf;
- fhyper_info.lo_bounds=lo_bounds;
- fhyper_info.hi_bounds=hi_bounds;
+ io_info.elmt_size=elmt_size;
+ io_info.space=mem_space;
+ io_info.iter=mem_iter;
+ io_info.nelmts=nelmts;
+ io_info.src=_buf;
+ io_info.dst=_tconv_buf;
+
+ /* Set up the size of the memory space */
+ HDmemcpy(io_info.mem_size, mem_space->extent.u.simple.size,mem_space->extent.u.simple.rank*sizeof(hsize_t));
+ io_info.mem_size[mem_space->extent.u.simple.rank]=elmt_size;
+
+ /* Set the hyperslab size to copy */
+ io_info.hsize[0]=1;
+ H5V_array_fill(io_info.hsize, io_info.hsize, sizeof(io_info.hsize[0]),mem_space->extent.u.simple.rank);
+ io_info.hsize[mem_space->extent.u.simple.rank]=elmt_size;
+
+ io_info.lo_bounds=lo_bounds;
+ io_info.hi_bounds=hi_bounds;
/* Recursively input the hyperslabs currently defined */
/* starting with the slowest changing dimension */
#ifdef QAK
printf("%s: check 4.0\n",FUNC);
#endif /* QAK */
- num_read=H5S_hyper_mread(-1,&fhyper_info);
+ num_read=H5S_hyper_mread(-1,&io_info);
#ifdef QAK
printf("%s: check 5.0, num_read=%d\n",FUNC,(int)num_read);
#endif /* QAK */
@@ -1435,11 +1429,8 @@ H5S_hyper_mgath (const void *_buf, size_t elmt_size,
*-------------------------------------------------------------------------
*/
static size_t
-H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
+H5S_hyper_mwrite (intn dim, H5S_hyper_io_info_t *io_info)
{
- hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*size of memory buffer*/
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
@@ -1450,7 +1441,7 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
FUNC_ENTER (H5S_hyper_mwrite, 0);
- assert(fhyper_info);
+ assert(io_info);
#ifdef QAK
printf("%s: check 1.0\n",FUNC);
#endif /* QAK */
@@ -1458,16 +1449,16 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
- fhyper_info->space->select.sel_info.hslab.hyper_lst->count,
- fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))>=0) {
+ io_info->space->select.sel_info.hslab.hyper_lst->count,
+ io_info->lo_bounds, io_info->hi_bounds,
+ io_info->iter->hyp.pos,io_info->space->select.offset))>=0) {
/* Get the pointer to the actual regions array */
regions=H5TB_buf_ptr(reg_id);
#ifdef QAK
printf("%s: check 2.0, rank=%d\n",
- FUNC,(int)fhyper_info->space->extent.u.simple.rank);
+ FUNC,(int)io_info->space->extent.u.simple.rank);
for(i=0; i<num_regions; i++)
printf("%s: check 2.1, region #%d: start=%d, end=%d\n",
FUNC,i,(int)regions[i].start,(int)regions[i].end);
@@ -1475,67 +1466,52 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Check if this is the second to last dimension in dataset */
/* (Which means that we've got a list of the regions in the fastest */
/* changing dimension and should input those regions) */
- if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
+ if((dim+2)==io_info->space->extent.u.simple.rank) {
/* Set up hyperslab I/O parameters which apply to all regions */
- /* Set up the size of the memory space */
- HDmemcpy(mem_size, fhyper_info->space->extent.u.simple.size,
- fhyper_info->space->extent.u.simple.rank*sizeof(hsize_t));
- mem_size[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
-
/* Copy the location of the region in the file */
- HDmemcpy(mem_offset, fhyper_info->iter->hyp.pos,
- (fhyper_info->space->extent.u.simple.rank*
- sizeof(hssize_t)));
- mem_offset[fhyper_info->space->extent.u.simple.rank]=0;
-
- /* Set the hyperslab size to copy */
- hsize[0]=1;
- H5V_array_fill(hsize, hsize, sizeof(hsize[0]),
- fhyper_info->space->extent.u.simple.rank);
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ HDmemcpy(io_info->offset, io_info->iter->hyp.pos, (io_info->space->extent.u.simple.rank* sizeof(hssize_t)));
+ io_info->offset[io_info->space->extent.u.simple.rank]=0;
#ifdef QAK
printf("%s: check 3.0\n",FUNC);
#endif /* QAK */
/* perform I/O on data from regions */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
- region_size=MIN(fhyper_info->nelmts,
- (regions[i].end-regions[i].start)+1);
- hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
- mem_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
+ region_size=MIN(io_info->nelmts, (regions[i].end-regions[i].start)+1);
+ io_info->hsize[io_info->space->extent.u.simple.rank-1]=region_size;
+ io_info->offset[io_info->space->extent.u.simple.rank-1]=regions[i].start;
/*
* Gather from memory.
*/
- if (H5V_hyper_copy (fhyper_info->space->extent.u.simple.rank+1,
- hsize, mem_size, mem_offset,
- fhyper_info->dst, hsize, zero,
- fhyper_info->src)<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0,
- "unable to gather data from memory");
+ if (H5V_hyper_copy (io_info->space->extent.u.simple.rank+1,
+ io_info->hsize, io_info->mem_size, io_info->offset,
+ io_info->dst, io_info->hsize, zero,
+ io_info->src)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "unable to gather data from memory");
}
/* Advance the pointer in the buffer */
- fhyper_info->src = ((const uint8_t *)fhyper_info->src) +
- region_size*fhyper_info->elmt_size;
+ io_info->src = ((const uint8_t *)io_info->src) +
+ region_size*io_info->elmt_size;
/* Increment the number of elements read */
num_read+=region_size;
/* Decrement the buffer left */
- fhyper_info->nelmts-=region_size;
+ io_info->nelmts-=region_size;
/* Set the next position to start at */
if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1))
- fhyper_info->iter->hyp.pos[dim+1]=(-1);
+ io_info->iter->hyp.pos[dim+1]=(-1);
else
- fhyper_info->iter->hyp.pos[dim+1] = regions[i].start +
+ io_info->iter->hyp.pos[dim+1] = regions[i].start +
region_size;
/* Decrement the iterator count */
- fhyper_info->iter->hyp.elmt_left-=region_size;
+ io_info->iter->hyp.elmt_left-=region_size;
} /* end for */
} else { /* recurse on each region to next dimension down */
@@ -1546,29 +1522,29 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
printf("%s: check 6.0, num_regions=%d\n",FUNC,(int)num_regions);
#endif /* QAK */
/* Step through each region in this dimension */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ for(i=0; i<num_regions && io_info->nelmts>0; i++) {
/* Step through each location in each region */
#ifdef QAK
printf("%s: check 7.0, start[%d]=%d, end[%d]=%d, nelmts=%d\n",
FUNC, i, (int)regions[i].start, i,
- (int)regions[i].end, (int)fhyper_info->nelmts);
+ (int)regions[i].end, (int)io_info->nelmts);
#endif /* QAK */
for(j=regions[i].start;
- j<=regions[i].end && fhyper_info->nelmts>0;
+ j<=regions[i].end && io_info->nelmts>0;
j++) {
/*
* If we are moving to a new position in this dim, reset
* the next lower dim. location.
*/
- if(fhyper_info->iter->hyp.pos[dim]!=j)
- fhyper_info->iter->hyp.pos[dim+1]=(-1);
+ if(io_info->iter->hyp.pos[dim]!=j)
+ io_info->iter->hyp.pos[dim+1]=(-1);
/* Set the correct position we are working on */
- fhyper_info->iter->hyp.pos[dim]=j;
+ io_info->iter->hyp.pos[dim]=j;
/* Go get the regions in the next lower dimension */
- num_read+=H5S_hyper_mwrite(dim, fhyper_info);
+ num_read+=H5S_hyper_mwrite(dim, io_info);
} /* end for */
} /* end for */
} /* end else */
@@ -1604,7 +1580,7 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size,
{
H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
- H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
+ H5S_hyper_io_info_t io_info; /* Block of parameters to pass into recursive calls */
intn i; /*counters */
size_t num_read; /* number of elements read into buffer */
@@ -1635,21 +1611,31 @@ H5S_hyper_mscat (const void *_tconv_buf, size_t elmt_size,
} /* end for */
/* Initialize parameter block for recursive calls */
- fhyper_info.elmt_size=elmt_size;
- fhyper_info.space=mem_space;
- fhyper_info.iter=mem_iter;
- fhyper_info.nelmts=nelmts;
- fhyper_info.src=_tconv_buf;
- fhyper_info.dst=_buf;
- fhyper_info.lo_bounds=lo_bounds;
- fhyper_info.hi_bounds=hi_bounds;
+ io_info.elmt_size=elmt_size;
+ io_info.space=mem_space;
+ io_info.iter=mem_iter;
+ io_info.nelmts=nelmts;
+ io_info.src=_tconv_buf;
+ io_info.dst=_buf;
+
+ /* Set up the size of the memory space */
+ HDmemcpy(io_info.mem_size, mem_space->extent.u.simple.size,mem_space->extent.u.simple.rank*sizeof(hsize_t));
+ io_info.mem_size[mem_space->extent.u.simple.rank]=elmt_size;
+
+ /* Set the hyperslab size to copy */
+ io_info.hsize[0]=1;
+ H5V_array_fill(io_info.hsize, io_info.hsize, sizeof(io_info.hsize[0]), mem_space->extent.u.simple.rank);
+ io_info.hsize[mem_space->extent.u.simple.rank]=elmt_size;
+
+ io_info.lo_bounds=lo_bounds;
+ io_info.hi_bounds=hi_bounds;
/* Recursively input the hyperslabs currently defined */
/* starting with the slowest changing dimension */
#ifdef QAK
printf("%s: check 1.0\n",FUNC);
#endif /* QAK */
- num_read=H5S_hyper_mwrite(-1,&fhyper_info);
+ num_read=H5S_hyper_mwrite(-1,&io_info);
#ifdef QAK
printf("%s: check 2.0\n",FUNC);
#endif /* QAK */
@@ -2919,6 +2905,7 @@ H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end)
FUNC_LEAVE (ret_value);
} /* H5Sget_hyper_bounds() */
+
/*--------------------------------------------------------------------------
NAME
@@ -2974,3 +2961,217 @@ H5S_hyper_select_contiguous(const H5S_t *space)
} /* end else */
FUNC_LEAVE (ret_value);
} /* H5S_hyper_select_contiguous() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_select_iterate_mem
+ *
+ * Purpose: Recursively iterates over data points in memory using the parameters
+ * passed to H5S_hyper_select_iterate.
+ *
+ * Return: Success: Number of elements copied.
+ *
+ * Failure: 0
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 22, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5S_hyper_select_iterate_mem (intn dim, H5S_hyper_iter_info_t *iter_info)
+{
+ hsize_t offset; /* offset of region in buffer */
+ void *tmp_buf; /* temporary location of the element in the buffer */
+ hid_t reg_id; /* ID of temporary region buffer */
+ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
+ size_t num_regions; /* number of regions overlapped */
+ herr_t user_ret=0; /* User's return value */
+ size_t i; /* Counters */
+ intn j;
+
+ FUNC_ENTER (H5S_hyper_mwrite, 0);
+
+ assert(iter_info);
+
+ /* Get a sorted list (in the next dimension down) of the regions which */
+ /* overlap the current index in this dim */
+ if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
+ iter_info->space->select.sel_info.hslab.hyper_lst->count,
+ iter_info->lo_bounds, iter_info->hi_bounds,
+ iter_info->iter->hyp.pos,iter_info->space->select.offset))>=0) {
+
+ /* Get the pointer to the actual regions array */
+ regions=H5TB_buf_ptr(reg_id);
+
+ /* Check if this is the second to last dimension in dataset */
+ /* (Which means that we've got a list of the regions in the fastest */
+ /* changing dimension and should input those regions) */
+ if((dim+2)==iter_info->space->extent.u.simple.rank) {
+
+ /* Iterate over data from regions */
+ for(i=0; i<num_regions && user_ret==0; i++) {
+ /* Set the location of the current hyperslab */
+ iter_info->mem_offset[iter_info->space->extent.u.simple.rank-1]=regions[i].start;
+
+ /* Get the offset in the memory buffer */
+ offset=H5V_array_offset(iter_info->space->extent.u.simple.rank+1,
+ iter_info->mem_size,iter_info->mem_offset);
+ tmp_buf=((char *)iter_info->src+offset);
+
+ /* Iterate over each element in the current region */
+ for(j=regions[i].start; j<=regions[i].end && user_ret==0; j++) {
+ /* Call the user's function */
+ user_ret=(*(iter_info->op))(tmp_buf,iter_info->dt,iter_info->space->extent.u.simple.rank,iter_info->mem_offset,iter_info->op_data);
+
+ /* Subtract the element from the selected region (not implemented yet) */
+
+ /* Advance the pointer in the buffer */
+ tmp_buf=((char *)tmp_buf+iter_info->elem_size);
+ } /* end for */
+
+ /* Decrement the iterator count */
+ iter_info->iter->hyp.elmt_left-=((regions[i].end-regions[i].start)+1);
+ } /* end for */
+
+ /* Set the next position to start at */
+ iter_info->iter->hyp.pos[dim+1]=(-1);
+ } else { /* recurse on each region to next dimension down */
+
+ /* Increment the dimension we are working with */
+ dim++;
+
+ /* Step through each region in this dimension */
+ for(i=0; i<num_regions && user_ret==0; i++) {
+ /* Step through each location in each region */
+ for(j=regions[i].start; j<=regions[i].end && user_ret==0; j++) {
+
+ /*
+ * If we are moving to a new position in this dim, reset
+ * the next lower dim. location.
+ */
+ if(iter_info->iter->hyp.pos[dim]!=j)
+ iter_info->iter->hyp.pos[dim+1]=(-1);
+
+ /* Set the correct position we are working on */
+ iter_info->iter->hyp.pos[dim]=j;
+
+ /* Go get the regions in the next lower dimension */
+ user_ret=H5S_hyper_select_iterate_mem(dim, iter_info);
+ } /* end for */
+ } /* end for */
+ } /* end else */
+
+ /* Release the temporary buffer */
+ H5TB_release_buf(reg_id);
+ } /* end if */
+
+ FUNC_LEAVE (user_ret);
+} /* H5S_hyper_select_iterate_mem() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_select_iterate
+ PURPOSE
+ Iterate over a hyperslab selection, calling a user's function for each
+ element.
+ USAGE
+ herr_t H5S_hyper_select_iterate(buf, type_id, space, operator, operator_data)
+ void *buf; IN/OUT: Buffer containing elements to iterate over
+ hid_t type_id; IN: Datatype ID of BUF array.
+ H5S_t *space; IN: Dataspace object containing selection to iterate over
+ H5D_operator_t operator; IN: Function pointer to the routine to be
+ called for each element in BUF iterated over.
+ void *operator_data; IN/OUT: Pointer to any user-defined data
+ associated with the operation.
+ RETURNS
+ Returns the return value of the last operator if it was non-zero, or zero
+ if all elements were processed. Otherwise returns a negative value.
+ DESCRIPTION
+ Iterates over the selected elements in a memory buffer, calling the user's
+ callback function for each element. The selection in the dataspace is
+ modified so that any elements already iterated over are removed from the
+ selection if the iteration is interrupted (by the H5D_operator_t function
+ returning non-zero) in the "middle" of the iteration and may be re-started
+ by the user where it left off.
+
+ NOTE: Until "subtracting" elements from a selection is implemented,
+ the selection is not modified.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator,
+ void *operator_data)
+{
+ H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
+ H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
+ H5S_hyper_iter_info_t iter_info; /* Block of parameters to pass into recursive calls */
+ H5S_sel_iter_t iter; /* selection iteration info*/
+ size_t min_elem_out=1; /* Minimum # of elements to output*/
+ intn i; /*counters */
+ herr_t ret_value=FAIL; /* return value */
+
+ FUNC_ENTER (H5S_hyper_select_iterate, FAIL);
+
+ assert(buf);
+ assert(space);
+ assert(operator);
+ assert(H5I_DATATYPE != H5I_get_type(type_id));
+
+ /* Initialize these before any errors can occur */
+ HDmemset(&iter,0,sizeof(H5S_sel_iter_t));
+
+ /* Initialize the selection iterator */
+ if (H5S_hyper_init(NULL, space, &iter, &min_elem_out)<0) {
+ HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL,
+ "unable to initialize selection information");
+ }
+
+ /* Allocate space for the low & high bound arrays */
+ lo_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+ hi_bounds = H5MM_malloc(space->extent.u.simple.rank * sizeof(H5S_hyper_bound_t *));
+
+ /*
+ * Initialize to correct order to walk through arrays. (When another
+ * iteration order besides the default 'C' order is chosen, this is the
+ * correct place to change the order of the array iterations)
+ */
+ for(i=0; i<space->extent.u.simple.rank; i++) {
+ lo_bounds[i]=space->select.sel_info.hslab.hyper_lst->lo_bounds[i];
+ hi_bounds[i]=space->select.sel_info.hslab.hyper_lst->hi_bounds[i];
+ } /* end for */
+
+ /* Initialize parameter block for recursive calls */
+ iter_info.dt=type_id;
+ iter_info.elem_size=H5Tget_size(type_id);
+ iter_info.space=space;
+ iter_info.iter=&iter;
+ iter_info.src=buf;
+ iter_info.lo_bounds=lo_bounds;
+ iter_info.hi_bounds=hi_bounds;
+ /* Set up the size of the memory space */
+ HDmemcpy(iter_info.mem_size, space->extent.u.simple.size, space->extent.u.simple.rank*sizeof(hsize_t));
+ iter_info.mem_size[space->extent.u.simple.rank]=iter_info.elem_size;
+ /* Copy the location of the region in the file */
+ HDmemcpy(iter_info.mem_offset, iter.hyp.pos,(space->extent.u.simple.rank*sizeof(hssize_t)));
+ iter_info.mem_offset[space->extent.u.simple.rank]=0;
+ iter_info.op=operator;
+ iter_info.op_data=operator_data;
+
+ /* Recursively input the hyperslabs currently defined */
+ /* starting with the slowest changing dimension */
+ ret_value=H5S_hyper_select_iterate_mem(-1,&iter_info);
+
+ /* Release the memory we allocated */
+ H5MM_xfree(lo_bounds);
+ H5MM_xfree(hi_bounds);
+
+done:
+ FUNC_LEAVE (ret_value);
+} /* H5S_hyper_select_iterate() */
diff --git a/src/H5Snone.c b/src/H5Snone.c
index f0971cf..508be0e 100644
--- a/src/H5Snone.c
+++ b/src/H5Snone.c
@@ -9,6 +9,7 @@
*/
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5Iprivate.h>
#include <H5Sprivate.h>
#include <H5Vprivate.h>
#include <H5Dprivate.h>
@@ -95,3 +96,44 @@ H5S_none_select_deserialize (H5S_t *space, const uint8_t UNUSED *buf)
done:
FUNC_LEAVE (ret_value);
} /* H5S_none_select_deserialize() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_none_select_iterate
+ PURPOSE
+ Iterate over a none selection, calling a user's function for each
+ element. (i.e. the user's function is not called because there are
+ zero elements selected)
+ USAGE
+ herr_t H5S_none_select_iterate(buf, type_id, space, operator, operator_data)
+ void *buf; IN/OUT: Buffer containing elements to iterate over
+ hid_t type_id; IN: Datatype ID of BUF array.
+ H5S_t *space; IN: Dataspace object containing selection to iterate over
+ H5D_operator_t operator; IN: Function pointer to the routine to be
+ called for each element in BUF iterated over.
+ void *operator_data; IN/OUT: Pointer to any user-defined data
+ associated with the operation.
+ RETURNS
+ Returns success (0).
+ DESCRIPTION
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_none_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator,
+ void UNUSED *operator_data)
+{
+ herr_t ret_value=SUCCEED; /* return value */
+
+ FUNC_ENTER (H5S_none_select_iterate, FAIL);
+
+ assert(buf);
+ assert(space);
+ assert(operator);
+ assert(H5I_DATATYPE != H5I_get_type(type_id));
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_hyper_select_iterate() */
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index ac3d3e1..583aab7 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -9,6 +9,7 @@
*/
#include <H5private.h>
#include <H5Eprivate.h>
+#include <H5Iprivate.h>
#include <H5MMprivate.h>
#include <H5Sprivate.h>
#include <H5Vprivate.h>
@@ -1107,4 +1108,78 @@ H5S_point_select_contiguous(const H5S_t *space)
ret_value=FALSE;
FUNC_LEAVE (ret_value);
-} /* H5S_select_contiguous() */
+} /* H5S_point_select_contiguous() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_point_select_iterate
+ PURPOSE
+ Iterate over a point selection, calling a user's function for each
+ element.
+ USAGE
+ herr_t H5S_point_select_iterate(buf, type_id, space, operator, operator_data)
+ void *buf; IN/OUT: Buffer containing elements to iterate over
+ hid_t type_id; IN: Datatype ID of BUF array.
+ H5S_t *space; IN: Dataspace object containing selection to iterate over
+ H5D_operator_t operator; IN: Function pointer to the routine to be
+ called for each element in BUF iterated over.
+ void *operator_data; IN/OUT: Pointer to any user-defined data
+ associated with the operation.
+ RETURNS
+ Returns the return value of the last operator if it was non-zero, or zero
+ if all elements were processed. Otherwise returns a negative value.
+ DESCRIPTION
+ Iterates over the selected elements in a memory buffer, calling the user's
+ callback function for each element. The selection in the dataspace is
+ modified so that any elements already iterated over are removed from the
+ selection if the iteration is interrupted (by the H5D_operator_t function
+ returning non-zero) in the "middle" of the iteration and may be re-started
+ by the user where it left off.
+
+ NOTE: Until "subtracting" elements from a selection is implemented,
+ the selection is not modified.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator,
+ void *operator_data)
+{
+ hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
+ hsize_t offset; /* offset of region in buffer */
+ void *tmp_buf; /* temporary location of the element in the buffer */
+ H5S_pnt_node_t *node; /* Point node */
+ intn rank; /* Dataspace rank */
+ herr_t ret_value=0; /* return value */
+
+ FUNC_ENTER (H5S_point_select_iterate, 0);
+
+ assert(buf);
+ assert(space);
+ assert(operator);
+ assert(H5I_DATATYPE != H5I_get_type(type_id));
+
+ /* Get the dataspace extent rank */
+ rank=space->extent.u.simple.rank;
+
+ /* Set up the size of the memory space */
+ HDmemcpy(mem_size, space->extent.u.simple.size, rank*sizeof(hsize_t));
+ mem_size[rank]=H5Tget_size(type_id);
+
+ /* Iterate through the node, checking the bounds on each element */
+ node=space->select.sel_info.pnt_lst->head;
+ while(node!=NULL && ret_value==0) {
+ /* Get the offset in the memory buffer */
+ offset=H5V_array_offset(rank+1,mem_size,node->pnt);
+ tmp_buf=((char *)buf+offset);
+
+ ret_value=(*operator)(tmp_buf,type_id,rank,node->pnt,operator_data);
+
+ node=node->next;
+ } /* end while */
+
+ FUNC_LEAVE (ret_value);
+} /* H5S_point_select_iterate() */
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 2dba002..4c1894f 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -342,6 +342,8 @@ __DLL__ hssize_t H5S_select_serial_size(const H5S_t *space);
__DLL__ herr_t H5S_select_serialize(const H5S_t *space, uint8_t *buf);
__DLL__ herr_t H5S_select_deserialize(H5S_t *space, const uint8_t *buf);
__DLL__ htri_t H5S_select_contiguous(const H5S_t *space);
+__DLL__ herr_t H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space,
+ H5D_operator_t operator, void *operator_data);
/* Point select functions */
__DLL__ herr_t H5S_point_add(H5S_t *space, size_t num_elemn,
@@ -355,6 +357,8 @@ __DLL__ herr_t H5S_point_select_serialize(const H5S_t *space, uint8_t *buf);
__DLL__ herr_t H5S_point_select_deserialize(H5S_t *space, const uint8_t *buf);
__DLL__ herr_t H5S_point_bounds(H5S_t *space, hsize_t *start, hsize_t *end);
__DLL__ htri_t H5S_point_select_contiguous(const H5S_t *space);
+__DLL__ herr_t H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space,
+ H5D_operator_t operator, void *operator_data);
/* "All" select functions */
__DLL__ herr_t H5S_all_release(H5S_t *space);
@@ -374,6 +378,8 @@ __DLL__ herr_t H5S_all_write(H5F_t *f, const struct H5O_layout_t *layout,
const H5S_t *file_space, const H5S_t *mem_space,
const H5F_xfer_t *xfer_parms, const void *buf,
hbool_t *must_convert/*out*/);
+__DLL__ herr_t H5S_all_select_iterate(void *buf, hid_t type_id, H5S_t *space,
+ H5D_operator_t operator, void *operator_data);
/* Hyperslab selection functions */
__DLL__ herr_t H5S_hyper_add(H5S_t *space, const hssize_t *start,
@@ -396,10 +402,14 @@ __DLL__ herr_t H5S_hyper_select_serialize(const H5S_t *space, uint8_t *buf);
__DLL__ herr_t H5S_hyper_select_deserialize(H5S_t *space, const uint8_t *buf);
__DLL__ herr_t H5S_hyper_bounds(H5S_t *space, hsize_t *start, hsize_t *end);
__DLL__ htri_t H5S_hyper_select_contiguous(const H5S_t *space);
+__DLL__ herr_t H5S_hyper_select_iterate(void *buf, hid_t type_id, H5S_t *space,
+ H5D_operator_t operator, void *operator_data);
/* "None" selection functions */
__DLL__ herr_t H5S_none_select_serialize(const H5S_t *space, uint8_t *buf);
__DLL__ herr_t H5S_none_select_deserialize(H5S_t *space, const uint8_t *buf);
+__DLL__ herr_t H5S_none_select_iterate(void *buf, hid_t type_id, H5S_t *space,
+ H5D_operator_t operator, void *operator_data);
#ifdef HAVE_PARALLEL
/* MPI-IO function to read directly from app buffer to file rky980813 */
diff --git a/src/H5Sselect.c b/src/H5Sselect.c
index 669cb94..1379617 100644
--- a/src/H5Sselect.c
+++ b/src/H5Sselect.c
@@ -1683,3 +1683,72 @@ H5S_select_contiguous(const H5S_t *space)
FUNC_LEAVE (ret_value);
} /* H5S_select_contiguous() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_iterate
+ PURPOSE
+ Iterate over the selected elements in a memory buffer.
+ USAGE
+ herr_t H5S_select_iterate(buf, type_id, space, operator, operator_data)
+ void *buf; IN/OUT: Buffer containing elements to iterate over
+ hid_t type_id; IN: Datatype ID of BUF array.
+ H5S_t *space; IN: Dataspace object containing selection to iterate over
+ H5D_operator_t operator; IN: Function pointer to the routine to be
+ called for each element in BUF iterated over.
+ void *operator_data; IN/OUT: Pointer to any user-defined data
+ associated with the operation.
+ RETURNS
+ Returns the return value of the last operator if it was non-zero, or zero
+ if all elements were processed. Otherwise returns a negative value.
+ DESCRIPTION
+ Iterates over the selected elements in a memory buffer, calling the user's
+ callback function for each element. The selection in the dataspace is
+ modified so that any elements already iterated over are removed from the
+ selection if the iteration is interrupted (by the H5D_operator_t function
+ returning non-zero) in the "middle" of the iteration and may be re-started
+ by the user where it left off.
+
+ NOTE: Until "subtracting" elements from a selection is implemented,
+ the selection is not modified.
+--------------------------------------------------------------------------*/
+herr_t
+H5S_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t operator,
+ void *operator_data)
+{
+ herr_t ret_value=FAIL;
+
+ FUNC_ENTER(H5S_select_iterate, FAIL);
+
+ /* Check args */
+ assert(buf);
+ assert(space);
+ assert(operator);
+ assert(H5I_DATATYPE != H5I_get_type(type_id));
+
+ switch(space->select.type) {
+ case H5S_SEL_POINTS: /* Sequence of points selected */
+ ret_value=H5S_point_select_iterate(buf,type_id,space,operator,operator_data);
+ break;
+
+ case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
+ ret_value=H5S_hyper_select_iterate(buf,type_id,space,operator,operator_data);
+ break;
+
+ case H5S_SEL_ALL: /* Entire extent selected */
+ ret_value=H5S_all_select_iterate(buf,type_id,space,operator,operator_data);
+ break;
+
+ case H5S_SEL_NONE: /* Nothing selected */
+ ret_value=H5S_none_select_iterate(buf,type_id,space,operator,operator_data);
+ break;
+
+ case H5S_SEL_ERROR:
+ case H5S_SEL_N:
+ break;
+ }
+
+ FUNC_LEAVE(SUCCEED);
+} /* end H5S_select_iterate() */
+
diff --git a/src/H5V.c b/src/H5V.c
index 15cf867..dc61b22 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -679,3 +679,49 @@ H5V_array_fill(void *_dst, const void *src, size_t size, size_t count)
FUNC_LEAVE(SUCCEED);
} /* H5V_array_fill() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5V_array_offset
+ *
+ * Purpose: Given a coordinate description of a location in an array, this
+ * function returns the byte offset of the coordinate.
+ *
+ * The dimensionality of the whole array, the hyperslab, and the
+ * returned stride array is N. The whole array dimensions are
+ * TOTAL_SIZE and the coordinate is at offset OFFSET.
+ *
+ * Return: Success: Byte offset from beginning of array to start
+ * of striding.
+ *
+ * Failure: abort() -- should never fail
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, June 22, 1999
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hsize_t
+H5V_array_offset(intn n, const hsize_t *total_size, const hssize_t *offset)
+{
+ hsize_t skip; /*starting point byte offset */
+ hsize_t acc; /*accumulator */
+ int i; /*counter */
+
+ FUNC_ENTER(H5V_array_stride, (HDabort(), 0));
+
+ assert(n >= 0 && n <= H5V_HYPER_NDIMS);
+ assert(total_size);
+ assert(offset);
+
+ /* others */
+ for (i=n-1, acc=1, skip=0; i>=0; --i) {
+ skip += acc * offset[i];
+ acc *= total_size[i];
+ }
+
+ FUNC_LEAVE(skip);
+}
+
diff --git a/src/H5Vprivate.h b/src/H5Vprivate.h
index fef02dc..c471b6a 100644
--- a/src/H5Vprivate.h
+++ b/src/H5Vprivate.h
@@ -72,6 +72,8 @@ __DLL__ herr_t H5V_stride_optimize2(intn *np, hsize_t *elmt_size,
hssize_t *stride2);
__DLL__ herr_t H5V_array_fill(void *_dst, const void *src, size_t size,
size_t count);
+__DLL__ hsize_t H5V_array_offset(intn n, const hsize_t *total_size,
+ const hssize_t *offset);
/*-------------------------------------------------------------------------