diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Sall.c | 158 | ||||
-rw-r--r-- | src/H5Shyper.c | 601 | ||||
-rw-r--r-- | src/H5Snone.c | 147 | ||||
-rw-r--r-- | src/H5Spkg.h | 33 | ||||
-rw-r--r-- | src/H5Spoint.c | 164 | ||||
-rw-r--r-- | src/H5Sprivate.h | 13 |
6 files changed, 957 insertions, 159 deletions
diff --git a/src/H5Sall.c b/src/H5Sall.c index 08dc8d3..ea6d6b1 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -27,11 +27,22 @@ #include "H5Spkg.h" /* Dataspace functions */ #include "H5Vprivate.h" /* Vector functions */ -/* Interface initialization */ +/* Pablo mask */ #define PABLO_MASK H5Sall_mask + +/* Interface initialization */ #define INTERFACE_INIT NULL static int interface_initialize_g = 0; +/* Static function prototypes */ +static herr_t H5S_all_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); +static herr_t H5S_all_iter_block(const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end); +static hsize_t H5S_all_iter_nelmts(const H5S_sel_iter_t *iter); +static htri_t H5S_all_iter_has_next_block(const H5S_sel_iter_t *iter); +static herr_t H5S_all_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +static herr_t H5S_all_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S_all_iter_release(H5S_sel_iter_t *sel_iter); + /*------------------------------------------------------------------------- * Function: H5S_all_iter_init @@ -66,8 +77,11 @@ H5S_all_iter_init (H5S_sel_iter_t *iter, const H5S_t *space, size_t UNUSED elmt_ /* Initialize methods for selection iterator */ iter->iter_coords=H5S_all_iter_coords; + iter->iter_block=H5S_all_iter_block; iter->iter_nelmts=H5S_all_iter_nelmts; + iter->iter_has_next_block=H5S_all_iter_has_next_block; iter->iter_next=H5S_all_iter_next; + iter->iter_next_block=H5S_all_iter_next_block; iter->iter_release=H5S_all_iter_release; done: @@ -90,12 +104,12 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5S_all_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords) { herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5S_all_iter_coords, FAIL); + FUNC_ENTER_NOINIT(H5S_all_iter_coords); /* Check args */ assert (iter); @@ -111,6 +125,46 @@ done: /*------------------------------------------------------------------------- + * Function: H5S_all_iter_block + * + * Purpose: Retrieve the current block of iterator for current + * selection + * + * Return: non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Monday, June 2, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S_all_iter_block (const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end) +{ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOINIT(H5S_all_iter_block); + + /* Check args */ + assert (iter); + assert (start); + assert (end); + + /* Get the start of the 'all' block */ + /* (Always '0' coordinates for now) */ + HDmemset(start,0,sizeof(hssize_t)*iter->rank); + + /* Compute the end of the 'all' block */ + /* (Always size of the extent for now) */ + for(u=0; u<iter->rank; u++) + end[u]=iter->dims[u]-1; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5S_all_iter_coords() */ + + +/*------------------------------------------------------------------------- * Function: H5S_all_iter_nelmts * * Purpose: Return number of elements left to process in iterator @@ -124,21 +178,15 @@ done: * *------------------------------------------------------------------------- */ -hsize_t +static hsize_t H5S_all_iter_nelmts (const H5S_sel_iter_t *iter) { - hsize_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_all_iter_nelmts, 0); + FUNC_ENTER_NOINIT(H5S_all_iter_nelmts); /* Check args */ assert (iter); - /* Set return value */ - ret_value=iter->elmt_left; - -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(iter->elmt_left); } /* H5S_all_iter_nelmts() */ @@ -146,6 +194,35 @@ done: NAME H5S_all_iter_next PURPOSE + Check if there is another block left in the current iterator + USAGE + htri_t H5S_all_iter_has_next_block(iter) + const H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative (TRUE/FALSE) on success/Negative on failure + DESCRIPTION + Check if there is another block available in the selection iterator. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S_all_iter_has_next_block (const H5S_sel_iter_t UNUSED *iter) +{ + FUNC_ENTER_NOINIT(H5S_all_iter_has_next_block); + + /* Check args */ + assert (iter); + + FUNC_LEAVE_NOAPI(FALSE); +} /* H5S_all_iter_has_next_block() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_all_iter_next + PURPOSE Increment selection iterator USAGE herr_t H5S_all_iter_next(iter, nelem) @@ -160,12 +237,10 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_all_iter_next(H5S_sel_iter_t *iter, size_t nelem) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_all_iter_next, FAIL); + FUNC_ENTER_NOINIT(H5S_all_iter_next); /* Check args */ assert (iter); @@ -174,13 +249,41 @@ H5S_all_iter_next(H5S_sel_iter_t *iter, size_t nelem) /* Increment the iterator */ iter->u.all.offset+=nelem; -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_all_iter_next() */ /*-------------------------------------------------------------------------- NAME + H5S_all_iter_next_block + PURPOSE + Increment selection iterator to next block + USAGE + herr_t H5S_all_iter_next_block(iter) + H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Advance selection iterator to the next block in the selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_all_iter_next_block(H5S_sel_iter_t UNUSED *iter) +{ + FUNC_ENTER_NOINIT(H5S_all_iter_next_block); + + /* Check args */ + assert (iter); + + FUNC_LEAVE_NOAPI(FAIL); +} /* H5S_all_iter_next_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_all_iter_release PURPOSE Release "all" selection iterator information for a dataspace @@ -196,18 +299,15 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_all_iter_release (H5S_sel_iter_t UNUSED * iter) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_all_iter_release, FAIL); + FUNC_ENTER_NOINIT(H5S_all_iter_release); /* Check args */ assert (iter); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_all_iter_release() */ @@ -436,10 +536,10 @@ done: PURPOSE Gets the bounding box containing the selection. USAGE - herr_t H5S_all_bounds(space, hsize_t *start, hsize_t *end) + herr_t H5S_all_bounds(space, start, end) H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t *start; OUT: Starting coordinate of bounding box - hsize_t *end; OUT: Opposite coordinate of bounding box + hssize_t *start; OUT: Starting coordinate of bounding box + hssize_t *end; OUT: Opposite coordinate of bounding box RETURNS Non-negative on success, negative on failure DESCRIPTION @@ -456,7 +556,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) +H5S_all_bounds(const H5S_t *space, hssize_t *start, hssize_t *end) { int rank; /* Dataspace rank */ int i; /* index variable */ @@ -474,7 +574,7 @@ H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) /* Just copy over the complete extent */ for(i=0; i<rank; i++) { start[i]=0; - end[i]=space->extent.u.simple.size[i]-1; + H5_ASSIGN_OVERFLOW(end[i],space->extent.u.simple.size[i]-1,hsize_t,hssize_t); } /* end for */ done: diff --git a/src/H5Shyper.c b/src/H5Shyper.c index e62dc4f..06cb6ae 100644 --- a/src/H5Shyper.c +++ b/src/H5Shyper.c @@ -28,8 +28,10 @@ #include "H5Spkg.h" /* Dataspace functions */ #include "H5Vprivate.h" /* Vector functions */ -/* Interface initialization */ +/* Pablo mask */ #define PABLO_MASK H5Shyper_mask + +/* Interface initialization */ #define INTERFACE_INIT NULL static int interface_initialize_g = 0; @@ -45,6 +47,13 @@ static herr_t H5S_hyper_span_precompute (H5S_hyper_span_info_t *spans, size_t el #ifdef NEW_HYPERSLAB_API static herr_t H5S_select_select (H5S_t *space1, H5S_seloper_t op, H5S_t *space2); #endif /*NEW_HYPERSLAB_API*/ +static herr_t H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); +static herr_t H5S_hyper_iter_block(const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end); +static hsize_t H5S_hyper_iter_nelmts(const H5S_sel_iter_t *iter); +static htri_t H5S_hyper_iter_has_next_block(const H5S_sel_iter_t *sel_iter); +static herr_t H5S_hyper_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +static herr_t H5S_hyper_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S_hyper_iter_release(H5S_sel_iter_t *sel_iter); /* Declare a free list to manage the H5S_hyper_span_t struct */ H5FL_DEFINE_STATIC(H5S_hyper_span_t); @@ -111,6 +120,11 @@ H5S_hyper_print_spans(const struct H5S_hyper_span_info_t *span_lst) * Programmer: Quincey Koziol * Saturday, February 24, 2001 * + * Notes: If the 'elmt_size' parameter is set to zero, the regular + * hyperslab selection iterator will not be 'flattened'. This + * is used by the H5S_select_shape_same() code to avoid changing + * the rank and appearance of the selection. + * * Modifications: * *------------------------------------------------------------------------- @@ -162,13 +176,18 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size) /* Initialize the number of contiguous dimensions to be the same as the dataspace's rank */ cont_dim=rank; - /* Check for a "contiguous" block */ - for(u=rank-1; u>0; u--) { - if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u]) - cont_dim=u; - else - break; - } /* end for */ + /* Don't flatten adjacent elements into contiguous block if the + * element size is 0. This is for the H5S_select_shape_same() code. + */ + if(elmt_size>0) { + /* Check for a "contiguous" block */ + for(u=rank-1; u>0; u--) { + if(tdiminfo[u].count==1 && tdiminfo[u].block==mem_size[u]) + cont_dim=u; + else + break; + } /* end for */ + } /* end if */ /* Check if the regular selection can be "flattened" */ if(cont_dim<rank) { @@ -289,8 +308,11 @@ H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size) /* Initialize methods for selection iterator */ iter->iter_coords=H5S_hyper_iter_coords; + iter->iter_block=H5S_hyper_iter_block; iter->iter_nelmts=H5S_hyper_iter_nelmts; + iter->iter_has_next_block=H5S_hyper_iter_has_next_block; iter->iter_next=H5S_hyper_iter_next; + iter->iter_next_block=H5S_hyper_iter_next_block; iter->iter_release=H5S_hyper_iter_release; done: @@ -313,12 +335,10 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_hyper_iter_coords, FAIL); + FUNC_ENTER_NOINIT(H5S_hyper_iter_coords); /* Check args */ assert (iter); @@ -348,12 +368,66 @@ H5S_hyper_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords) else HDmemcpy(coords,iter->u.hyp.off,sizeof(hssize_t)*iter->rank); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_hyper_iter_coords() */ /*------------------------------------------------------------------------- + * Function: H5S_hyper_iter_block + * + * Purpose: Retrieve the current block of iterator for current + * selection + * + * Return: non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Monday, June 2, 2003 + * + * Notes: This routine assumes that the iterator is always located at + * the beginning of a block. + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S_hyper_iter_block (const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end) +{ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOINIT(H5S_hyper_iter_block); + + /* Check args */ + assert (iter); + assert (start); + assert (end); + + /* Copy the offset of the current point */ + + /* Check for a single "regular" hyperslab */ + if(iter->u.hyp.diminfo!=NULL) { + /* Copy the current iterator offset as the start */ + HDmemcpy(start,iter->u.hyp.off,sizeof(hssize_t)*iter->rank); + + /* Compute the end of the block */ + for(u=0; u<iter->rank; u++) + end[u]=(start[u]+iter->u.hyp.diminfo[u].block)-1; + } /* end if */ + else { + /* Copy the start of the block */ + for(u=0; u<iter->rank; u++) + start[u]=iter->u.hyp.span[u]->low; + + /* Copy the end of the block */ + for(u=0; u<iter->rank; u++) + end[u]=iter->u.hyp.span[u]->high; + } /* end else */ + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5S_hyper_iter_block() */ + + +/*------------------------------------------------------------------------- * Function: H5S_hyper_iter_nelmts * * Purpose: Return number of elements left to process in iterator @@ -367,22 +441,73 @@ done: * *------------------------------------------------------------------------- */ -hsize_t +static hsize_t H5S_hyper_iter_nelmts (const H5S_sel_iter_t *iter) { - hsize_t ret_value; /* Return value */ + FUNC_ENTER_NOINIT(H5S_hyper_iter_nelmts); + + /* Check args */ + assert (iter); + + FUNC_LEAVE_NOAPI(iter->elmt_left); +} /* H5S_hyper_iter_nelmts() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_iter_has_next_block + PURPOSE + Check if there is another block left in the current iterator + USAGE + htri_t H5S_hyper_iter_has_next_block(iter) + const H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative (TRUE/FALSE) on success/Negative on failure + DESCRIPTION + Check if there is another block available in the selection iterator. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S_hyper_iter_has_next_block(const H5S_sel_iter_t *iter) +{ + unsigned u; /* Local index variable */ + herr_t ret_value=FALSE; /* Return value */ - FUNC_ENTER_NOAPI(H5S_hyper_iter_nelmts, 0); + FUNC_ENTER_NOINIT(H5S_hyper_iter_has_next_block); /* Check args */ assert (iter); - /* Set return value */ - ret_value=iter->elmt_left; + /* Check for a single "regular" hyperslab */ + if(iter->u.hyp.diminfo!=NULL) { + const H5S_hyper_dim_t *tdiminfo; /* Temporary pointer to diminfo information */ + const hssize_t *toff; /* Temporary offset in selection */ + + /* Check if the offset of the iterator is at the last location in all dimensions */ + tdiminfo=iter->u.hyp.diminfo; + toff=iter->u.hyp.off; + for(u=0; u<iter->rank; u++) { + /* If there is only one block, continue */ + if(tdiminfo[u].count==1) + continue; + H5_CHECK_OVERFLOW(tdiminfo[u].start+((tdiminfo[u].count-1)*tdiminfo[u].stride),hsize_t,hssize_t); + if(toff[u]!=(hssize_t)(tdiminfo[u].start+((tdiminfo[u].count-1)*tdiminfo[u].stride))) + HGOTO_DONE(TRUE); + } /* end for */ + } /* end if */ + else { + /* Check for any levels of the tree with more sequences in them */ + for(u=0; u<iter->rank; u++) + if(iter->u.hyp.span[u]->next!=NULL) + HGOTO_DONE(TRUE); + } /* end else */ done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5S_hyper_iter_nelmts() */ +} /* H5S_hyper_iter_has_next_block() */ /*------------------------------------------------------------------------- @@ -403,7 +528,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) { unsigned ndims; /* Number of dimensions of dataset */ @@ -602,6 +727,191 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) } /* H5S_hyper_iter_next() */ +/*------------------------------------------------------------------------- + * Function: H5S_hyper_iter_next_block + * + * Purpose: Moves a hyperslab iterator to the beginning of the next sequence + * of elements to read. Handles walking off the end in all dimensions. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Quincey Koziol + * Tuesday, June 3, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S_hyper_iter_next_block(H5S_sel_iter_t *iter) +{ + unsigned ndims; /* Number of dimensions of dataset */ + int fast_dim; /* Rank of the fastest changing dimension for the dataspace */ + unsigned u; /* Counters */ + + FUNC_ENTER_NOINIT(H5S_hyper_iter_next_block); + + /* Check for the special case of just one H5Sselect_hyperslab call made */ + /* (i.e. a regular hyperslab selection */ + if(iter->u.hyp.diminfo!=NULL) { + 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]; + int temp_dim; /* Temporary rank holder */ + + /* Check if this is a "flattened" regular hyperslab selection */ + if(iter->u.hyp.iter_rank!=0 && iter->u.hyp.iter_rank<iter->rank) { + /* Set the aliases for the dimension rank */ + ndims=iter->u.hyp.iter_rank; + } /* end if */ + else { + /* Set the aliases for the dimension rank */ + ndims=iter->rank; + } /* end else */ + + /* Set the fastest dimension rank */ + fast_dim=ndims-1; + + /* Set the local copy of the diminfo pointer */ + tdiminfo=iter->u.hyp.diminfo; + + /* Calculate the offset and block count for each dimension */ + for(u=0; u<ndims; u++) { + if(tdiminfo[u].stride==1) { + iter_offset[u]=iter->u.hyp.off[u]-tdiminfo[u].start; + iter_count[u]=0; + } /* end if */ + else { + iter_offset[u]=(iter->u.hyp.off[u]-tdiminfo[u].start)%tdiminfo[u].stride; + iter_count[u]=(iter->u.hyp.off[u]-tdiminfo[u].start)/tdiminfo[u].stride; + } /* end else */ + } /* end for */ + + /* Advance one block */ + temp_dim=fast_dim; /* Start with the fastest changing dimension */ + while(temp_dim>=0) { + if(temp_dim==fast_dim) { + /* Move iterator over current block */ + iter_offset[temp_dim]+=tdiminfo[temp_dim].block; + } /* end if */ + else { + /* Move to the next row in the current dimension */ + iter_offset[temp_dim]++; + } /* end else */ + + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(iter_offset[temp_dim]<tdiminfo[temp_dim].block) + break; + else { + /* Move to the next block in the current dimension */ + iter_offset[temp_dim]=0; + iter_count[temp_dim]++; + + /* If this block is still in the range of blocks to output for the dimension, break out of loop */ + if(iter_count[temp_dim]<tdiminfo[temp_dim].count) + break; + else + iter_count[temp_dim]=0; /* reset back to the beginning of the line */ + } /* end else */ + + /* Decrement dimension count */ + temp_dim--; + } /* end while */ + + /* Translate current iter_offset and iter_count into iterator position */ + for(u=0; u<ndims; u++) + iter->u.hyp.off[u]=tdiminfo[u].start+(tdiminfo[u].stride*iter_count[u])+iter_offset[u]; + } /* end if */ + /* Must be an irregular hyperslab selection */ + else { + H5S_hyper_span_t *curr_span; /* Current hyperslab span node */ + H5S_hyper_span_t **ispan; /* Iterator's hyperslab span nodes */ + hssize_t *abs_arr; /* Absolute hyperslab span position */ + int curr_dim; /* Temporary rank holder */ + + /* Set the rank of the fastest changing dimension */ + ndims=iter->rank; + fast_dim=(ndims-1); + + /* Get the pointers to the current span info and span nodes */ + abs_arr=iter->u.hyp.off; + ispan=iter->u.hyp.span; + + /* Loop through, advancing the span information, until all the nelements are accounted for */ + curr_dim=fast_dim; /* Start at the fastest dim */ + + /* Work back up through the dimensions */ + while(curr_dim>=0) { + /* Reset the current span */ + curr_span=ispan[curr_dim]; + + /* Increment absolute position */ + if(curr_dim==fast_dim) { + /* Move the iterator over rest of element in span */ + abs_arr[curr_dim]=curr_span->high+1; + } /* end if */ + else { + /* Move to the next row in the current dimension */ + abs_arr[curr_dim]++; + } /* end else */ + + /* Check if we are still within the span */ + if(abs_arr[curr_dim]<=curr_span->high) { + break; + } /* end if */ + /* If we walked off that span, advance to the next span */ + else { + /* Advance span in this dimension */ + curr_span=curr_span->next; + + /* Check if we have a valid span in this dimension still */ + if(curr_span!=NULL) { + /* Reset the span in the current dimension */ + ispan[curr_dim]=curr_span; + + /* Reset absolute position */ + abs_arr[curr_dim]=curr_span->low; + + break; + } /* end if */ + else { + /* If we finished the span list in this dimension, decrement the dimension worked on and loop again */ + curr_dim--; + } /* end else */ + } /* end else */ + } /* end while */ + + /* Check if we are finished with the spans in the tree */ + if(curr_dim>=0) { + /* Walk back down the iterator positions, reseting them */ + while(curr_dim<fast_dim) { + assert(curr_span); + assert(curr_span->down); + assert(curr_span->down->head); + + /* Increment current dimension */ + curr_dim++; + + /* Set the new span_info & span for this dimension */ + ispan[curr_dim]=curr_span->down->head; + + /* Advance span down the tree */ + curr_span=curr_span->down->head; + + /* Reset the absolute offset for the dim */ + abs_arr[curr_dim]=curr_span->low; + } /* end while */ + + /* Verify that the curr_span points to the fastest dim */ + assert(curr_span==ispan[fast_dim]); + } /* end if */ + } /* end else */ + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5S_hyper_iter_next() */ + + /*-------------------------------------------------------------------------- NAME H5S_hyper_iter_release @@ -619,12 +929,10 @@ H5S_hyper_iter_next(H5S_sel_iter_t *iter, size_t nelem) EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_hyper_iter_release (H5S_sel_iter_t *iter) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_hyper_iter_release, FAIL); + FUNC_ENTER_NOINIT(H5S_hyper_iter_release); /* Check args */ assert (iter); @@ -655,8 +963,7 @@ H5S_hyper_iter_release (H5S_sel_iter_t *iter) if(iter->u.hyp.span!=NULL) H5FL_ARR_FREE(H5S_hyper_span_t,iter->u.hyp.span); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_hyper_iter_release() */ @@ -769,7 +1076,7 @@ H5S_hyper_span_precompute_helper (H5S_hyper_span_info_t *spans, size_t elmt_size H5S_hyper_span_t *span; /* Hyperslab span */ herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_NOINIT(H5S_hyper_span_precompute); + FUNC_ENTER_NOINIT(H5S_hyper_span_precompute_helper); assert(spans); @@ -2294,7 +2601,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ static herr_t -H5S_hyper_bounds_helper (const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hsize_t *start, hsize_t *end) +H5S_hyper_bounds_helper (const H5S_hyper_span_info_t *spans, const hssize_t *offset, hsize_t rank, hssize_t *start, hssize_t *end) { H5S_hyper_span_t *curr; /* Hyperslab information nodes */ herr_t ret_value=SUCCEED; /* Return value */ @@ -2311,9 +2618,9 @@ H5S_hyper_bounds_helper (const H5S_hyper_span_info_t *spans, const hssize_t *off curr=spans->head; while(curr!=NULL) { /* Check if the current span extends the bounding box */ - if((hsize_t)(curr->low+offset[rank])<start[rank]) + if((curr->low+offset[rank])<start[rank]) start[rank]=curr->low+offset[rank]; - if((hsize_t)(curr->high+offset[rank])>end[rank]) + if((curr->high+offset[rank])>end[rank]) end[rank]=curr->high+offset[rank]; /* Recurse if this node has down spans */ @@ -2359,7 +2666,7 @@ H5S_hyper_bounds_helper (const H5S_hyper_span_info_t *spans, const hssize_t *off REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) +H5S_hyper_bounds(const H5S_t *space, hssize_t *start, hssize_t *end) { int rank; /* Dataspace rank */ int i; /* index variable */ @@ -2374,8 +2681,8 @@ H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) /* Set the start and end arrays up */ rank=space->extent.u.simple.rank; for(i=0; i<rank; i++) { - start[i]=HSIZET_MAX; - end[i]=0; + start[i]=HSSIZET_MAX; + end[i]=HSSIZET_MIN; } /* end for */ /* Check for a "regular" hyperslab selection */ @@ -3414,9 +3721,6 @@ H5S_hyper_adjust_helper (H5S_hyper_span_info_t *spans, const hssize_t *offset) /* Iterate over the spans in tree */ while(span!=NULL) { -#ifdef QAK -HDfprintf(stderr,"%s: span={%Hd, %Hd}, *offset=%Hd\n",FUNC,span->low,span->high,*offset); -#endif /* QAK */ /* Adjust span offset */ span->low-=*offset; assert(span->low>=0); @@ -4732,6 +5036,139 @@ done: FUNC_LEAVE_NOAPI(ret_value); } /* H5S_hyper_make_spans() */ + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_can_rebuild + PURPOSE + Check if optimized hyperslab information can be recovered + USAGE + htri_t H5S_hyper_can_rebuild(space) + const H5S_t *space; IN: Dataspace to check + RETURNS + TRUE/FALSE on success, <0 on failure + DESCRIPTION + Examine the span tree for a hyperslab selection and determine if it + can be used to rebuild the start/stride/count/block information for + the selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + To be able to recover the optimized information, the span tree must conform + to span tree able to be generated from a single H5S_SELECT_SET operation. + + This routine doesn't currently detect strided block situations. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S_hyper_can_rebuild (const H5S_t *space) +{ + H5S_hyper_span_t *span; /* Current hyperslab span */ + htri_t ret_value=TRUE; /* Return value */ + + FUNC_ENTER_NOINIT(H5S_hyper_can_rebuild); + + /* Check args */ + assert (space); + assert (space->select.sel_info.hslab.span_lst); + + /* For each level of the span tree check that there is only one span at + * that level. + */ + span=space->select.sel_info.hslab.span_lst->head; + while(span!=NULL) { + if(span->next!=NULL) + HGOTO_DONE(FALSE); + if(span->down) + span=span->down->head; + else + break; + } /* end while */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5S_hyper_can_rebuild() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_hyper_rebuild + PURPOSE + Recover optimized hyperslab information from span tree + USAGE + herr_t H5S_hyper_rebuild(space) + H5S_t *space; IN: Dataspace to rebuild optimized selection within + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Use the span tree information to recover the optimized form of a hyperslab + selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + The recovered optimized information will be similar to that generated from + a single H5S_SELECT_SET operation. + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_hyper_rebuild (H5S_t *space) +{ + H5S_hyper_dim_t *diminfo; /* Per-dimension info for the selection */ + H5S_hyper_dim_t *app_diminfo; /* "Application view" per-dimension for the selection */ + H5S_hyper_span_t *span; /* Current hyperslab span */ + unsigned curr_dim; /* Current dimension being worked on */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_NOINIT(H5S_hyper_rebuild); + + /* Check args */ + assert (space); + assert (space->select.sel_info.hslab.span_lst); + + /* Get head of span list */ + span=space->select.sel_info.hslab.span_lst->head; + + /* 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; + while(span!=NULL) { + /* Sanity check */ + assert(curr_dim<space->extent.u.simple.rank); + + /* Recover the optimized dimension information */ + app_diminfo[curr_dim].start = diminfo[curr_dim].start = span->low; + app_diminfo[curr_dim].stride = diminfo[curr_dim].stride = 1; + app_diminfo[curr_dim].count = diminfo[curr_dim].count = 1; + app_diminfo[curr_dim].block = diminfo[curr_dim].block = (span->high-span->low)+1; + assert(diminfo[curr_dim].block>0); + + /* Walk down the span tree */ + if(span->down) { + span=span->down->head; + curr_dim++; + } /* end if */ + else + 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; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* H5S_hyper_rebuild() */ + #ifndef NEW_HYPERSLAB_API /*------------------------------------------------------------------------- @@ -4758,12 +5195,13 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, hsize_t stride[H5O_LAYOUT_NDIMS]; /* Optimized stride information */ hsize_t count[H5O_LAYOUT_NDIMS]; /* Optimized count information */ hsize_t block[H5O_LAYOUT_NDIMS]; /* Optimized block information */ - H5S_hyper_span_info_t *new_spans; /* Span tree for new hyperslab */ + H5S_hyper_span_info_t *new_spans=NULL; /* Span tree for new hyperslab */ H5S_hyper_span_info_t *a_not_b=NULL; /* Span tree for hyperslab spans in old span tree and not in new span tree */ H5S_hyper_span_info_t *a_and_b=NULL; /* Span tree for hyperslab spans in both old and new span trees */ H5S_hyper_span_info_t *b_not_a=NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ hssize_t nelem; /* Number of elements in hyperslab span tree */ unsigned u; /* Counters */ + htri_t status; /* Status from internal calls */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOINIT(H5S_generate_hyperslab); @@ -4921,6 +5359,7 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, default: HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "invalid selection operation"); } /* end switch */ + /* Free the hyperslab trees generated from the clipping algorithm */ if(a_not_b) H5S_hyper_free_span_info(a_not_b); @@ -4928,13 +5367,49 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, H5S_hyper_free_span_info(a_and_b); if(b_not_a) H5S_hyper_free_span_info(b_not_a); + + /* Check if the resulting hyperslab span tree is empty */ + if(space->select.sel_info.hslab.span_lst==NULL) { + H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + + /* Sanity check */ + assert(space->select.num_elem==0); + + /* Allocate a span info node */ + if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span"); + + /* Set the reference count */ + spans->count=1; + + /* Reset the scratch pad space */ + spans->scratch=0; + + /* Set to empty tree */ + spans->head=NULL; + + /* Set pointer to empty span tree */ + space->select.sel_info.hslab.span_lst=spans; + } /* end if */ + else { + /* Check if the resulting hyperslab span tree can be used to re-build + * "optimized" start/stride/count/block information. + */ + status=H5S_hyper_can_rebuild(space); + if(status<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't check for rebuilding hyperslab info"); + if(status>0) + if(H5S_hyper_rebuild(space)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't rebuild hyperslab info"); + } /* end else */ } /* end else */ +done: /* Free the new spans */ - if(H5S_hyper_free_span_info(new_spans)<0) - HGOTO_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans"); + if(new_spans!=NULL) + if(H5S_hyper_free_span_info(new_spans)<0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans"); -done: FUNC_LEAVE_NOAPI(ret_value); } /* end H5S_generate_hyperslab() */ @@ -5136,7 +5611,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, /* Sanity check */ assert(space->select.type==H5S_SEL_HYPERSLABS); - /* Is this the first 'or' operation? */ + /* 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); @@ -5256,6 +5731,7 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper H5S_hyper_span_info_t *a_and_b=NULL; /* Span tree for hyperslab spans in both old and new span trees */ H5S_hyper_span_info_t *b_not_a=NULL; /* Span tree for hyperslab spans in new span tree and not in old span tree */ hssize_t nelem; /* Number of elements in hyperslab span tree */ + htri_t status; /* Status from internal calls */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOINIT(H5S_operate_hyperslab); @@ -5385,6 +5861,41 @@ H5S_operate_hyperslab (H5S_t *result, H5S_hyper_span_info_t *spans1, H5S_seloper H5S_hyper_free_span_info(a_and_b); if(b_not_a) H5S_hyper_free_span_info(b_not_a); + + /* Check if the resulting hyperslab span tree is empty */ + if(space->select.sel_info.hslab.span_lst==NULL) { + H5S_hyper_span_info_t *spans; /* Empty hyperslab span tree */ + + /* Sanity check */ + assert(space->select.num_elem==0); + + /* Allocate a span info node */ + if((spans = H5FL_MALLOC(H5S_hyper_span_info_t))==NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate hyperslab span"); + + /* Set the reference count */ + spans->count=1; + + /* Reset the scratch pad space */ + spans->scratch=0; + + /* Set to empty tree */ + spans->head=NULL; + + /* Set pointer to empty span tree */ + space->select.sel_info.hslab.span_lst=spans; + } /* end if */ + else { + /* Check if the resulting hyperslab span tree can be used to re-build + * "optimized" start/stride/count/block information. + */ + status=H5S_hyper_can_rebuild(result); + if(status<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't check for rebuilding hyperslab info"); + if(status>0) + if(H5S_hyper_rebuild(result)<0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't rebuild hyperslab info"); + } /* end else */ } /* end else */ /* Set selection type */ @@ -5478,9 +5989,11 @@ H5S_generate_hyperslab (H5S_t *space, H5S_seloper_t op, done: /* Free temporary data structures */ if(tmp_spans!=NULL) - H5S_hyper_free_span_info(tmp_spans); + if(H5S_hyper_free_span_info(tmp_spans)<0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans"); if(new_spans!=NULL) - H5S_hyper_free_span_info(new_spans); + if(H5S_hyper_free_span_info(new_spans)<0) + HDONE_ERROR(H5E_INTERNAL, H5E_CANTFREE, FAIL, "failed to release temporary hyperslab spans"); FUNC_LEAVE_NOAPI(ret_value); } /* end H5S_generate_hyperslab() */ diff --git a/src/H5Snone.c b/src/H5Snone.c index a1d6127..7d1aa12 100644 --- a/src/H5Snone.c +++ b/src/H5Snone.c @@ -28,11 +28,22 @@ #include "H5Vprivate.h" #include "H5Dprivate.h" -/* Interface initialization */ +/* Pablo mask */ #define PABLO_MASK H5Snone_mask + +/* Interface initialization */ #define INTERFACE_INIT NULL static int interface_initialize_g = 0; +/* Static function prototypes */ +static herr_t H5S_none_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); +static herr_t H5S_none_iter_block(const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end); +static hsize_t H5S_none_iter_nelmts(const H5S_sel_iter_t *iter); +static htri_t H5S_none_iter_has_next_block(const H5S_sel_iter_t *iter); +static herr_t H5S_none_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +static herr_t H5S_none_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S_none_iter_release(H5S_sel_iter_t *sel_iter); + /*------------------------------------------------------------------------- * Function: H5S_none_iter_init @@ -61,8 +72,11 @@ H5S_none_iter_init (H5S_sel_iter_t *iter, const H5S_t UNUSED *space, size_t UNUS /* Initialize methods for selection iterator */ iter->iter_coords=H5S_none_iter_coords; + iter->iter_block=H5S_none_iter_block; iter->iter_nelmts=H5S_none_iter_nelmts; + iter->iter_has_next_block=H5S_none_iter_has_next_block; iter->iter_next=H5S_none_iter_next; + iter->iter_next_block=H5S_none_iter_next_block; iter->iter_release=H5S_none_iter_release; done: @@ -85,23 +99,49 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5S_none_iter_coords (const H5S_sel_iter_t UNUSED *iter, hssize_t UNUSED *coords) { - herr_t ret_value=FAIL; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_none_iter_coords, FAIL); + FUNC_ENTER_NOINIT(H5S_none_iter_coords); /* Check args */ assert (iter); assert (coords); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(FAIL); } /* H5S_none_iter_coords() */ /*------------------------------------------------------------------------- + * Function: H5S_none_iter_block + * + * Purpose: Retrieve the current block of iterator for current + * selection + * + * Return: non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Monday, June 2, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S_none_iter_block (const H5S_sel_iter_t UNUSED *iter, hssize_t UNUSED *start, hssize_t UNUSED *end) +{ + FUNC_ENTER_NOINIT(H5S_none_iter_block); + + /* Check args */ + assert (iter); + assert (start); + assert (end); + + FUNC_LEAVE_NOAPI(FAIL); +} /* H5S_none_iter_block() */ + + +/*------------------------------------------------------------------------- * Function: H5S_none_iter_nelmts * * Purpose: Return number of elements left to process in iterator @@ -115,23 +155,49 @@ done: * *------------------------------------------------------------------------- */ -hsize_t +static hsize_t H5S_none_iter_nelmts (const H5S_sel_iter_t UNUSED *iter) { - hsize_t ret_value=0; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_none_iter_nelmts, 0); + FUNC_ENTER_NOINIT(H5S_none_iter_nelmts); /* Check args */ assert (iter); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(0); } /* H5S_none_iter_nelmts() */ /*-------------------------------------------------------------------------- NAME + H5S_none_iter_has_next_block + PURPOSE + Check if there is another block left in the current iterator + USAGE + htri_t H5S_none_iter_has_next_block(iter) + const H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative (TRUE/FALSE) on success/Negative on failure + DESCRIPTION + Check if there is another block available in the selection iterator. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S_none_iter_has_next_block(const H5S_sel_iter_t UNUSED *iter) +{ + FUNC_ENTER_NOINIT(H5S_none_iter_has_next_block); + + /* Check args */ + assert (iter); + + FUNC_LEAVE_NOAPI(FAIL); +} /* H5S_none_iter_has_next_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_none_iter_next PURPOSE Increment selection iterator @@ -148,24 +214,50 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_none_iter_next(H5S_sel_iter_t UNUSED *iter, size_t UNUSED nelem) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_none_iter_next, FAIL); + FUNC_ENTER_NOINIT(H5S_none_iter_next); /* Check args */ assert (iter); assert (nelem>0); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_none_iter_next() */ /*-------------------------------------------------------------------------- NAME + H5S_none_iter_next_block + PURPOSE + Increment selection iterator to next block + USAGE + herr_t H5S_none_iter_next(iter) + H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Advance selection iterator to the next block in the selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_none_iter_next_block(H5S_sel_iter_t UNUSED *iter) +{ + FUNC_ENTER_NOINIT(H5S_none_iter_next); + + /* Check args */ + assert (iter); + + FUNC_LEAVE_NOAPI(FAIL); +} /* H5S_none_iter_next_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_none_iter_release PURPOSE Release "none" selection iterator information for a dataspace @@ -181,18 +273,15 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_none_iter_release (H5S_sel_iter_t UNUSED * iter) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_none_iter_release, FAIL); + FUNC_ENTER_NOINIT(H5S_none_iter_release); /* Check args */ assert (iter); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_none_iter_release() */ @@ -416,10 +505,10 @@ done: PURPOSE Gets the bounding box containing the selection. USAGE - herr_t H5S_none_bounds(space, hsize_t *start, hsize_t *end) + herr_t H5S_none_bounds(space, start, end) H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t *start; OUT: Starting coordinate of bounding box - hsize_t *end; OUT: Opposite coordinate of bounding box + hssize_t *start; OUT: Starting coordinate of bounding box + hssize_t *end; OUT: Opposite coordinate of bounding box RETURNS Non-negative on success, negative on failure DESCRIPTION @@ -436,7 +525,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_none_bounds(const H5S_t UNUSED *space, hsize_t UNUSED *start, hsize_t UNUSED *end) +H5S_none_bounds(const H5S_t UNUSED *space, hssize_t UNUSED *start, hssize_t UNUSED *end) { herr_t ret_value=FAIL; /* Return value */ diff --git a/src/H5Spkg.h b/src/H5Spkg.h index 9d10460..e23cda9 100644 --- a/src/H5Spkg.h +++ b/src/H5Spkg.h @@ -139,7 +139,7 @@ typedef hssize_t (*H5S_sel_serial_size_func_t)(const H5S_t *space); /* Method to store current selection in "serialized" form (a byte sequence suitable for storing on disk) */ typedef herr_t (*H5S_sel_serialize_func_t)(const H5S_t *space, uint8_t *buf); /* Method to determine to smallest n-D bounding box containing the current selection */ -typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hsize_t *start, hsize_t *end); +typedef herr_t (*H5S_sel_bounds_func_t)(const H5S_t *space, hssize_t *start, hssize_t *end); /* Method to determine if current selection is contiguous */ typedef htri_t (*H5S_sel_is_contiguous_func_t)(const H5S_t *space); /* Method to determine if current selection is a single block */ @@ -184,15 +184,9 @@ H5_DLL herr_t H5S_release_simple(H5S_simple_t *simple); H5_DLL herr_t H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src); /* Operations on selections */ -H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src); -H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2); /* Point selection iterator functions */ H5_DLL herr_t H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); -H5_DLL herr_t H5S_point_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); -H5_DLL hsize_t H5S_point_iter_nelmts(const H5S_sel_iter_t *iter); -H5_DLL herr_t H5S_point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); -H5_DLL herr_t H5S_point_iter_release(H5S_sel_iter_t *sel_iter); /* Point selection functions */ H5_DLL herr_t H5S_point_release(H5S_t *space); @@ -202,7 +196,7 @@ H5_DLL htri_t H5S_point_is_valid(const H5S_t *space); H5_DLL hssize_t H5S_point_serial_size(const H5S_t *space); H5_DLL herr_t H5S_point_serialize(const H5S_t *space, uint8_t *buf); H5_DLL herr_t H5S_point_deserialize(H5S_t *space, const uint8_t *buf); -H5_DLL herr_t H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +H5_DLL herr_t H5S_point_bounds(const H5S_t *space, hssize_t *start, hssize_t *end); H5_DLL htri_t H5S_point_is_contiguous(const H5S_t *space); H5_DLL htri_t H5S_point_is_single(const H5S_t *space); H5_DLL htri_t H5S_point_is_regular(const H5S_t *space); @@ -212,10 +206,6 @@ H5_DLL herr_t H5S_point_get_seq_list(const H5S_t *space, unsigned flags, /* "All" selection iterator functions */ H5_DLL herr_t H5S_all_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); -H5_DLL herr_t H5S_all_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); -H5_DLL hsize_t H5S_all_iter_nelmts(const H5S_sel_iter_t *iter); -H5_DLL herr_t H5S_all_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); -H5_DLL herr_t H5S_all_iter_release(H5S_sel_iter_t *sel_iter); /* "All" selection functions */ H5_DLL herr_t H5S_all_release(H5S_t *space); @@ -224,7 +214,7 @@ H5_DLL htri_t H5S_all_is_valid(const H5S_t *space); H5_DLL hssize_t H5S_all_serial_size(const H5S_t *space); H5_DLL herr_t H5S_all_serialize(const H5S_t *space, uint8_t *buf); H5_DLL herr_t H5S_all_deserialize(H5S_t *space, const uint8_t *buf); -H5_DLL herr_t H5S_all_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +H5_DLL herr_t H5S_all_bounds(const H5S_t *space, hssize_t *start, hssize_t *end); H5_DLL htri_t H5S_all_is_contiguous(const H5S_t *space); H5_DLL htri_t H5S_all_is_single(const H5S_t *space); H5_DLL htri_t H5S_all_is_regular(const H5S_t *space); @@ -234,10 +224,6 @@ H5_DLL herr_t H5S_all_get_seq_list(const H5S_t *space, unsigned flags, /* Hyperslab selection iterator functions */ H5_DLL herr_t H5S_hyper_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); -H5_DLL herr_t H5S_hyper_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); -H5_DLL hsize_t H5S_hyper_iter_nelmts(const H5S_sel_iter_t *iter); -H5_DLL herr_t H5S_hyper_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); -H5_DLL herr_t H5S_hyper_iter_release(H5S_sel_iter_t *sel_iter); /* Hyperslab selection functions */ H5_DLL herr_t H5S_hyper_release(H5S_t *space); @@ -247,7 +233,7 @@ H5_DLL htri_t H5S_hyper_is_valid(const H5S_t *space); H5_DLL hssize_t H5S_hyper_serial_size(const H5S_t *space); H5_DLL herr_t H5S_hyper_serialize(const H5S_t *space, uint8_t *buf); H5_DLL herr_t H5S_hyper_deserialize(H5S_t *space, const uint8_t *buf); -H5_DLL herr_t H5S_hyper_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +H5_DLL herr_t H5S_hyper_bounds(const H5S_t *space, hssize_t *start, hssize_t *end); H5_DLL htri_t H5S_hyper_is_contiguous(const H5S_t *space); H5_DLL htri_t H5S_hyper_is_single(const H5S_t *space); H5_DLL htri_t H5S_hyper_is_regular(const H5S_t *space); @@ -257,10 +243,6 @@ H5_DLL herr_t H5S_hyper_get_seq_list(const H5S_t *space, unsigned flags, /* "None" selection iterator functions */ H5_DLL herr_t H5S_none_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t elmt_size); -H5_DLL herr_t H5S_none_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); -H5_DLL hsize_t H5S_none_iter_nelmts(const H5S_sel_iter_t *iter); -H5_DLL herr_t H5S_none_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); -H5_DLL herr_t H5S_none_iter_release(H5S_sel_iter_t *sel_iter); /* "None" selection functions */ H5_DLL herr_t H5S_none_release(H5S_t *space); @@ -269,7 +251,7 @@ H5_DLL htri_t H5S_none_is_valid(const H5S_t *space); H5_DLL hssize_t H5S_none_serial_size(const H5S_t *space); H5_DLL herr_t H5S_none_serialize(const H5S_t *space, uint8_t *buf); H5_DLL herr_t H5S_none_deserialize(H5S_t *space, const uint8_t *buf); -H5_DLL herr_t H5S_none_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +H5_DLL herr_t H5S_none_bounds(const H5S_t *space, hssize_t *start, hssize_t *end); H5_DLL htri_t H5S_none_is_contiguous(const H5S_t *space); H5_DLL htri_t H5S_none_is_single(const H5S_t *space); H5_DLL htri_t H5S_none_is_regular(const H5S_t *space); @@ -303,4 +285,9 @@ H5_DLL htri_t H5S_mpio_opt_possible(const H5S_t *mem_space, #endif /* H5_HAVE_PARALLEL */ +/* Testing functions */ +#ifdef H5S_TESTING +H5_DLL htri_t H5S_select_shape_same_test(hid_t sid1, hid_t sid2); +#endif /* H5S_TESTING */ + #endif /*_H5Spkg_H*/ diff --git a/src/H5Spoint.c b/src/H5Spoint.c index 7c45a11..8da8884 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -29,14 +29,23 @@ #include "H5Spkg.h" /* Dataspace functions */ #include "H5Vprivate.h" /* Vector functions */ -/* Interface initialization */ +/* Pablo mask */ #define PABLO_MASK H5Spoint_mask + +/* Interface initialization */ #define INTERFACE_INIT NULL static int interface_initialize_g = 0; /* Static function prototypes */ static herr_t H5S_select_elements (H5S_t *space, H5S_seloper_t op, size_t num_elem, const hssize_t **coord); +static herr_t H5S_point_iter_coords(const H5S_sel_iter_t *iter, hssize_t *coords); +static herr_t H5S_point_iter_block(const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end); +static hsize_t H5S_point_iter_nelmts(const H5S_sel_iter_t *iter); +static htri_t H5S_point_iter_has_next_block(const H5S_sel_iter_t *iter); +static herr_t H5S_point_iter_next(H5S_sel_iter_t *sel_iter, size_t nelem); +static herr_t H5S_point_iter_next_block(H5S_sel_iter_t *sel_iter); +static herr_t H5S_point_iter_release(H5S_sel_iter_t *sel_iter); /* Declare a free list to manage the H5S_pnt_node_t struct */ H5FL_DEFINE_STATIC(H5S_pnt_node_t); @@ -78,8 +87,11 @@ H5S_point_iter_init(H5S_sel_iter_t *iter, const H5S_t *space, size_t UNUSED elmt /* Initialize methods for selection iterator */ iter->iter_coords=H5S_point_iter_coords; + iter->iter_block=H5S_point_iter_block; iter->iter_nelmts=H5S_point_iter_nelmts; + iter->iter_has_next_block=H5S_point_iter_has_next_block; iter->iter_next=H5S_point_iter_next; + iter->iter_next_block=H5S_point_iter_next_block; iter->iter_release=H5S_point_iter_release; done: @@ -102,12 +114,10 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5S_point_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_point_iter_coords, FAIL); + FUNC_ENTER_NOINIT(H5S_point_iter_coords); /* Check args */ assert (iter); @@ -116,12 +126,44 @@ H5S_point_iter_coords (const H5S_sel_iter_t *iter, hssize_t *coords) /* Copy the offset of the current point */ HDmemcpy(coords,iter->u.pnt.curr->pnt,sizeof(hssize_t)*iter->rank); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_point_iter_coords() */ /*------------------------------------------------------------------------- + * Function: H5S_point_iter_block + * + * Purpose: Retrieve the current block of iterator for current + * selection + * + * Return: non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Monday, June 2, 2003 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +static herr_t +H5S_point_iter_block (const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end) +{ + FUNC_ENTER_NOINIT(H5S_point_iter_block); + + /* Check args */ + assert (iter); + assert (start); + assert (end); + + /* Copy the current point as a block */ + HDmemcpy(start,iter->u.pnt.curr->pnt,sizeof(hssize_t)*iter->rank); + HDmemcpy(end,iter->u.pnt.curr->pnt,sizeof(hssize_t)*iter->rank); + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5S_point_iter_block() */ + + +/*------------------------------------------------------------------------- * Function: H5S_point_iter_nelmts * * Purpose: Return number of elements left to process in iterator @@ -135,22 +177,52 @@ done: * *------------------------------------------------------------------------- */ -hsize_t +static hsize_t H5S_point_iter_nelmts (const H5S_sel_iter_t *iter) { - hsize_t ret_value; /* Return value */ + FUNC_ENTER_NOINIT(H5S_point_iter_nelmts); - FUNC_ENTER_NOAPI(H5S_point_iter_nelmts, 0); + /* Check args */ + assert (iter); + + FUNC_LEAVE_NOAPI(iter->elmt_left); +} /* H5S_point_iter_nelmts() */ + + +/*-------------------------------------------------------------------------- + NAME + H5S_point_iter_has_next_block + PURPOSE + Check if there is another block left in the current iterator + USAGE + htri_t H5S_point_iter_has_next_block(iter) + const H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative (TRUE/FALSE) on success/Negative on failure + DESCRIPTION + Check if there is another block available in the selection iterator. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static htri_t +H5S_point_iter_has_next_block(const H5S_sel_iter_t *iter) +{ + htri_t ret_value=TRUE; /* Return value */ + + FUNC_ENTER_NOINIT(H5S_point_iter_has_next_block); /* Check args */ assert (iter); - /* Set return value */ - ret_value=iter->elmt_left; + /* Check if there is another point in the list */ + if(iter->u.pnt.curr->next==NULL) + HGOTO_DONE(FALSE); done: FUNC_LEAVE_NOAPI(ret_value); -} /* H5S_point_iter_nelmts() */ +} /* H5S_point_iter_has_next_block() */ /*-------------------------------------------------------------------------- @@ -171,12 +243,10 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_point_iter_next(H5S_sel_iter_t *iter, size_t nelem) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_point_iter_next, FAIL); + FUNC_ENTER_NOINIT(H5S_point_iter_next); /* Check args */ assert (iter); @@ -188,13 +258,44 @@ H5S_point_iter_next(H5S_sel_iter_t *iter, size_t nelem) nelem--; } /* end while */ -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_point_iter_next() */ /*-------------------------------------------------------------------------- NAME + H5S_point_iter_next_block + PURPOSE + Increment selection iterator to next block + USAGE + herr_t H5S_point_iter_next_block(iter) + H5S_sel_iter_t *iter; IN: Pointer to selection iterator + RETURNS + Non-negative on success/Negative on failure + DESCRIPTION + Advance selection iterator to the next block in the selection. + GLOBAL VARIABLES + COMMENTS, BUGS, ASSUMPTIONS + EXAMPLES + REVISION LOG +--------------------------------------------------------------------------*/ +static herr_t +H5S_point_iter_next_block(H5S_sel_iter_t *iter) +{ + FUNC_ENTER_NOINIT(H5S_point_iter_next_block); + + /* Check args */ + assert (iter); + + /* Increment the iterator */ + iter->u.pnt.curr=iter->u.pnt.curr->next; + + FUNC_LEAVE_NOAPI(SUCCEED); +} /* H5S_point_iter_next_block() */ + + +/*-------------------------------------------------------------------------- + NAME H5S_point_iter_release PURPOSE Release point selection iterator information for a dataspace @@ -210,18 +311,15 @@ done: EXAMPLES REVISION LOG --------------------------------------------------------------------------*/ -herr_t +static herr_t H5S_point_iter_release (H5S_sel_iter_t UNUSED * iter) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5S_point_iter_release, FAIL); + FUNC_ENTER_NOINIT(H5S_point_iter_release); /* Check args */ assert (iter); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(SUCCEED); } /* H5S_point_iter_release() */ @@ -962,10 +1060,10 @@ done: PURPOSE Gets the bounding box containing the selection. USAGE - herr_t H5S_point_bounds(space, hsize_t *start, hsize_t *end) + herr_t H5S_point_bounds(space, start, end) H5S_t *space; IN: Dataspace pointer of selection to query - hsize_t *start; OUT: Starting coordinate of bounding box - hsize_t *end; OUT: Opposite coordinate of bounding box + hssize_t *start; OUT: Starting coordinate of bounding box + hssize_t *end; OUT: Opposite coordinate of bounding box RETURNS Non-negative on success, negative on failure DESCRIPTION @@ -983,7 +1081,7 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) +H5S_point_bounds(const H5S_t *space, hssize_t *start, hssize_t *end) { H5S_pnt_node_t *node; /* Point node */ int rank; /* Dataspace rank */ @@ -1001,17 +1099,17 @@ H5S_point_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) /* Set the start and end arrays up */ for(i=0; i<rank; i++) { - start[i]=HSIZET_MAX; - end[i]=0; + start[i]=HSSIZET_MAX; + end[i]=HSSIZET_MIN; } /* end for */ /* Iterate through the node, checking the bounds on each element */ node=space->select.sel_info.pnt_lst->head; while(node!=NULL) { for(i=0; i<rank; i++) { - if(start[i]>(hsize_t)(node->pnt[i]+space->select.offset[i])) + if(start[i]>(node->pnt[i]+space->select.offset[i])) start[i]=node->pnt[i]+space->select.offset[i]; - if(end[i]<(hsize_t)(node->pnt[i]+space->select.offset[i])) + if(end[i]<(node->pnt[i]+space->select.offset[i])) end[i]=node->pnt[i]+space->select.offset[i]; } /* end for */ node=node->next; diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 4e6eda7..c05df2a 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -79,10 +79,16 @@ typedef struct H5S_sel_iter_t H5S_sel_iter_t; /* Method to retrieve the current coordinates of iterator for current selection */ typedef herr_t (*H5S_sel_iter_coords_func_t)(const H5S_sel_iter_t *iter, hssize_t *coords); +/* Method to retrieve the current block of iterator for current selection */ +typedef herr_t (*H5S_sel_iter_block_func_t)(const H5S_sel_iter_t *iter, hssize_t *start, hssize_t *end); /* Method to determine number of elements left in iterator for current selection */ typedef hsize_t (*H5S_sel_iter_nelmts_func_t)(const H5S_sel_iter_t *iter); +/* Method to determine if there are more blocks left in the current selection */ +typedef htri_t (*H5S_sel_iter_has_next_block_func_t)(const H5S_sel_iter_t *iter); /* Method to move selection iterator to the next element in the selection */ typedef herr_t (*H5S_sel_iter_next_func_t)(H5S_sel_iter_t *iter, size_t nelem); +/* Method to move selection iterator to the next block in the selection */ +typedef herr_t (*H5S_sel_iter_next_block_func_t)(H5S_sel_iter_t *iter); /* Method to release iterator for current selection */ typedef herr_t (*H5S_sel_iter_release_func_t)(H5S_sel_iter_t *iter); @@ -102,8 +108,11 @@ struct H5S_sel_iter_t { /* Methods on selections */ H5S_sel_iter_coords_func_t iter_coords; /* Method to retrieve the current coordinates of iterator for current selection */ + H5S_sel_iter_block_func_t iter_block; /* Method to retrieve the current block of iterator for current selection */ H5S_sel_iter_nelmts_func_t iter_nelmts; /* Method to determine number of elements left in iterator for current selection */ + H5S_sel_iter_has_next_block_func_t iter_has_next_block; /* Method to query if there is another block left in the selection */ H5S_sel_iter_next_func_t iter_next; /* Method to move selection iterator to the next element in the selection */ + H5S_sel_iter_next_block_func_t iter_next_block; /* Method to move selection iterator to the next block in the selection */ H5S_sel_iter_release_func_t iter_release; /* Method to release iterator for current selection */ }; @@ -205,8 +214,10 @@ H5_DLL herr_t H5S_select_write(H5F_t *f, struct H5O_layout_t *layout, const void *buf/*out*/); H5_DLL htri_t H5S_select_valid(const H5S_t *space); H5_DLL hssize_t H5S_get_select_npoints(const H5S_t *space); -H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end); +H5_DLL herr_t H5S_get_select_bounds(const H5S_t *space, hssize_t *start, hssize_t *end); H5_DLL herr_t H5S_select_offset(H5S_t *space, const hssize_t *offset); +H5_DLL herr_t H5S_select_copy(H5S_t *dst, const H5S_t *src); +H5_DLL htri_t H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2); H5_DLL herr_t H5S_select_release(H5S_t *ds); H5_DLL herr_t H5S_select_all(H5S_t *space, unsigned rel_prev); H5_DLL herr_t H5S_select_none(H5S_t *space); |