summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2004-06-13 03:11:27 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2004-06-13 03:11:27 (GMT)
commitab989cd1a8d5b65120fe88a84b3b925f1b174db8 (patch)
treee03c7f4c28b4ab9ee6bde47f1d7d151b6cc58f27
parent46e9134612e3d88ebdd6677dcfe9805ef4bc2f9f (diff)
downloadhdf5-ab989cd1a8d5b65120fe88a84b3b925f1b174db8.zip
hdf5-ab989cd1a8d5b65120fe88a84b3b925f1b174db8.tar.gz
hdf5-ab989cd1a8d5b65120fe88a84b3b925f1b174db8.tar.bz2
[svn-r8670] Purpose:
Code optimization Description: Avoid a memory copy by directly reading from the variable-length sequence buffer when there is no type conversion on the way to disk. Platforms tested: Solaris 2.7 (arabica) FreeBSD 4.10 (sleipnir) w/parallel Too minor to require h5committest
-rw-r--r--src/H5Tconv.c52
-rw-r--r--src/H5Tpkg.h2
-rw-r--r--src/H5Tvlen.c90
3 files changed, 128 insertions, 16 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 57ed1c3..8d3e44a 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -2429,6 +2429,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
H5T_vlen_alloc_info_t vl_alloc_info;/* VL allocation information */
H5T_path_t *tpath; /* Type conversion path */
hbool_t noop_conv=FALSE; /* Flag to indicate a noop conversion */
+ hbool_t write_to_file=FALSE; /* Flag to indicate writing to file */
hid_t tsrc_id = -1, tdst_id = -1;/*temporary type atoms */
H5T_t *src = NULL; /*source data type */
H5T_t *dst = NULL; /*destination data type */
@@ -2442,12 +2443,11 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
hssize_t seq_len; /*the number of elements in the current sequence*/
hsize_t bg_seq_len=0, parent_seq_len=0;
size_t src_base_size, dst_base_size;/*source & destination base size*/
- size_t src_size, dst_size; /*source & destination total size in bytes*/
void *conv_buf=NULL; /*temporary conversion buffer */
size_t conv_buf_size=0; /*size of conversion buffer in bytes */
void *tmp_buf=NULL; /*temporary background buffer */
size_t tmp_buf_size=0; /*size of temporary bkg buffer */
- int nested=0; /*flag of nested VL case */
+ hbool_t nested=FALSE; /*flag of nested VL case */
hsize_t elmtno; /*element number counter */
hsize_t i;
herr_t ret_value=SUCCEED; /* Return value */
@@ -2530,8 +2530,12 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
if(H5T_vlen_get_alloc_info(dxpl_id,&vl_alloc_info)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info");
+ /* Set flags to indicate we are writing to or reading from the file */
+ if(dst->u.vlen.f!=NULL)
+ write_to_file=TRUE;
+
/* Set the flag for nested VL case */
- if(dst->u.vlen.f!=NULL && H5T_detect_class(dst->parent,H5T_VLEN) && bkg!=NULL)
+ if(write_to_file && H5T_detect_class(dst->parent,H5T_VLEN) && bkg!=NULL)
nested=1;
/* The outer loop of the type conversion macro, controlling which */
@@ -2580,21 +2584,33 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
/* Get length of element sequences */
if((seq_len=(*(src->u.vlen.getlen))(s))<0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "incorrect length");
- H5_CHECK_OVERFLOW(seq_len,hssize_t,size_t);
- src_size=(size_t)seq_len*src_base_size;
- dst_size=(size_t)seq_len*dst_base_size;
-
- /* Check if conversion buffer is large enough, resize if
- * necessary */
- if(conv_buf_size<MAX3(src_size,dst_size,H5T_VLEN_MIN_CONF_BUF_SIZE)) {
- conv_buf_size=MAX3(src_size,dst_size,H5T_VLEN_MIN_CONF_BUF_SIZE);
- if((conv_buf=H5FL_BLK_REALLOC(vlen_seq,conv_buf, conv_buf_size))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+
+ /* If we are reading from memory and there is no conversion, just get the pointer to sequence */
+ if(write_to_file && noop_conv) {
+ /* Get direct pointer to sequence */
+ if((conv_buf=(*(src->u.vlen.getptr))(s))==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid source pointer");
} /* end if */
+ else {
+ size_t src_size, dst_size; /*source & destination total size in bytes*/
+
+ H5_CHECK_OVERFLOW(seq_len,hssize_t,size_t);
+ src_size=(size_t)seq_len*src_base_size;
+ dst_size=(size_t)seq_len*dst_base_size;
+
+ /* Check if conversion buffer is large enough, resize if
+ * necessary */
+ if(conv_buf_size<MAX(src_size,dst_size)) {
+ /* Only allocate conversion buffer in H5T_VLEN_MIN_CONF_BUF_SIZE increments */
+ conv_buf_size=((MAX(src_size,dst_size)/H5T_VLEN_MIN_CONF_BUF_SIZE)+1)*H5T_VLEN_MIN_CONF_BUF_SIZE;
+ if((conv_buf=H5FL_BLK_REALLOC(vlen_seq,conv_buf, conv_buf_size))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion");
+ } /* end if */
- /* Read in VL sequence */
- if((*(src->u.vlen.read))(src->u.vlen.f,dxpl_id,s,conv_buf,src_size)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data");
+ /* Read in VL sequence */
+ if((*(src->u.vlen.read))(src->u.vlen.f,dxpl_id,s,conv_buf,src_size)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_READERROR, FAIL, "can't read VL data");
+ } /* end else */
if(!noop_conv) {
/* Check if temporary buffer is large enough, resize if necessary */
@@ -2672,6 +2688,10 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, hsize_t nelmts,
nelmts-=safe;
} /* end while */
+ /* Reset the conversion buffer pointer, so it doesn't get freed */
+ if(write_to_file && noop_conv)
+ conv_buf=NULL;
+
/* Release the temporary datatype IDs used */
if (tsrc_id >= 0)
H5I_dec_ref(tsrc_id);
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 13118e0..68789bb 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -144,6 +144,7 @@ typedef struct H5T_enum_t {
/* VL function pointers */
typedef hssize_t (*H5T_vlen_getlenfunc_t)(void *vl_addr);
+typedef void * (*H5T_vlen_getptrfunc_t)(void *vl_addr);
typedef htri_t (*H5T_vlen_isnullfunc_t)(H5F_t *f, void *vl_addr);
typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, hid_t dxpl_id, void *_vl, void *buf, size_t len);
typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *buf, void *_bg, hsize_t seq_len, hsize_t base_size);
@@ -165,6 +166,7 @@ typedef struct H5T_vlen_t {
H5T_str_t pad; /* For VL string. space or null padding of
* extra bytes */
H5F_t *f; /* File ID (if VL data is on disk) */
+ H5T_vlen_getptrfunc_t getptr; /* Function to get VL sequence pointer */
H5T_vlen_getlenfunc_t getlen; /* Function to get VL sequence size (in element units, not bytes) */
H5T_vlen_isnullfunc_t isnull; /* Function to check if VL value is NIL */
H5T_vlen_readfunc_t read; /* Function to read VL sequence into buffer */
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index a2ef55a..bec8611 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -44,16 +44,19 @@ H5FL_EXTERN(H5T_t);
/* Local functions */
static herr_t H5T_vlen_reclaim_recurse(void *elem, const H5T_t *dt, H5MM_free_t free_func, void *free_info);
static hssize_t H5T_vlen_seq_mem_getlen(void *_vl);
+static void * H5T_vlen_seq_mem_getptr(void *_vl);
static htri_t H5T_vlen_seq_mem_isnull(H5F_t *f, void *_vl);
static herr_t H5T_vlen_seq_mem_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, size_t len);
static herr_t H5T_vlen_seq_mem_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, hsize_t seq_len, hsize_t base_size);
static herr_t H5T_vlen_seq_mem_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg);
static hssize_t H5T_vlen_str_mem_getlen(void *_vl);
+static void * H5T_vlen_str_mem_getptr(void *_vl);
static htri_t H5T_vlen_str_mem_isnull(H5F_t *f, void *_vl);
static herr_t H5T_vlen_str_mem_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, size_t len);
static herr_t H5T_vlen_str_mem_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, hsize_t seq_len, hsize_t base_size);
static herr_t H5T_vlen_str_mem_setnull(H5F_t *f, hid_t dxpl_id, void *_vl, void *_bg);
static hssize_t H5T_vlen_disk_getlen(void *_vl);
+static void * H5T_vlen_disk_getptr(void *_vl);
static htri_t H5T_vlen_disk_isnull(H5F_t *f, void *_vl);
static herr_t H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *_vl, void *_buf, size_t len);
static herr_t H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, const H5T_vlen_alloc_info_t *vl_alloc_info, void *_vl, void *_buf, void *_bg, hsize_t seq_len, hsize_t base_size);
@@ -229,6 +232,7 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Set up the function pointers to access the VL sequence in memory */
dt->u.vlen.getlen=H5T_vlen_seq_mem_getlen;
+ dt->u.vlen.getptr=H5T_vlen_seq_mem_getptr;
dt->u.vlen.isnull=H5T_vlen_seq_mem_isnull;
dt->u.vlen.read=H5T_vlen_seq_mem_read;
dt->u.vlen.write=H5T_vlen_seq_mem_write;
@@ -239,6 +243,7 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Set up the function pointers to access the VL string in memory */
dt->u.vlen.getlen=H5T_vlen_str_mem_getlen;
+ dt->u.vlen.getptr=H5T_vlen_str_mem_getptr;
dt->u.vlen.isnull=H5T_vlen_str_mem_isnull;
dt->u.vlen.read=H5T_vlen_str_mem_read;
dt->u.vlen.write=H5T_vlen_str_mem_write;
@@ -267,6 +272,7 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
/* Set up the function pointers to access the VL information on disk */
/* VL sequences and VL strings are stored identically on disk, so use the same functions */
dt->u.vlen.getlen=H5T_vlen_disk_getlen;
+ dt->u.vlen.getptr=H5T_vlen_disk_getptr;
dt->u.vlen.isnull=H5T_vlen_disk_isnull;
dt->u.vlen.read=H5T_vlen_disk_read;
dt->u.vlen.write=H5T_vlen_disk_write;
@@ -315,6 +321,34 @@ H5T_vlen_seq_mem_getlen(void *_vl)
/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_seq_mem_getptr
+ *
+ * Purpose: Retrieves the pointer for a memory based VL element.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, June 12, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5T_vlen_seq_mem_getptr(void *_vl)
+{
+ hvl_t *vl=(hvl_t *)_vl; /* Pointer to the user's hvl_t information */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_seq_mem_getptr)
+
+ /* check parameters */
+ assert(vl);
+
+ FUNC_LEAVE_NOAPI(vl->p)
+} /* end H5T_vlen_seq_mem_getptr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_vlen_seq_mem_isnull
*
* Purpose: Checks if a memory sequence is the "null" sequence
@@ -499,6 +533,34 @@ H5T_vlen_str_mem_getlen(void *_vl)
/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_str_mem_getptr
+ *
+ * Purpose: Retrieves the pointer for a memory based VL string.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, June 12, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5T_vlen_str_mem_getptr(void *_vl)
+{
+ char *s=*(char **)_vl; /* Pointer to the user's string information */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_str_mem_getptr)
+
+ /* check parameters */
+ assert(s);
+
+ FUNC_LEAVE_NOAPI(s)
+} /* end H5T_vlen_str_mem_getptr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_vlen_str_mem_isnull
*
* Purpose: Checks if a memory string is a NULL pointer
@@ -669,6 +731,34 @@ H5T_vlen_disk_getlen(void *_vl)
/*-------------------------------------------------------------------------
+ * Function: H5T_vlen_disk_getptr
+ *
+ * Purpose: Retrieves the pointer to a disk based VL element.
+ *
+ * Return: Non-NULL on success/NULL on failure
+ *
+ * Programmer: Quincey Koziol
+ * Saturday, June 12, 2004
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5T_vlen_disk_getptr(void *_vl)
+{
+ uint8_t *vl=(uint8_t *)_vl; /* Pointer to the disk VL information */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_vlen_disk_getptr)
+
+ /* check parameters */
+ assert(vl);
+
+ FUNC_LEAVE_NOAPI(NULL)
+} /* end H5T_vlen_disk_getptr() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_vlen_disk_isnull
*
* Purpose: Checks if a disk VL info object is the "nil" object