diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 1998-09-21 23:43:19 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 1998-09-21 23:43:19 (GMT) |
commit | 1fe48c7f19c2eed94a22179459efc1487ee65217 (patch) | |
tree | 41249aed6d1d5f95f6db00fa33ee7d40f434ca2a /src | |
parent | 7b189913384c500b71cb82d1780d6d07b170583c (diff) | |
download | hdf5-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')
-rw-r--r-- | src/.distdep | 15 | ||||
-rw-r--r-- | src/H5D.c | 69 | ||||
-rw-r--r-- | src/H5Distore.c | 2 | ||||
-rw-r--r-- | src/H5Dprivate.h | 2 | ||||
-rw-r--r-- | src/H5Fistore.c | 2 | ||||
-rw-r--r-- | src/H5P.c | 84 | ||||
-rw-r--r-- | src/H5Ppublic.h | 2 | ||||
-rw-r--r-- | src/H5Sall.c | 15 | ||||
-rw-r--r-- | src/H5Shyper.c | 537 | ||||
-rw-r--r-- | src/H5Spoint.c | 15 | ||||
-rw-r--r-- | src/H5Sprivate.h | 31 | ||||
-rw-r--r-- | src/H5Sselect.c | 12 | ||||
-rw-r--r-- | src/H5TB.c | 92 | ||||
-rw-r--r-- | src/H5TBprivate.h | 10 | ||||
-rw-r--r-- | src/H5V.c | 52 |
15 files changed, 664 insertions, 276 deletions
diff --git a/src/.distdep b/src/.distdep index 52a7f29..3da24b4 100644 --- a/src/.distdep +++ b/src/.distdep @@ -25,10 +25,7 @@ H5.o: \ H5Gpublic.h \ H5Oprivate.h \ H5Opublic.h \ - H5HGprivate.h \ - H5HGpublic.h \ - H5Tprivate.h \ - H5Tpublic.h + H5HGprivate.h H5A.o: \ H5A.c \ H5private.h \ @@ -166,7 +163,9 @@ H5F.o: \ H5Eprivate.h \ H5Epublic.h \ H5MMprivate.h \ - H5MMpublic.h + H5MMpublic.h \ + H5Pprivate.h \ + H5Ppublic.h H5Farray.o: \ H5Farray.c \ H5private.h \ @@ -1140,8 +1139,4 @@ H5Z.o: \ H5HGprivate.h \ H5HGpublic.h \ H5Tprivate.h \ - H5Tpublic.h \ - H5Sprivate.h \ - H5Spublic.h \ - H5Zprivate.h \ - H5Zpublic.h + H5Tpublic.h @@ -28,6 +28,7 @@ static char RcsId[] = "@(#)$Revision$"; #include <H5Oprivate.h> /* Object headers */ #include <H5Pprivate.h> /* Property lists */ #include <H5Sprivate.h> /* Dataspace functions rky 980813 */ +#include <H5TBprivate.h> /* Temporary buffers */ #include <H5Zprivate.h> /* Data filters */ #ifdef QAK @@ -71,6 +72,12 @@ const H5D_xfer_t H5D_xfer_dflt = { NULL, /* Type conversion buffer or NULL */ NULL, /* Background buffer or NULL */ H5T_BKG_NO, /* Type of background buffer needed */ +#ifndef HAVE_PARALLEL + 1, /* Cache the hyperslab blocks by default */ +#else /* HAVE_PARALLEL */ + 0, /* Don't cache the hyperslab blocks by default (for parallel) */ +#endif /* HAVE_PARALLEL */ + 0, /* Default to no upper limit on hyperslab block size to cache */ #ifdef HAVE_PARALLEL H5D_XFER_DFLT, /* Independent data transfer */ #endif @@ -1280,6 +1287,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, hsize_t nelmts; /*number of elements */ size_t smine_start; /*strip mine start loc */ size_t n, smine_nelmts; /*elements per strip */ + hid_t tconv_id=FAIL, bkg_id=FAIL; /* Conversion buffer IDs */ uint8 *tconv_buf = NULL; /*data type conv buffer */ uint8 *bkg_buf = NULL; /*background buffer */ H5T_conv_t tconv_func = NULL; /*conversion function */ @@ -1457,16 +1465,18 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/ } if (NULL==(tconv_buf=xfer_parms->tconv_buf)) { - if (NULL==(tconv_buf = H5MM_malloc (target_size))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - } + /* Allocate temporary buffer */ + if (FAIL==(tconv_id = H5TB_get_buf (target_size,1,(void **)&tconv_buf))) { + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } } if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) { - if (NULL==(bkg_buf = H5MM_malloc (request_nelmts * dst_type_size))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for background buffer"); - } + /* Allocate temporary buffer */ + if (FAIL==(bkg_id = H5TB_get_buf (request_nelmts*dst_type_size,1,(void **)&bkg_buf))) { + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } } #ifdef QAK @@ -1497,7 +1507,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->pline), &(dataset->create_parms->efl), src_type_size, file_space, &file_iter, smine_nelmts, - xfer_parms->xfer_mode, tconv_buf/*out*/); + xfer_parms, tconv_buf/*out*/); #ifdef H5S_DEBUG H5_timer_end(&(sconv->stats[1].gath_timer), &timer); sconv->stats[1].gath_nbytes += n * src_type_size; @@ -1599,8 +1609,8 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (src_id >= 0) H5I_dec_ref(src_id); if (dst_id >= 0) H5I_dec_ref(dst_id); - if (tconv_buf && NULL==xfer_parms->tconv_buf) H5MM_xfree(tconv_buf); - if (bkg_buf && NULL==xfer_parms->bkg_buf) H5MM_xfree (bkg_buf); + if (tconv_buf && NULL==xfer_parms->tconv_buf) H5TB_release_buf(tconv_id); + if (bkg_buf && NULL==xfer_parms->bkg_buf) H5TB_release_buf (bkg_id); if (free_this_space) H5S_close (free_this_space); FUNC_LEAVE(ret_value); } @@ -1636,6 +1646,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, hsize_t nelmts; /*total number of elmts */ size_t smine_start; /*strip mine start loc */ size_t n, smine_nelmts; /*elements per strip */ + hid_t tconv_id=FAIL, bkg_id=FAIL; /* Conversion buffer IDs */ uint8 *tconv_buf = NULL; /*data type conv buffer */ uint8 *bkg_buf = NULL; /*background buffer */ H5T_conv_t tconv_func = NULL; /*conversion function */ @@ -1821,16 +1832,18 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/ } if (NULL==(tconv_buf=xfer_parms->tconv_buf)) { - if (NULL==(tconv_buf = H5MM_malloc (target_size))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for type conversion"); - } + /* Allocate temporary buffer */ + if (FAIL==(tconv_id = H5TB_get_buf (target_size,1,(void **)&tconv_buf))) { + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } } if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) { - if (NULL==(bkg_buf = H5MM_malloc (request_nelmts * dst_type_size))) { - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed for background buffer"); - } + /* Allocate temporary buffer */ + if (FAIL==(bkg_id = H5TB_get_buf (request_nelmts*dst_type_size,1,(void **)&bkg_buf))) { + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed for type conversion"); + } } #ifdef QAK @@ -1894,8 +1907,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->pline), &(dataset->create_parms->efl), dst_type_size, file_space, &bkg_iter, smine_nelmts, - xfer_parms->xfer_mode, - bkg_buf/*out*/); + xfer_parms, bkg_buf/*out*/); #ifdef H5S_DEBUG H5_timer_end(&(sconv->stats[0].bkg_timer), &timer); sconv->stats[0].bkg_nbytes += n * dst_type_size; @@ -1923,6 +1935,9 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed"); } +#ifdef QAK + printf("%s: check 6.3\n",FUNC); +#endif /* * Scatter the data out to the file. @@ -1934,7 +1949,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, &(dataset->create_parms->pline), &(dataset->create_parms->efl), dst_type_size, file_space, &file_iter, smine_nelmts, - xfer_parms->xfer_mode, tconv_buf); + xfer_parms, tconv_buf); +#ifdef QAK + printf("%s: check 6.35\n",FUNC); +#endif #ifdef H5S_DEBUG H5_timer_end(&(sconv->stats[0].scat_timer), &timer); sconv->stats[0].scat_nbytes += smine_nelmts * dst_type_size; @@ -1945,6 +1963,9 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, } } +#ifdef QAK + printf("%s: check 6.4\n",FUNC); +#endif /* * Update modification time. We have to do this explicitly because * writing to a dataset doesn't necessarily change the object header. @@ -1965,8 +1986,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, if (src_id >= 0) H5I_dec_ref(src_id); if (dst_id >= 0) H5I_dec_ref(dst_id); - if (tconv_buf && NULL==xfer_parms->tconv_buf) H5MM_xfree(tconv_buf); - if (bkg_buf && NULL==xfer_parms->bkg_buf) H5MM_xfree (bkg_buf); + if (tconv_buf && NULL==xfer_parms->tconv_buf) H5TB_release_buf(tconv_id); + if (bkg_buf && NULL==xfer_parms->bkg_buf) H5TB_release_buf (bkg_id); if (free_this_space) H5S_close (free_this_space); FUNC_LEAVE(ret_value); } diff --git a/src/H5Distore.c b/src/H5Distore.c index 48ad749..aa7c266 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1051,7 +1051,6 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, size_t chunk_alloc=0; /*allocated chunk size */ herr_t status; /*func return status */ void *chunk=NULL; /*the file chunk */ - void *temp=NULL; /*temporary chunk buffer*/ void *ret_value=NULL; /*return value */ FUNC_ENTER (H5F_istore_lock, NULL); @@ -1216,7 +1215,6 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, ret_value = chunk; done: if (!ret_value) H5MM_xfree (chunk); - H5MM_xfree (temp); FUNC_LEAVE (ret_value); } diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 245ed58..5bc6920 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -55,6 +55,8 @@ typedef struct H5D_xfer_t { void *tconv_buf; /*type conversion buffer or null */ void *bkg_buf; /*background buffer or null */ H5T_bkg_t need_bkg; /*type of background buffer needed */ + uintn cache_hyper; /* Whether to (try to) cache hyperslab blocks during I/O */ + uintn block_limit; /* The largest hyperslab block to try to cache */ H5D_transfer_t xfer_mode; /*independent or collective transfer */ } H5D_xfer_t; diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 48ad749..aa7c266 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1051,7 +1051,6 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, size_t chunk_alloc=0; /*allocated chunk size */ herr_t status; /*func return status */ void *chunk=NULL; /*the file chunk */ - void *temp=NULL; /*temporary chunk buffer*/ void *ret_value=NULL; /*return value */ FUNC_ENTER (H5F_istore_lock, NULL); @@ -1216,7 +1215,6 @@ H5F_istore_lock (H5F_t *f, const H5O_layout_t *layout, ret_value = chunk; done: if (!ret_value) H5MM_xfree (chunk); - H5MM_xfree (temp); FUNC_LEAVE (ret_value); } @@ -2074,6 +2074,90 @@ H5Pget_buffer(hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/) /*------------------------------------------------------------------------- + * Function: H5Pset_hyper_cache + * + * Purpose: Given a dataset transfer property list, indicate whether to cache + * the hyperslab blocks during the I/O (which speeds things up) and the + * maximum size of the hyperslab block to cache. If a block is smaller + * than to limit, it may still not be cached if no memory is available. + * Setting the limit to 0 indicates no limitation on the size of block + * to attempt to cache. + * + * The default is to cache blocks with no limit on block size for serial + * I/O and to not cache blocks for parallel I/O + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Monday, September 21, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit) +{ + H5D_xfer_t *plist = NULL; + + FUNC_ENTER (H5Pset_hyper_cache, FAIL); + + /* Check arguments */ + if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); + } + + /* Update property list */ + plist->cache_hyper = (cache>0) ? 1 : 0; + plist->block_limit = limit; + + FUNC_LEAVE (SUCCEED); +} /* end H5P_set_hyper_cache() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_hyper_cache + * + * Purpose: Reads values previously set with H5Pset_hyper_cache(). + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Monday, September 21, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_hyper_cache(hid_t plist_id, unsigned *cache/*out*/, unsigned *limit/*out*/) +{ + H5D_xfer_t *plist = NULL; + + FUNC_ENTER (H5Pget_hyper_cache, 0); + + /* Check arguments */ + if (H5P_DATASET_XFER != H5P_get_class (plist_id) || + NULL == (plist = H5I_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, 0, + "not a dataset transfer property list"); + } + + /* Return values */ + if (cache) *cache = plist->cache_hyper; + if (limit) *limit = plist->block_limit; + + FUNC_LEAVE (SUCCEED); +} /* end H5Pget_hyper_cache() */ + + +/*------------------------------------------------------------------------- * Function: H5Pset_preserve * * Purpose: When reading or writing compound data types and the diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 028fa57..d82bb83 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -105,6 +105,8 @@ herr_t H5Pset_cache (hid_t plist_id, int mdc_nelmts, size_t rdcc_nbytes, double rdcc_w0); herr_t H5Pget_cache (hid_t plist_id, int *mdc_nelmts, size_t *rdcc_nbytes, double *rdcc_w0); +herr_t H5Pset_hyper_cache(hid_t plist_id, unsigned cache, unsigned limit); +herr_t H5Pget_hyper_cache(hid_t plist_id, unsigned *cache, unsigned *limit); #ifdef HAVE_PARALLEL herr_t H5Pset_mpi (hid_t plist_id, MPI_Comm comm, MPI_Info info); diff --git a/src/H5Sall.c b/src/H5Sall.c index 022170c..71d8181 100644 --- a/src/H5Sall.c +++ b/src/H5Sall.c @@ -11,6 +11,7 @@ #include <H5Eprivate.h> #include <H5Sprivate.h> #include <H5Vprivate.h> +#include <H5Dprivate.h> /* Interface initialization */ #define PABLO_MASK H5S_all_mask @@ -26,14 +27,14 @@ static size_t H5S_all_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_all_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_all_mgath (const void *_buf, size_t elmt_size, const H5S_t *mem_space, H5S_sel_iter_t *mem_iter, @@ -170,8 +171,9 @@ H5S_all_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, void *_buf/*out*/) + const void *_xfer_parms, void *_buf/*out*/) { + const H5D_xfer_t *xfer_parms=(const H5D_xfer_t *)_xfer_parms; /* Coerce the type */ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ @@ -224,7 +226,7 @@ H5S_all_fgath (H5F_t *f, const struct H5O_layout_t *layout, * Gather from file. */ if (H5F_arr_read (f, layout, pline, efl, hsize, hsize, zero, file_offset, - xfer_mode, buf/*out*/)<0) { + xfer_parms->xfer_mode, buf/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } @@ -260,8 +262,9 @@ H5S_all_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 *_buf) + const void *_xfer_parms, const void *_buf) { + const H5D_xfer_t *xfer_parms=(const H5D_xfer_t *)_xfer_parms; /* Coerce the type */ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */ @@ -310,7 +313,7 @@ H5S_all_fscat (H5F_t *f, const struct H5O_layout_t *layout, * Scatter to file. */ if (H5F_arr_write (f, layout, pline, efl, hsize, hsize, zero, - file_offset, xfer_mode, buf)<0) { + file_offset, xfer_parms->xfer_mode, buf)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, FAIL, "write error"); } 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 **)®); /* 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 **)®); /* 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"); diff --git a/src/H5Spoint.c b/src/H5Spoint.c index cf6fdee..f3edd63 100644 --- a/src/H5Spoint.c +++ b/src/H5Spoint.c @@ -12,6 +12,7 @@ #include <H5MMprivate.h> #include <H5Sprivate.h> #include <H5Vprivate.h> +#include <H5Dprivate.h> /* Interface initialization */ #define PABLO_MASK H5S_point_mask @@ -27,14 +28,14 @@ static size_t H5S_point_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_point_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_point_mgath (const void *_buf, size_t elmt_size, const H5S_t *mem_space, @@ -266,9 +267,10 @@ H5S_point_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 */ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of slab in file*/ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero */ @@ -317,7 +319,7 @@ H5S_point_fgath (H5F_t *f, const struct H5O_layout_t *layout, /* Go read the point */ if (H5F_arr_read (f, layout, pline, efl, hsize, hsize, zero, - file_offset, xfer_mode, buf/*out*/)<0) { + file_offset, xfer_parms->xfer_mode, buf/*out*/)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_READERROR, 0, "read error"); } @@ -375,9 +377,10 @@ H5S_point_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 */ hssize_t file_offset[H5O_LAYOUT_NDIMS]; /*offset of hyperslab */ hsize_t hsize[H5O_LAYOUT_NDIMS]; /*size of hyperslab */ hssize_t zero[H5O_LAYOUT_NDIMS]; /*zero vector */ @@ -445,7 +448,7 @@ H5S_point_fscat (H5F_t *f, const struct H5O_layout_t *layout, #endif /* QAK */ /* Go write the point */ if (H5F_arr_write (f, layout, pline, efl, hsize, hsize, zero, - file_offset, xfer_mode, buf)<0) { + file_offset, xfer_parms->xfer_mode, buf)<0) { HRETURN_ERROR (H5E_DATASPACE, H5E_WRITEERROR, 0, "write error"); } diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h index 862de9a..95c6ae6 100644 --- a/src/H5Sprivate.h +++ b/src/H5Sprivate.h @@ -71,19 +71,28 @@ typedef struct { H5S_pnt_node_t *head; /* Pointer to head of point list */ } H5S_pnt_list_t; +/* Node in hyperslab selection list */ +typedef struct H5S_hyper_node_tag { + hssize_t *start; /* Pointer to a corner of a hyperslab closest to the origin */ + hssize_t *end; /* Pointer to a corner of a hyperslab furthest from the origin */ + struct { + uintn cached; /* Flag to indicate that the block is cached (during I/O only) */ + uintn size; /* Size of cached block (in elements) */ + uintn left; /* Elements left to access in block */ + hid_t block_id; /* Temporary buffer ID */ + uint8 *block; /* Pointer into temporary buffer for cache */ + uint8 *pos; /* Pointer to current location within block */ + } cinfo; + struct H5S_hyper_node_tag *next; /* pointer to next hyperslab in list */ +} H5S_hyper_node_t; + /* Region in dimension */ typedef struct H5S_hyper_region_tag { hssize_t start; /* The low bound of a region in a dimension */ hssize_t end; /* The high bound of a region in a dimension */ + H5S_hyper_node_t *node; /* pointer to the node the region is in */ } H5S_hyper_region_t; -/* Node in hyperslab selection list */ -typedef struct H5S_hyper_node_tag { - hssize_t *start; /* Pointer to a corner of a hyperslab closest to the origin */ - hssize_t *end; /* Pointer to a corner of a hyperslab furthest from the origin */ - struct H5S_hyper_node_tag *next; /* pointer to next hyperslab in list */ -} H5S_hyper_node_t; - /* Information about hyperslab boundary and pointer to hyperslab node */ typedef struct { hssize_t bound; /* Location of boundary */ @@ -183,7 +192,7 @@ typedef struct H5S_fconv_t { 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 *tconv_buf/*out*/); /* Scatter elements from type conversion buffer to disk */ @@ -191,7 +200,7 @@ typedef struct H5S_fconv_t { 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 *tconv_buf); } H5S_fconv_t; @@ -276,10 +285,6 @@ extern const H5S_mconv_t H5S_ALL_MCONV[]; extern const H5S_fconv_t H5S_HYPER_FCONV[]; extern const H5S_mconv_t H5S_HYPER_MCONV[]; -#ifdef LATER_ROBB -#endif - - H5S_t *H5S_create (H5S_class_t type); H5S_t *H5S_copy (const H5S_t *src); herr_t H5S_close_simple (H5S_simple_t *simple); diff --git a/src/H5Sselect.c b/src/H5Sselect.c index 4d9a84d..0620570 100644 --- a/src/H5Sselect.c +++ b/src/H5Sselect.c @@ -14,6 +14,7 @@ #include <H5MMprivate.h> #include <H5Sprivate.h> #include <H5Vprivate.h> +#include <H5TBprivate.h> /* Interface initialization */ #define PABLO_MASK H5S_select_mask @@ -293,7 +294,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, const hsize_t count[/*space_id*/], const hsize_t block[/*space_id*/]) { - + hid_t stride_id=FAIL,block_id=FAIL; /* Stride & block temp. buffer IDs */ hsize_t *_stride=NULL; /* Stride array */ hsize_t *_block=NULL; /* Block size array */ hssize_t slab[H5O_LAYOUT_NDIMS]; /* Location of the block to add for strided selections */ @@ -316,7 +317,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if(stride==NULL) { hssize_t fill=1; - if((_stride = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))==NULL) + /* Allocate temporary buffer */ + if((stride_id = H5TB_get_buf(sizeof(hssize_t)*space->extent.u.simple.rank,0,(void **)&_stride)) ==FAIL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate stride vector"); H5V_array_fill(_stride,&fill,sizeof(hssize_t),space->extent.u.simple.rank); @@ -327,7 +329,7 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, if(block==NULL) { hssize_t fill=1; - if((_block = H5MM_malloc(sizeof(hssize_t)*space->extent.u.simple.rank))==NULL) + if((block_id = H5TB_get_buf(sizeof(hssize_t)*space->extent.u.simple.rank,0,(void **)&_block))==FAIL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate block vector"); H5V_array_fill(_block,&fill,sizeof(hssize_t),space->extent.u.simple.rank); @@ -444,8 +446,8 @@ H5S_select_hyperslab (H5S_t *space, H5S_seloper_t op, #endif /* QAK */ done: - H5MM_xfree(_stride); - H5MM_xfree(_block); + if(_stride!=NULL) H5TB_release_buf(stride_id); + if(_block!=NULL) H5TB_release_buf(block_id); FUNC_LEAVE (ret_value); } @@ -18,11 +18,11 @@ * Purpose: Temporary buffer management functions * * Library Public API Functions: - * H5TBget_buf - Get an ID for a temporary buffer - * H5TBbuf_ptr - Get a pointer to the temporary buffer's memory - * H5TBresize_buf - Resize a temporary buffer - * H5TBgarbage_coll- Free all unused temporary buffers - * H5TBrelease_buf - Release temporary buffer + * H5TB_get_buf - Get an ID for a temporary buffer + * H5TB_buf_ptr - Get a pointer to the temporary buffer's memory + * H5TB_resize_buf - Resize a temporary buffer + * H5TB_garbage_coll- Free all unused temporary buffers + * H5TB_release_buf - Release temporary buffer * * Modifications: * @@ -112,8 +112,25 @@ H5TB_init_interface(void) static void H5TB_term_interface(void) { + H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */ + *next; /* pointer to next temp. buffer */ + /* Destroy the atom group */ + H5I_destroy_group(H5_TEMPBUF); + /* Step through the list and free the buffers */ + while(curr!=NULL) { + next=curr->next; + + if(curr->buf!=NULL) + H5MM_xfree(curr->buf); + H5MM_xfree(curr); + + curr=next; + } /* end while */ + + /* Reset head & tail pointers */ + H5TB_list_head=H5TB_list_tail=NULL; } /*------------------------------------------------------------------------- @@ -147,14 +164,16 @@ herr_t H5TB_close(H5TB_t *tb) /*-------------------------------------------------------------------------- NAME - H5TBget_buf + H5TB_get_buf PURPOSE Get an ID for a temporary buffer USAGE - hid_t H5TBget_buf(size,resize) + hid_t H5TB_get_buf(size,resize,ptr) hsize_t size; IN: Minimum size of buffer requested hbool_t resize; IN: Whether to resize an existing buffer or get a new buffer if one doesn't match the correct size + void **ptr; OUT: Pointer to a pointer to set to the buffer + address, if not NULL RETURNS Valid buffer ID on success, negative on failure DESCRIPTION @@ -169,17 +188,16 @@ herr_t H5TB_close(H5TB_t *tb) REVISION LOG --------------------------------------------------------------------------*/ hid_t -H5TBget_buf(hsize_t size, hbool_t resize) +H5TB_get_buf(hsize_t size, hbool_t resize, void **ptr) { hid_t ret_value = FAIL; H5TB_t *curr=H5TB_list_head, /* pointer to current temp. buffer */ *new; /* pointer to a newly created temp. buffer */ - FUNC_ENTER (H5TBget_buf, FAIL); - H5TRACE2("i","hb",size,resize); + FUNC_ENTER (H5TB_get_buf, FAIL); while(curr!=NULL) { - if(!curr->inuse && size<curr->size) + if(!curr->inuse && size<=curr->size) break; curr=curr->next; } /* end while */ @@ -250,6 +268,7 @@ H5TBget_buf(hsize_t size, hbool_t resize) /* set this so we can fall through to getting the ID */ curr=new; + break; } /* end if */ } /* end for */ @@ -270,19 +289,23 @@ H5TBget_buf(hsize_t size, hbool_t resize) HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register temp. buffer atom"); } + /* Assign the pointer to the buffer, if requested */ + if(ptr!=NULL) + *ptr=curr->buf; + done: if (ret_value < 0) { } FUNC_LEAVE(ret_value); -} /* H5TBget_buf() */ +} /* H5TB_get_buf() */ /*-------------------------------------------------------------------------- NAME - H5TBbuf_ptr + H5TB_buf_ptr PURPOSE Get the pointer to a temp. buffer memory USAGE - void *H5TBbuf_ptr(tbuf_id) + void *H5TB_buf_ptr(tbuf_id) hid_t tbuf_id; IN: Temp. buffer ID RETURNS Non-NULL pointer to buffer memory on success, NULL on failure @@ -294,12 +317,12 @@ done: REVISION LOG --------------------------------------------------------------------------*/ void * -H5TBbuf_ptr(hid_t tbuf_id) +H5TB_buf_ptr(hid_t tbuf_id) { void *ret_value = NULL; H5TB_t *tbuf; /* Pointer to temporary buffer */ - FUNC_ENTER (H5TBbuf_ptr, NULL); + FUNC_ENTER (H5TB_buf_ptr, NULL); if (H5_TEMPBUF != H5I_group(tbuf_id) || NULL == (tbuf = H5I_object(tbuf_id))) { @@ -314,15 +337,15 @@ done: if (ret_value == NULL) { } FUNC_LEAVE(ret_value); -} /* H5TBbuf_ptr() */ +} /* H5TB_buf_ptr() */ /*-------------------------------------------------------------------------- NAME - H5TBresize_ptr + H5TB_resize_buf PURPOSE Resize a temp. buffer to a new size USAGE - herr_t H5TBresize_ptr(tbid, size) + herr_t H5TB_resize_buf(tbid, size) hid_t tbid; IN: Temp. buffer ID to resize hsize_t size; IN: New size of temp. buffer RETURNS @@ -335,15 +358,14 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5TBresize_ptr(hid_t tbuf_id, hsize_t size) +H5TB_resize_buf(hid_t tbuf_id, hsize_t size) { herr_t ret_value = FAIL; H5TB_t *tbuf, /* Pointer to temporary buffer */ *curr; /* Pointer to temp. buffer node */ void * old_ptr; /* Pointer to the previous buffer */ - FUNC_ENTER (H5TBresize_ptr, FAIL); - H5TRACE2("e","ih",tbuf_id,size); + FUNC_ENTER (H5TB_resize_buf, FAIL); if (H5_TEMPBUF != H5I_group(tbuf_id) || NULL == (tbuf = H5I_object(tbuf_id))) { @@ -410,15 +432,15 @@ done: if (ret_value == FAIL) { } FUNC_LEAVE(ret_value); -} /* H5TBresize_ptr() */ +} /* H5TB_resize_buf() */ /*-------------------------------------------------------------------------- NAME - H5TBgarbage_coll + H5TB_garbage_coll PURPOSE Release all unused temporary buffers USAGE - herr_t H5TBgarbase_coll() + herr_t H5TB_garbase_coll() RETURNS non-negative on success, negative on failure DESCRIPTION @@ -430,13 +452,12 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5TBgarbage_coll(void) +H5TB_garbage_coll(void) { herr_t ret_value = FAIL; H5TB_t *curr,*next; /* Current temp. buffer node */ - FUNC_ENTER (H5TBgarbage_coll, FAIL); - H5TRACE0("e",""); + FUNC_ENTER (H5TB_garbage_coll, FAIL); /* * Step through the list, remove each unused node, repair the list and @@ -474,15 +495,15 @@ done: if (ret_value == FAIL) { } FUNC_LEAVE(ret_value); -} /* H5TBgarbage_coll() */ +} /* H5TB_garbage_coll() */ /*-------------------------------------------------------------------------- NAME - H5TBrelease_buf + H5TB_release_buf PURPOSE Release a temp. buffer back to the list of unused ones. USAGE - herr_t H5TBrelease_buf(tbuf_id) + herr_t H5TB_release_buf(tbuf_id) hid_t tbuf_id; IN: Temp. buffer ID to release RETURNS non-negative on success, negative on failure @@ -494,16 +515,15 @@ done: REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5TBrelease_buf(hid_t tbuf_id) +H5TB_release_buf(hid_t tbuf_id) { herr_t ret_value = FAIL; H5TB_t *tbuf; /* Pointer to temporary buffer */ - FUNC_ENTER (H5TBresize_ptr, FAIL); - H5TRACE1("e","i",tbuf_id); + FUNC_ENTER (H5TB_release_buf, FAIL); if (H5_TEMPBUF != H5I_group(tbuf_id) || - NULL == (tbuf = H5I_object(tbuf_id))) { + NULL == (tbuf = H5I_remove(tbuf_id))) { HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a temp. buffer"); } @@ -518,5 +538,5 @@ done: if (ret_value == FAIL) { } FUNC_LEAVE(ret_value); -} /* H5TBresize_ptr() */ +} /* H5TB_release_buf() */ diff --git a/src/H5TBprivate.h b/src/H5TBprivate.h index 2d48b1c..2ed46d9 100644 --- a/src/H5TBprivate.h +++ b/src/H5TBprivate.h @@ -17,10 +17,10 @@ #define _H5TBprivate_H /* Functions defined in H5TB.c */ -hid_t H5TBget_buf(hsize_t size, hbool_t resize); -void *H5TBbuf_ptr(hid_t tbid); -herr_t H5TBresize_ptr(hid_t tbid, hsize_t size); -herr_t H5TBgarbage_coll(void); -herr_t H5TBrelease_buf(hid_t tbid); +hid_t H5TB_get_buf(hsize_t size, hbool_t resize, void **ptr); +void *H5TB_buf_ptr(hid_t tbid); +herr_t H5TB_resize_buf(hid_t tbid, hsize_t size); +herr_t H5TB_garbage_coll(void); +herr_t H5TB_release_buf(hid_t tbid); #endif @@ -170,11 +170,11 @@ H5V_hyper_stride(intn n, const hsize_t *size, /* others */ for (i=n-2, acc=1; i>=0; --i) { - hsize_t tmp = acc * (total_size[i+1] - size[i+1]); - assert (tmp<((hsize_t)1<<(8*sizeof(hssize_t)-1))); - stride[i] = (hssize_t)tmp; /*overflow checked*/ - acc *= total_size[i+1]; - skip += acc * (offset ? offset[i] : 0); + hsize_t tmp = acc * (total_size[i+1] - size[i+1]); + assert (tmp<((hsize_t)1<<(8*sizeof(hssize_t)-1))); + stride[i] = (hssize_t)tmp; /*overflow checked*/ + acc *= total_size[i+1]; + skip += acc * (offset ? offset[i] : 0); } FUNC_LEAVE(skip); @@ -410,26 +410,42 @@ H5V_hyper_copy(intn n, const hsize_t *_size, assert(src_size[i] > 0); } #endif -#ifdef QAK - { - intn i; - - printf("%s: n=%d, _dst=%p, _src=%p\n",FUNC,(int)n,_dst,_src); - for(i=0; i<n; i++) { - printf("%d: size=%d, dst_size=%d, dst_offset=%d, src_size=%d, " - "src_offset=%d\n", - i, (int)size[i], (int)dst_size[i], (int)dst_offset[i], - (int)src_size[i], (int)src_offset[i]); - } /* end for */ - } -#endif /* QAK */ /* Copy the size vector so we can modify it */ H5V_vector_cpy(n, size, _size); /* Compute stride vectors for source and destination */ +#ifdef NO_INLINED_CODE dst_start = H5V_hyper_stride(n, size, dst_size, dst_offset, dst_stride); src_start = H5V_hyper_stride(n, size, src_size, src_offset, src_stride); +#else /* NO_INLINED_CODE */ + /* in-line version of two calls to H5V_hyper_stride() */ + { + hsize_t dst_acc; /*accumulator */ + hsize_t src_acc; /*accumulator */ + int i; /*counter */ + + /* init */ + dst_stride[n-1] = 1; + src_stride[n-1] = 1; + dst_start = dst_offset ? dst_offset[n-1] : 0; + src_start = src_offset ? src_offset[n-1] : 0; + + /* others */ + for (i=n-2, dst_acc=1, src_acc=1; i>=0; --i) { + hsize_t tmp1 = dst_acc * (dst_size[i+1] - size[i+1]); + hsize_t tmp2 = src_acc * (src_size[i+1] - size[i+1]); + assert (tmp1<((hsize_t)1<<(8*sizeof(hssize_t)-1))); + assert (tmp2<((hsize_t)1<<(8*sizeof(hssize_t)-1))); + dst_stride[i] = (hssize_t)tmp1; /*overflow checked*/ + src_stride[i] = (hssize_t)tmp2; /*overflow checked*/ + dst_acc *= dst_size[i+1]; + src_acc *= src_size[i+1]; + dst_start += dst_acc * (dst_offset ? dst_offset[i] : 0); + src_start += src_acc * (src_offset ? src_offset[i] : 0); + } + } +#endif /* NO_INLINED_CODE */ /* Optimize the strides as a pair */ H5V_stride_optimize2(&n, &elmt_size, size, dst_stride, src_stride); |