summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/.distdep15
-rw-r--r--src/H5D.c69
-rw-r--r--src/H5Distore.c2
-rw-r--r--src/H5Dprivate.h2
-rw-r--r--src/H5Fistore.c2
-rw-r--r--src/H5P.c84
-rw-r--r--src/H5Ppublic.h2
-rw-r--r--src/H5Sall.c15
-rw-r--r--src/H5Shyper.c537
-rw-r--r--src/H5Spoint.c15
-rw-r--r--src/H5Sprivate.h31
-rw-r--r--src/H5Sselect.c12
-rw-r--r--src/H5TB.c92
-rw-r--r--src/H5TBprivate.h10
-rw-r--r--src/H5V.c52
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
diff --git a/src/H5D.c b/src/H5D.c
index 5ad5145..02beee5 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -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);
}
diff --git a/src/H5P.c b/src/H5P.c
index 93f5a02..99b4e67 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -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 **)&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");
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);
}
diff --git a/src/H5TB.c b/src/H5TB.c
index d625bfc..5079d27 100644
--- a/src/H5TB.c
+++ b/src/H5TB.c
@@ -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
diff --git a/src/H5V.c b/src/H5V.c
index a72452f..7708794 100644
--- a/src/H5V.c
+++ b/src/H5V.c
@@ -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);