From d9ccc0e0f5edf32e0b70355f4cf2cfb583a12482 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 22 Apr 2004 15:21:44 -0500 Subject: [svn-r8408] Purpose: Code optimization Description: Instead of dynamicly allocating various arrays for various pieces of information about a selection or selection iterator, just use fixed size array of size H5S_MAX_RANK (as the rest of the library does). Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.9 (sleipnir) h5committest --- src/H5S.c | 13 +- src/H5Shyper.c | 356 +++++++++++++++++-------------------------------------- src/H5Spkg.h | 17 +-- src/H5Sprivate.h | 20 +++- src/H5Sselect.c | 12 +- 5 files changed, 143 insertions(+), 275 deletions(-) diff --git a/src/H5S.c b/src/H5S.c index e0c73ea..3a7ec60 100644 --- a/src/H5S.c +++ b/src/H5S.c @@ -645,12 +645,15 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src) FUNC_ENTER_NOAPI(H5S_extent_copy, FAIL); /* Copy the regular fields */ - *dst=*src; + dst->type=src->type; + dst->nelem=src->nelem; + dst->u.simple.rank=src->u.simple.rank; switch (src->type) { case H5S_NULL: case H5S_SCALAR: - /*nothing needed */ + dst->u.simple.size=NULL; + dst->u.simple.max=NULL; break; case H5S_SIMPLE: @@ -659,11 +662,15 @@ H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src) for (u = 0; u < src->u.simple.rank; u++) dst->u.simple.size[u] = src->u.simple.size[u]; } + else + dst->u.simple.size=NULL; if (src->u.simple.max) { dst->u.simple.max = H5FL_ARR_MALLOC(hsize_t,src->u.simple.rank); for (u = 0; u < src->u.simple.rank; u++) dst->u.simple.max[u] = src->u.simple.max[u]; } + else + dst->u.simple.max=NULL; break; case H5S_COMPLEX: @@ -708,8 +715,10 @@ H5S_copy(const H5S_t *src) if (NULL==(dst = H5FL_MALLOC(H5S_t))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); +#ifdef LATER /* Copy the field in the struct */ *dst = *src; +#endif /* LATER */ /* Copy the source dataspace's extent */ if (H5S_extent_copy(&(dst->extent),&(src->extent))<0) diff --git a/src/H5Shyper.c b/src/H5Shyper.c index 60d1269..de4529f 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -71,21 +71,9 @@ static const hsize_t _block[H5O_LAYOUT_NDIMS]={ /* Default block size ar /* Declare a free list to manage the H5S_hyper_span_t struct */ H5FL_DEFINE_STATIC(H5S_hyper_span_t); -/* Declare a free list to manage arrays of H5S_hyper_span_t */ -H5FL_ARR_DEFINE_STATIC(H5S_hyper_span_t,H5S_MAX_RANK); - /* Declare a free list to manage the H5S_hyper_span_info_t struct */ H5FL_DEFINE_STATIC(H5S_hyper_span_info_t); -/* Declare external the free list for hssize_t arrays */ -H5FL_ARR_EXTERN(hssize_t); - -/* Declare a free list to manage arrays of hsize_t */ -H5FL_ARR_EXTERN(hsize_t); - -/* Declare a free list to manage arrays of H5S_hyper_dim_t */ -H5FL_ARR_DEFINE_STATIC(H5S_hyper_dim_t,H5S_MAX_RANK); - /* #define H5S_HYPER_DEBUG */ #ifdef H5S_HYPER_DEBUG static herr_t @@ -160,7 +148,7 @@ H5S_hyper_print_diminfo(FILE *f, const H5S_t *space) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5S_hyper_print_diminfo); - H5S_hyper_print_diminfo_helper(f,"diminfo",space->extent.u.simple.rank,space->select.sel_info.hslab.diminfo); + H5S_hyper_print_diminfo_helper(f,"diminfo",space->extent.u.simple.rank,space->select.sel_info.hslab.opt_diminfo); H5S_hyper_print_diminfo_helper(f,"app_diminfo",space->extent.u.simple.rank,space->select.sel_info.hslab.app_diminfo); FUNC_LEAVE_NOAPI(SUCCEED); @@ -212,10 +200,10 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size) rank=space->extent.u.simple.rank; /* Set the temporary pointer to the dimension information */ - tdiminfo=space->select.sel_info.hslab.diminfo; + tdiminfo=space->select.sel_info.hslab.opt_diminfo; /* Check for the special case of just one H5Sselect_hyperslab call made */ - if(tdiminfo!=NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { /* Initialize the information needed for regular hyperslab I/O */ const hsize_t *mem_size; /* Temporary pointer to dataspace extent's dimension sizes */ hsize_t acc; /* Accumulator for "flattened" dimension's sizes */ @@ -251,16 +239,6 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size) /* Set the iterator's rank to the contiguous dimensions */ iter->u.hyp.iter_rank=flat_rank; - /* Allocate the position & initialize to initial location */ - iter->u.hyp.off = H5FL_ARR_MALLOC(hsize_t,flat_rank); - assert(iter->u.hyp.off); - iter->u.hyp.diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,flat_rank); - assert(iter->u.hyp.diminfo); - iter->u.hyp.size = H5FL_ARR_MALLOC(hsize_t,flat_rank); - assert(iter->u.hyp.size); - iter->u.hyp.sel_off = H5FL_ARR_MALLOC(hssize_t,flat_rank); - assert(iter->u.hyp.sel_off); - /* "Flatten" dataspace extent and selection information */ curr_dim=flat_rank-1; for(i=rank-1, acc=1; i>=0; i--) { @@ -312,14 +290,6 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size) iter->u.hyp.off[u]=iter->u.hyp.diminfo[u].start; } /* end if */ else { - /* Allocate the position & initialize to initial location */ - iter->u.hyp.off = H5FL_ARR_MALLOC(hsize_t,rank); - assert(iter->u.hyp.off); - - /* Allocate the storage for the regular selection information */ - iter->u.hyp.diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,rank); - assert(iter->u.hyp.diminfo); - /* Initialize position to initial location */ /* Also make local copy of the regular selection information */ for(u=0; uu.hyp.off[u]=tdiminfo[u].start; } /* end if */ - - /* Initialize other regular region information also (for release) */ - iter->u.hyp.size = NULL; - iter->u.hyp.sel_off = NULL; } /* end else */ + /* Flag the diminfo information as valid in the iterator */ + iter->u.hyp.diminfo_valid=TRUE; + /* Initialize irregular region information also (for release) */ iter->u.hyp.spans=NULL; - iter->u.hyp.span=NULL; } /* end if */ else { /* Initialize the information needed for non-regular hyperslab I/O */ @@ -350,12 +318,6 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size) /* Set the nelem & pstride values according to the element size */ H5S_hyper_span_precompute(iter->u.hyp.spans,elmt_size); - /* Allocate the span tree pointers, span pointers and positions */ - iter->u.hyp.span = H5FL_ARR_MALLOC(H5S_hyper_span_t,rank); - assert(iter->u.hyp.span); - iter->u.hyp.off = H5FL_ARR_MALLOC(hsize_t,rank); - assert(iter->u.hyp.off); - /* Initialize the starting span_info's and spans */ spans=iter->u.hyp.spans; for(u=0; uhead->down; } /* end for */ - /* Initialize regular region information also (for release) */ - iter->u.hyp.diminfo = NULL; - iter->u.hyp.size = NULL; - iter->u.hyp.sel_off = NULL; + /* Flag the diminfo information as not valid in the iterator */ + iter->u.hyp.diminfo_valid=FALSE; + } /* end else */ /* Initialize methods for selection iterator */ @@ -420,7 +381,7 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords) /* Copy the offset of the current point */ /* Check for a single "regular" hyperslab */ - if(iter->u.hyp.diminfo!=NULL) { + if(iter->u.hyp.diminfo_valid) { /* Check if this is a "flattened" regular hyperslab selection */ if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rankrank) { unsigned flat_dim; /* The rank of the flattened dimension */ @@ -478,7 +439,7 @@ H5S_hyper_iter_block (const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end /* Copy the offset of the current point */ /* Check for a single "regular" hyperslab */ - if(iter->u.hyp.diminfo!=NULL) { + if(iter->u.hyp.diminfo_valid) { /* Copy the current iterator offset as the start */ HDmemcpy(start,iter->u.hyp.off,sizeof(hssize_t)*iter->rank); @@ -555,7 +516,7 @@ H5S_hyper_iter_has_next_block(const H5S_sel_iter_t *iter) assert (iter); /* Check for a single "regular" hyperslab */ - if(iter->u.hyp.diminfo!=NULL) { + if(iter->u.hyp.diminfo_valid) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ const hssize_t *toff; /* Temporary offset in selection */ @@ -612,7 +573,7 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) /* Check for the special case of just one H5Sselect_hyperslab call made */ /* (i.e. a regular hyperslab selection */ - if(iter->u.hyp.diminfo!=NULL) { + if(iter->u.hyp.diminfo_valid) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ hsize_t iter_offset[H5O_LAYOUT_NDIMS]; hsize_t iter_count[H5O_LAYOUT_NDIMS]; @@ -827,7 +788,7 @@ H5S_hyper_iter_next_block(H5S_sel_iter_t *iter) /* Check for the special case of just one H5Sselect_hyperslab call made */ /* (i.e. a regular hyperslab selection */ - if(iter->u.hyp.diminfo!=NULL) { + if(iter->u.hyp.diminfo_valid) { const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ hsize_t iter_offset[H5O_LAYOUT_NDIMS]; hsize_t iter_count[H5O_LAYOUT_NDIMS]; @@ -1010,32 +971,11 @@ H5S_hyper_iter_release (H5S_sel_iter_t *iter) /* Check args */ assert (iter); - /* Release the common array of offsets/positions */ - if(iter->u.hyp.off!=NULL) - H5FL_ARR_FREE(hsize_t,iter->u.hyp.off); - -/* Release the information needed for "flattened" regular hyperslab I/O */ - /* Free the "flattened" dataspace extent */ - if(iter->u.hyp.size!=NULL) - H5FL_ARR_FREE(hsize_t,iter->u.hyp.size); - - /* Free the "flattened" regular hyperslab selection */ - if(iter->u.hyp.diminfo!=NULL) - H5FL_ARR_FREE(H5S_hyper_dim_t,iter->u.hyp.diminfo); - - /* Free the "flattened" selection offset */ - if(iter->u.hyp.sel_off!=NULL) - H5FL_ARR_FREE(hssize_t,iter->u.hyp.sel_off); - /* Release the information needed for non-regular hyperslab I/O */ /* Free the copy of the selections span tree */ if(iter->u.hyp.spans!=NULL) H5S_hyper_free_span_info(iter->u.hyp.spans); - /* Release the array of pointers to span nodes */ - if(iter->u.hyp.span!=NULL) - H5FL_ARR_FREE(H5S_hyper_span_t,iter->u.hyp.span); - FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_hyper_iter_release() */ @@ -1626,8 +1566,6 @@ done: herr_t H5S_hyper_copy (H5S_t *dst, const H5S_t *src) { - H5S_hyper_dim_t *new_diminfo=NULL; /* New per-dimension info array[rank] */ - unsigned u; /* Counters */ herr_t ret_value=SUCCEED; /* return value */ FUNC_ENTER_NOAPI(H5S_hyper_copy, FAIL); @@ -1635,40 +1573,8 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src) assert(src); assert(dst); - /* Check if there is regular hyperslab information to copy */ - if(src->select.sel_info.hslab.diminfo!=NULL) { - /* Create the per-dimension selection info */ - if((new_diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array"); - - /* Copy the per-dimension selection info */ - for(u=0; uextent.u.simple.rank; u++) { - new_diminfo[u].start = src->select.sel_info.hslab.diminfo[u].start; - new_diminfo[u].stride = src->select.sel_info.hslab.diminfo[u].stride; - new_diminfo[u].count = src->select.sel_info.hslab.diminfo[u].count; - new_diminfo[u].block = src->select.sel_info.hslab.diminfo[u].block; - } /* end for */ - dst->select.sel_info.hslab.diminfo = new_diminfo; - - /* Create the per-dimension selection info */ - if((new_diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,src->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension array"); - - /* Copy the per-dimension selection info */ - for(u=0; uextent.u.simple.rank; u++) { - new_diminfo[u].start = src->select.sel_info.hslab.app_diminfo[u].start; - new_diminfo[u].stride = src->select.sel_info.hslab.app_diminfo[u].stride; - new_diminfo[u].count = src->select.sel_info.hslab.app_diminfo[u].count; - new_diminfo[u].block = src->select.sel_info.hslab.app_diminfo[u].block; - } /* end for */ - dst->select.sel_info.hslab.app_diminfo = new_diminfo; - } /* end if */ - else { - dst->select.sel_info.hslab.diminfo = new_diminfo; - dst->select.sel_info.hslab.app_diminfo = new_diminfo; - } /* end else */ - /* Check if there is hyperslab span information to copy */ + /* (Regular hyperslab information is copied with the selection structure) */ if(src->select.sel_info.hslab.span_lst!=NULL) { /* Copy the hyperslab span information */ dst->select.sel_info.hslab.span_lst=H5S_hyper_copy_span(src->select.sel_info.hslab.span_lst); @@ -1776,8 +1682,8 @@ H5S_hyper_is_valid (const H5S_t *space) assert(space); /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab.diminfo != NULL) { - const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab.diminfo; /* local alias for diminfo */ + if(space->select.sel_info.hslab.diminfo_valid) { + const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab.opt_diminfo; /* local alias for diminfo */ hssize_t end; /* The high bound of a region in a dimension */ /* Check each dimension */ @@ -1889,7 +1795,7 @@ H5S_get_select_hyper_nblocks(H5S_t *space) assert(space); /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab.diminfo != NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { /* Check each dimension */ for(ret_value=1,u=0; uextent.u.simple.rank; u++) ret_value*=space->select.sel_info.hslab.app_diminfo[u].count; @@ -1977,10 +1883,10 @@ H5S_hyper_serial_size (const H5S_t *space) ret_value=24; /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab.diminfo != NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { /* Check each dimension */ for(block_count=1,u=0; uextent.u.simple.rank; u++) - block_count*=space->select.sel_info.hslab.diminfo[u].count; + block_count*=space->select.sel_info.hslab.opt_diminfo[u].count; ret_value+=8*block_count*space->extent.u.simple.rank; } /* end if */ else { @@ -2094,7 +2000,7 @@ done: herr_t H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) { - H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ + const H5S_hyper_dim_t *diminfo; /* Alias for dataspace's diminfo information */ hsize_t tmp_count[H5O_LAYOUT_NDIMS]; /* Temporary hyperslab counts */ hssize_t offset[H5O_LAYOUT_NDIMS]; /* Offset of element in dataspace */ hssize_t start[H5O_LAYOUT_NDIMS]; /* Location of start of hyperslab */ @@ -2126,11 +2032,11 @@ H5S_hyper_serialize (const H5S_t *space, uint8_t *buf) len+=4; /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab.diminfo != NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { /* Set some convienence values */ ndims=space->extent.u.simple.rank; fast_dim=ndims-1; - diminfo=space->select.sel_info.hslab.diminfo; + diminfo=space->select.sel_info.hslab.opt_diminfo; /* Check each dimension */ for(block_count=1,i=0; iselect.sel_info.hslab.diminfo != NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { /* Set some convienence values */ ndims=space->extent.u.simple.rank; fast_dim=ndims-1; @@ -2499,7 +2386,7 @@ H5S_get_select_hyper_blocklist(H5S_t *space, hbool_t internal, hsize_t startbloc * Use the "optimized dimension information" to pass back information * on the blocks set, not the "application information". */ - diminfo=space->select.sel_info.hslab.diminfo; + diminfo=space->select.sel_info.hslab.opt_diminfo; else /* * Use the "application dimension information" to pass back to the user @@ -2759,8 +2646,8 @@ H5S_hyper_bounds(const H5S_t *space, hssize_t *start, hssize_t *end) } /* end for */ /* Check for a "regular" hyperslab selection */ - if(space->select.sel_info.hslab.diminfo!=NULL) { - const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab.diminfo; /* local alias for diminfo */ + if(space->select.sel_info.hslab.diminfo_valid) { + const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab.opt_diminfo; /* local alias for diminfo */ /* Check each dimension */ for(i=0; iselect.sel_info.hslab.diminfo != NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { + const H5S_hyper_dim_t *diminfo=space->select.sel_info.hslab.opt_diminfo; /* local alias for diminfo */ + /* * For a regular hyperslab to be contiguous, it must have only one * block (i.e. count==1 in all dimensions) and the block size must be @@ -2834,11 +2723,11 @@ H5S_hyper_is_contiguous(const H5S_t *space) /* Check for a "large contigous" block */ for(u=0; uextent.u.simple.rank; u++) { - if(space->select.sel_info.hslab.diminfo[u].count>1) { + if(diminfo[u].count>1) { large_contiguous=FALSE; break; } /* end if */ - if(u>0 && space->select.sel_info.hslab.diminfo[u].block!=space->extent.u.simple.size[u]) { + if(u>0 && diminfo[u].block!=space->extent.u.simple.size[u]) { large_contiguous=FALSE; break; } /* end if */ @@ -2848,11 +2737,11 @@ H5S_hyper_is_contiguous(const H5S_t *space) if(large_contiguous==FALSE) { small_contiguous=TRUE; for(u=0; uextent.u.simple.rank; u++) { - if(space->select.sel_info.hslab.diminfo[u].count>1) { + if(diminfo[u].count>1) { small_contiguous=FALSE; break; } /* end if */ - if(u<(space->extent.u.simple.rank-1) && space->select.sel_info.hslab.diminfo[u].block!=1) { + if(u<(space->extent.u.simple.rank-1) && diminfo[u].block!=1) { small_contiguous=FALSE; break; } /* end if */ @@ -2995,7 +2884,7 @@ H5S_hyper_is_single(const H5S_t *space) assert(space); /* Check for a "single" hyperslab selection */ - if(space->select.sel_info.hslab.diminfo != NULL) { + if(space->select.sel_info.hslab.diminfo_valid) { /* * For a regular hyperslab to be single, it must have only one * block (i.e. count==1 in all dimensions) @@ -3006,7 +2895,7 @@ H5S_hyper_is_single(const H5S_t *space) /* Check for a single block */ for(u=0; uextent.u.simple.rank; u++) { - if(space->select.sel_info.hslab.diminfo[u].count>1) { + if(space->select.sel_info.hslab.opt_diminfo[u].count>1) { ret_value=FALSE; break; } /* end if */ @@ -3074,7 +2963,7 @@ H5S_hyper_is_regular(const H5S_t *space) assert(space); /* Only simple check for regular hyperslabs for now... */ - if(space->select.sel_info.hslab.diminfo != NULL) + if(space->select.sel_info.hslab.diminfo_valid) ret_value=TRUE; else ret_value=FALSE; @@ -3119,13 +3008,8 @@ H5S_hyper_release (H5S_t *space) /* Reset the number of points selected */ space->select.num_elem=0; - /* Release the regular selection info */ - if(space->select.sel_info.hslab.diminfo!=NULL) { - H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo); - space->select.sel_info.hslab.diminfo = NULL; - H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.app_diminfo); - space->select.sel_info.hslab.app_diminfo = NULL; - } /* end if */ + /* Reset the regular selection info flag */ + space->select.sel_info.hslab.diminfo_valid=FALSE; /* Release irregular hyperslab information */ if(space->select.sel_info.hslab.span_lst!=NULL) { @@ -3498,9 +3382,8 @@ H5S_hyper_add_span_element(H5S_t *space, unsigned rank, hssize_t *coords) /* Set selection type */ space->select.type=H5S_SEL_HYPERSLABS; - /* Reset "regular" hyperslab fields */ - space->select.sel_info.hslab.diminfo = NULL; - space->select.sel_info.hslab.app_diminfo = NULL; + /* Reset "regular" hyperslab flag */ + space->select.sel_info.hslab.diminfo_valid=FALSE; /* Set selection methods */ space->select.get_seq_list=H5S_hyper_get_seq_list; @@ -3968,10 +3851,10 @@ H5S_hyper_adjust(H5S_t *space, const hssize_t *offset) assert(offset); /* Subtract the offset from the "regular" coordinates, if they exist */ - if(space->select.sel_info.hslab.diminfo) { + if(space->select.sel_info.hslab.diminfo_valid) { for(u=0; uextent.u.simple.rank; u++) { - space->select.sel_info.hslab.diminfo[u].start-=offset[u]; - assert(space->select.sel_info.hslab.diminfo[u].start>=0); + space->select.sel_info.hslab.opt_diminfo[u].start-=offset[u]; + assert(space->select.sel_info.hslab.opt_diminfo[u].start>=0); } /* end for */ } /* end if */ @@ -4083,10 +3966,10 @@ H5S_hyper_move(H5S_t *space, const hssize_t *offset) assert(offset); /* Move to the offset with the "regular" coordinates, if they exist */ - if(space->select.sel_info.hslab.diminfo) { + if(space->select.sel_info.hslab.diminfo_valid) { for(u=0; uextent.u.simple.rank; u++) { - space->select.sel_info.hslab.diminfo[u].start=offset[u]; - assert(space->select.sel_info.hslab.diminfo[u].start>=0); + space->select.sel_info.hslab.opt_diminfo[u].start=offset[u]; + assert(space->select.sel_info.hslab.opt_diminfo[u].start>=0); } /* end for */ } /* end if */ @@ -5385,16 +5268,10 @@ H5S_hyper_rebuild (H5S_t *space) /* Protect against empty tree */ if(span!=NULL) { - /* Allocate space for the optimized hyperslab information */ - if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); - - /* Allocate space for the optimized hyperslab information */ - if((app_diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); - /* Iterate down the span tree */ curr_dim=0; + diminfo=space->select.sel_info.hslab.opt_diminfo; + app_diminfo=space->select.sel_info.hslab.app_diminfo; while(span!=NULL) { /* Sanity check */ assert(curr_dimextent.u.simple.rank); @@ -5415,9 +5292,8 @@ H5S_hyper_rebuild (H5S_t *space) break; } /* end while */ - /* Set the dataspace's pointers to the new optimized information */ - space->select.sel_info.hslab.diminfo = diminfo; - space->select.sel_info.hslab.app_diminfo = app_diminfo; + /* Indicate that the diminfo is valid */ + space->select.sel_info.hslab.diminfo_valid=TRUE; } /* end if */ done: @@ -5824,24 +5700,17 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if((*space->select.release)(space)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab"); - /* Copy all the application per-dimension selection info into the space descriptor */ - if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); + /* Save the diminfo */ + diminfo=space->select.sel_info.hslab.opt_diminfo; for(u=0; uextent.u.simple.rank; u++) { - diminfo[u].start = start[u]; - diminfo[u].stride = stride[u]; - diminfo[u].count = count[u]; - diminfo[u].block = block[u]; - } /* end for */ - space->select.sel_info.hslab.app_diminfo = diminfo; + space->select.sel_info.hslab.app_diminfo[u].start = start[u]; + space->select.sel_info.hslab.app_diminfo[u].stride = stride[u]; + space->select.sel_info.hslab.app_diminfo[u].count = count[u]; + space->select.sel_info.hslab.app_diminfo[u].block = block[u]; - /* Allocate room for the optimized per-dimension selection info */ - if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); + /* Optimize the hyperslab selection to detect contiguously selected block/stride information */ + /* Modify the stride, block & count for contiguous hyperslab selections */ - /* Optimize the hyperslab selection to detect contiguously selected block/stride information */ - /* Modify the stride, block & count for contiguous hyperslab selections */ - for(u=0; uextent.u.simple.rank; u++) { /* Starting location doesn't get optimized */ diminfo[u].start = start[u]; @@ -5862,7 +5731,9 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, diminfo[u].block=block[u]; } /* end else */ } /* end for */ - space->select.sel_info.hslab.diminfo = diminfo; + + /* Indicate that the dimension information is valid */ + space->select.sel_info.hslab.diminfo_valid=TRUE; /* Build the hyperslab information also */ if(H5S_generate_hyperslab (space, H5S_SELECT_SET, start, stride, count, block)<0) @@ -5872,16 +5743,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Sanity check */ assert(space->select.type==H5S_SEL_HYPERSLABS); - /* Is this the first operation? */ - if(space->select.sel_info.hslab.diminfo != NULL) { - /* Remove the 'diminfo' information, since we're adding to it */ - H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo); - space->select.sel_info.hslab.diminfo = NULL; - - /* Remove the 'app_diminfo' information also, since we're adding to it */ - H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.app_diminfo); - space->select.sel_info.hslab.app_diminfo = NULL; - } /* end if */ + /* Indicate that the regular dimensions are no longer valid */ + space->select.sel_info.hslab.diminfo_valid=FALSE; /* Add in the new hyperslab information */ if(H5S_generate_hyperslab (space, op, start, stride, count, block)<0) @@ -6015,10 +5878,6 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper assert(spans2); assert(op>H5S_SELECT_NOOP && opselect.release)(result)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release result selection"); - /* Just copy the selection from spans2 if we are setting the selection */ /* ('space1' to 'result' aliasing happens at the next layer up) */ if(op==H5S_SELECT_SET) { @@ -6271,9 +6130,16 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't create hyperslab information"); /* Copy the original dataspace */ - if(space->select.sel_info.hslab.span_lst!=NULL) - if (NULL==(tmp_spans=H5S_hyper_copy_span(space->select.sel_info.hslab.span_lst))) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy data space"); + if(space->select.sel_info.hslab.span_lst!=NULL) { + /* Take ownership of the dataspace's hyperslab spans */ + /* (These are freed later) */ + tmp_spans=space->select.sel_info.hslab.span_lst; + space->select.sel_info.hslab.span_lst=NULL; + + /* Reset the other dataspace selection information */ + if((*space->select.release)(space)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection"); + } /* end if */ /* Combine tmp_space (really space) & new_space, with the result in space */ if(H5S_operate_hyperslab(space,tmp_spans,op,new_spans,TRUE,&span2_owned)<0) @@ -6431,24 +6297,21 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if((*space->select.release)(space)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release hyperslab"); - /* Copy all the application per-dimension selection info into the space descriptor */ - if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); + /* Build the hyperslab information also */ + if(H5S_generate_hyperslab (space, H5S_SELECT_SET, start, stride, count, block)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs"); + + /* Save the diminfo */ + diminfo=space->select.sel_info.hslab.opt_diminfo; for(u=0; uextent.u.simple.rank; u++) { - diminfo[u].start = start[u]; - diminfo[u].stride = stride[u]; - diminfo[u].count = count[u]; - diminfo[u].block = block[u]; - } /* end for */ - space->select.sel_info.hslab.app_diminfo = diminfo; + space->select.sel_info.hslab.app_diminfo[u].start = start[u]; + space->select.sel_info.hslab.app_diminfo[u].stride = stride[u]; + space->select.sel_info.hslab.app_diminfo[u].count = count[u]; + space->select.sel_info.hslab.app_diminfo[u].block = block[u]; - /* Allocate room for the optimized per-dimension selection info */ - if((diminfo = H5FL_ARR_MALLOC(H5S_hyper_dim_t,space->extent.u.simple.rank))==NULL) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate per-dimension vector"); + /* Optimize the hyperslab selection to detect contiguously selected block/stride information */ + /* Modify the stride, block & count for contiguous hyperslab selections */ - /* Optimize the hyperslab selection to detect contiguously selected block/stride information */ - /* Modify the stride, block & count for contiguous hyperslab selections */ - for(u=0; uextent.u.simple.rank; u++) { /* Starting location doesn't get optimized */ diminfo[u].start = start[u]; @@ -6469,30 +6332,20 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, diminfo[u].block=block[u]; } /* end else */ } /* end for */ - space->select.sel_info.hslab.diminfo = diminfo; - /* Build the hyperslab information also */ - if(H5S_generate_hyperslab (space, H5S_SELECT_SET, start, stride, count, block)<0) - HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs"); + /* Indicate that the dimension information is valid */ + space->select.sel_info.hslab.diminfo_valid=TRUE; } /* end if */ else if(op>=H5S_SELECT_OR && op<=H5S_SELECT_NOTA) { /* Sanity check */ assert(space->select.type==H5S_SEL_HYPERSLABS); - /* Is this the first 'or' operation? */ - if(space->select.sel_info.hslab.diminfo != NULL) { - /* Remove the 'diminfo' information, since we're adding to it */ - H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.diminfo); - space->select.sel_info.hslab.diminfo = NULL; - - /* Remove the 'app_diminfo' information also, since we're adding to it */ - H5FL_ARR_FREE(H5S_hyper_dim_t,space->select.sel_info.hslab.app_diminfo); - space->select.sel_info.hslab.app_diminfo = NULL; - } /* end if */ - /* Add in the new hyperslab information */ if(H5S_generate_hyperslab (space, op, start, stride, count, block)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINSERT, FAIL, "can't generate hyperslabs"); + + /* Indicate that the regular dimensions are no longer valid */ + space->select.sel_info.hslab.diminfo_valid=FALSE; } /* end if */ else HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation"); @@ -6675,6 +6528,10 @@ H5S_combine_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) if (NULL==(new_space=H5S_copy (space1))) HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to copy data space"); + /* Free the current selection for the new dataspace */ + if((*new_space->select.release)(new_space)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, NULL, "can't release selection"); + /* Combine space1 & space2, with the result in new_space */ if(H5S_operate_hyperslab(new_space,space1->select.sel_info.hslab.span_lst,op,space2->select.sel_info.hslab.span_lst,FALSE,&span2_owned)<0) HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, NULL, "can't clip hyperslab information"); @@ -6783,9 +6640,14 @@ H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2) assert(space2); assert(op>H5S_SELECT_NOOP && opselect.sel_info.hslab.span_lst))) - HGOTO_ERROR (H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy data space"); + /* Take ownership of the dataspace's hyperslab spans */ + /* (These are freed later) */ + tmp_spans=space1->select.sel_info.hslab.span_lst; + space1->select.sel_info.hslab.span_lst=NULL; + + /* Reset the other dataspace selection information */ + if((*space1->select.release)(space1)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't release selection"); /* Combine tmp_spans (from space1) & spans from space2, with the result in space1 */ if(H5S_operate_hyperslab(space1,tmp_spans,op,space2->select.sel_info.hslab.span_lst,FALSE,&span2_owned)<0) @@ -7823,7 +7685,7 @@ H5S_hyper_get_seq_list(const H5S_t *space, unsigned UNUSED flags, H5S_sel_iter_t assert(len); /* Check for the special case of just one H5Sselect_hyperslab call made */ - if(space->select.sel_info.hslab.diminfo!=NULL) + if(space->select.sel_info.hslab.diminfo_valid) /* Use optimized call to generate sequence list */ ret_value=H5S_hyper_get_seq_list_opt(space,iter,elem_size,maxseq,maxbytes,nseq,nbytes,off,len); else diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 8eb2682..3053dd8 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -98,22 +98,11 @@ struct H5S_hyper_span_info_t { struct H5S_hyper_span_t *head; /* Pointer to list of spans in next dimension down */ }; -/* Information about one dimension in a hyperslab selection */ -struct H5S_hyper_dim_t { - hssize_t start; - hsize_t stride; - hsize_t count; - hsize_t block; -}; - /* Information about new-style hyperslab selection */ typedef struct { - H5S_hyper_dim_t *diminfo; /* ->[rank] of per-dim selection info */ - /* diminfo only points to one array, which holds the information - * for one hyperslab selection. Perhaps this might need to be - * expanded into a list of arrays when the H5Sselect_hyperslab's - * restriction to H5S_SELECT_SET is removed. */ - H5S_hyper_dim_t *app_diminfo;/* ->[rank] of per-dim selection info */ + hbool_t diminfo_valid; /* Whether the dataset has valid diminfo */ + H5S_hyper_dim_t opt_diminfo[H5S_MAX_RANK]; /* per-dim selection info */ + H5S_hyper_dim_t app_diminfo[H5S_MAX_RANK]; /* per-dim selection info */ /* 'diminfo' points to a [potentially] optimized version of the user's * hyperslab information. 'app_diminfo' points to the actual parameters * that the application used for setting the hyperslab selection. These diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 94510b2..d350738 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -42,7 +42,14 @@ typedef struct H5S_t H5S_t; typedef struct H5S_pnt_node_t H5S_pnt_node_t; typedef struct H5S_hyper_span_t H5S_hyper_span_t; typedef struct H5S_hyper_span_info_t H5S_hyper_span_info_t; -typedef struct H5S_hyper_dim_t H5S_hyper_dim_t; + +/* Information about one dimension in a hyperslab selection */ +typedef struct H5S_hyper_dim_t { + hssize_t start; + hsize_t stride; + hsize_t count; + hsize_t block; +} H5S_hyper_dim_t; /* Point selection iteration container */ typedef struct { @@ -52,22 +59,23 @@ typedef struct { /* Hyperslab selection iteration container */ typedef struct { /* Common fields for all hyperslab selections */ - hssize_t *off; /* Offset in span node (used as position for regular hyperslabs) */ + hssize_t off[H5S_MAX_RANK]; /* Offset in span node (used as position for regular hyperslabs) */ unsigned iter_rank; /* Rank of iterator information */ /* (This should always be the same as the dataspace * rank, except for regular hyperslab selections in * which there are contiguous regions in the lower * dimensions which have been "flattened" out */ + hbool_t diminfo_valid; /* Whether the dimension information is valid */ /* "Flattened" regular hyperslab selection fields */ - H5S_hyper_dim_t *diminfo; /* "Flattened" regular selection information */ - hsize_t *size; /* "Flattened" dataspace extent information */ - hssize_t *sel_off; /* "Flattened" selection offset information */ + H5S_hyper_dim_t diminfo[H5S_MAX_RANK]; /* "Flattened" regular selection information */ + hsize_t size[H5S_MAX_RANK]; /* "Flattened" dataspace extent information */ + hssize_t sel_off[H5S_MAX_RANK]; /* "Flattened" selection offset information */ /* Irregular hyperslab selection fields */ H5S_hyper_span_info_t *spans; /* Pointer to copy of the span tree */ - H5S_hyper_span_t **span;/* Array of pointers to span nodes */ + H5S_hyper_span_t *span[H5S_MAX_RANK];/* Array of pointers to span nodes */ } H5S_hyper_iter_t; /* "All" selection iteration container */ diff --git a/src/H5Sselect.c b/src/H5Sselect.c index eeea8c7..3904730 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -130,7 +130,7 @@ H5S_select_copy (H5S_t *dst, const H5S_t *src) assert(src); /* Copy regular fields */ - dst->select=src->select; + HDmemcpy(&dst->select,&src->select,sizeof(H5S_select_t)); /* Need to copy order information still */ @@ -1114,16 +1114,16 @@ HDfprintf(stderr,"%s: Entering\n",FUNC); else if(space1->select.type==H5S_SEL_NONE || space2->select.type==H5S_SEL_NONE) { HGOTO_DONE(TRUE); } /* end if */ - else if((space1->select.type==H5S_SEL_HYPERSLABS && space1->select.sel_info.hslab.diminfo) - && (space2->select.type==H5S_SEL_HYPERSLABS && space2->select.sel_info.hslab.diminfo)) { + else if((space1->select.type==H5S_SEL_HYPERSLABS && space1->select.sel_info.hslab.diminfo_valid) + && (space2->select.type==H5S_SEL_HYPERSLABS && space2->select.sel_info.hslab.diminfo_valid)) { /* Check that the shapes are the same */ for (u=0; uextent.u.simple.rank; u++) { - if(space1->select.sel_info.hslab.diminfo[u].stride!=space2->select.sel_info.hslab.diminfo[u].stride) + if(space1->select.sel_info.hslab.opt_diminfo[u].stride!=space2->select.sel_info.hslab.opt_diminfo[u].stride) HGOTO_DONE(FALSE); - if(space1->select.sel_info.hslab.diminfo[u].count!=space2->select.sel_info.hslab.diminfo[u].count) + if(space1->select.sel_info.hslab.opt_diminfo[u].count!=space2->select.sel_info.hslab.opt_diminfo[u].count) HGOTO_DONE(FALSE); - if(space1->select.sel_info.hslab.diminfo[u].block!=space2->select.sel_info.hslab.diminfo[u].block) + if(space1->select.sel_info.hslab.opt_diminfo[u].block!=space2->select.sel_info.hslab.opt_diminfo[u].block) HGOTO_DONE(FALSE); } /* end for */ } /* end if */ -- cgit v0.12