diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Dio.c | 2 | ||||
-rw-r--r-- | src/H5Dpkg.h | 2 | ||||
-rw-r--r-- | src/H5Dscatgath.c | 20 | ||||
-rw-r--r-- | src/H5T.c | 12 | ||||
-rw-r--r-- | src/H5Tconv.c | 56 | ||||
-rw-r--r-- | src/H5Tpkg.h | 4 | ||||
-rw-r--r-- | src/H5Tprivate.h | 7 |
7 files changed, 61 insertions, 42 deletions
diff --git a/src/H5Dio.c b/src/H5Dio.c index 45fa21a..b7c1d72 100644 --- a/src/H5Dio.c +++ b/src/H5Dio.c @@ -745,7 +745,7 @@ H5D_typeinfo_init(const H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, type_info->is_conv_noop = H5T_path_noop(type_info->tpath); type_info->is_xform_noop = H5Z_xform_noop(dxpl_cache->data_xform_prop); if(type_info->is_xform_noop && type_info->is_conv_noop) { - type_info->cmpd_subset = H5T_SUBSET_FALSE; + type_info->cmpd_subset = NULL; type_info->need_bkg = H5T_BKG_NO; } /* end if */ else { diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 9f02dbc..f6732ff 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -86,7 +86,7 @@ typedef struct H5D_type_info_t { size_t max_type_size; /* Size of largest source/destination type */ hbool_t is_conv_noop; /* Whether the type conversion is a NOOP */ hbool_t is_xform_noop; /* Whether the data transform is a NOOP */ - H5T_subset_t cmpd_subset; /* Whether (and which) the source/destination datatypes are compound subsets of one another */ + const H5T_subset_info_t *cmpd_subset; /* Info related to the compound subset conversion functions */ H5T_bkg_t need_bkg; /* Type of background buf needed */ size_t request_nelmts; /* Requested strip mine */ uint8_t *tconv_buf; /* Datatype conv buffer */ diff --git a/src/H5Dscatgath.c b/src/H5Dscatgath.c index cb07708..867303f 100644 --- a/src/H5Dscatgath.c +++ b/src/H5Dscatgath.c @@ -519,7 +519,7 @@ H5D_scatgath_read(const H5D_io_info_t *io_info, const H5D_type_info_t *type_info * and no conversion is needed, copy the data directly into user's buffer and * bypass the rest of steps. */ - if(H5T_SUBSET_FALSE != type_info->cmpd_subset) { + if(type_info->cmpd_subset && H5T_SUBSET_FALSE != type_info->cmpd_subset->subset) { if(H5D_compound_opt_read(smine_nelmts, mem_space, &mem_iter, dxpl_cache, type_info, buf /*out*/) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed") @@ -649,7 +649,8 @@ H5D_scatgath_write(const H5D_io_info_t *io_info, const H5D_type_info_t *type_inf * is a subset of the destination, the optimization is done in conversion * function H5T_conv_struct_opt to protect the background data. */ - if(H5T_SUBSET_DST == type_info->cmpd_subset) { + if(type_info->cmpd_subset && H5T_SUBSET_DST == type_info->cmpd_subset->subset + && type_info->dst_type_size == type_info->cmpd_subset->copy_size) { if(H5D_compound_opt_write(smine_nelmts, type_info) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "datatype conversion failed") } /* end if */ @@ -745,7 +746,7 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space, hsize_t *off = NULL; /* Pointer to sequence offsets */ size_t _len[H5D_IO_VECTOR_SIZE]; /* Array to store sequence lengths */ size_t *len = NULL; /* Pointer to sequence lengths */ - size_t src_stride, dst_stride, type_size; + size_t src_stride, dst_stride, copy_size; herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI_NOINIT(H5D_compound_opt_read) @@ -756,6 +757,9 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space, HDassert(iter); HDassert(dxpl_cache); HDassert(type_info); + HDassert(type_info->cmpd_subset); + HDassert(H5T_SUBSET_SRC == type_info->cmpd_subset->subset || + H5T_SUBSET_DST == type_info->cmpd_subset->subset); HDassert(user_buf); /* Allocate the vector I/O arrays */ @@ -774,12 +778,8 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space, src_stride = type_info->src_type_size; dst_stride = type_info->dst_type_size; - if(H5T_SUBSET_SRC == type_info->cmpd_subset) - type_size = src_stride; - else { - HDassert(H5T_SUBSET_DST == type_info->cmpd_subset); - type_size = dst_stride; - } /* end else */ + /* Get the size, in bytes, to copy for each element */ + copy_size = type_info->cmpd_subset->copy_size; /* Loop until all elements are written */ xdbuf = type_info->tconv_buf; @@ -811,7 +811,7 @@ H5D_compound_opt_read(size_t nelmts, const H5S_t *space, /* Copy the data into the right place. */ for(i = 0; i < curr_nelmts; i++) { - HDmemmove(xubuf, xdbuf, type_size); + HDmemmove(xubuf, xdbuf, copy_size); /* Update pointers */ xdbuf += src_stride; @@ -4526,19 +4526,23 @@ H5T_path_noop(const H5T_path_t *p) * TYPE5 E; * }; * - * Return: One of the values of H5T_subset_t (can't fail). + * Return: A pointer to the subset info struct in p, or NULL if there are + * no compounds. Points directly into the H5T_path_t structure. * * Programmer: Raymond Lu * 8 June 2007 * - * Modifications: + * Modifications: Neil Fortner + * 19 September 2008 + * Changed return value to H5T_subset_info_t + * (to allow it to return copy_size) * *------------------------------------------------------------------------- */ -H5T_subset_t +H5T_subset_info_t * H5T_path_compound_subset(const H5T_path_t *p) { - H5T_subset_t ret_value = FALSE; + H5T_subset_info_t *ret_value = NULL; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_path_compound_subset); diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 276d05a..b02e72a 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -883,7 +883,7 @@ typedef struct H5T_conv_struct_t { hid_t *src_memb_id; /*source member type ID's */ hid_t *dst_memb_id; /*destination member type ID's */ H5T_path_t **memb_path; /*conversion path for each member */ - H5T_subset_t smembs_subset; /*are source and dest members a subset of each other? */ + H5T_subset_info_t subset_info; /*info related to compound subsets */ } H5T_conv_struct_t; /* Conversion data for H5T_conv_enum() */ @@ -1827,7 +1827,8 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) /* The flag of special optimization to indicate if source members and destination * members are a subset of each other. Initialize it to FALSE */ - priv->smembs_subset = H5T_SUBSET_FALSE; + priv->subset_info.subset = H5T_SUBSET_FALSE; + priv->subset_info.copy_size = 0; /* * Insure that members are sorted. @@ -1899,23 +1900,41 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) cdata->need_bkg = H5T_BKG_YES; if(src_nmembs < dst_nmembs) { - priv->smembs_subset = H5T_SUBSET_SRC; + priv->subset_info.subset = H5T_SUBSET_SRC; for(i = 0; i < src_nmembs; i++) { /* If any of source members doesn't have counterpart in the same * order or there's conversion between members, don't do the * optimization. */ - if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) - priv->smembs_subset = H5T_SUBSET_FALSE; + if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) { + priv->subset_info.subset = H5T_SUBSET_FALSE; + break; + } /* end if */ } /* end for */ + /* Compute the size of the data to be copied for each element. It + * may be smaller than either src or dst if there is extra space at + * the end of src. + */ + if(priv->subset_info.subset == H5T_SUBSET_SRC) + priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset + + src->shared->u.compnd.memb[src_nmembs-1].size; } else if(dst_nmembs < src_nmembs) { - priv->smembs_subset = H5T_SUBSET_DST; + priv->subset_info.subset = H5T_SUBSET_DST; for(i = 0; i < dst_nmembs; i++) { /* If any of source members doesn't have counterpart in the same order or * there's conversion between members, don't do the optimization. */ - if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) - priv->smembs_subset = H5T_SUBSET_FALSE; + if(src2dst[i] != i || (src->shared->u.compnd.memb[i].offset != dst->shared->u.compnd.memb[i].offset) || (priv->memb_path[i])->is_noop == FALSE) { + priv->subset_info.subset = H5T_SUBSET_FALSE; + break; + } } /* end for */ + /* Compute the size of the data to be copied for each element. It + * may be smaller than either src or dst if there is extra space at + * the end of dst. + */ + if(priv->subset_info.subset == H5T_SUBSET_DST) + priv->subset_info.copy_size = dst->shared->u.compnd.memb[dst_nmembs-1].offset + + dst->shared->u.compnd.memb[dst_nmembs-1].size; } else /* If the numbers of source and dest members are equal and no conversion is needed, * the case should have been handled as noop earlier in H5Dio.c. */ ; @@ -1945,14 +1964,15 @@ done: * TYPE5 E; * }; * - * Return: One of the value from H5T_subset_t. + * Return: A pointer to the subset info struct in p. Points directly + * into the structure. * * Programmer: Raymond Lu * 8 June 2007 * *------------------------------------------------------------------------- */ -H5T_subset_t +H5T_subset_info_t * H5T_conv_struct_subset(const H5T_cdata_t *cdata) { H5T_conv_struct_t *priv; @@ -1964,7 +1984,7 @@ H5T_conv_struct_subset(const H5T_cdata_t *cdata) priv = (H5T_conv_struct_t *)(cdata->priv); - FUNC_LEAVE_NOAPI(priv->smembs_subset) + FUNC_LEAVE_NOAPI((H5T_subset_info_t *) &priv->subset_info) } /* end H5T_conv_struct_subset() */ @@ -2388,22 +2408,12 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, buf_stride = src->shared->size; } - if(priv->smembs_subset == H5T_SUBSET_SRC || priv->smembs_subset == H5T_SUBSET_DST) { + if(priv->subset_info.subset == H5T_SUBSET_SRC || priv->subset_info.subset == H5T_SUBSET_DST) { /* If the optimization flag is set to indicate source members are a subset and * in the top of the destination, simply copy the source members to background buffer. */ xbuf = buf; xbkg = bkg; - if(dst->shared->size <= src->shared->size) - /* This is to deal with a very special situation when the fields and their - * offset for both source and destination are identical but the datatype - * sizes of source and destination are different. The library still - * considers these two types different and does conversion. It happens - * in table API test (hdf5/hl/test/test_table.c) when a table field is - * deleted. - */ - copy_size = dst->shared->size; - else - copy_size = src->shared->size; + copy_size = priv->subset_info.copy_size; for (elmtno=0; elmtno<nelmts; elmtno++) { HDmemmove(xbkg, xbuf, copy_size); diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index a534f1b..7ef4b63 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -288,7 +288,7 @@ typedef enum H5T_sort_t { typedef struct H5T_cmemb_t { char *name; /*name of this member */ size_t offset; /*offset from beginning of struct */ - size_t size; /*total size: dims * type_size */ + size_t size; /*size of this member */ struct H5T_t *type; /*type of this member */ } H5T_cmemb_t; @@ -1380,7 +1380,7 @@ H5_DLL herr_t H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member); H5_DLL size_t H5T_get_member_size(const H5T_t *dt, unsigned membno); H5_DLL htri_t H5T_is_packed(const H5T_t *dt); -H5_DLL H5T_subset_t H5T_conv_struct_subset(const H5T_cdata_t *cdata); +H5_DLL H5T_subset_info_t *H5T_conv_struct_subset(const H5T_cdata_t *cdata); /* Enumerated type functions */ H5_DLL H5T_t *H5T_enum_create(const H5T_t *parent); diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index f8f2abc..9189f04 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -92,6 +92,11 @@ typedef enum { H5T_SUBSET_CAP /* Must be the last value */ } H5T_subset_t; +typedef struct H5T_subset_info_t { + H5T_subset_t subset; /* See above */ + size_t copy_size; /* Size in bytes, to copy for each element */ +} H5T_subset_info_t; + /* Forward declarations for prototype arguments */ struct H5O_t; @@ -119,7 +124,7 @@ H5_DLL H5T_path_t *H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, H5T_conv_t func, hid_t dxpl_id, hbool_t is_api); H5_DLL hbool_t H5T_path_noop(const H5T_path_t *p); H5_DLL H5T_bkg_t H5T_path_bkg(const H5T_path_t *p); -H5_DLL H5T_subset_t H5T_path_compound_subset(const H5T_path_t *p); +H5_DLL H5T_subset_info_t *H5T_path_compound_subset(const H5T_path_t *p); H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, size_t nelmts, size_t buf_stride, size_t bkg_stride, void *buf, void *bkg, hid_t dset_xfer_plist); |