summaryrefslogtreecommitdiffstats
path: root/src/H5Spoint.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2002-07-24 18:56:48 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2002-07-24 18:56:48 (GMT)
commit40df66ebd027351e48eea8b7499490c9654d3943 (patch)
tree9dd8b9170bec792e840e2b350ca48153cd45ce88 /src/H5Spoint.c
parentc968525b29ce8cee8e842f6a7a1bbd78acc6b63f (diff)
downloadhdf5-40df66ebd027351e48eea8b7499490c9654d3943.zip
hdf5-40df66ebd027351e48eea8b7499490c9654d3943.tar.gz
hdf5-40df66ebd027351e48eea8b7499490c9654d3943.tar.bz2
[svn-r5834] Purpose:
Large code cleanup/re-write Description: This is phase 1 of the data I/O re-architecture, with the following changes: - Changed the selection drivers to not actually do any I/O, they only generate the sequences of offset/length pairs needed for the I/O (or memory access, in the case of iterating or filling a selection in a memory buffer) - Wrote more abstract I/O routines which get the sequence of offset/ length pairs for each selection and access perform the I/O or memory access. Benefits of this change include: - Removed ~3400 lines of quite redundant code, with corresponding reduction in the size of library binary. - Any selection can now directly access memory when performing I/O, if no type conversions are required, instead of just "regular" hyperslab and 'all' selections, which speeds up I/O. - Sped up I/O for hyperslab selections which have contiguous lower dimensions by "flattening" them out into lesser dimensional objects for the I/O. No file format or API changes were necessary for this change. The next phase will be to create a "selection driver" for each type of selection, allowing each type of selection to directly call certain methods that only apply to that type of selection, instead of passing through dozens of functions which have switch statements to call the appropriate method for each selection type. This will also reduce the amount of code in the library and speed things up a bit more. Phase 3 will involve generating an MPI datatype for all types of selections, instead of only "regular" hyperslab and 'all' selections. This will allow collective parallel I/O for all I/O operations which don't require type conversions. It will also open up the door for allowing collective I/O on datasets which require type conversion. Phase 4 will involve changing the access pattern to deal with chunked datasets in a more optimal way (in serial). Phase 5 will deal with accessing chunked datasets more optimally for collective parallel I/O operations. Platforms tested: FreeBSD 4.6 (sleipnir) w/ parallel & C++ and IRIX64 6.5 (modi4) w/parallel
Diffstat (limited to 'src/H5Spoint.c')
-rw-r--r--src/H5Spoint.c644
1 files changed, 133 insertions, 511 deletions
diff --git a/src/H5Spoint.c b/src/H5Spoint.c
index 9dcfc4c..e7f32ef 100644
--- a/src/H5Spoint.c
+++ b/src/H5Spoint.c
@@ -10,61 +10,26 @@
#define H5S_PACKAGE /*suppress error about including H5Spkg */
-#include "H5private.h"
-#include "H5Dprivate.h"
-#include "H5Eprivate.h"
-#include "H5Iprivate.h"
-#include "H5MMprivate.h"
-#include "H5Spkg.h"
-#include "H5Tprivate.h" /* Datatypes */
-#include "H5Vprivate.h"
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Iprivate.h" /* ID Functions */
+#include "H5MMprivate.h" /* Memory Management functions */
+#include "H5Spkg.h" /* Dataspace functions */
+#include "H5Vprivate.h" /* Vector functions */
/* Interface initialization */
#define PABLO_MASK H5Spoint_mask
#define INTERFACE_INIT NULL
static int interface_initialize_g = 0;
-static herr_t H5S_point_init (const H5S_t *space, size_t elmt_size, H5S_sel_iter_t *iter);
-static hsize_t H5S_point_favail (const H5S_t *space, const H5S_sel_iter_t *iter,
- hsize_t max);
-static hsize_t H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, hsize_t nelmts,
- hid_t dxpl_id, void *buf/*out*/);
-static herr_t H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, hsize_t nelmts,
- hid_t dxpl_id, const void *buf);
-static hsize_t H5S_point_mgath (const void *_buf, size_t elmt_size,
- const H5S_t *mem_space,
- H5S_sel_iter_t *mem_iter, hsize_t nelmts,
- void *_tconv_buf/*out*/);
-static herr_t H5S_point_mscat (const void *_tconv_buf, size_t elmt_size,
- const H5S_t *mem_space,
- H5S_sel_iter_t *mem_iter, hsize_t nelmts,
- void *_buf/*out*/);
-
-const H5S_fconv_t H5S_POINT_FCONV[1] = {{
- "point", /*name */
- H5S_SEL_POINTS, /*selection type */
- H5S_point_init, /*initialize */
- H5S_point_favail, /*available */
- H5S_point_fgath, /*gather */
- H5S_point_fscat, /*scatter */
-}};
-
-const H5S_mconv_t H5S_POINT_MCONV[1] = {{
- "point", /*name */
- H5S_SEL_POINTS, /*selection type */
- H5S_point_init, /*initialize */
- H5S_point_mgath, /*gather */
- H5S_point_mscat, /*scatter */
-}};
-
-
+/* Declare a free list to manage the H5S_pnt_node_t struct */
+H5FL_DEFINE_STATIC(H5S_pnt_node_t);
+/* Declare a free list to manage the H5S_pnt_list_t struct */
+H5FL_DEFINE_STATIC(H5S_pnt_list_t);
+
+
/*-------------------------------------------------------------------------
* Function: H5S_point_init
*
@@ -79,7 +44,7 @@ const H5S_mconv_t H5S_POINT_MCONV[1] = {{
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5S_point_init (const H5S_t *space, size_t UNUSED elmt_size, H5S_sel_iter_t *sel_iter)
{
FUNC_ENTER_NOAPI(H5S_point_init, FAIL);
@@ -134,7 +99,7 @@ herr_t H5S_point_add (H5S_t *space, H5S_seloper_t op, size_t num_elem, const hss
top=curr=NULL;
for(i=0; i<num_elem; i++) {
/* Allocate space for the new node */
- if((new_node = H5MM_malloc(sizeof(H5S_pnt_node_t)))==NULL)
+ if((new_node = H5FL_ALLOC(H5S_pnt_node_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
@@ -199,7 +164,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static hsize_t
+hsize_t
H5S_point_favail (const H5S_t * UNUSED space,
const H5S_sel_iter_t *sel_iter, hsize_t max)
{
@@ -211,337 +176,7 @@ H5S_point_favail (const H5S_t * UNUSED space,
FUNC_LEAVE (MIN(sel_iter->pnt.elmt_left,max));
} /* H5S_point_favail() */
-
-/*-------------------------------------------------------------------------
- * Function: H5S_point_fgath
- *
- * Purpose: Gathers data points from file F and accumulates them in the
- * type conversion buffer BUF. The LAYOUT argument describes
- * how the data is stored on disk and EFL describes how the data
- * is organized in external files. ELMT_SIZE is the size in
- * bytes of a datum which this function treats as opaque.
- * FILE_SPACE describes the data space of the dataset on disk
- * and the elements that have been selected for reading (via
- * hyperslab, etc). This function will copy at most NELMTS
- * elements.
- *
- * Notes: This could be optimized by gathering selected elements near (how
- * near?) each other into one I/O request and then moving the correct
- * elements into the return buffer
- *
- * Return: Success: Number of elements copied.
- *
- * Failure: 0
- *
- * Programmer: Quincey Koziol
- * Tuesday, June 16, 1998
- *
- * Modifications:
- * Robb Matzke, 1999-08-03
- * The data transfer properties are passed by ID since that's
- * what the virtual file layer needs.
- *-------------------------------------------------------------------------
- */
-static hsize_t
-H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id,
- void *_buf/*out*/)
-{
- hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
- uint8_t *buf=(uint8_t *)_buf; /* Alias for pointer arithmetic */
- unsigned ndims; /* Number of dimensions of dataset */
- unsigned u; /*counters */
- hsize_t num_read; /* number of elements read into buffer */
- FUNC_ENTER_NOAPI(H5S_point_fgath, 0);
-
- /* Check args */
- assert (f);
- assert (layout);
- assert (elmt_size>0);
- assert (file_space);
- assert (file_iter);
- assert (nelmts>0);
- assert (buf);
-
- ndims=file_space->extent.u.simple.rank;
- /* initialize hyperslab size and offset in memory buffer */
- for(u=0; u<ndims+1; u++) {
- hsize[u]=1; /* hyperslab size is 1, except for last element */
- zero[u]=0; /* memory offset is 0 */
- } /* end for */
- hsize[ndims] = elmt_size;
-
- /*
- * Walk though and request each element we need and put it into the
- * buffer.
- */
- num_read=0;
- while(num_read<nelmts) {
- if(file_iter->pnt.elmt_left>0) {
- /* Copy the location of the point to get */
- HDmemcpy(file_offset, file_iter->pnt.curr->pnt, ndims*sizeof(hssize_t));
- file_offset[ndims] = 0;
-
- /* Add in the offset */
- for(u=0; u<file_space->extent.u.simple.rank; u++)
- file_offset[u] += file_space->select.offset[u];
-
- /* Go read the point */
- if (H5F_arr_read(f, dxpl_id, layout, dc_plist, hsize, hsize, zero, file_offset, buf/*out*/)<0)
- HRETURN_ERROR(H5E_DATASPACE, H5E_READERROR, 0, "read error");
-
- /* Increment the offset of the buffer */
- buf+=elmt_size;
-
- /* Increment the count read */
- num_read++;
-
- /* Advance the point iterator */
- file_iter->pnt.elmt_left--;
- file_iter->pnt.curr=file_iter->pnt.curr->next;
- } else {
- break; /* out of elements in the selection */
- } /* end else */
- } /* end while */
-
- FUNC_LEAVE (num_read);
-} /* H5S_point_fgath() */
-
-/*-------------------------------------------------------------------------
- * Function: H5S_point_fscat
- *
- * Purpose: Scatters dataset elements from the type conversion buffer BUF
- * to the file F where the data points are arranged according to
- * the file data space FILE_SPACE and stored according to
- * LAYOUT and EFL. Each element is ELMT_SIZE bytes.
- * The caller is requesting that NELMTS elements are copied.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Tuesday, June 16, 1998
- *
- * Modifications:
- * Robb Matzke, 1999-08-03
- * The data transfer properties are passed by ID since that's
- * what the virtual file layer needs.
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout,
- H5P_genplist_t *dc_plist,
- size_t elmt_size, const H5S_t *file_space,
- H5S_sel_iter_t *file_iter, hsize_t nelmts, hid_t dxpl_id,
- const void *_buf)
-{
- hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */
- hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */
- const uint8_t *buf=(const uint8_t *)_buf; /* Alias for pointer arithmetic */
- unsigned ndims; /* Number of dimensions of dataset */
- unsigned u; /*counters */
- hsize_t num_written; /* number of elements written from buffer */
-
- FUNC_ENTER_NOAPI(H5S_point_fscat, FAIL);
-
- /* Check args */
- assert (f);
- assert (layout);
- assert (elmt_size>0);
- assert (file_space);
- assert (file_iter);
- assert (nelmts>0);
- assert (buf);
-
- /* Hold the number of dimensions of the dataspace */
- ndims=file_space->extent.u.simple.rank;
-
- /* initialize hyperslab size and offset in memory buffer */
- for(u=0; u<ndims+1; u++) {
- hsize[u]=1; /* hyperslab size is 1, except for last element */
- zero[u]=0; /* memory offset is 0 */
- } /* end for */
- hsize[ndims] = elmt_size;
-
- /*
- * Walk though and request each element we need and put it into the
- * buffer.
- */
- num_written=0;
- while(num_written<nelmts && file_iter->pnt.elmt_left>0) {
- /* Copy the location of the point to get */
- HDmemcpy(file_offset,file_iter->pnt.curr->pnt,ndims*sizeof(hssize_t));
- file_offset[ndims] = 0;
-
- /* Add in the offset, if there is one */
- for(u=0; u<file_space->extent.u.simple.rank; u++)
- file_offset[u] += file_space->select.offset[u];
-
- /* Go write the point */
- if (H5F_arr_write(f, dxpl_id, layout, dc_plist, hsize, hsize, zero, file_offset, buf)<0)
- HRETURN_ERROR(H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
-
- /* Increment the offset of the buffer */
- buf+=elmt_size;
-
- /* Increment the count read */
- num_written++;
-
- /* Advance the point iterator */
- file_iter->pnt.elmt_left--;
- file_iter->pnt.curr=file_iter->pnt.curr->next;
- } /* end while */
-
- FUNC_LEAVE (num_written>0 ? SUCCEED : FAIL);
-} /* H5S_point_fscat() */
-
-/*-------------------------------------------------------------------------
- * Function: H5S_point_mgath
- *
- * Purpose: Gathers dataset elements from application memory BUF and
- * copies them into the data type conversion buffer TCONV_BUF.
- * Each element is ELMT_SIZE bytes and arranged in application
- * memory according to MEM_SPACE.
- * The caller is requesting that at most NELMTS be gathered.
- *
- * Return: Success: Number of elements copied.
- *
- * Failure: 0
- *
- * Programmer: Quincey Koziol
- * Tuesday, June 16, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static hsize_t
-H5S_point_mgath (const void *_buf, size_t elmt_size,
- const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
- hsize_t nelmts, void *_tconv_buf/*out*/)
-{
- hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */
- const uint8_t *buf=(const uint8_t *)_buf; /* Get local copies for address arithmetic */
- uint8_t *tconv_buf=(uint8_t *)_tconv_buf;
- hsize_t acc; /* coordinate accumulator */
- hsize_t off; /* coordinate offset */
- int space_ndims; /*dimensionality of space*/
- int i; /*counters */
- hsize_t num_gath; /* number of elements gathered */
-
- FUNC_ENTER_NOAPI(H5S_point_mgath, 0);
-
- /* Check args */
- assert (buf);
- assert (elmt_size>0);
- assert (mem_space && H5S_SEL_POINTS==mem_space->select.type);
- assert (nelmts>0);
- assert (tconv_buf);
-
- /* Get the dataspace dimensions */
- if ((space_ndims=H5S_get_simple_extent_dims (mem_space, mem_size, NULL))<0)
- HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, 0, "unable to retrieve data space dimensions");
-
- /* Loop through all the points selected */
- for(num_gath=0; num_gath<nelmts; num_gath++) {
- if(mem_iter->pnt.elmt_left>0) {
- /* Compute the location of the point to get */
- for(i=space_ndims-1,acc=elmt_size,off=0; i>=0; i--) {
- off+=(mem_iter->pnt.curr->pnt[i]+mem_space->select.offset[i])*acc;
- acc*=mem_size[i];
- } /* end for */
-
- /* Copy the elements into the type conversion buffer */
- HDmemcpy(tconv_buf,buf+off,elmt_size);
-
- /* Increment the offset of the buffers */
- tconv_buf+=elmt_size;
-
- /* Advance the point iterator */
- mem_iter->pnt.elmt_left--;
- mem_iter->pnt.curr=mem_iter->pnt.curr->next;
- } else {
- break; /* out of elements in the selection */
- } /* end else */
- } /* end for */
-
- FUNC_LEAVE (num_gath);
-} /* H5S_point_mgath() */
-
-/*-------------------------------------------------------------------------
- * Function: H5S_point_mscat
- *
- * Purpose: Scatters NELMTS data points from the type conversion buffer
- * TCONV_BUF to the application buffer BUF. Each element is
- * ELMT_SIZE bytes and they are organized in application memory
- * according to MEM_SPACE.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * Wednesday, June 17, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5S_point_mscat (const void *_tconv_buf, size_t elmt_size,
- const H5S_t *mem_space, H5S_sel_iter_t *mem_iter,
- hsize_t nelmts, void *_buf/*out*/)
-{
- hsize_t mem_size[H5O_LAYOUT_NDIMS]; /*total size of app buf */
- uint8_t *buf=(uint8_t *)_buf; /* Get local copies for address arithmetic */
- const uint8_t *tconv_buf=(const uint8_t *)_tconv_buf;
- hsize_t acc; /* coordinate accumulator */
- hsize_t off; /* coordinate offset */
- int space_ndims; /*dimensionality of space*/
- int i; /*counters */
- hsize_t num_scat; /* Number of elements scattered */
-
- FUNC_ENTER_NOAPI(H5S_point_mscat, FAIL);
-
- /* Check args */
- assert (tconv_buf);
- assert (elmt_size>0);
- assert (mem_space && H5S_SEL_POINTS==mem_space->select.type);
- assert (nelmts>0);
- assert (buf);
-
- /* Get the dataspace dimensions */
- if ((space_ndims=H5S_get_simple_extent_dims (mem_space, mem_size, NULL))<0)
- HRETURN_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve data space dimensions");
-
- /* Loop through all the points selected */
- for(num_scat=0; num_scat<nelmts; num_scat++) {
- if(mem_iter->pnt.elmt_left>0) {
- /* Compute the location of the point to get */
- for(i=space_ndims-1,acc=elmt_size,off=0; i>=0; i--) {
- off+=(mem_iter->pnt.curr->pnt[i]+mem_space->select.offset[i])*acc;
- acc*=mem_size[i];
- } /* end for */
-
- /* Copy the elements into the type conversion buffer */
- HDmemcpy(buf+off,tconv_buf,elmt_size);
-
- /* Increment the offset of the buffers */
- tconv_buf+=elmt_size;
-
- /* Advance the point iterator */
- mem_iter->pnt.elmt_left--;
- mem_iter->pnt.curr=mem_iter->pnt.curr->next;
- } else {
- break; /* out of elements in the selection */
- } /* end else */
- } /* end for */
-
- FUNC_LEAVE (SUCCEED);
-} /* H5S_point_mscat() */
/*--------------------------------------------------------------------------
NAME
@@ -575,12 +210,12 @@ H5S_point_release (H5S_t *space)
while(curr!=NULL) {
next=curr->next;
H5MM_xfree(curr->pnt);
- H5MM_xfree(curr);
+ H5FL_FREE(H5S_pnt_node_t,curr);
curr=next;
} /* end while */
/* Free & reset the point list header */
- H5MM_xfree(space->select.sel_info.pnt_lst);
+ H5FL_FREE(H5S_pnt_list_t,space->select.sel_info.pnt_lst);
space->select.sel_info.pnt_lst=NULL;
/* Reset the number of elements in the selection */
@@ -588,6 +223,7 @@ H5S_point_release (H5S_t *space)
FUNC_LEAVE (SUCCEED);
} /* H5S_point_release() */
+
/*--------------------------------------------------------------------------
NAME
@@ -616,6 +252,7 @@ H5S_point_npoints (const H5S_t *space)
FUNC_LEAVE (space->select.num_elem);
} /* H5S_point_npoints() */
+
/*--------------------------------------------------------------------------
NAME
@@ -648,7 +285,7 @@ H5S_point_copy (H5S_t *dst, const H5S_t *src)
assert(dst);
/* Allocate room for the head of the point list */
- if((dst->select.sel_info.pnt_lst=H5MM_malloc(sizeof(H5S_pnt_list_t)))==NULL)
+ if((dst->select.sel_info.pnt_lst=H5FL_ALLOC(H5S_pnt_list_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
@@ -656,7 +293,7 @@ H5S_point_copy (H5S_t *dst, const H5S_t *src)
new_head=NULL;
while(curr!=NULL) {
/* Create each point */
- if((new_node=H5MM_malloc(sizeof(H5S_pnt_node_t)))==NULL)
+ if((new_node=H5FL_ALLOC(H5S_pnt_node_t,0))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
if((new_node->pnt = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL)
@@ -679,6 +316,7 @@ H5S_point_copy (H5S_t *dst, const H5S_t *src)
done:
FUNC_LEAVE (ret_value);
} /* end H5S_point_copy() */
+
/*--------------------------------------------------------------------------
NAME
@@ -730,6 +368,7 @@ H5S_point_select_valid (const H5S_t *space)
FUNC_LEAVE (ret_value);
} /* end H5S_point_select_valid() */
+
/*--------------------------------------------------------------------------
NAME
@@ -776,6 +415,7 @@ H5S_point_select_serial_size (const H5S_t *space)
FUNC_LEAVE (ret_value);
} /* end H5S_point_select_serial_size() */
+
/*--------------------------------------------------------------------------
NAME
@@ -845,6 +485,7 @@ H5S_point_select_serialize (const H5S_t *space, uint8_t *buf)
FUNC_LEAVE (ret_value);
} /* H5S_point_select_serialize() */
+
/*--------------------------------------------------------------------------
NAME
@@ -909,6 +550,7 @@ done:
FUNC_LEAVE (ret_value);
} /* H5S_point_select_deserialize() */
+
/*--------------------------------------------------------------------------
NAME
@@ -1134,13 +776,13 @@ herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem,
if(op==H5S_SELECT_SET) {
if(H5S_select_release(space)<0) {
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL,
- "can't release hyperslab");
+ "can't release point selection");
} /* end if */
} /* end if */
/* Allocate space for the point selection information if necessary */
if(space->select.type!=H5S_SEL_POINTS || space->select.sel_info.pnt_lst==NULL) {
- if((space->select.sel_info.pnt_lst = H5MM_calloc(sizeof(H5S_pnt_list_t)))==NULL)
+ if((space->select.sel_info.pnt_lst = H5FL_ALLOC(H5S_pnt_list_t,1))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate element information");
} /* end if */
@@ -1222,161 +864,141 @@ done:
/*--------------------------------------------------------------------------
NAME
- H5S_point_select_iterate
+ H5S_point_select_get_seq_list
PURPOSE
- Iterate over a point selection, calling a user's function for each
- element.
+ Create a list of offsets & lengths for a selection
USAGE
- herr_t H5S_point_select_iterate(buf, type_id, space, op, 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 op; 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
- QAK - 2002/4/5 - Wasn't using selection offset in calculation, corrected.
---------------------------------------------------------------------------*/
-herr_t
-H5S_point_select_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op,
- void *operator_data)
-{
- hsize_t mem_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
- hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /* Point offset */
- 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 */
- unsigned rank; /* Dataspace rank */
- H5T_t *dt; /* Datatype structure */
- unsigned u; /* Local index variable */
- herr_t ret_value=0; /* return value */
-
- FUNC_ENTER_NOAPI(H5S_point_select_iterate, 0);
-
- assert(buf);
- assert(space);
- assert(op);
- 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));
-
- /* Set the size of the datatype */
- if (NULL==(dt=H5I_object(type_id)))
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype");
- mem_size[rank]=H5T_get_size(dt);
-
- /* Iterate through the node, checking the bounds on each element */
- node=space->select.sel_info.pnt_lst->head;
- while(node!=NULL && ret_value==0) {
- /* Set up the location of the point */
- HDmemcpy(mem_offset, node->pnt, rank*sizeof(hssize_t));
- mem_offset[rank]=0;
-
- /* Add in the selection offset */
- for(u=0; u<rank; u++)
- mem_offset[u]+=space->select.offset[u];
-
- /* Get the offset in the memory buffer */
- offset=H5V_array_offset(rank+1,mem_size,(const hssize_t *)mem_offset);
- tmp_buf=((char *)buf+offset);
-
- ret_value=(*op)(tmp_buf,type_id,(hsize_t)rank,mem_offset,operator_data);
-
- node=node->next;
- } /* end while */
-
- FUNC_LEAVE (ret_value);
-} /* H5S_point_select_iterate() */
-
-
-/*--------------------------------------------------------------------------
- NAME
- H5S_point_select_fill
- PURPOSE
- Fill a point selection in memory with a value
- USAGE
- herr_t H5S_point_select_fill(fill,fill_size,space,buf)
- const void *fill; IN: Pointer to fill value to use
- size_t fill_size; IN: Size of elements in memory buffer & size of
- fill value
- H5S_t *space; IN: Dataspace describing memory buffer &
- containing selection to use.
- void *buf; IN/OUT: Memory buffer to fill selection in
+ herr_t H5S_point_select_get_seq_list(flags,space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len)
+ unsigned flags; IN: Flags for extra information about operation
+ 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.
+ size_t elem_size; IN: Size of an element
+ size_t maxseq; IN: Maximum number of sequences to generate
+ size_t maxbytes; IN: Maximum number of bytes to include in the
+ generated sequences
+ size_t *nseq; OUT: Actual number of sequences generated
+ size_t *nbytes; OUT: Actual number of bytes in sequences generated
+ hsize_t *off; OUT: Array of offsets
+ size_t *len; OUT: Array of lengths
RETURNS
Non-negative on success/Negative on failure.
DESCRIPTION
- Use the selection in the dataspace to fill elements in a memory buffer.
+ Use the selection in the dataspace to generate a list of byte offsets and
+ lengths for the region(s) selected. Start/Restart from the position in the
+ ITER parameter. The number of sequences generated is limited by the MAXSEQ
+ parameter and the number of sequences actually generated is stored in the
+ NSEQ parameter.
GLOBAL VARIABLES
COMMENTS, BUGS, ASSUMPTIONS
- The memory buffer elements are assumed to have the same datatype as the
- fill value being placed into them.
EXAMPLES
REVISION LOG
--------------------------------------------------------------------------*/
herr_t
-H5S_point_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf)
+H5S_point_select_get_seq_list(unsigned flags, 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)
{
- hsize_t size[H5O_LAYOUT_NDIMS]; /* Total size of memory buf */
- uint8_t *buf=(uint8_t *)_buf; /* Alias for memory buffer */
- hsize_t acc; /* Coordinate accumulator */
- hsize_t off; /* Coordinate offset */
+ hsize_t bytes_left; /* The number of bytes left in the selection */
+ hsize_t start_bytes_left; /* The initial number of bytes left in the selection */
H5S_pnt_node_t *node; /* Point node */
+ hsize_t dims[H5O_LAYOUT_NDIMS]; /* Total size of memory buf */
int ndims; /* Dimensionality of space*/
- int i; /* Index variable */
- herr_t ret_value=SUCCEED; /* return value */
+ hsize_t acc; /* Coordinate accumulator */
+ hsize_t loc; /* Coordinate offset */
+ size_t curr_seq; /* Current sequence being operated on */
+ int i; /* Local index variable */
+ herr_t ret_value=SUCCEED; /* return value */
- FUNC_ENTER_NOAPI(H5S_point_select_fill, FAIL);
+ FUNC_ENTER_NOAPI (H5S_point_select_get_seq_list, FAIL);
/* Check args */
- assert(fill);
- assert(fill_size>0);
assert(space);
- assert(buf);
+ assert(iter);
+ assert(elem_size>0);
+ assert(maxseq>0);
+ assert(maxbytes>0);
+ assert(nseq);
+ assert(nbytes);
+ assert(off);
+ assert(len);
- /* Fill the selection in the memory buffer */
+ /* "round" off the maxbytes allowed to a multiple of the element size */
+ maxbytes=(maxbytes/elem_size)*elem_size;
+
+ /* Choose the minimum number of bytes to sequence through */
+ start_bytes_left=bytes_left=MIN(iter->pnt.elmt_left*elem_size,maxbytes);
/* Get the dataspace dimensions */
- if ((ndims=H5S_get_simple_extent_dims (space, size, NULL))<0)
+ if ((ndims=H5S_get_simple_extent_dims (space, dims, NULL))<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to retrieve data space dimensions");
- /* Loop through all the points selected */
- node=space->select.sel_info.pnt_lst->head;
+ /* Walk through the points in the selection, starting at the current */
+ /* location in the iterator */
+ node=iter->pnt.curr;
+ curr_seq=0;
while(node!=NULL) {
/* Compute the offset of each selected point in the buffer */
- for(i=ndims-1,acc=fill_size,off=0; i>=0; i--) {
- off+=(node->pnt[i]+space->select.offset[i])*acc;
- acc*=size[i];
+ for(i=ndims-1,acc=elem_size,loc=0; i>=0; i--) {
+ loc+=(node->pnt[i]+space->select.offset[i])*acc;
+ acc*=dims[i];
} /* end for */
- /* Set the selected point to the fill value */
- HDmemcpy(buf+off,fill,fill_size);
+ /* Check if this is a later point in the selection */
+ if(curr_seq>0) {
+ /* If a sorted sequence is requested, make certain we don't go backwards in the offset */
+ if((flags&H5S_GET_SEQ_LIST_SORTED) && loc<off[curr_seq-1])
+ break;
+
+ /* Check if this point extends the previous sequence */
+ /* (Unlikely, but possible) */
+ if(loc==(off[curr_seq-1]+len[curr_seq-1])) {
+ /* Extend the previous sequence */
+ len[curr_seq-1]+=elem_size;
+ } /* end if */
+ else {
+ /* Add a new sequence */
+ off[curr_seq]=loc;
+ len[curr_seq]=elem_size;
+
+ /* Increment sequence count */
+ curr_seq++;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Add a new sequence */
+ off[curr_seq]=loc;
+ len[curr_seq]=elem_size;
+
+ /* Increment sequence count */
+ curr_seq++;
+ } /* end else */
+
+ /* Decrement number of bytes left to process */
+ bytes_left-=elem_size;
+
+ /* Move the iterator */
+ iter->pnt.curr=node->next;
+ iter->pnt.elmt_left--;
+
+ /* Check if we're finished with all sequences */
+ if(curr_seq==maxseq)
+ break;
+
+ /* Check if we're finished with all the bytes available */
+ if(bytes_left==0)
+ break;
/* Advance to the next point */
node=node->next;
} /* end while */
+ /* Set the number of sequences generated */
+ *nseq=curr_seq;
+
+ /* Set the number of bytes used */
+ *nbytes=(start_bytes_left-bytes_left);
+
done:
FUNC_LEAVE (ret_value);
-} /* H5S_point_select_fill() */
-
+} /* end H5S_point_select_get_seq_list() */