summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2017-05-21 21:28:26 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2017-05-21 21:28:26 (GMT)
commitd91d6d3a4c068424f60a0eb9671c4843f372b1d0 (patch)
treeb52d6874fd4f897b445412362dda91f4f2136f79
parentde0682627b39a6af2009b001791ddce4c333db68 (diff)
downloadhdf5-d91d6d3a4c068424f60a0eb9671c4843f372b1d0.zip
hdf5-d91d6d3a4c068424f60a0eb9671c4843f372b1d0.tar.gz
hdf5-d91d6d3a4c068424f60a0eb9671c4843f372b1d0.tar.bz2
Add support for variable length types (not within compound or array, with no sub-type conversions) with attributes. Added h5dsm_tvlen.c to test this. Other minor fixes/cleanup.
-rw-r--r--examples/Makefile.am44
-rwxr-xr-xexamples/h5dsm_test.sh8
-rw-r--r--examples/h5dsm_ttconv.c2
-rw-r--r--examples/h5dsm_tvlen.c342
-rw-r--r--src/H5VLdaosm.c531
-rw-r--r--src/H5VLint.c6
6 files changed, 808 insertions, 125 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index f83145a..3f28819 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -42,9 +42,16 @@ EXAMPLE_PROG = h5_write h5_read h5_extend_write h5_chunk_read h5_compound \
h5_vds h5_vds-exc \
h5_vds-exclim h5_vds-eiger h5_vds-simpleIO h5_vds-percival \
h5_vds-percival-unlim h5_vds-percival-unlim-maxmin \
- h5dsm_file_create h5dsm_file_open h5dsm_dset_create h5dsm_dset_open \
- h5dsm_dset_write h5dsm_dset_read h5dsm_map
-TEST_SCRIPT=testh5cc.sh
+ h5dsm_file_create h5dsm_file_open h5dsm_group_create \
+ h5dsm_group_open h5dsm_dset_create h5dsm_dset_open \
+ h5dsm_dset_write h5dsm_dset_read
+ h5dsm_dset_wpartial h5dsm_dset_rpartial h5dsm_dset_w1m \
+ h5dsm_dset_r1m h5dsm_link_exists h5dsm_link_iter \
+ h5dsm_attr_create h5dsm_attr_open h5dsm_attr_write \
+ h5dsm_attr_read h5dsm_attr_iter h5dsm_slink_create \
+ h5dsm_obj_open h5dsm_obj_open_addr h5dsm_obj_info h5dsm_map \
+ h5dsm_ttconv h5dsm_tvlen
+TEST_SCRIPT=testh5cc.sh h5dsm_test.sh
TEST_EXAMPLES_SCRIPT=$(INSTALL_SCRIPT_FILES)
# Install files
@@ -59,8 +66,15 @@ INSTALL_FILES = h5_write.c h5_read.c h5_extend_write.c h5_chunk_read.c \
h5_vds.c h5_vds-exc.c \
h5_vds-exclim.c h5_vds-eiger.c h5_vds-simpleIO.c h5_vds-percival.c \
h5_vds-percival-unlim.c h5_vds-percival-unlim-maxmin.c \
- h5dsm_file_create.c h5dsm_file_open.c h5dsm_dset_create.c \
- h5dsm_dset_open.c h5dsm_dset_write.c h5dsm_dset_read.c
+ h5dsm_file_create.c h5dsm_file_open.c h5dsm_group_create.c \
+ h5dsm_group_open.c h5dsm_dset_create.c \
+ h5dsm_dset_open.c h5dsm_dset_write.c h5dsm_dset_read.c \
+ h5dsm_dset_wpartial.c h5dsm_dset_rpartial.c h5dsm_dset_w1m.c \
+ h5dsm_dset_r1m.c h5dsm_link_exists.c h5dsm_link_iter.c \
+ h5dsm_attr_create.c h5dsm_attr_open.c h5dsm_attr_write.c \
+ h5dsm_attr_read.c h5dsm_attr_iter.c h5dsm_slink_create.c \
+ h5dsm_obj_open.c h5dsm_obj_open_addr.c h5dsm_obj_info.c h5dsm_map.c \
+ h5dsm_ttconv.c h5dsm_tvlen.c
@@ -140,10 +154,30 @@ h5_vds-percival-unlim: $(srcdir)/h5_vds-percival-unlim.c
h5_vds-percival-unlim-maxmin: $(srcdir)/h5_vds-percival-unlim-maxmin.c
h5dsm_file_create: $(srcdir)/h5dsm_file_create.c
h5dsm_file_open: $(srcdir)/h5dsm_file_open.c
+h5dsm_group_create: $(srcdir)/h5dsm_group_create.c
+h5dsm_group_open: $(srcdir)/h5dsm_group_open.c
h5dsm_dset_create: $(srcdir)/h5dsm_dset_create.c
h5dsm_dset_open: $(srcdir)/h5dsm_dset_open.c
h5dsm_dset_write: $(srcdir)/h5dsm_dset_write.c
h5dsm_dset_read: $(srcdir)/h5dsm_dset_read.c
+h5dsm_dset_wpartial: $(srcdir)/h5dsm_dset_wpartial.c
+h5dsm_dset_rpartial: $(srcdir)/h5dsm_dset_rpartial.c
+h5dsm_dset_w1m: $(srcdir)/h5dsm_dset_w1m.c
+h5dsm_dset_r1m: $(srcdir)/h5dsm_dset_r1m.c
+h5dsm_link_exists: $(srcdir)/h5dsm_link_exists.c
+h5dsm_link_iter: $(srcdir)/h5dsm_link_iter.c
+h5dsm_attr_create: $(srcdir)/h5dsm_attr_create.c
+h5dsm_attr_open: $(srcdir)/h5dsm_attr_open.c
+h5dsm_attr_write: $(srcdir)/h5dsm_attr_write.c
+h5dsm_attr_read: $(srcdir)/h5dsm_attr_read.c
+h5dsm_attr_iter: $(srcdir)/h5dsm_attr_iter.c
+h5dsm_slink_create: $(srcdir)/h5dsm_slink_create.c
+h5dsm_obj_open: $(srcdir)/h5dsm_obj_open.c
+h5dsm_obj_open_addr: $(srcdir)/h5dsm_obj_open_addr.c
+h5dsm_obj_info: $(srcdir)/h5dsm_obj_info.c
+h5dsm_map: $(srcdir)/h5dsm_map.c
+h5dsm_ttconv: $(srcdir)/h5dsm_ttconv.c
+h5dsm_tvlen: $(srcdir)/h5dsm_tvlen.c
if BUILD_SHARED_SZIP_CONDITIONAL
LD_LIBRARY_PATH=$(LL_PATH)
diff --git a/examples/h5dsm_test.sh b/examples/h5dsm_test.sh
index 5b7eda6..c38e2ca 100755
--- a/examples/h5dsm_test.sh
+++ b/examples/h5dsm_test.sh
@@ -552,6 +552,14 @@ if test $? -ne 0; then
exit 1
fi
+# --------------- Variable Length types --------------- #
+echo h5dsm_tvlen
+orterun -np 1 $EXEC_ARGS ./h5dsm_tvlen $POOL_UUID -q
+if test $? -ne 0; then
+ echo FAILED
+ exit 1
+fi
+
# --------------- Output Comparison --------------- #
sed -i -e 's/#.*//' -e 's/[ ^I]*$//' -e '/^$/ d' h5dsm_test.out
echo cmp h5dsm_test.out h5dsm_test.out.exp
diff --git a/examples/h5dsm_ttconv.c b/examples/h5dsm_ttconv.c
index 731573c..6b10d53 100644
--- a/examples/h5dsm_ttconv.c
+++ b/examples/h5dsm_ttconv.c
@@ -20,7 +20,7 @@ hbool_t verbose_g = 1;
int main(int argc, char *argv[]) {
uuid_t pool_uuid;
char *pool_grp = NULL;
- hid_t file = -1, dset = -1, dset_a = -1, dset_b = -1, dset_c = -1, dset2 = -1, attr = -1, attr_a = -1, attr_b = -1 , attr_c = -1, space = -1, space2 = -1, space2_contig, fapl = -1;
+ hid_t file = -1, dset = -1, dset_a = -1, dset_b = -1, dset_c = -1, dset2 = -1, attr = -1, attr_a = -1, attr_b = -1 , attr_c = -1, space = -1, space2 = -1, space2_contig = -1, fapl = -1;
hid_t file_type = -1, file_type_a = -1, file_type_b = -1, file_type_c = -1;
hid_t mem_type = -1, mem_type_conv = -1, mem_type_a = -1, mem_type_b = -1, mem_type_c = -1;
hsize_t dims[2] = {4, 2};
diff --git a/examples/h5dsm_tvlen.c b/examples/h5dsm_tvlen.c
new file mode 100644
index 0000000..ffe4933
--- /dev/null
+++ b/examples/h5dsm_tvlen.c
@@ -0,0 +1,342 @@
+#include "h5dsm_example.h"
+#include <time.h>
+
+#define FILE_NAME "tvlen.h5"
+#define NITER 10
+
+hbool_t verbose_g = 1;
+
+static void print_vla(const hvl_t *vla) {
+ int i, j, k;
+
+ for(i = 0; i < 4; i++) {
+ for(j = 0; j < 2; j++) {
+ if(j > 0)
+ printf(", ");
+ printf("{");
+ for(k = 0; k < (int)vla[2 * i + j].len; k++) {
+ if(k > 0)
+ printf(", ");
+ printf("%d", ((int *)vla[2 * i + j].p)[k]);
+ } /* end for */
+ printf("}");
+ } /* end for */
+ printf("\n");
+ } /* end for */
+
+ return;
+} /* end print_vla() */
+
+static int check_vla(const hvl_t *vla1, const hvl_t *vla2) {
+ int i, j, k;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 2; j++) {
+ if(vla1[2 * i + j].len != vla2[2 * i + j].len)
+ PRINTF_ERROR("vlen array length at location %d, %d does not match", i, j);
+ for(k = 0; k < (int)vla1[2 * i + j].len; k++)
+ if(((int *)vla1[2 * i + j].p)[k] != ((int *)vla2[2 * i + j].p)[k])
+ PRINTF_ERROR("vlen array data at location %d, %d, %d does not match", i, j, k);
+ } /* end for */
+
+ return 0;
+
+error:
+ return -1;
+} /* end check_vla() */
+
+static void print_vls(char **vls) {
+ int i, j;
+
+ for(i = 0; i < 4; i++) {
+ for(j = 0; j < 2; j++) {
+ if(j > 0)
+ printf(", ");
+ if(vls[2 * i + j])
+ printf("\"%s\"", vls[2 * i + j]);
+ else
+ printf("NULL");
+ } /* end for */
+ printf("\n");
+ } /* end for */
+
+ return;
+} /* end print_vls() */
+
+static int check_vls(char **vls1, char **vls2) {
+ int i, j;
+
+ for(i = 0; i < 4; i++)
+ for(j = 0; j < 2; j++) {
+ if((vls1[2 * i + j] == NULL) != (vls2[2 * i + j] == NULL))
+ PRINTF_ERROR("one vlen string at location %d, %d is NULL and the other is not", i, j);
+ if(vls1[2 * i + j] && strcmp(vls1[2 * i + j], vls2[2 * i + j]))
+ PRINTF_ERROR("vlen strings at location %d, %d do not match", i, j);
+ } /* end for */
+
+ return 0;
+
+error:
+ return -1;
+} /* end check_vls() */
+
+int main(int argc, char *argv[]) {
+ uuid_t pool_uuid;
+ char *pool_grp = NULL;
+ hid_t file = -1, dset_vla = -1, dset_vls = -1, attr_vla = -1, attr_vls = -1, space = -1, fapl = -1;
+ hid_t type_vla = -1, type_vls = -1;
+ hsize_t dims[2] = {4, 2};
+ int static_buf_vla[4][2][8];
+ char static_buf_vls[4][2][8];
+ hvl_t rbuf_vla[4][2];
+ char *rbuf_vls[4][2];
+ hvl_t wbuf_vla[4][2];
+ char *wbuf_vls[4][2];
+ int bogus_int = -1;
+ char bogus_str[3] = {'-', '1', '\0'};
+ const hvl_t rbuf_vla_init[4][2] = {{{1, &bogus_int}, {1, &bogus_int}},
+ {{1, &bogus_int}, {1, &bogus_int}},
+ {{1, &bogus_int}, {1, &bogus_int}},
+ {{1, &bogus_int}, {1, &bogus_int}}};
+ char * const rbuf_vls_init[4][2] = {{bogus_str, bogus_str},
+ {bogus_str, bogus_str},
+ {bogus_str, bogus_str},
+ {bogus_str, bogus_str}};
+ const hvl_t wbuf_vla_init[4][2] = {{{0, &static_buf_vla[0][0][0]}, {0, &static_buf_vla[0][1][0]}},
+ {{0, &static_buf_vla[1][0][0]}, {0, &static_buf_vla[1][1][0]}},
+ {{0, &static_buf_vla[2][0][0]}, {0, &static_buf_vla[2][1][0]}},
+ {{0, &static_buf_vla[3][0][0]}, {1, &static_buf_vla[3][1][0]}}};
+ char * const wbuf_vls_init[4][2] = {{&static_buf_vls[0][0][0], &static_buf_vls[0][1][0]},
+ {&static_buf_vls[1][0][0], &static_buf_vls[1][1][0]},
+ {&static_buf_vls[2][0][0], &static_buf_vls[2][1][0]},
+ {&static_buf_vls[3][0][0], &static_buf_vls[3][1][0]}};
+ int i, j, k, l;
+
+ (void)MPI_Init(&argc, &argv);
+
+ /* Seed random number generator */
+ srand(time(NULL));
+
+ if((argc != 2) && (argc != 3))
+ PRINTF_ERROR("argc must be 2 or 3\n");
+
+ if(argc == 3)
+ verbose_g = 0;
+
+ /* Parse UUID */
+ if(0 != uuid_parse(argv[1], pool_uuid))
+ ERROR;
+
+ /* Initialize VOL */
+ if(H5VLdaosm_init(MPI_COMM_WORLD, pool_uuid, pool_grp) < 0)
+ ERROR;
+
+ /* Set up FAPL */
+ if((fapl = H5Pcreate(H5P_FILE_ACCESS)) < 0)
+ ERROR;
+ if(H5Pset_fapl_daosm(fapl, MPI_COMM_WORLD, MPI_INFO_NULL) < 0)
+ ERROR;
+ if(H5Pset_all_coll_metadata_ops(fapl, true) < 0)
+ ERROR;
+
+ /* Create file */
+ if((file = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
+ ERROR;
+
+ /* Set up dataspace */
+ if((space = H5Screate_simple(2, dims, NULL)) < 0)
+ ERROR;
+
+ /*
+ * Set up types
+ */
+ /* Create variable length array */
+ /* Set up file "all" type */
+ if((type_vla = H5Tvlen_create(H5T_NATIVE_INT)) < 0)
+ ERROR;
+
+ /* Set up variable length string type */
+ if((type_vls = H5Tcopy(H5T_C_S1)) < 0)
+ ERROR;
+ if(H5Tset_size(type_vls, H5T_VARIABLE) < 0)
+ ERROR;
+
+ /*
+ * Create objects
+ */
+ /* Create vla dataset */
+ if((dset_vla = H5Dcreate2(file, "vla_dset", type_vla, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+
+ /* Create vls dataset */
+ if((dset_vls = H5Dcreate2(file, "vls_dset", type_vls, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+
+ /* Create vla attribute */
+ if((attr_vla = H5Acreate2(dset_vla, "vla_attr", type_vla, space, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+
+ /* Create vls attribute */
+ if((attr_vls = H5Acreate2(dset_vla, "vls_attr", type_vls, space, H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+
+ /*
+ * Test attribute
+ */
+ /* Loop over iterations */
+ for(i = 0; i < NITER; i++) {
+ /*
+ * Variable length array attribute test
+ */
+ /* Fill write data buffer */
+ for(j = 0; j < dims[0]; j++)
+ for(k = 0; k < dims[1]; k++)
+ for(l = 0; l < (sizeof(static_buf_vla[0][0]) / sizeof(static_buf_vla[0][0][0])); l++)
+ static_buf_vla[j][k][l] = rand() % 100;
+
+ /* Fill write buffer */
+ memcpy(wbuf_vla, wbuf_vla_init, sizeof(wbuf_vla));
+ for(j = 0; j < dims[0]; j++)
+ for(k = 0; k < dims[1]; k++) {
+ /* 10% chance of having a NULL sequence */
+ if(rand() % 10)
+ wbuf_vla[j][k].len = rand() % 9;
+ else {
+ wbuf_vla[j][k].len = 0;
+ wbuf_vla[j][k].p = NULL;
+ } /* end if */
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing attribute with variable length arrays. buf =\n");
+ print_vla(wbuf_vla[0]);
+ } /* end if */
+
+ /* Write data */
+ if(H5Awrite(attr_vla, type_vla, wbuf_vla) < 0)
+ ERROR;
+
+ /* Read data */
+ memcpy(rbuf_vla, rbuf_vla_init, sizeof(rbuf_vla));
+ if(H5Aread(attr_vla, type_vla, rbuf_vla) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read attribute with variable length arrays. buf =\n");
+ print_vla(rbuf_vla[0]);
+ } /* end if */
+
+ /* Check buffer */
+ if(check_vla(wbuf_vla[0], rbuf_vla[0]) < 0) {
+ (void)H5Dvlen_reclaim(type_vla, space, H5P_DEFAULT, rbuf_vla);
+ ERROR;
+ } /* end if */
+
+ /* Reclaim read buffer */
+ if(H5Dvlen_reclaim(type_vla, space, H5P_DEFAULT, rbuf_vla) < 0)
+ ERROR;
+
+ if(verbose_g)
+ printf("\n");
+
+ /*
+ * Variable length string attribute test
+ */
+ /* Fill write data buffer */
+ for(j = 0; j < dims[0]; j++)
+ for(k = 0; k < dims[1]; k++)
+ for(l = 0; l < (sizeof(static_buf_vls[0][0]) / sizeof(static_buf_vls[0][0][0])); l++)
+ static_buf_vls[j][k][l] = 'a' + rand() % 26;
+
+ /* Fill write buffer */
+ memcpy(wbuf_vls, wbuf_vls_init, sizeof(wbuf_vls));
+ for(j = 0; j < dims[0]; j++)
+ for(k = 0; k < dims[1]; k++) {
+ /* 10% chance of having a NULL sequence */
+ if(rand() % 10)
+ static_buf_vls[j][k][rand() % 8] = '\0';
+ else
+ wbuf_vls[j][k] = NULL;
+ } /* end for */
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Writing attribute with variable length strings. buf =\n");
+ print_vls(wbuf_vls[0]);
+ } /* end if */
+
+ /* Write data */
+ if(H5Awrite(attr_vls, type_vls, wbuf_vls) < 0)
+ ERROR;
+
+ /* Read data */
+ memcpy(rbuf_vls, rbuf_vls_init, sizeof(rbuf_vls));
+ if(H5Aread(attr_vls, type_vls, rbuf_vls) < 0)
+ ERROR;
+
+ /* Print message */
+ if(verbose_g) {
+ printf("Read attribute with variable length strings. buf =\n");
+ print_vls(rbuf_vls[0]);
+ } /* end if */
+
+ /* Check buffer */
+ if(check_vls(wbuf_vls[0], rbuf_vls[0]) < 0) {
+ (void)H5Dvlen_reclaim(type_vls, space, H5P_DEFAULT, rbuf_vls);
+ ERROR;
+ } /* end if */
+
+ /* Reclaim read buffer */
+ if(H5Dvlen_reclaim(type_vls, space, H5P_DEFAULT, rbuf_vls) < 0)
+ ERROR;
+
+ if(verbose_g)
+ printf("\n");
+ } /* end for */
+
+ /*
+ * Close
+ */
+ if(H5Aclose(attr_vla) < 0)
+ ERROR;
+ if(H5Aclose(attr_vls) < 0)
+ ERROR;
+ if(H5Dclose(dset_vla) < 0)
+ ERROR;
+ if(H5Dclose(dset_vls) < 0)
+ ERROR;
+ if(H5Fclose(file) < 0)
+ ERROR;
+ if(H5Tclose(type_vla) < 0)
+ ERROR;
+ if(H5Tclose(type_vls) < 0)
+ ERROR;
+ if(H5Sclose(space) < 0)
+ ERROR;
+ if(H5Pclose(fapl) < 0)
+ ERROR;
+
+ printf("Success\n");
+
+ (void)MPI_Finalize();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Aclose(attr_vla);
+ H5Aclose(attr_vls);
+ H5Dclose(dset_vla);
+ H5Dclose(dset_vls);
+ H5Fclose(file);
+ H5Tclose(type_vla);
+ H5Tclose(type_vls);
+ H5Sclose(space);
+ H5Pclose(fapl);
+ } H5E_END_TRY;
+
+ (void)MPI_Finalize();
+ return 1;
+}
+
diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c
index 0e883be..12ec6b3 100644
--- a/src/H5VLdaosm.c
+++ b/src/H5VLdaosm.c
@@ -5324,20 +5324,22 @@ H5VL_daosm_attribute_read(void *_attr, hid_t mem_type_id, void *buf,
size_t akey_len;
daos_key_t dkey;
char *akey = NULL;
- daos_iod_t iod;
- daos_recx_t recx;
- daos_sg_list_t sgl;
- daos_iov_t sg_iov;
+ uint8_t **akeys = NULL;
+ daos_iod_t *iods = NULL;
+ daos_sg_list_t *sgls = NULL;
+ daos_iov_t *sg_iovs = NULL;
char attr_key[] = H5VL_DAOSM_ATTR_KEY;
+ hid_t base_type_id = FAIL;
size_t file_type_size;
- size_t mem_type_size;
+ size_t base_type_size = 0;
uint64_t attr_size;
void *tconv_buf = NULL;
void *bkg_buf = NULL;
- H5VL_daosm_tconv_reuse_t reuse = H5VL_DAOSM_TCONV_REUSE_NONE;
- hbool_t fill_bkg = FALSE;
+ H5T_class_t type_class;
+ hbool_t is_vl = FALSE;
+ htri_t is_vl_str = FALSE;
int ret;
- int i;
+ uint64_t i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
@@ -5350,76 +5352,233 @@ H5VL_daosm_attribute_read(void *_attr, hid_t mem_type_id, void *buf,
/* Calculate attribute size */
attr_size = (uint64_t)1;
- for(i = 0; i < ndims; i++)
+ for(i = 0; i < (uint64_t)ndims; i++)
attr_size *= (uint64_t)dim[i];
- /* Check for type conversion */
- if(H5VL_daosm_tconv_init(attr->type_id, &file_type_size, mem_type_id, &mem_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, &reuse, &fill_bkg) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion")
+ /* Set up dkey */
+ daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1));
- /* Reuse buffer as appropriate */
- if(reuse == H5VL_DAOSM_TCONV_REUSE_TCONV)
- tconv_buf = buf;
- else if(reuse == H5VL_DAOSM_TCONV_REUSE_BKG)
- bkg_buf = buf;
+ /* Check for vlen */
+ if(H5T_NO_CLASS == (type_class = H5Tget_class(mem_type_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype class")
+ if(type_class == H5T_VLEN) {
+ is_vl = TRUE;
+
+ /* Calculate base type size */
+ if((base_type_id = H5Tget_super(mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type")
+ if(0 == (base_type_size = H5Tget_size(base_type_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type size")
+ } /* end if */
+ else if(type_class == H5T_STRING) {
+ /* check for vlen string */
+ if((is_vl_str = H5Tis_variable_str(mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for variable length string")
+ if(is_vl_str)
+ is_vl = TRUE;
+ } /* end if */
- /* Fill background buffer if necessary */
- if(fill_bkg && (bkg_buf != buf))
- (void)HDmemcpy(bkg_buf, buf, (size_t)attr_size * mem_type_size);
+ /* Check for variable length */
+ if(is_vl) {
+ size_t akey_str_len;
+ uint64_t offset = 0;
+ uint8_t *p;
+
+ /* Calculate akey length */
+ akey_str_len = HDstrlen(attr->name) + 2;
+ akey_len = akey_str_len + sizeof(uint64_t);
+
+ /* Allocate array of akey pointers */
+ if(NULL == (akeys = (uint8_t **)H5MM_calloc(attr_size * sizeof(uint8_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey array")
+
+ /* Allocate array of iods */
+ if(NULL == (iods = (daos_iod_t *)H5MM_malloc(attr_size * sizeof(daos_iod_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for I/O descriptor array")
+
+ /* First loop over elements, set up operation to read vl sizes */
+ for(i = 0; i < attr_size; i++) {
+ /* Create akey for this element */
+ if(NULL == (akeys[i] = (uint8_t *)H5MM_malloc(akey_len)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey")
+ akeys[i][0] = 'V';
+ akeys[i][1] = '-';
+ (void)HDstrcpy((char *)akeys[i] + 2, attr->name);
+ p = akeys[i] + akey_str_len;
+ UINT64ENCODE(p, i)
+
+ /* Set up iod. Use "single" records of varying size. */
+ HDmemset(&iods[i], 0, sizeof(iods[0]));
+ daos_iov_set(&iods[i].iod_name, (void *)akeys[i], (daos_size_t)akey_len);
+ daos_csum_set(&iods[i].iod_kcsum, NULL, 0);
+ iods[i].iod_nr = 1u;
+ iods[i].iod_size = DAOS_REC_ANY;
+ iods[i].iod_type = DAOS_IOD_SINGLE;
+ } /* end for */
- /* Set up operation to read data */
- /* Set up dkey */
- daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1));
+ /* Read vl sizes from attribute */
+ /* Note cast to unsigned reduces width to 32 bits. Should eventually
+ * check for overflow and iterate over 2^32 size blocks */
+ if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, (unsigned)attr_size, iods, NULL, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read vl data sizes from attribute: %d", ret)
+
+ /* Allocate array of sg_iovs */
+ if(NULL == (sg_iovs = (daos_iov_t *)H5MM_malloc(attr_size * sizeof(daos_iov_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list")
+
+ /* Allocate array of sgls */
+ if(NULL == (sgls = (daos_sg_list_t *)H5MM_malloc(attr_size * sizeof(daos_sg_list_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list array")
+
+ /* Second loop over elements, set up operation to read vl data */
+ for(i = 0; i < attr_size; i++) {
+ /* Set up constant sgl info */
+ sgls[i].sg_nr.num = 1;
+ sgls[i].sg_iovs = &sg_iovs[i];
+
+ /* Check for empty element */
+ if(iods[i].iod_size == 0) {
+ /* Increment offset, slide down following elements */
+ offset++;
+
+ /* Zero out read buffer */
+ if(is_vl_str)
+ ((char **)buf)[i] = NULL;
+ else
+ HDmemset(&((hvl_t *)buf)[i], 0, sizeof(hvl_t));
+ } /* end if */
+ else {
+ HDassert(i >= offset);
- /* Create akey string (prefix "V-") */
- akey_len = HDstrlen(attr->name) + 2;
- if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey")
- akey[0] = 'V';
- akey[1] = '-';
- (void)HDstrcpy(akey + 2, attr->name);
+ /* Check for vlen string */
+ if(is_vl_str) {
+ char *elem = NULL;
- /* Set up recx */
- recx.rx_idx = (uint64_t)0;
- recx.rx_nr = attr_size;
+ /* Allocate buffer for this vl element */
+ if(NULL == (elem = (char *)HDmalloc((size_t)iods[i].iod_size + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate vl data buffer")
+ ((char **)buf)[i] = elem;
- /* Set up iod */
- HDmemset(&iod, 0, sizeof(iod));
- daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len);
- daos_csum_set(&iod.iod_kcsum, NULL, 0);
- iod.iod_nr = 1u;
- iod.iod_recxs = &recx;
- iod.iod_size = (uint64_t)file_type_size;
- iod.iod_type = DAOS_IOD_ARRAY;
+ /* Add null terminator */
+ elem[iods[i].iod_size] = '\0';
- /* Set up sgl */
- daos_iov_set(&sg_iov, tconv_buf ? tconv_buf : buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
- sgl.sg_nr.num = 1;
- sgl.sg_iovs = &sg_iov;
+ /* Set buffer location in sgl */
+ daos_iov_set(&sg_iovs[i - offset], elem, iods[i].iod_size);
+ } /* end if */
+ else {
+ /* Standard vlen, find hvl_t struct for this element */
+ hvl_t *elem = &((hvl_t *)buf)[i];
- /* Read data from attribute */
- if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
- HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret)
+ HDassert(base_type_size > 0);
- /* Perform type conversion if necessary */
- if(tconv_buf) {
- /* Type conversion */
- if(H5Tconvert(attr->type_id, mem_type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion")
+ /* Allocate buffer for this vl element and set size */
+ elem->len = (size_t)iods[i].iod_size / base_type_size;
+ if(NULL == (elem->p = HDmalloc((size_t)iods[i].iod_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate vl data buffer")
+
+ /* Set buffer location in sgl */
+ daos_iov_set(&sg_iovs[i - offset], elem->p, iods[i].iod_size);
+ } /* end if */
+
+ /* Slide down iod if necessary */
+ if(offset)
+ iods[i - offset] = iods[i];
+ } /* end else */
+ } /* end for */
- /* Copy to user's buffer if necessary */
- if(buf != tconv_buf)
- (void)HDmemcpy(buf, tconv_buf, (size_t)attr_size * mem_type_size);
+ /* Read data from attribute */
+ /* Note cast to unsigned reduces width to 32 bits. Should eventually
+ * check for overflow and iterate over 2^32 size blocks */
+ if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, (unsigned)(attr_size - offset), iods, sgls, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret)
} /* end if */
+ else {
+ daos_iod_t iod;
+ daos_recx_t recx;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ size_t mem_type_size;
+ H5VL_daosm_tconv_reuse_t reuse = H5VL_DAOSM_TCONV_REUSE_NONE;
+ hbool_t fill_bkg = FALSE;
+
+ /* Check for type conversion */
+ if(H5VL_daosm_tconv_init(attr->type_id, &file_type_size, mem_type_id, &mem_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, &reuse, &fill_bkg) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion")
+
+ /* Reuse buffer as appropriate */
+ if(reuse == H5VL_DAOSM_TCONV_REUSE_TCONV)
+ tconv_buf = buf;
+ else if(reuse == H5VL_DAOSM_TCONV_REUSE_BKG)
+ bkg_buf = buf;
+
+ /* Fill background buffer if necessary */
+ if(fill_bkg && (bkg_buf != buf))
+ (void)HDmemcpy(bkg_buf, buf, (size_t)attr_size * mem_type_size);
+
+ /* Set up operation to read data */
+ /* Create akey string (prefix "V-") */
+ akey_len = HDstrlen(attr->name) + 2;
+ if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey")
+ akey[0] = 'V';
+ akey[1] = '-';
+ (void)HDstrcpy(akey + 2, attr->name);
+
+ /* Set up recx */
+ recx.rx_idx = (uint64_t)0;
+ recx.rx_nr = attr_size;
+
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len);
+ daos_csum_set(&iod.iod_kcsum, NULL, 0);
+ iod.iod_nr = 1u;
+ iod.iod_recxs = &recx;
+ iod.iod_size = (uint64_t)file_type_size;
+ iod.iod_type = DAOS_IOD_ARRAY;
+
+ /* Set up sgl */
+ daos_iov_set(&sg_iov, tconv_buf ? tconv_buf : buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ /* Read data from attribute */
+ if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret)
+
+ /* Perform type conversion if necessary */
+ if(tconv_buf) {
+ /* Type conversion */
+ if(H5Tconvert(attr->type_id, mem_type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion")
+
+ /* Copy to user's buffer if necessary */
+ if(buf != tconv_buf)
+ (void)HDmemcpy(buf, tconv_buf, (size_t)attr_size * mem_type_size);
+ } /* end if */
+ } /* end else */
done:
/* Free memory */
akey = (char *)H5MM_xfree(akey);
+ iods = (daos_iod_t *)H5MM_xfree(iods);
+ sgls = (daos_sg_list_t *)H5MM_xfree(sgls);
+ sg_iovs = (daos_iov_t *)H5MM_xfree(sg_iovs);
if(tconv_buf && (tconv_buf != buf))
H5MM_free(tconv_buf);
if(bkg_buf && (bkg_buf != buf))
H5MM_free(bkg_buf);
+ if(akeys) {
+ for(i = 0; i < attr_size; i++)
+ H5MM_xfree(akeys[i]);
+ H5MM_free(akeys);
+ } /* end if */
+
+ if(base_type_id != FAIL)
+ if(H5I_dec_app_ref(base_type_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close base type id")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_attribute_read() */
@@ -5447,19 +5606,22 @@ H5VL_daosm_attribute_write(void *_attr, hid_t H5_ATTR_UNUSED mem_type_id,
size_t akey_len;
daos_key_t dkey;
char *akey = NULL;
- daos_iod_t iod;
- daos_recx_t recx;
- daos_sg_list_t sgl;
- daos_iov_t sg_iov;
+ uint8_t **akeys = NULL;
+ daos_iod_t *iods = NULL;
+ daos_sg_list_t *sgls = NULL;
+ daos_iov_t *sg_iovs = NULL;
char attr_key[] = H5VL_DAOSM_ATTR_KEY;
+ hid_t base_type_id = FAIL;
size_t file_type_size;
- size_t mem_type_size;
+ size_t base_type_size = 0;
uint64_t attr_size;
void *tconv_buf = NULL;
void *bkg_buf = NULL;
- hbool_t fill_bkg = FALSE;
+ H5T_class_t type_class;
+ hbool_t is_vl = FALSE;
+ htri_t is_vl_str = FALSE;
int ret;
- int i;
+ uint64_t i;
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT
@@ -5476,79 +5638,214 @@ H5VL_daosm_attribute_write(void *_attr, hid_t H5_ATTR_UNUSED mem_type_id,
/* Calculate attribute size */
attr_size = (uint64_t)1;
- for(i = 0; i < ndims; i++)
+ for(i = 0; i < (uint64_t)ndims; i++)
attr_size *= (uint64_t)dim[i];
- /* Check for type conversion */
- if(H5VL_daosm_tconv_init(mem_type_id, &mem_type_size, attr->type_id, &file_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, NULL, &fill_bkg) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion")
-
- /* Set up operation to write data */
/* Set up dkey */
daos_iov_set(&dkey, attr_key, (daos_size_t)(sizeof(attr_key) - 1));
- /* Create akey string (prefix "V-") */
- akey_len = HDstrlen(attr->name) + 2;
- if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey")
- akey[0] = 'V';
- akey[1] = '-';
- (void)HDstrcpy(akey + 2, attr->name);
+ /* Check for vlen */
+ if(H5T_NO_CLASS == (type_class = H5Tget_class(mem_type_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype class")
+ if(type_class == H5T_VLEN) {
+ is_vl = TRUE;
+
+ /* Calculate base type size */
+ if((base_type_id = H5Tget_super(mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type")
+ if(0 == (base_type_size = H5Tget_size(base_type_id)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't get datatype base type size")
+ } /* end if */
+ else if(type_class == H5T_STRING) {
+ /* check for vlen string */
+ if((is_vl_str = H5Tis_variable_str(mem_type_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, FAIL, "can't check for variable length string")
+ if(is_vl_str)
+ is_vl = TRUE;
+ } /* end if */
- /* Set up recx */
- recx.rx_idx = (uint64_t)0;
- recx.rx_nr = attr_size;
+ /* Check for variable length */
+ if(is_vl) {
+ size_t akey_str_len;
+ uint8_t *p;
+
+ /* Calculate akey length */
+ akey_str_len = HDstrlen(attr->name) + 2;
+ akey_len = akey_str_len + sizeof(uint64_t);
+
+ /* Allocate array of akey pointers */
+ if(NULL == (akeys = (uint8_t **)H5MM_calloc(attr_size * sizeof(uint8_t *))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey array")
+
+ /* Allocate array of iods */
+ if(NULL == (iods = (daos_iod_t *)H5MM_malloc(attr_size * sizeof(daos_iod_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for I/O descriptor array")
+
+ /* Allocate array of sg_iovs */
+ if(NULL == (sg_iovs = (daos_iov_t *)H5MM_malloc(attr_size * sizeof(daos_iov_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list")
+
+ /* Allocate array of sgls */
+ if(NULL == (sgls = (daos_sg_list_t *)H5MM_malloc(attr_size * sizeof(daos_sg_list_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for scatter gather list array")
+
+ /* Loop over elements */
+ for(i = 0; i < attr_size; i++) {
+ /* Create akey for this element */
+ if(NULL == (akeys[i] = (uint8_t *)H5MM_malloc(akey_len)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey")
+ akeys[i][0] = 'V';
+ akeys[i][1] = '-';
+ (void)HDstrcpy((char *)akeys[i] + 2, attr->name);
+ p = akeys[i] + akey_str_len;
+ UINT64ENCODE(p, i)
+
+ /* Set up iod, determine size below. Use "single" records of
+ * varying size. */
+ HDmemset(&iods[i], 0, sizeof(iods[0]));
+ daos_iov_set(&iods[i].iod_name, (void *)akeys[i], (daos_size_t)akey_len);
+ daos_csum_set(&iods[i].iod_kcsum, NULL, 0);
+ iods[i].iod_nr = 1u;
+ iods[i].iod_type = DAOS_IOD_SINGLE;
+
+ /* Set up constant sgl info */
+ sgls[i].sg_nr.num = 1;
+ sgls[i].sg_iovs = &sg_iovs[i];
+
+ /* Check for vlen string */
+ if(is_vl_str) {
+ /* Find string for this element */
+ char *elem = ((char * const *)buf)[i];
+
+ /* Set string length in iod and buffer location in sgl. If we
+ * are writing an empty string ("\0"), increase the size by one
+ * to differentiate it from NULL strings. Note that this will
+ * cause the read buffer to be one byte longer than it needs to
+ * be in this case. This should not cause any ill effects. */
+ if(elem) {
+ iods[i].iod_size = (daos_size_t)HDstrlen(elem);
+ if(iods[i].iod_size == 0)
+ iods[i].iod_size = 1;
+ daos_iov_set(&sg_iovs[i], (void *)elem, iods[i].iod_size);
+ } /* end if */
+ else {
+ iods[i].iod_size = 0;
+ daos_iov_set(&sg_iovs[i], NULL, 0);
+ } /* end else */
+ } /* end if */
+ else {
+ /* Standard vlen, find hvl_t struct for this element */
+ const hvl_t *elem = &((const hvl_t *)buf)[i];
- /* Set up iod */
- HDmemset(&iod, 0, sizeof(iod));
- daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len);
- daos_csum_set(&iod.iod_kcsum, NULL, 0);
- iod.iod_nr = 1u;
- iod.iod_recxs = &recx;
- iod.iod_size = (uint64_t)file_type_size;
- iod.iod_type = DAOS_IOD_ARRAY;
+ HDassert(base_type_size > 0);
- /* Set up constant sgl info */
- sgl.sg_nr.num = 1;
- sgl.sg_iovs = &sg_iov;
+ /* Set buffer length in iod and buffer location in sgl */
+ if(elem->len > 0) {
+ iods[i].iod_size = (daos_size_t)(elem->len * base_type_size);
+ daos_iov_set(&sg_iovs[i], (void *)elem->p, iods[i].iod_size);
+ } /* end if */
+ else {
+ iods[i].iod_size = 0;
+ daos_iov_set(&sg_iovs[i], NULL, 0);
+ } /* end else */
+ } /* end if */
+ } /* end for */
- /* Check for type conversion */
- if(tconv_buf) {
- /* Check if we need to fill background buffer */
- if(fill_bkg) {
- HDassert(bkg_buf);
+ /* Write data to attribute */
+ /* Note cast to unsigned reduces width to 32 bits. Should eventually
+ * check for overflow and iterate over 2^32 size blocks */
+ if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, (unsigned)attr_size, iods, sgls, NULL /*event*/)))
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret)
+ } /* end if */
+ else {
+ daos_iod_t iod;
+ daos_recx_t recx;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ size_t mem_type_size;
+ hbool_t fill_bkg = FALSE;
- /* Read data from attribute to background buffer */
- daos_iov_set(&sg_iov, bkg_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
+ /* Check for type conversion */
+ if(H5VL_daosm_tconv_init(mem_type_id, &mem_type_size, attr->type_id, &file_type_size, (size_t)attr_size, &tconv_buf, &bkg_buf, NULL, &fill_bkg) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "can't initialize type conversion")
- if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
- HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret)
- } /* end if */
+ /* Set up operation to write data */
+ /* Create akey string (prefix "V-") */
+ akey_len = HDstrlen(attr->name) + 2;
+ if(NULL == (akey = (char *)H5MM_malloc(akey_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, FAIL, "can't allocate buffer for akey")
+ akey[0] = 'V';
+ akey[1] = '-';
+ (void)HDstrcpy(akey + 2, attr->name);
- /* Copy data to type conversion buffer */
- (void)HDmemcpy(tconv_buf, buf, (size_t)attr_size * mem_type_size);
+ /* Set up recx */
+ recx.rx_idx = (uint64_t)0;
+ recx.rx_nr = attr_size;
- /* Perform type conversion */
- if(H5Tconvert(mem_type_id, attr->type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0)
- HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion")
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.iod_name, (void *)akey, (daos_size_t)akey_len);
+ daos_csum_set(&iod.iod_kcsum, NULL, 0);
+ iod.iod_nr = 1u;
+ iod.iod_recxs = &recx;
+ iod.iod_size = (uint64_t)file_type_size;
+ iod.iod_type = DAOS_IOD_ARRAY;
- /* Set sgl to write from tconv_buf */
- daos_iov_set(&sg_iov, tconv_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
- } /* end if */
- else
- /* Set sgl to write from buf */
- daos_iov_set(&sg_iov, (void *)buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
+ /* Set up constant sgl info */
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ /* Check for type conversion */
+ if(tconv_buf) {
+ /* Check if we need to fill background buffer */
+ if(fill_bkg) {
+ HDassert(bkg_buf);
+
+ /* Read data from attribute to background buffer */
+ daos_iov_set(&sg_iov, bkg_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
- /* Write data to attribute */
- if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/)))
- HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret)
+ if(0 != (ret = daos_obj_fetch(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "can't read data from attribute: %d", ret)
+ } /* end if */
+
+ /* Copy data to type conversion buffer */
+ (void)HDmemcpy(tconv_buf, buf, (size_t)attr_size * mem_type_size);
+
+ /* Perform type conversion */
+ if(H5Tconvert(mem_type_id, attr->type_id, attr_size, tconv_buf, bkg_buf, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCONVERT, FAIL, "can't perform type conversion")
+
+ /* Set sgl to write from tconv_buf */
+ daos_iov_set(&sg_iov, tconv_buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
+ } /* end if */
+ else
+ /* Set sgl to write from buf */
+ daos_iov_set(&sg_iov, (void *)buf, (daos_size_t)(attr_size * (uint64_t)file_type_size));
+
+ /* Write data to attribute */
+ if(0 != (ret = daos_obj_update(attr->parent->obj_oh, attr->item.file->epoch, &dkey, 1, &iod, &sgl, NULL /*event*/)))
+ HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "can't write data to attribute: %d", ret)
+ } /* end else */
done:
/* Free memory */
akey = (char *)H5MM_xfree(akey);
+ iods = (daos_iod_t *)H5MM_xfree(iods);
+ sgls = (daos_sg_list_t *)H5MM_xfree(sgls);
+ sg_iovs = (daos_iov_t *)H5MM_xfree(sg_iovs);
tconv_buf = H5MM_xfree(tconv_buf);
bkg_buf = H5MM_xfree(bkg_buf);
+ if(akeys) {
+ for(i = 0; i < attr_size; i++)
+ H5MM_xfree(akeys[i]);
+ H5MM_free(akeys);
+ } /* end if */
+
+ if(base_type_id != FAIL)
+ if(H5I_dec_app_ref(base_type_id) < 0)
+ HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close base type id")
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_attribute_write() */
@@ -5673,7 +5970,7 @@ H5VL_daosm_attribute_specific(void *_item, H5VL_loc_params_t loc_params,
{
H5VL_daosm_item_t *item = (H5VL_daosm_item_t *)_item;
H5VL_daosm_obj_t *target_obj = NULL;
- hid_t target_obj_id = -1;
+ hid_t target_obj_id = FAIL;
char *akey_buf = NULL;
size_t akey_buf_len = 0;
H5VL_daosm_attr_t *attr = NULL;
@@ -5862,10 +6159,10 @@ H5VL_daosm_attribute_specific(void *_item, H5VL_loc_params_t loc_params,
} /* end switch */
done:
- if(target_obj_id >= 0) {
+ if(target_obj_id != FAIL) {
if(H5I_dec_app_ref(target_obj_id) < 0)
HDONE_ERROR(H5E_ATTR, H5E_CLOSEERROR, FAIL, "can't close object id")
- target_obj_id = -1;
+ target_obj_id = FAIL;
target_obj = NULL;
} /* end if */
else if(target_obj) {
diff --git a/src/H5VLint.c b/src/H5VLint.c
index 4dcc095..fda58fa 100644
--- a/src/H5VLint.c
+++ b/src/H5VLint.c
@@ -378,8 +378,9 @@ H5VL_object(hid_t id)
/* Get the symbol table entry */
switch(H5I_get_type(id)) {
case H5I_GROUP:
+ case H5I_MAP:
case H5I_DATASET:
- case H5I_FILE:
+ case H5I_FILE:
case H5I_ATTR:
/* get the object */
if(NULL == (obj = (H5VL_object_t *)H5I_object(id)))
@@ -447,8 +448,9 @@ H5VL_object_verify(hid_t id, H5I_type_t obj_type)
/* Get the symbol table entry */
switch(obj_type) {
case H5I_GROUP:
+ case H5I_MAP:
case H5I_DATASET:
- case H5I_FILE:
+ case H5I_FILE:
case H5I_ATTR:
/* get the object */
if(NULL == (obj = (H5VL_object_t *)H5I_object_verify(id, obj_type)))