summaryrefslogtreecommitdiffstats
path: root/src/H5Tconv.c
diff options
context:
space:
mode:
authorRobb Matzke <matzke@llnl.gov>1999-06-23 16:16:51 (GMT)
committerRobb Matzke <matzke@llnl.gov>1999-06-23 16:16:51 (GMT)
commitc78a6aedafdf878d0cdd18977d5b10a90763b20d (patch)
treeaec30e31144a64dcdf818248c3598acb82c03c29 /src/H5Tconv.c
parent0350710f5baa5177674289e06737c99cb201ecc5 (diff)
downloadhdf5-c78a6aedafdf878d0cdd18977d5b10a90763b20d.zip
hdf5-c78a6aedafdf878d0cdd18977d5b10a90763b20d.tar.gz
hdf5-c78a6aedafdf878d0cdd18977d5b10a90763b20d.tar.bz2
[svn-r1371]
Changes since 19990618 ---------------------- ./configure.in ./configure [REGENERATED] Now that compound struct conversions don't make so many calls to convert their members I turned the H5T debugging back on by default (it will still be disabled in a production version). ./src/H5AC.c ./src/H5B.c Made it possible to turn off messages about debugging these two packages using the same method as for all other packages. Just supply an invalid file descriptor number or use the shell to redirect said descriptor to /dev/null like this: $ HDF5_DEBUG=99,ac,b 99>/dev/null a.out ./src/H5T.c Changed the name of the old compound conversion function from `struct' to `struct(no-opt)' to be more consistent with the new version named `struct(opt)'. Fixed a bug in H5T_cmp() that caused any two VL types to compare as being equal. Removed duplicate code for bitfield comparisons in H5T_cmp(). ./src/H5Tconv.c Relaxed some constraints in the new compound conversion function so it applies to more cases. Also eliminated a memcpy in a tight loop. ./test/cmpd_dset.c Added a `--noopt' command line switch which unregisters the optimized compound conversion so we can test the non-optimized version.
Diffstat (limited to 'src/H5Tconv.c')
-rw-r--r--src/H5Tconv.c112
1 files changed, 71 insertions, 41 deletions
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index f469c61..dc9a7bc 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -1145,12 +1145,14 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
* For each member of the struct
* If sizeof detination type <= sizeof source type then
* Convert member to destination type for all elements
- * Move member as far left as possible for all elements
+ * Move memb to BKG buffer for all elements
+ * Else
+ * Move member as far left as possible for all elements
*
* For each member of the struct (in reverse order)
* If not destination type then
* Convert member to destination type for all elements
- * Move member to correct position in BKG for all elements
+ * Move member to correct position in BKG for all elements
*
* Copy BKG to BUF for all elements
*
@@ -1194,7 +1196,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
size_t offset; /*byte offset wrt struct */
uintn elmtno; /*element counter */
intn i, j; /*counters */
- H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv);
+ H5T_conv_struct_t *priv = NULL; /*private data */
FUNC_ENTER (H5T_conv_struct_opt, FAIL);
@@ -1215,26 +1217,63 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
assert (H5T_COMPOUND==src->type);
assert (H5T_COMPOUND==dst->type);
- /*
- * This optimized version only works when the source and destination
- * datatypes are the same size.
- */
- if (src->size < dst->size) {
- HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
- "conversion is unsupported by this function");
- }
-
/* Initialize data which is relatively constant */
if (H5T_conv_struct_init (src, dst, cdata)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize conversion data");
}
+ priv = (H5T_conv_struct_t *)(cdata->priv);
+ src2dst = priv->src2dst;
+
+ /*
+ * If the destination type is not larger than the source type then
+ * this conversion function is guaranteed to work (provided all
+ * members can be converted also). Otherwise the determination is
+ * quite a bit more complicated. Essentially we have to make sure
+ * that there is always room in the source buffer to do the
+ * conversion of a member in place. This is basically the same pair
+ * of loops as in the actual conversion except it checks that there
+ * is room for each conversion instead of actually doing anything.
+ */
+ if (dst->size > src->size) {
+ for (i=0, offset=0; i<src->u.compnd.nmembs; i++) {
+ if (src2dst[i]<0) continue;
+ src_memb = src->u.compnd.memb + i;
+ dst_memb = dst->u.compnd.memb + src2dst[i];
+ src_memb_size = src_memb->size / priv->memb_nelmts[i];
+ dst_memb_size = dst_memb->size / priv->memb_nelmts[i];
+ for (j=0; j<(intn)(priv->memb_nelmts[i]); j++) {
+ if (dst_memb_size > src_memb_size) {
+ offset += src_memb_size;
+ }
+ }
+ }
+ for (i=src->u.compnd.nmembs-1; i>=0; --i) {
+ if (src2dst[i]<0) continue;
+ src_memb = src->u.compnd.memb + i;
+ dst_memb = dst->u.compnd.memb + src2dst[i];
+ src_memb_size = src_memb->size / priv->memb_nelmts[i];
+ dst_memb_size = dst_memb->size / priv->memb_nelmts[i];
+
+ for (j=priv->memb_nelmts[i]-1; j>=0; --j) {
+ if (dst_memb_size > src_memb_size) {
+ offset -= src_memb_size;
+ if (dst_memb_size > src->size-offset) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL,
+ "convertion is unsupported by this "
+ "function");
+ }
+ }
+ }
+ }
+ }
break;
case H5T_CONV_FREE:
/*
* Free the private conversion data.
*/
+ priv = (H5T_conv_struct_t *)(cdata->priv);
H5MM_xfree(priv->src2dst);
H5MM_xfree(priv->src_memb_id);
H5MM_xfree(priv->dst_memb_id);
@@ -1253,30 +1292,30 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
NULL == (dst = H5I_object(dst_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
- assert(src->size>=dst->size);
- assert(priv);
- assert(bkg && cdata->need_bkg>=H5T_BKG_TEMP);
+ /* Update cached data if necessary */
if (cdata->recalc &&
H5T_conv_struct_init (src, dst, cdata)<0) {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to initialize conversion data");
}
+ priv = (H5T_conv_struct_t *)(cdata->priv);
+ src2dst = priv->src2dst;
+ assert(priv);
+ assert(bkg && cdata->need_bkg>=H5T_BKG_TEMP);
/*
* Insure that members are sorted.
*/
H5T_sort_value(src, NULL);
H5T_sort_value(dst, NULL);
- src2dst = priv->src2dst;
/*
* For each member where the destination is not larger than the
- * source, stride through all the elements converting only that
- * member in each element.
- *
- * Shift struct member (converted or not) as far left as possible
- * within each element.
+ * source, stride through all the elements converting only that member
+ * in each element and then copying the element to its final
+ * destination in the bkg buffer. Otherwise move the element as far
+ * left as possible in the buffer.
*/
for (i=0, offset=0; i<src->u.compnd.nmembs; i++) {
if (src2dst[i]<0) continue;
@@ -1299,13 +1338,11 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
"unable to convert compound data "
"type member");
}
- for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) {
- HDmemmove(xbuf+offset,
- xbuf+src_memb->offset+j*src_memb_size,
- dst_memb_size);
+ for (elmtno=0; elmtno<nelmts; elmtno++) {
+ HDmemmove(xbkg, xbuf, dst_memb_size);
xbuf += stride ? stride : src->size;
+ xbkg += stride ? stride : dst->size;
}
- offset += dst_memb_size;
} else {
for (xbuf=buf, elmtno=0; elmtno<nelmts; elmtno++) {
HDmemmove(xbuf+offset,
@@ -1320,11 +1357,9 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
/*
* Work from right to left, converting those members that weren't
- * converted in the previous loop -- those members where the
- * destination is larger than the source.
- *
- * Move the member (converted in this loop or not) to the final
- * position in the bkg buffer.
+ * converted in the previous loop (those members where the destination
+ * is larger than the source) and them to their final position in the
+ * bkg buffer.
*/
for (i=src->u.compnd.nmembs-1; i>=0; --i) {
if (src2dst[i]<0) continue;
@@ -1347,16 +1382,11 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
"unable to convert compound data "
"type member");
}
- } else {
- offset -= dst_memb_size;
- xbuf = buf + offset;
- xbkg = bkg + dst_memb->offset + j*dst_memb_size;
- }
-
- for (elmtno=0; elmtno<nelmts; elmtno++) {
- HDmemmove(xbkg, xbuf, dst_memb_size);
- xbuf += stride ? stride : src->size;
- xbkg += stride ? stride : dst->size;
+ for (elmtno=0; elmtno<nelmts; elmtno++) {
+ HDmemmove(xbkg, xbuf, dst_memb_size);
+ xbuf += stride ? stride : src->size;
+ xbkg += stride ? stride : dst->size;
+ }
}
}
}