diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 1998-07-10 17:54:19 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 1998-07-10 17:54:19 (GMT) |
commit | b7f334adb4acec6ff0171b8dda6f9873d8c67bb5 (patch) | |
tree | 74e271bf28a0277206d4d438d9752fa50a6794a8 /src | |
parent | f87dbef4ca00da7bb9b89faf3d982156878c600d (diff) | |
download | hdf5-b7f334adb4acec6ff0171b8dda6f9873d8c67bb5.zip hdf5-b7f334adb4acec6ff0171b8dda6f9873d8c67bb5.tar.gz hdf5-b7f334adb4acec6ff0171b8dda6f9873d8c67bb5.tar.bz2 |
[svn-r480] Fixed an ugly bug by teaching the recursive hyperslab I/O code how to resume
when a buffer gets full. Also removed the check for disallowing zero-dim
extents on unlimited dimension datasets, per user's request.
Diffstat (limited to 'src')
-rw-r--r-- | src/H5D.c | 6 | ||||
-rw-r--r-- | src/H5S.c | 9 | ||||
-rw-r--r-- | src/H5Shyper.c | 178 | ||||
-rw-r--r-- | src/H5Spoint.c | 67 | ||||
-rw-r--r-- | src/H5Sprivate.h | 1 | ||||
-rw-r--r-- | src/H5Spublic.h | 2 | ||||
-rw-r--r-- | src/H5Sselect.c | 92 | ||||
-rw-r--r-- | src/H5public.h | 2 |
8 files changed, 284 insertions, 73 deletions
@@ -1420,8 +1420,7 @@ printf("%s: check 4.0, nelmts=%d, need_bkg=%d\n",FUNC,(int)nelmts,(int)need_bkg) /* Start strip mining... */ for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) { /* Go figure out how many elements to read from the file */ - smine_nelmts = (sconv_func.favail)(file_space,&file_iter, - MIN(request_nelmts,(nelmts-smine_start))); + smine_nelmts = (sconv_func.favail)(file_space,&file_iter, MIN(request_nelmts,(nelmts-smine_start))); #ifdef QAK printf("%s: check 5.0, nelmts=%d, smine_start=%d, smine_nelmts=%d\n",FUNC,(int)nelmts,(int)smine_start,(int)smine_nelmts); #endif /* QAK */ @@ -1745,8 +1744,7 @@ printf("%s: check 4.0, nelmts=%d, need_bkg=%d\n",FUNC,(int)nelmts,(int)need_bkg) /* Start strip mining... */ for (smine_start=0; smine_start<nelmts; smine_start+=smine_nelmts) { /* Go figure out how many elements to read from the file */ - smine_nelmts = (sconv_func.favail)(file_space,&file_iter, - MIN(request_nelmts,(nelmts-smine_start))); + smine_nelmts = (sconv_func.favail)(file_space,&file_iter, MIN(request_nelmts,(nelmts-smine_start))); #ifdef QAK printf("%s: check 5.0, nelmts=%d, smine_start=%d, smine_nelmts=%d\n",FUNC,(int)nelmts,(int)smine_start,(int)smine_nelmts); #endif /* QAK */ @@ -1048,15 +1048,6 @@ H5Sset_extent_simple (hid_t sid, int rank, const hsize_t *dims, if (rank<0) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank"); } - if (dims) { - for (u=0; u<rank; u++) { - if (((max!=NULL && max[u]!=H5S_UNLIMITED) || max==NULL) && - dims[u]==0) { - HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, - "invalid dimension size"); - } - } - } if (max!=NULL) { if(dims==NULL) { HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 757b21c..0c9371e 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -73,8 +73,10 @@ H5S_hyper_init (const struct H5O_layout_t __unused__ *layout, /* Initialize the number of points to iterate over */ sel_iter->hyp.elmt_left=space->select.num_elem; - /* Start at the origin of the array */ - sel_iter->hyp.pos = H5MM_calloc(space->extent.u.simple.rank*sizeof(hssize_t)); + /* Allocate the position & initialize to invalid location */ + sel_iter->hyp.pos = H5MM_malloc(space->extent.u.simple.rank*sizeof(hssize_t)); + sel_iter->hyp.pos[0]=(-1); + H5V_array_fill(sel_iter->hyp.pos,sel_iter->hyp.pos,sizeof(hssize_t),space->extent.u.simple.rank); FUNC_LEAVE (SUCCEED); } /* H5S_hyper_init() */ @@ -102,6 +104,9 @@ H5S_hyper_favail (const H5S_t __unused__ *space, const H5S_sel_iter_t *sel_iter, assert (space && H5S_SEL_HYPERSLABS==space->select.type); assert (sel_iter); +#ifdef QAK +printf("%s: max=%d\n",FUNC,(int)max); +#endif /* QAK */ FUNC_LEAVE (MIN(sel_iter->hyp.elmt_left,max)); } /* H5S_hyper_favail() */ @@ -142,6 +147,8 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count, #ifdef QAK printf("%s: check 1.0, dim=%d\n",FUNC,dim); +for(i=0; i<2; i++) + printf("%s: %d - pos=%d\n",FUNC,i,(int)pos[i]); #endif /* QAK */ /* Check if we need to generate a list of regions for the 0th dim. */ @@ -150,34 +157,37 @@ printf("%s: check 1.0, dim=%d\n",FUNC,dim); printf("%s: check 1.1, bound_count=%d\n",FUNC,bound_count); #endif /* QAK */ for(i=0; i<bound_count; i++) { - /* Check if we've allocated the array yet */ - if(num_reg==0) { - /* Allocate array */ - ret_value=H5MM_malloc(sizeof(H5S_hyper_region_t)); - - /* Initialize with first region */ - ret_value[0].start=lo_bounds[0][i].bound; - ret_value[0].end=hi_bounds[0][i].bound; - - /* Increment the number of regions */ - num_reg++; - } else { - /* Check if we should merge this region into the current region */ - if(lo_bounds[0][i].bound<ret_value[curr_reg].end) - ret_value[curr_reg].end=MAX(hi_bounds[0][i].bound,ret_value[curr_reg].end); - else { /* no overlap with previous region, add new region */ - /* Enlarge array */ - ret_value=H5MM_realloc(ret_value,sizeof(H5S_hyper_region_t)*(num_reg+1)); - - /* Initialize with new region */ - ret_value[num_reg].start=lo_bounds[0][i].bound; - ret_value[num_reg].end=hi_bounds[0][i].bound; - - /* Increment the number of regions & the current region */ + /* Skip past already iterated regions */ + if(pos[0]==(-1) || (pos[0]>=lo_bounds[0][i].bound && pos[0]<=hi_bounds[0][i].bound)) { + /* Check if we've allocated the array yet */ + if(num_reg==0) { + /* Allocate array */ + ret_value=H5MM_malloc(sizeof(H5S_hyper_region_t)); + + /* Initialize with first region */ + ret_value[0].start=MAX(lo_bounds[0][i].bound,pos[0]); + ret_value[0].end=hi_bounds[0][i].bound; + + /* Increment the number of regions */ num_reg++; - curr_reg++; + } else { + /* Check if we should merge this region into the current region */ + if(lo_bounds[0][i].bound<ret_value[curr_reg].end) + ret_value[curr_reg].end=MAX(hi_bounds[0][i].bound,ret_value[curr_reg].end); + else { /* no overlap with previous region, add new region */ + /* Enlarge array */ + ret_value=H5MM_realloc(ret_value,sizeof(H5S_hyper_region_t)*(num_reg+1)); + + /* Initialize with new region */ + ret_value[num_reg].start=lo_bounds[0][i].bound; + ret_value[num_reg].end=hi_bounds[0][i].bound; + + /* Increment the number of regions & the current region */ + num_reg++; + curr_reg++; + } /* end else */ } /* end else */ - } /* end else */ + } /* end if */ } /* end for */ } else { /* Generate list of regions based on the current position */ #ifdef QAK @@ -200,7 +210,7 @@ printf("%s: check 2.0, bound_count=%d\n",FUNC,bound_count); ret_value=H5MM_malloc(sizeof(H5S_hyper_region_t)); /* Initialize with first region */ - ret_value[0].start=lo_bounds[next_dim][i].bound; + ret_value[0].start=MAX(lo_bounds[next_dim][i].bound,pos[next_dim]); ret_value[0].end=hi_bounds[next_dim][i].bound; /* Increment the number of regions */ @@ -258,6 +268,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_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 */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ @@ -305,11 +316,12 @@ for(i=0; i<num_regions; i++) HDmemset (zero, 0, fhyper_info->layout->ndims*sizeof(*zero)); /* perform I/O on data from regions */ - for(i=0; i<num_regions; i++) { + for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { #ifdef QAK -printf("%s: check 2.1, i=%d\n",FUNC,(int)i); +printf("%s: check 2.2, i=%d\n",FUNC,(int)i); #endif /* QAK */ - hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1; + region_size=MIN(fhyper_info->nelmts,(regions[i].end-regions[i].start)+1); + hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size; file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; /* @@ -322,17 +334,28 @@ printf("%s: check 2.1, i=%d\n",FUNC,(int)i); HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } #ifdef QAK -printf("%s: check 2.2\n",FUNC); +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]); #endif /* QAK */ /* Advance the pointer in the buffer */ - fhyper_info->dst=((uint8 *)fhyper_info->dst)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size; + fhyper_info->dst=((uint8 *)fhyper_info->dst)+region_size*fhyper_info->elmt_size; /* Increment the number of elements read */ - num_read+=(regions[i].end-regions[i].start)+1; + num_read+=region_size; + + /* Decrement the buffer left */ + fhyper_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); + else + fhyper_info->iter->hyp.pos[dim+1]=regions[i].start+region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1; + fhyper_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ #ifdef QAK @@ -343,9 +366,9 @@ printf("%s: check 3.0, num_regions=%d\n",FUNC,(int)num_regions); dim++; /* Step through each region in this dimension */ - for(i=0; i<num_regions; i++) { + for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; j<=regions[i].end; j++) { + for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) { #ifdef QAK printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j); #endif /* QAK */ @@ -483,6 +506,7 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_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 */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ @@ -521,8 +545,9 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) HDmemset (zero, 0, fhyper_info->layout->ndims*sizeof(*zero)); /* perform I/O on data from regions */ - for(i=0; i<num_regions; i++) { - hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1; + 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; file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start; /* @@ -536,13 +561,22 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info) } /* Advance the pointer in the buffer */ - fhyper_info->src=((const uint8 *)fhyper_info->src)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size; + fhyper_info->src=((const uint8 *)fhyper_info->src)+region_size*fhyper_info->elmt_size; /* Increment the number of elements read */ - num_written+=(regions[i].end-regions[i].start)+1; + num_written+=region_size; + + /* Decrement the buffer left */ + fhyper_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); + else + fhyper_info->iter->hyp.pos[dim+1]=regions[i].start+region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1; + fhyper_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ @@ -550,9 +584,9 @@ 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; i++) { + for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; j<=regions[i].end; j++) { + for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) { /* Set the correct position we are working on */ fhyper_info->iter->hyp.pos[dim]=j; @@ -679,6 +713,7 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_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 */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ @@ -731,11 +766,12 @@ for(i=0; i<num_regions; i++) HDmemset (zero, 0, (fhyper_info->space->extent.u.simple.rank+1)*sizeof(*zero)); /* perform I/O on data from regions */ - for(i=0; i<num_regions; i++) { + for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { #ifdef QAK printf("%s: check 2.1, i=%d\n",FUNC,(int)i); #endif /* QAK */ - hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1; + 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; /* @@ -748,13 +784,22 @@ printf("%s: check 2.1, i=%d\n",FUNC,(int)i); } /* Advance the pointer in the buffer */ - fhyper_info->dst=((uint8 *)fhyper_info->dst)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size; + fhyper_info->dst=((uint8 *)fhyper_info->dst)+region_size*fhyper_info->elmt_size; /* Increment the number of elements read */ - num_read+=(regions[i].end-regions[i].start)+1; + num_read+=region_size; + + /* Decrement the buffer left */ + fhyper_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); + else + fhyper_info->iter->hyp.pos[dim+1]=regions[i].start+region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1; + fhyper_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ #ifdef QAK @@ -765,9 +810,9 @@ printf("%s: check 3.0, num_regions=%d\n",FUNC,(int)num_regions); dim++; /* Step through each region in this dimension */ - for(i=0; i<num_regions; i++) { + for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; j<=regions[i].end; j++) { + for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) { #ifdef QAK printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j); #endif /* QAK */ @@ -913,6 +958,7 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_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 */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */ size_t num_regions; /* number of regions overlapped */ @@ -966,8 +1012,9 @@ for(i=0; i<num_regions; i++) printf("%s: check 3.0\n",FUNC); #endif /* QAK */ /* perform I/O on data from regions */ - for(i=0; i<num_regions; i++) { - hsize[fhyper_info->space->extent.u.simple.rank-1]=(regions[i].end-regions[i].start)+1; + 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; /* @@ -980,13 +1027,22 @@ printf("%s: check 3.0\n",FUNC); } /* Advance the pointer in the buffer */ - fhyper_info->src=((const uint8 *)fhyper_info->src)+((regions[i].end-regions[i].start)+1)*fhyper_info->elmt_size; + fhyper_info->src=((const uint8 *)fhyper_info->src)+region_size*fhyper_info->elmt_size; /* Increment the number of elements read */ - num_read+=(regions[i].end-regions[i].start)+1; + num_read+=region_size; + + /* Decrement the buffer left */ + fhyper_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); + else + fhyper_info->iter->hyp.pos[dim+1]=regions[i].start+region_size; /* Decrement the iterator count */ - fhyper_info->iter->hyp.elmt_left-=(regions[i].end-regions[i].start)+1; + fhyper_info->iter->hyp.elmt_left-=region_size; } /* end for */ } else { /* recurse on each region to next dimension down */ @@ -994,9 +1050,9 @@ printf("%s: check 3.0\n",FUNC); dim++; /* Step through each region in this dimension */ - for(i=0; i<num_regions; i++) { + for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) { /* Step through each location in each region */ - for(j=regions[i].start; j<=regions[i].end; j++) { + for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) { /* Set the correct position we are working on */ fhyper_info->iter->hyp.pos[dim]=j; @@ -1013,6 +1069,7 @@ printf("%s: check 3.0\n",FUNC); FUNC_LEAVE (num_read); } /* H5S_hyper_mwrite() */ + /*------------------------------------------------------------------------- * Function: H5S_hyper_mscat * @@ -1214,6 +1271,9 @@ printf("%s: check 2.0\n",FUNC); #endif /* QAK */ /* Set boundary on new node */ for(i=0,elem_count=1; i<space->extent.u.simple.rank; i++) { +#ifdef QAK +printf("%s: check 2.1, %d: start=%d, size=%d, elem_count=%d\n",FUNC,(int)i,(int)start[i],(int)size[i],(int)elem_count); +#endif /* QAK */ slab->start[i]=start[i]; slab->end[i]=start[i]+size[i]-1; elem_count*=size[i]; diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 1472489..3864293 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -9,6 +9,7 @@ */ #include <H5private.h> #include <H5Eprivate.h> +#include <H5MMprivate.h> #include <H5Sprivate.h> #include <H5Vprivate.h> @@ -51,6 +52,72 @@ H5S_point_init (const struct H5O_layout_t __unused__ *layout, FUNC_LEAVE (SUCCEED); } +/*-------------------------------------------------------------------------- + NAME + H5S_point_add + PURPOSE + Add a series of elements to a point selection + USAGE + herr_t H5S_point_add(space, num_elem, coord) + H5S_t *space; IN: Dataspace of selection to modify + size_t num_elem; IN: Number of elements in COORD array. + const hssize_t *coord[]; IN: The location of each element selected + RETURNS + SUCCEED/FAIL + DESCRIPTION + This function adds elements to the current point selection for a dataspace + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5S_point_add (H5S_t *space, size_t num_elem, const hssize_t *coord[]) +{ + H5S_pnt_node_t *top, *curr, *new; /* Point selection nodes */ + uintn i; /* Counter */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5S_point_add, FAIL); + + assert(space); + assert(num_elem>0); + assert(coord); + + top=curr=NULL; + for(i=0; i<num_elem; i++) { + /* Allocate space for the new node */ + if((new = H5MM_malloc(sizeof(H5S_pnt_node_t)))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "can't allocate point node"); + if((new->pnt = H5MM_malloc(space->extent.u.simple.rank*sizeof(hssize_t)))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "can't allocate coordinate information"); + + /* Copy over the coordinates */ + HDmemcpy(new->pnt,coord[i],(space->extent.u.simple.rank*sizeof(hssize_t))); + + /* Link into list */ + new->next=NULL; + if(top==NULL) + top=new; + else + curr->next=new; + curr=new; + } /* end for */ + + /* Append current list, if there is one */ + if(space->select.sel_info.pnt_lst->head!=NULL) + curr->next=space->select.sel_info.pnt_lst->head; + + /* Put new list in point selection */ + space->select.sel_info.pnt_lst->head=top; + + ret_value=SUCCEED; + +done: + FUNC_LEAVE (ret_value); +} /* H5S_point_add() */ + /*------------------------------------------------------------------------- * Function: H5S_point_favail * diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 8aaee07..c31d746 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -281,6 +281,7 @@ size_t H5S_point_mgath (const void *_buf, size_t elmt_size, herr_t H5S_point_mscat (const void *_tconv_buf, size_t elmt_size, const H5S_t *mem_space, H5S_sel_iter_t *mem_iter, size_t nelmts, void *_buf/*out*/); +herr_t H5S_point_add (H5S_t *space, size_t num_elemn, const hssize_t *coord[]); herr_t H5S_point_release (H5S_t *space); hsize_t H5S_point_npoints (const H5S_t *space); diff --git a/src/H5Spublic.h b/src/H5Spublic.h index 3a1b437..d3d75b6 100644 --- a/src/H5Spublic.h +++ b/src/H5Spublic.h @@ -57,6 +57,8 @@ hsize_t H5Sselect_npoints (hid_t spaceid); herr_t H5Sselect_hyperslab (hid_t spaceid, H5S_seloper_t op, const hssize_t *start, const hsize_t *_stride, const hsize_t *count, const hsize_t *_block); +herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elemn, + const hssize_t *coord[]); #ifdef __cplusplus } diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 8c45deb..83e6b38 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -311,6 +311,98 @@ done: /*-------------------------------------------------------------------------- NAME + H5Sselect_elements + PURPOSE + Specify a series of elements in the dataspace to select + USAGE + herr_t H5Sselect_elements(dsid, op, num_elem, coord) + hid_t dsid; IN: Dataspace ID of selection to modify + H5S_seloper_t op; IN: Operation to perform on current selection + size_t num_elem; IN: Number of elements in COORD array. + const hssize_t *coord[]; IN: The location of each element selected + RETURNS + SUCCEED/FAIL + DESCRIPTION + This function selects array elements to be included in the selection for + the dataspace. The COORD array is a 2-D array of size <dataspace rank> + by NUM_ELEM (ie. a list of coordinates in the dataspace). The order of + the element coordinates in the COORD array specifies the order that the + array elements are iterated through when I/O is performed. Duplicate + coordinates are not checked for. The selection operator, OP, determines + how the new selection is to be combined with the existing selection for + the dataspace. Currently, only H5S_SELECT_SET is supported, which replaces + the existing selection with the one defined in this call. When operators + other than H5S_SELECT_SET are used to combine a new selection with an + existing selection, the selection ordering is reset to 'C' array ordering. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +herr_t H5Sselect_elements (hid_t spaceid, H5S_seloper_t op, size_t num_elem, + const hssize_t *coord[]) +{ + H5S_t *space = NULL; /* Dataspace to modify selection of */ + herr_t ret_value=FAIL; /* return value */ + + FUNC_ENTER (H5Sselect_elements, FAIL); + + /* Check args */ + if (H5_DATASPACE != H5I_group(spaceid) || + NULL == (space=H5I_object(spaceid))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space"); + } + if(coord==NULL || num_elem==0) { + HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "elements not specified"); + } /* end if */ + if(op!=H5S_SELECT_SET) { + HRETURN_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, + "operations other than H5S_SELECT_SET not supported currently"); + } /* end if */ + +#ifdef QAK +printf("%s: check 1.0\n",FUNC); +#endif /* QAK */ + /* If we are setting a new selection, remove current selection first */ + if(op==H5S_SELECT_SET) { + if(H5S_select_release(space)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, + "can't release hyperslab"); + } /* end if */ + } /* end if */ + +#ifdef QAK +printf("%s: check 2.0\n",FUNC); +#endif /* QAK */ + /* 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) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "can't allocate element information"); + } /* end if */ + +#ifdef QAK +printf("%s: check 3.0\n",FUNC); +#endif /* QAK */ + /* Add points to selection */ + if(H5S_point_add(space,num_elem,coord)<0) { + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, + "can't insert elements"); + } + + /* Set selection type */ + space->select.type=H5S_SEL_POINTS; + ret_value=SUCCEED; +#ifdef QAK +printf("%s: check 4.0\n",FUNC); +#endif /* QAK */ + +done: + FUNC_LEAVE (ret_value); +} /* H5Sselect_elements() */ + +/*-------------------------------------------------------------------------- + NAME H5Sselect_npoints PURPOSE Get the number of elements in current selection diff --git a/src/H5public.h b/src/H5public.h index d14b3e0..67b5b45 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -27,7 +27,7 @@ /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface changes */ #define H5_VERS_MINOR 0 /* For minor interface changes */ -#define H5_VERS_RELEASE 9 /* For interface tweaks & bug-fixes */ +#define H5_VERS_RELEASE 11 /* For interface tweaks & bug-fixes */ #define H5_VERS_PATCH 0 /* For small groups of bug fixes */ #define H5check() H5vers_check(H5_VERS_MAJOR,H5_VERS_MINOR,\ |