summaryrefslogtreecommitdiffstats
path: root/src/H5Shyper.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>1998-09-21 23:43:19 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>1998-09-21 23:43:19 (GMT)
commit1fe48c7f19c2eed94a22179459efc1487ee65217 (patch)
tree41249aed6d1d5f95f6db00fa33ee7d40f434ca2a /src/H5Shyper.c
parent7b189913384c500b71cb82d1780d6d07b170583c (diff)
downloadhdf5-1fe48c7f19c2eed94a22179459efc1487ee65217.zip
hdf5-1fe48c7f19c2eed94a22179459efc1487ee65217.tar.gz
hdf5-1fe48c7f19c2eed94a22179459efc1487ee65217.tar.bz2
[svn-r712] Added temporary buffer support to several places in the library which were
calling malloc too often. Also, added caching of hyperslab blocks, which improves performance _significantly_ for hyperslab I/O.
Diffstat (limited to 'src/H5Shyper.c')
-rw-r--r--src/H5Shyper.c537
1 files changed, 388 insertions, 149 deletions
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index c59d38e..24fca4c 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -12,6 +12,8 @@
#include <H5Sprivate.h>
#include <H5Vprivate.h>
#include <H5MMprivate.h>
+#include <H5TBprivate.h>
+#include <H5Dprivate.h>
/* Interface initialization */
#define PABLO_MASK H5S_hyper_mask
@@ -29,7 +31,7 @@ typedef struct {
const H5S_t *space;
H5S_sel_iter_t *iter;
size_t nelmts;
- H5D_transfer_t xfer_mode;
+ const H5D_xfer_t *xfer_parms;
const void *src;
void *dst;
H5S_hyper_bound_t **lo_bounds;
@@ -39,7 +41,7 @@ typedef struct {
/* Static function prototypes */
static intn H5S_hyper_bsearch(hssize_t size, H5S_hyper_bound_t *barr,
size_t count);
-static H5S_hyper_region_t *
+static hid_t
H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
H5S_hyper_bound_t **lo_bounds,
H5S_hyper_bound_t **hi_bounds, hssize_t *pos,
@@ -56,14 +58,14 @@ static size_t H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
- const H5D_transfer_t xfer_mode,
+ const void *_xfer_parms,
void *buf/*out*/);
static herr_t H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space,
H5S_sel_iter_t *file_iter, size_t nelmts,
- const H5D_transfer_t xfer_mode,
+ const void *_xfer_parms,
const void *buf);
static size_t H5S_hyper_mgath (const void *_buf, size_t elmt_size,
const H5S_t *mem_space,
@@ -91,6 +93,9 @@ const H5S_mconv_t H5S_HYPER_MCONV[1] = {{
H5S_hyper_mscat, /*scatter */
}};
+/* Array for use with I/O algorithms which frequently need array of zeros */
+static const hssize_t zero[H5O_LAYOUT_NDIMS]={0}; /* Array of zeros */
+
/*-------------------------------------------------------------------------
* Function: H5S_hyper_init
@@ -178,14 +183,12 @@ H5S_hyper_favail (const H5S_t __unused__ *space,
int
H5S_hyper_compare_regions (const void *r1, const void *r2)
{
- if (((const H5S_hyper_region_t *)r1)->start <
- ((const H5S_hyper_region_t *)r2)->start)
+ if (((const H5S_hyper_region_t *)r1)->start < ((const H5S_hyper_region_t *)r2)->start)
return(-1);
- else if (((const H5S_hyper_region_t *)r1)->start >
- ((const H5S_hyper_region_t *)r2)->start)
- return(1);
+ else if (((const H5S_hyper_region_t *)r1)->start > ((const H5S_hyper_region_t *)r2)->start)
+ return(1);
else
- return(0);
+ return(0);
} /* end H5S_hyper_compare_regions */
/*-------------------------------------------------------------------------
@@ -205,12 +208,13 @@ H5S_hyper_compare_regions (const void *r1, const void *r2)
*
*-------------------------------------------------------------------------
*/
-static H5S_hyper_region_t *
+static hid_t
H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
H5S_hyper_bound_t **lo_bounds, H5S_hyper_bound_t **hi_bounds, hssize_t *pos,
hssize_t *offset)
{
- H5S_hyper_region_t *ret_value=NULL; /* Pointer to array to return */
+ hid_t ret_value=FAIL; /* Id of temporary buffer to return */
+ H5S_hyper_region_t *reg=NULL; /* Pointer to array of regions */
H5S_hyper_node_t *node; /* Region node for a given boundary */
size_t num_reg=0; /* Number of regions in array */
size_t curr_reg=0; /* The current region we are working with */
@@ -219,7 +223,7 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
intn temp_dim; /* Temporary dim. holder */
size_t i; /* Counters */
- FUNC_ENTER (H5S_hyper_get_regions, NULL);
+ FUNC_ENTER (H5S_hyper_get_regions, FAIL);
assert(num_regions);
assert(lo_bounds);
@@ -242,12 +246,13 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
if(pos[0]==(-1) || ((pos[0]+offset[0])>=lo_bounds[0][i].bound && (pos[0]+offset[0]) <= hi_bounds[0][i].bound)) {
/* Check if we've allocated the array yet */
if(num_reg==0) {
- /* Allocate array */
- ret_value=H5MM_malloc(sizeof(H5S_hyper_region_t));
+ /* Allocate temporary buffer */
+ ret_value=H5TB_get_buf(sizeof(H5S_hyper_region_t),0,(void **)&reg);
/* Initialize with first region */
- ret_value[0].start=MAX(lo_bounds[0][i].bound,pos[0])+offset[0];
- ret_value[0].end=hi_bounds[0][i].bound+offset[0];
+ reg[0].start=MAX(lo_bounds[0][i].bound,pos[0])+offset[0];
+ reg[0].end=hi_bounds[0][i].bound+offset[0];
+ reg[0].node=hi_bounds[0][i].node;
/* Increment the number of regions */
num_reg++;
@@ -256,20 +261,22 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
* Check if we should merge this region into the current
* region.
*/
- if(lo_bounds[0][i].bound<ret_value[curr_reg].end) {
- ret_value[curr_reg].end=MAX(hi_bounds[0][i].bound,
- ret_value[curr_reg].end)+(offset!=NULL ? offset[0] : 0 );
+ if(lo_bounds[0][i].bound<reg[curr_reg].end) {
+ reg[curr_reg].end=MAX(hi_bounds[0][i].bound,
+ reg[curr_reg].end)+(offset!=NULL ? offset[0] : 0 );
} else { /* no overlap with previous region, add new region */
/* Check if this is actually a different region */
- if(lo_bounds[0][i].bound!=ret_value[curr_reg].start &&
- hi_bounds[0][i].bound!=ret_value[curr_reg].end) {
+ if(lo_bounds[0][i].bound!=reg[curr_reg].start &&
+ hi_bounds[0][i].bound!=reg[curr_reg].end) {
/* Enlarge array */
- ret_value=H5MM_realloc(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)));
+ H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)));
+ reg=H5TB_buf_ptr(ret_value);
/* Initialize with new region */
- ret_value[num_reg].start=lo_bounds[0][i].bound+offset[0];
- ret_value[num_reg].end=hi_bounds[0][i].bound+offset[0];
+ reg[num_reg].start=lo_bounds[0][i].bound+offset[0];
+ reg[num_reg].end=hi_bounds[0][i].bound+offset[0];
+ reg[num_reg].node=hi_bounds[0][i].node;
/*
* Increment the number of regions & the current
@@ -329,19 +336,20 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
#ifdef QAK
printf("%s: check 3.1\n", FUNC);
#endif /* QAK */
- /* Allocate array */
- ret_value=H5MM_malloc(sizeof(H5S_hyper_region_t));
+ /* Allocate temporary buffer */
+ ret_value=H5TB_get_buf(sizeof(H5S_hyper_region_t),0,(void **)&reg);
/* Initialize with first region */
- ret_value[0].start=MAX(node->start[next_dim],pos[next_dim])+offset[next_dim];
- ret_value[0].end=node->end[next_dim]+offset[next_dim];
+ reg[0].start=MAX(node->start[next_dim],pos[next_dim])+offset[next_dim];
+ reg[0].end=node->end[next_dim]+offset[next_dim];
+ reg[0].node=node;
#ifdef QAK
printf("%s: check 3.2, lo_bounds=%d, start=%d, "
"hi_bounds=%d, end=%d\n",
FUNC, (int)node->start[next_dim],
- (int)ret_value[curr_reg].start,
+ (int)reg[curr_reg].start,
(int)node->end[next_dim],
- (int)ret_value[curr_reg].end);
+ (int)reg[curr_reg].end);
#endif /* QAK */
/* Increment the number of regions */
@@ -351,18 +359,18 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
printf("%s: check 4.0, lo_bounds=%d, start=%d, "
"hi_bounds=%d, end=%d\n",
FUNC, (int)node->start[next_dim],
- (int)ret_value[curr_reg].start,
+ (int)reg[curr_reg].start,
(int)node->end[next_dim],
- (int)ret_value[curr_reg].end);
+ (int)reg[curr_reg].end);
#endif /* QAK */
/* Enlarge array */
- ret_value=H5MM_realloc(ret_value,
- (sizeof(H5S_hyper_region_t)*
- (num_reg+1)));
+ H5TB_resize_buf(ret_value,(sizeof(H5S_hyper_region_t)*(num_reg+1)));
+ reg=H5TB_buf_ptr(ret_value);
/* Initialize with new region */
- ret_value[num_reg].start=node->start[next_dim]+offset[next_dim];
- ret_value[num_reg].end=node->end[next_dim]+offset[next_dim];
+ reg[num_reg].start=node->start[next_dim]+offset[next_dim];
+ reg[num_reg].end=node->end[next_dim]+offset[next_dim];
+ reg[num_reg].node=node;
/* Increment the number of regions & the current region */
num_reg++;
@@ -373,15 +381,15 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
/* Sort region list and eliminate duplicates if necessary */
if(num_reg>1) {
- HDqsort(ret_value,num_reg,sizeof(H5S_hyper_region_t),
- H5S_hyper_compare_regions);
+ HDqsort(reg,num_reg,sizeof(H5S_hyper_region_t),H5S_hyper_compare_regions);
for(i=1,curr_reg=0,uniq_reg=1; i<num_reg; i++) {
- if(ret_value[curr_reg].start!=ret_value[i].start &&
- ret_value[curr_reg].end!=ret_value[i].end) {
+ if(reg[curr_reg].start!=reg[i].start &&
+ reg[curr_reg].end!=reg[i].end) {
uniq_reg++;
curr_reg++;
- ret_value[curr_reg].start=ret_value[i].start;
- ret_value[curr_reg].end=ret_value[i].end;
+ reg[curr_reg].start=reg[i].start;
+ reg[curr_reg].end=reg[i].end;
+ reg[curr_reg].node=reg[i].node;
} /* end if */
} /* end for */
num_reg=uniq_reg;
@@ -392,17 +400,194 @@ H5S_hyper_get_regions (size_t *num_regions, intn dim, size_t bound_count,
*num_regions=num_reg;
#ifdef QAK
- printf("%s: check 10.0, ret_value=%p, num_reg=%d\n",
- FUNC,ret_value,num_reg);
+ printf("%s: check 10.0, reg=%p, num_reg=%d\n",
+ FUNC,reg,num_reg);
for(i=0; i<num_reg; i++)
printf("%s: start[%d]=%d, end[%d]=%d\n",
- FUNC,i,(int)ret_value[i].start,i,(int)ret_value[i].end);
+ FUNC,i,(int)reg[i].start,i,(int)reg[i].end);
#endif /* QAK */
FUNC_LEAVE (ret_value);
} /* end H5S_hyper_get_regions() */
/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_block_cache
+ *
+ * Purpose: Cache a hyperslab block for reading or writing.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 21, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_block_cache (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, uintn block_read)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ intn i; /* Counters */
+
+ FUNC_ENTER (H5S_hyper_block_cache, SUCCEED);
+
+ assert(node);
+ assert(fhyper_info);
+
+ /* Allocate temporary buffer of proper size */
+ if((node->cinfo.block_id=H5TB_get_buf(node->cinfo.size*fhyper_info->elmt_size,1,(void **)&(node->cinfo.block)))==FAIL)
+ HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "can't allocate hyperslab cache block");
+
+ /* Read in block, if we are read caching */
+ if(block_read) {
+ /* Copy the location of the region in the file */
+ HDmemcpy(file_offset,node->start,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to read */
+ for(i=0; i<fhyper_info->space->extent.u.simple.rank; i++)
+ hsize[i]=(node->end[i]-node->start[i])+1;
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ if (H5F_arr_read (fhyper_info->f, fhyper_info->layout,
+ fhyper_info->pline, fhyper_info->efl,
+ hsize, hsize, zero, file_offset,
+ fhyper_info->xfer_parms->xfer_mode, node->cinfo.block/*out*/)<0)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, FAIL, "read error");
+ } /* end if */
+ else {
+/* keep information for writing block later? */
+ } /* end else */
+
+ /* Set up parameters for accessing block */
+ node->cinfo.left=node->cinfo.size;
+ node->cinfo.pos=node->cinfo.block;
+
+ /* Set cached flag */
+ node->cinfo.cached=1;
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_block_cache() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_block_read
+ *
+ * Purpose: Read in data from a cached hyperslab block
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 21, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_block_read (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, hsize_t region_size)
+{
+ FUNC_ENTER (H5S_hyper_block_read, SUCCEED);
+
+ assert(node && node->cinfo.cached);
+ assert(fhyper_info);
+
+ /* Copy the elements into the user's buffer */
+ /*
+ !! NOTE !! This will need to be changed for different dimension
+ permutations from the standard 'C' ordering!
+ */
+ HDmemcpy(fhyper_info->dst,node->cinfo.pos,region_size*fhyper_info->elmt_size);
+
+ /* Decrement the number of elements left in block to read & move the offset */
+ node->cinfo.pos+=region_size*fhyper_info->elmt_size;
+ node->cinfo.left-=region_size;
+
+ /* If we've read in all the elements from the block, throw it away */
+ if(node->cinfo.left==0) {
+ /* Release the temporary buffer */
+ H5TB_release_buf(node->cinfo.block_id);
+
+ /* Reset the caching flag for next time */
+ node->cinfo.cached=0;
+ } /* end if */
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_block_read() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5S_hyper_block_write
+ *
+ * Purpose: Write out data to a cached hyperslab block
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 21, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5S_hyper_block_write (H5S_hyper_node_t *node, H5S_hyper_fhyper_info_t *fhyper_info, hsize_t region_size)
+{
+ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
+ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
+ intn i; /* Counters */
+
+ FUNC_ENTER (H5S_hyper_block_write, SUCCEED);
+
+ assert(node && node->cinfo.cached);
+ assert(fhyper_info);
+
+ /* Copy the elements into the user's buffer */
+ /*
+ !! NOTE !! This will need to be changed for different dimension
+ permutations from the standard 'C' ordering!
+ */
+ HDmemcpy(node->cinfo.pos,fhyper_info->src,region_size*fhyper_info->elmt_size);
+
+ /* Decrement the number of elements left in block to read & move the offset */
+ node->cinfo.pos+=region_size*fhyper_info->elmt_size;
+ node->cinfo.left-=region_size;
+
+ /* If we've read in all the elements from the block, throw it away */
+ if(node->cinfo.left==0) {
+ /* Copy the location of the region in the file */
+ HDmemcpy(file_offset,node->start,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to write */
+ for(i=0; i<fhyper_info->space->extent.u.simple.rank; i++)
+ hsize[i]=(node->end[i]-node->start[i])+1;
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ if (H5F_arr_write (fhyper_info->f, fhyper_info->layout,
+ fhyper_info->pline, fhyper_info->efl,
+ hsize, hsize, zero, file_offset,
+ fhyper_info->xfer_parms->xfer_mode, node->cinfo.block/*out*/)<0)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error");
+
+ /* Release the temporary buffer */
+ H5TB_release_buf(node->cinfo.block_id);
+
+ /* Reset the caching flag for next time */
+ node->cinfo.cached=0;
+ } /* end if */
+
+ FUNC_LEAVE (SUCCEED);
+} /* H5S_hyper_block_write() */
+
+/*-------------------------------------------------------------------------
* Function: H5S_hyper_fread
*
* Purpose: Recursively gathers data points from a file using the
@@ -425,7 +610,8 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ uintn parm_init=0; /* Whether one-shot parameters set up */
+ hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -442,10 +628,13 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
fhyper_info->space->select.sel_info.hyper.hyper_lst->count,
fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=NULL) {
+ fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=FAIL) {
+
+ /* Get the pointer to the actual regions array */
+ regions=H5TB_buf_ptr(reg_id);
/*
* Check if this is the second to last dimension in dataset (Which
@@ -461,50 +650,63 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
#endif /* QAK */
if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
- /* Set up hyperslab I/O parameters which apply to all regions */
-
- /* Copy the location of the region in the file */
- HDmemcpy(file_offset, fhyper_info->iter->hyp.pos,
- (fhyper_info->space->extent.u.simple.rank *
- sizeof(hssize_t)));
- file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+ /* perform I/O on data from regions */
+ for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ /* Compute the size of the region to read */
+ region_size=MIN(fhyper_info->nelmts, (regions[i].end-regions[i].start)+1);
- /* Set the hyperslab size to copy */
- hsize[0]=1;
- H5V_array_fill(hsize, hsize, sizeof(hsize[0]),
- fhyper_info->space->extent.u.simple.rank);
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ /* Check if this hyperslab block is cached or could be cached */
+ if(!regions[i].node->cinfo.cached && (fhyper_info->xfer_parms->cache_hyper && (fhyper_info->xfer_parms->block_limit==0 || fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) {
+ /* if we aren't cached, attempt to cache the block */
+ H5S_hyper_block_cache(regions[i].node,fhyper_info,1);
+ } /* end if */
- /* Set the memory offset to the origin */
- HDmemset (zero, 0, fhyper_info->layout->ndims*sizeof(*zero));
+ /* Read information from the cached block */
+ if(regions[i].node->cinfo.cached) {
+ if(H5S_hyper_block_read(regions[i].node,fhyper_info,region_size)==FAIL)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error");
+ }
+ else {
+ /* Set up hyperslab I/O parameters which apply to all regions */
+ if(!parm_init) {
+ /* Copy the location of the region in the file */
+ HDmemcpy(file_offset,fhyper_info->iter->hyp.pos,(fhyper_info->space->extent.u.simple.rank * sizeof(hssize_t)));
+ file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+
+ /* Set the hyperslab size to copy */
+ hsize[0]=1;
+ H5V_array_fill(hsize,hsize,sizeof(hsize[0]),fhyper_info->space->extent.u.simple.rank);
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+
+ /* Set flag */
+ parm_init=1;
+ } /* end if */
- /* perform I/O on data from regions */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
#ifdef QAK
- printf("%s: check 2.2, i=%d\n",FUNC,(int)i);
+ printf("%s: check 2.2, i=%d\n",FUNC,(int)i);
#endif /* QAK */
- region_size=MIN(fhyper_info->nelmts,
- (regions[i].end-regions[i].start)+1);
- hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
- file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+ /* Fill in the region specific parts of the I/O request */
+ hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
+ file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
- /*
- * Gather from file.
- */
- if (H5F_arr_read (fhyper_info->f, fhyper_info->layout,
- fhyper_info->pline, fhyper_info->efl,
- hsize, hsize, zero, file_offset,
- fhyper_info->xfer_mode,
- fhyper_info->dst/*out*/)<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0,
- "read error");
- }
+ /*
+ * Gather from file.
+ */
+ if (H5F_arr_read (fhyper_info->f, fhyper_info->layout,
+ fhyper_info->pline, fhyper_info->efl,
+ hsize, hsize, zero, file_offset,
+ fhyper_info->xfer_parms->xfer_mode,
+ fhyper_info->dst/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0,
+ "read error");
+ }
#ifdef QAK
- printf("%s: check 2.3, region #%d\n",FUNC,(int)i);
- for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++)
- printf("%s: %d - pos=%d\n",
- FUNC,j,(int)fhyper_info->iter->hyp.pos[j]);
+ printf("%s: check 2.3, region #%d\n",FUNC,(int)i);
+ for(j=0; j<fhyper_info->space->extent.u.simple.rank; j++)
+ printf("%s: %d - pos=%d\n",
+ FUNC,j,(int)fhyper_info->iter->hyp.pos[j]);
#endif /* QAK */
+ } /* end else */
/* Advance the pointer in the buffer */
fhyper_info->dst = ((uint8 *)fhyper_info->dst) +
@@ -520,8 +722,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
if(region_size==(hsize_t)((regions[i].end-regions[i].start)+1))
fhyper_info->iter->hyp.pos[dim+1]=(-1);
else
- fhyper_info->iter->hyp.pos[dim+1] = regions[i].start +
- region_size;
+ fhyper_info->iter->hyp.pos[dim+1] = regions[i].start + region_size;
/* Decrement the iterator count */
fhyper_info->iter->hyp.elmt_left-=region_size;
@@ -537,9 +738,7 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Step through each region in this dimension */
for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
/* Step through each location in each region */
- for(j=regions[i].start;
- j<=regions[i].end && fhyper_info->nelmts>0;
- j++) {
+ for(j=regions[i].start; j<=regions[i].end && fhyper_info->nelmts>0; j++) {
#ifdef QAK
printf("%s: check 4.0, dim=%d, location=%d\n",FUNC,dim,j);
#endif /* QAK */
@@ -560,8 +759,8 @@ H5S_hyper_fread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
} /* end for */
} /* end else */
- /* Free the region space */
- H5MM_xfree(regions);
+ /* Release the temporary buffer */
+ H5TB_release_buf(reg_id);
} /* end if */
FUNC_LEAVE (num_read);
@@ -595,9 +794,10 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
- size_t nelmts, const H5D_transfer_t xfer_mode,
+ size_t nelmts, const void *_xfer_parms,
void *_buf/*out*/)
{
+ const H5D_xfer_t *xfer_parms=(const H5D_xfer_t *)_xfer_parms; /* Coerce the type */
H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
@@ -642,7 +842,7 @@ H5S_hyper_fgath (H5F_t *f, const struct H5O_layout_t *layout,
fhyper_info.space=file_space;
fhyper_info.iter=file_iter;
fhyper_info.nelmts=nelmts;
- fhyper_info.xfer_mode=xfer_mode;
+ fhyper_info.xfer_parms=xfer_parms;
fhyper_info.src=NULL;
fhyper_info.dst=_buf;
fhyper_info.lo_bounds=lo_bounds;
@@ -688,7 +888,8 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ uintn parm_init=0; /* Whether one-shot parameters set up */
+ hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -699,52 +900,77 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
assert(fhyper_info);
+#ifdef QAK
+ printf("%s: check 1.0\n", FUNC);
+#endif /* QAK */
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
fhyper_info->space->select.sel_info.hyper.hyper_lst->count,
fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=NULL) {
+ fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=FAIL) {
+
+ /* Get the pointer to the actual regions array */
+ regions=H5TB_buf_ptr(reg_id);
+#ifdef QAK
+ printf("%s: check 1.1, regions=%p\n", FUNC,regions);
+#endif /* QAK */
/* Check if this is the second to last dimension in dataset */
/* (Which means that we've got a list of the regions in the fastest */
/* changing dimension and should input those regions) */
if((dim+2)==fhyper_info->space->extent.u.simple.rank) {
- /* Set up hyperslab I/O parameters which apply to all regions */
+ /* perform I/O on data from regions */
+ for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
+ /* Compute the size of the region to read */
+ region_size=MIN(fhyper_info->nelmts, (regions[i].end-regions[i].start)+1);
- /* Copy the location of the region in the file */
- HDmemcpy(file_offset, fhyper_info->iter->hyp.pos,
- (fhyper_info->space->extent.u.simple.rank *
- sizeof(hssize_t)));
- file_offset[fhyper_info->space->extent.u.simple.rank]=0;
+ /* Check if this hyperslab block is cached or could be cached */
+ if(!regions[i].node->cinfo.cached && (fhyper_info->xfer_parms->cache_hyper && (fhyper_info->xfer_parms->block_limit==0 || fhyper_info->xfer_parms->block_limit>=(regions[i].node->cinfo.size*fhyper_info->elmt_size)))) {
+ /* if we aren't cached, attempt to cache the block */
+ H5S_hyper_block_cache(regions[i].node,fhyper_info,0);
+ } /* end if */
- /* Set the hyperslab size to copy */
- hsize[0]=1;
- H5V_array_fill(hsize, hsize, sizeof(hsize[0]),
- fhyper_info->space->extent.u.simple.rank);
- hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
+ /* Read information from the cached block */
+ if(regions[i].node->cinfo.cached) {
+ if(H5S_hyper_block_write(regions[i].node,fhyper_info,region_size)==FAIL)
+ HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
+ }
+ else {
+ /* Set up hyperslab I/O parameters which apply to all regions */
+ if(!parm_init) {
- /* Set the memory offset to the origin */
- HDmemset (zero, 0, fhyper_info->layout->ndims*sizeof(*zero));
+ /* Copy the location of the region in the file */
+ HDmemcpy(file_offset, fhyper_info->iter->hyp.pos,
+ (fhyper_info->space->extent.u.simple.rank *
+ sizeof(hssize_t)));
+ file_offset[fhyper_info->space->extent.u.simple.rank]=0;
- /* perform I/O on data from regions */
- for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
- region_size=MIN(fhyper_info->nelmts,
- (regions[i].end-regions[i].start)+1);
- hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
- file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+ /* Set the hyperslab size to copy */
+ hsize[0]=1;
+ H5V_array_fill(hsize, hsize, sizeof(hsize[0]),
+ fhyper_info->space->extent.u.simple.rank);
+ hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
- /*
- * Scatter from file.
- */
- if (H5F_arr_write (fhyper_info->f, fhyper_info->layout,
- fhyper_info->pline, fhyper_info->efl,
- hsize, hsize, zero, file_offset,
- fhyper_info->xfer_mode,
- fhyper_info->src)<0) {
- HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
- }
+ /* Set flag */
+ parm_init=1;
+ } /* end if */
+
+ hsize[fhyper_info->space->extent.u.simple.rank-1]=region_size;
+ file_offset[fhyper_info->space->extent.u.simple.rank-1]=regions[i].start;
+
+ /*
+ * Scatter to file.
+ */
+ if (H5F_arr_write (fhyper_info->f, fhyper_info->layout,
+ fhyper_info->pline, fhyper_info->efl,
+ hsize, hsize, zero, file_offset,
+ fhyper_info->xfer_parms->xfer_mode,
+ fhyper_info->src)<0) {
+ HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error");
+ }
+ } /* end else */
/* Advance the pointer in the buffer */
fhyper_info->src = ((const uint8 *)fhyper_info->src) +
@@ -794,10 +1020,13 @@ H5S_hyper_fwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
} /* end for */
} /* end else */
- /* Free the region space */
- H5MM_xfree(regions);
+ /* Release the temporary buffer */
+ H5TB_release_buf(reg_id);
} /* end if */
+#ifdef QAK
+ printf("%s: check 2.0\n", FUNC);
+#endif /* QAK */
FUNC_LEAVE (num_written);
} /* H5S_hyper_fwrite() */
@@ -826,9 +1055,10 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
const struct H5O_pline_t *pline,
const struct H5O_efl_t *efl, size_t elmt_size,
const H5S_t *file_space, H5S_sel_iter_t *file_iter,
- size_t nelmts, const H5D_transfer_t xfer_mode,
+ size_t nelmts, const void *_xfer_parms,
const void *_buf)
{
+ const H5D_xfer_t *xfer_parms=(const H5D_xfer_t *)_xfer_parms; /* Coerce the type */
H5S_hyper_bound_t **lo_bounds; /* Lower (closest to the origin) bound array for each dimension */
H5S_hyper_bound_t **hi_bounds; /* Upper (farthest from the origin) bound array for each dimension */
H5S_hyper_fhyper_info_t fhyper_info; /* Block of parameters to pass into recursive calls */
@@ -874,7 +1104,7 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
fhyper_info.space=file_space;
fhyper_info.iter=file_iter;
fhyper_info.nelmts=nelmts;
- fhyper_info.xfer_mode=xfer_mode;
+ fhyper_info.xfer_parms=xfer_parms;
fhyper_info.src=_buf;
fhyper_info.dst=NULL;
fhyper_info.lo_bounds=lo_bounds;
@@ -888,6 +1118,9 @@ H5S_hyper_fscat (H5F_t *f, const struct H5O_layout_t *layout,
H5MM_xfree(lo_bounds);
H5MM_xfree(hi_bounds);
+#ifdef QAK
+ printf("%s: check 2.0\n", FUNC);
+#endif /* QAK */
FUNC_LEAVE (num_written);
} /* H5S_hyper_fscat() */
@@ -915,7 +1148,7 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in memory*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -932,10 +1165,13 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
fhyper_info->space->select.sel_info.hyper.hyper_lst->count,
fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=NULL) {
+ fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=FAIL) {
+
+ /* Get the pointer to the actual regions array */
+ regions=H5TB_buf_ptr(reg_id);
/* Check if this is the second to last dimension in dataset */
/* (Which means that we've got a list of the regions in the fastest */
@@ -970,10 +1206,6 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
fhyper_info->space->extent.u.simple.rank);
hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
- /* Set the memory offset to the origin */
- HDmemset (zero, 0, ((fhyper_info->space->extent.u.simple.rank+1)*
- sizeof(*zero)));
-
/* perform I/O on data from regions */
for(i=0; i<num_regions && fhyper_info->nelmts>0; i++) {
region_size=MIN(fhyper_info->nelmts,
@@ -1049,8 +1281,8 @@ H5S_hyper_mread (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
} /* end for */
} /* end else */
- /* Free the region space */
- H5MM_xfree(regions);
+ /* Release the temporary buffer */
+ H5TB_release_buf(reg_id);
} /* end if */
FUNC_LEAVE (num_read);
@@ -1190,7 +1422,7 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
hssize_t mem_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/
hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */
hsize_t region_size; /* Size of lowest region */
- hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */
+ hid_t reg_id; /* ID of temporary region buffer */
H5S_hyper_region_t *regions; /* Pointer to array of hyperslab nodes overlapped */
size_t num_regions; /* number of regions overlapped */
size_t i; /* Counters */
@@ -1206,10 +1438,13 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
/* Get a sorted list (in the next dimension down) of the regions which */
/* overlap the current index in this dim */
- if((regions=H5S_hyper_get_regions(&num_regions,dim,
+ if((reg_id=H5S_hyper_get_regions(&num_regions,dim,
fhyper_info->space->select.sel_info.hyper.hyper_lst->count,
fhyper_info->lo_bounds, fhyper_info->hi_bounds,
- fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=NULL) {
+ fhyper_info->iter->hyp.pos,fhyper_info->space->select.offset))!=FAIL) {
+
+ /* Get the pointer to the actual regions array */
+ regions=H5TB_buf_ptr(reg_id);
#ifdef QAK
printf("%s: check 2.0, rank=%d\n",
@@ -1242,10 +1477,6 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
fhyper_info->space->extent.u.simple.rank);
hsize[fhyper_info->space->extent.u.simple.rank]=fhyper_info->elmt_size;
- /* Set the memory offset to the origin */
- HDmemset (zero, 0, ((fhyper_info->space->extent.u.simple.rank+1)*
- sizeof(*zero)));
-
#ifdef QAK
printf("%s: check 3.0\n",FUNC);
#endif /* QAK */
@@ -1323,8 +1554,8 @@ H5S_hyper_mwrite (intn dim, H5S_hyper_fhyper_info_t *fhyper_info)
} /* end for */
} /* end else */
- /* Free the region space */
- H5MM_xfree(regions);
+ /* Release the temporary buffer */
+ H5TB_release_buf(reg_id);
} /* end if */
FUNC_LEAVE (num_read);
@@ -1545,6 +1776,13 @@ H5S_hyper_add (H5S_t *space, const hssize_t *start, const hsize_t *size)
elem_count*=size[i];
} /* end for */
+ /* Initialize caching parameters */
+ slab->cinfo.cached=0;
+ slab->cinfo.size=elem_count;
+ slab->cinfo.left=0;
+ slab->cinfo.block_id=(-1);
+ slab->cinfo.block=slab->cinfo.pos=NULL;
+
#ifdef QAK
printf("%s: check 3.0, lo_bounds=%p, hi_bounds=%p\n",
FUNC, space->select.sel_info.hyper.hyper_lst->lo_bounds,
@@ -1942,6 +2180,7 @@ H5S_hyper_copy (H5S_t *dst, const H5S_t *src)
if((new = H5MM_malloc(sizeof(H5S_hyper_node_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate point node");
+ HDmemcpy(new,curr,sizeof(H5S_hyper_node_t)); /* copy caching information */
if((new->start = H5MM_malloc(src->extent.u.simple.rank*sizeof(hssize_t)))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"can't allocate coordinate information");