summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-04-10 14:44:58 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-04-10 14:44:58 (GMT)
commiteb7a675f0a1bb565bdeb4c97697c9821c5ce72cc (patch)
treeb83bfafc05ea36dbc675eb832debe1571c5f0026
parent48d84a1bbc72fc52241a7b0cbdd8ac1fb7544d9b (diff)
downloadhdf5-eb7a675f0a1bb565bdeb4c97697c9821c5ce72cc.zip
hdf5-eb7a675f0a1bb565bdeb4c97697c9821c5ce72cc.tar.gz
hdf5-eb7a675f0a1bb565bdeb4c97697c9821c5ce72cc.tar.bz2
[svn-r8335] Purpose:
Code optimization Description: Change algorithm to directly use coordinates describing a chunk's position in a dataspace instead of creating a dataspace with the chunk's position selected. This reduces the number of copies of dataspaces we need to keep around. Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.9 (sleipnir) w/parallel too minor to require h5committest
-rw-r--r--src/H5Dio.c26
-rw-r--r--src/H5Shyper.c122
-rw-r--r--src/H5Sprivate.h3
3 files changed, 132 insertions, 19 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c
index 1008215..207efbf 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -2669,13 +2669,13 @@ done:
static herr_t
H5D_create_chunk_file_map_hyper(const fm_map *fm)
{
- H5S_t *tmp_fspace=NULL; /* Temporary file dataspace */
hssize_t sel_points; /* Number of elements in file selection */
hssize_t sel_start[H5O_LAYOUT_NDIMS]; /* Offset of low bound of file selection */
hssize_t sel_end[H5O_LAYOUT_NDIMS]; /* Offset of high bound of file selection */
hssize_t start_coords[H5O_LAYOUT_NDIMS]; /* Starting coordinates of selection */
hssize_t coords[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
hsize_t count[H5O_LAYOUT_NDIMS]; /* Hyperslab count information */
+ hssize_t end[H5O_LAYOUT_NDIMS]; /* Current coordinates of chunk */
hsize_t chunk_index; /* Index of chunk */
int curr_dim; /* Current dimension to increment */
unsigned u; /* Local index variable */
@@ -2686,16 +2686,12 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
/* Sanity check */
assert(fm->f_ndims>0);
- /* Make a copy of file dataspace */
- if((tmp_fspace = H5S_copy(fm->file_space))==NULL)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy memory space")
-
/* Get number of elements selected in file */
- if((sel_points=H5S_get_select_npoints(tmp_fspace))<0)
+ if((sel_points=H5S_get_select_npoints(fm->file_space))<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection # of elements")
/* Get bounding box for selection (to reduce the number of chunks to iterate over) */
- if(H5S_get_select_bounds(tmp_fspace, sel_start, sel_end)<0)
+ if(H5S_get_select_bounds(fm->file_space, sel_start, sel_end)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get file selection bound info")
/* Set initial chunk location & hyperslab size */
@@ -2704,12 +2700,9 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
start_coords[u]=(sel_start[u]/(hssize_t)fm->layout->dim[u])*(hssize_t)fm->layout->dim[u];
coords[u]=start_coords[u];
count[u]=fm->layout->dim[u];
+ end[u]=(coords[u]+count[u])-1;
} /* end for */
- /* Select initial chunk as hyperslab */
- if(H5S_select_hyperslab(tmp_fspace,H5S_SELECT_SET,coords,NULL,count,NULL)<0) /*lint !e772 The coords and count arrays should always be initialized */
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't create hyperslab selection")
-
/* Calculate the index of this chunk */
if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
@@ -2717,7 +2710,7 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
/* Iterate through each chunk in the dataset */
while(sel_points) {
/* Check for intersection of temporary chunk and file selection */
- if(H5S_hyper_intersect(tmp_fspace,fm->file_space)==TRUE) {
+ if(H5S_hyper_intersect_block(fm->file_space,coords,end)==TRUE) {
H5S_t *tmp_fchunk; /* Temporary file dataspace */
H5D_chunk_info_t *new_chunk_info; /* chunk information to insert into tree */
hssize_t chunk_points; /* Number of elements in chunk selection */
@@ -2797,6 +2790,7 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
/* Increment chunk location in fastest changing dimension */
H5_CHECK_OVERFLOW(count[curr_dim],hsize_t,hssize_t);
coords[curr_dim]+=(hssize_t)count[curr_dim];
+ end[curr_dim]+=(hssize_t)count[curr_dim];
/* Bring chunk location back into bounds, if necessary */
if(coords[curr_dim]>sel_end[curr_dim]) {
@@ -2809,22 +2803,16 @@ H5D_create_chunk_file_map_hyper(const fm_map *fm)
/* Increment chunk location in current dimension */
coords[curr_dim]+=(hssize_t)count[curr_dim];
+ end[curr_dim]=(coords[curr_dim]+(hssize_t)count[curr_dim])-1;
} while(coords[curr_dim]>sel_end[curr_dim]);
/* Re-Calculate the index of this chunk */
if(H5V_chunk_index(fm->f_ndims,coords,fm->layout->dim,fm->chunks,fm->down_chunks,&chunk_index)<0)
HGOTO_ERROR (H5E_DATASPACE, H5E_BADRANGE, FAIL, "can't get chunk index")
} /* end if */
-
- /* Move template chunk's offset to current location of chunk */
- if(H5S_hyper_move(tmp_fspace,coords)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't move chunk selection")
} /* end while */
done:
- if(tmp_fspace)
- if(H5S_close(tmp_fspace)<0)
- HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "can't release file dataspace copy")
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_create_chunk_file_map_hyper() */
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 589ddd0..6a6d604 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -3624,6 +3624,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_hyper_convert() */
+#ifdef LATER
/*--------------------------------------------------------------------------
NAME
@@ -3740,6 +3741,127 @@ H5S_hyper_intersect (H5S_t *space1, H5S_t *space2)
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_hyper_intersect() */
+#endif /* LATER */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_intersect_block_helper
+ PURPOSE
+ Helper routine to detect intersections in span trees
+ USAGE
+ htri_t H5S_hyper_intersect_block_helper(spans, start, end)
+ H5S_hyper_span_info_t *spans; IN: First span tree to operate with
+ hssize_t *offset; IN: Selection offset coordinate
+ hssize_t *start; IN: Starting coordinate for block
+ hssize_t *end; IN: Ending coordinate for block
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Quickly detect intersections between span tree and block
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static htri_t
+H5S_hyper_intersect_block_helper (const H5S_hyper_span_info_t *spans, hssize_t *offset, hssize_t *start, hssize_t *end)
+{
+ H5S_hyper_span_t *curr; /* Pointer to current span in 1st span tree */
+ htri_t status; /* Status from recursive call */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_intersect_block_helper);
+
+ /* Sanity check */
+ assert(spans);
+ assert(offset);
+ assert(start);
+ assert(end);
+
+ /* Get the span list for spans in this tree */
+ curr=spans->head;
+
+ /* Iterate over the spans in the tree */
+ while(curr!=NULL) {
+ /* Check for span entirely before block */
+ if((curr->high+*offset)<*start)
+ /* Advance to next span in this dimension */
+ curr=curr->next;
+ /* If this span is past the end of the block, then we're done in this dimension */
+ else if((curr->low+*offset)>*end)
+ HGOTO_DONE(FALSE)
+ /* block & span overlap */
+ else {
+ if(curr->down==NULL)
+ HGOTO_DONE(TRUE)
+ else {
+ /* Recursively check spans in next dimension down */
+ if((status=H5S_hyper_intersect_block_helper(curr->down,offset+1,start+1,end+1))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check");
+
+ /* If there is a span intersection in the down dimensions, the span trees overlap */
+ if(status==TRUE)
+ HGOTO_DONE(TRUE);
+
+ /* No intersection in down dimensions, advance to next span */
+ curr=curr->next;
+ } /* end else */
+ } /* end else */
+ } /* end while */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_intersect_block_helper() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_hyper_intersect_block
+ PURPOSE
+ Detect intersections in span trees
+ USAGE
+ htri_t H5S_hyper_intersect_block(space, start, end)
+ H5S_t *space; IN: First dataspace to operate on span tree
+ hssize_t *start; IN: Starting coordinate for block
+ hssize_t *end; IN: Ending coordinate for block
+ RETURNS
+ Non-negative on success, negative on failure
+ DESCRIPTION
+ Quickly detect intersections between span tree and block
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5S_hyper_intersect_block (const H5S_t *space, hssize_t *start, hssize_t *end)
+{
+ htri_t ret_value=FAIL; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5S_hyper_intersect_block);
+
+ /* Sanity check */
+ assert(space);
+ assert(start);
+ assert(end);
+
+ /* Check for 'all' selection, instead of a hyperslab selection */
+ /* (Technically, this shouldn't be in the "hyperslab" routines...) */
+ if(space->select.type==H5S_SEL_ALL)
+ HGOTO_DONE(TRUE);
+
+ /* Check that the space selections both have span trees */
+ if(space->select.sel_info.hslab.span_lst==NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNINITIALIZED, FAIL, "dataspace does not have span tree");
+
+ /* Perform the span-by-span intersection check */
+ if((ret_value=H5S_hyper_intersect_block_helper(space->select.sel_info.hslab.span_lst,space->select.offset,start,end))<0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSELECT, FAIL, "can't perform hyperslab intersection check");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5S_hyper_intersect_block() */
/*--------------------------------------------------------------------------
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index 2fcdad7..94510b2 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -241,7 +241,10 @@ H5_DLL herr_t H5S_hyper_add_span_element(H5S_t *space, unsigned rank,
hssize_t *coords);
H5_DLL herr_t H5S_hyper_reset_scratch(H5S_t *space);
H5_DLL herr_t H5S_hyper_convert(H5S_t *space);
+#ifdef LATER
H5_DLL htri_t H5S_hyper_intersect (H5S_t *space1, H5S_t *space2);
+#endif /* LATER */
+H5_DLL htri_t H5S_hyper_intersect_block (const H5S_t *space, hssize_t *start, hssize_t *end);
H5_DLL herr_t H5S_hyper_adjust(H5S_t *space, const hssize_t *offset);
H5_DLL herr_t H5S_hyper_move(H5S_t *space, const hssize_t *offset);
H5_DLL herr_t H5S_hyper_normalize_offset(H5S_t *space);