diff options
Diffstat (limited to 'src/H5Spoint.c')
-rw-r--r-- | src/H5Spoint.c | 644 |
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() */ |