summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2017-05-11 22:28:20 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2017-05-11 22:28:20 (GMT)
commit8fc280b3fc9b4f16d4bb3eef300df5d5158e26b0 (patch)
tree6f9e59f31a42a63f164383109886af312f57e1c8
parent06a0c4a64638d11f4e52c8c84c9d395e6bf85b7c (diff)
downloadhdf5-8fc280b3fc9b4f16d4bb3eef300df5d5158e26b0.zip
hdf5-8fc280b3fc9b4f16d4bb3eef300df5d5158e26b0.tar.gz
hdf5-8fc280b3fc9b4f16d4bb3eef300df5d5158e26b0.tar.bz2
Add maps implementation (based on a patch supplied by Mohamad
Chaarawi). Add h5dsm_map.c example. Other minor fixes/cleanup.
-rw-r--r--examples/Makefile.am2
-rw-r--r--examples/h5dsm_map.c231
-rw-r--r--src/H5.c3
-rw-r--r--src/H5FF.c4
-rw-r--r--src/H5I.c8
-rw-r--r--src/H5Ipublic.h1
-rw-r--r--src/H5M.c575
-rw-r--r--src/H5Mmodule.h32
-rw-r--r--src/H5Mpkg.h31
-rw-r--r--src/H5Mprivate.h40
-rw-r--r--src/H5Mpublic.h66
-rw-r--r--src/H5Opublic.h1
-rw-r--r--src/H5Pint.c65
-rw-r--r--src/H5Pprivate.h6
-rw-r--r--src/H5Ppublic.h8
-rw-r--r--src/H5VLdaosm.c911
-rw-r--r--src/H5VLdaosm.h22
-rw-r--r--src/H5VLprivate.h1
-rw-r--r--src/H5err.txt1
-rw-r--r--src/H5private.h2
-rw-r--r--src/Makefile.am5
-rw-r--r--src/hdf5.h1
22 files changed, 1995 insertions, 21 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 623e3ae..f83145a 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -43,7 +43,7 @@ EXAMPLE_PROG = h5_write h5_read h5_extend_write h5_chunk_read h5_compound \
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_dset_write h5dsm_dset_read h5dsm_map
TEST_SCRIPT=testh5cc.sh
TEST_EXAMPLES_SCRIPT=$(INSTALL_SCRIPT_FILES)
diff --git a/examples/h5dsm_map.c b/examples/h5dsm_map.c
new file mode 100644
index 0000000..c42ef18
--- /dev/null
+++ b/examples/h5dsm_map.c
@@ -0,0 +1,231 @@
+#include "h5dsm_example.h"
+
+#define VL_INCREMENT 4
+#define NUM_KEYS 345
+
+int main(int argc, char *argv[]) {
+ uuid_t pool_uuid;
+ char *pool_grp = NULL;
+ hid_t file = -1, map1 = -1, map2 = -1, map3 = -1, fapl = -1;
+ hid_t dtid1, dtid2;
+ const char *str_wdata[5]= {
+ "Four score and seven years ago our forefathers brought forth on this continent a new nation,",
+ "conceived in liberty and dedicated to the proposition that all men are created equal.",
+ "Now we are engaged in a great civil war,",
+ "testing whether that nation or any nation so conceived and so dedicated can long endure.",
+ "President Abraham Lincoln"
+ }; /* Information to write */
+ char *str_rdata[5]; /* Information read in */
+ hvl_t wdata[5];
+ hvl_t rdata[5];
+ int i, value, ret;
+ hsize_t count;
+ hbool_t exists;
+
+ (void)MPI_Init(&argc, &argv);
+
+ if(argc != 3)
+ PRINTF_ERROR("argc must be 3\n");
+
+ /* Set write buffer for VL data*/
+ {
+ int n = 0;
+ int j;
+
+ /* Allocate and initialize VL data to write */
+ for(i = 0; i < 5; i++) {
+ int temp = i * VL_INCREMENT + VL_INCREMENT;
+
+ wdata[i].p = malloc(temp * sizeof(unsigned int));
+ wdata[i].len = temp;
+ for(j = 0; j < temp; j++)
+ ((unsigned int *)wdata[i].p)[j] = n++;
+ } /* end for */
+ } /* end block */
+
+ /* 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;
+
+ /* Open file */
+ if((file = H5Fopen(argv[2], H5F_ACC_RDWR, fapl)) < 0)
+ ERROR;
+
+ printf("Creating Maps\n");
+
+ dtid1 = H5Tvlen_create (H5T_NATIVE_UINT);
+
+ /* Create an HDF5 VL string datatype */
+ dtid2 = H5Tcopy(H5T_C_S1);
+ H5Tset_size(dtid2, H5T_VARIABLE);
+
+ if((map1 = H5Mcreate(file, "MAP_VL_T", H5T_NATIVE_INT, dtid1,
+ H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+ if((map2 = H5Mcreate(file, "MAP_VL_STR", H5T_NATIVE_INT, dtid2,
+ H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+ if((map3 = H5Mcreate(file, "MAP_FIXED", H5T_NATIVE_INT, H5T_NATIVE_INT,
+ H5P_DEFAULT, H5P_DEFAULT)) < 0)
+ ERROR;
+
+ for(i = 0 ; i < 5 ; i++) {
+ ret = H5Mset(map1, H5T_NATIVE_INT, &i, dtid1, &wdata[i],
+ H5P_DEFAULT);
+ if (ret != 0)
+ ERROR;
+ } /* end for */
+
+ for(i = 0 ; i < 5 ; i++) {
+ ret = H5Mset(map2, H5T_NATIVE_INT, &i, dtid2, str_wdata[i],
+ H5P_DEFAULT);
+ if (ret != 0)
+ ERROR;
+ } /* end for */
+
+ for(i = 0 ; i < NUM_KEYS ; i++) {
+ value = 1000 + i;
+ ret = H5Mset(map3, H5T_NATIVE_INT, &i, H5T_NATIVE_INT, &value,
+ H5P_DEFAULT);
+ if (ret != 0)
+ ERROR;
+ } /* end for */
+
+ if(H5Mclose(map1) < 0)
+ ERROR;
+ if(H5Mclose(map2) < 0)
+ ERROR;
+ if(H5Mclose(map3) < 0)
+ ERROR;
+
+ printf("Opening and reading maps\n");
+
+ if((map1 = H5Mopen(file, "MAP_VL_T", H5P_DEFAULT)) < 0)
+ ERROR;
+ if((map2 = H5Mopen(file, "MAP_VL_STR", H5P_DEFAULT)) < 0)
+ ERROR;
+ if((map3 = H5Mopen(file, "MAP_FIXED", H5P_DEFAULT)) < 0)
+ ERROR;
+
+ ret = H5Mget_count(map1, &count);
+ if (ret != 0)
+ ERROR;
+ printf("KEY count %s = %llu\n", "MAP_VL_T", count);
+ if(count != 5)
+ ERROR;
+ ret = H5Mget_count(map2, &count);
+ if (ret != 0)
+ ERROR;
+ printf("KEY count %s = %llu\n", "MAP_VL_STR", count);
+ if(count != 5)
+ ERROR;
+ ret = H5Mget_count(map3, &count);
+ if (ret != 0)
+ ERROR;
+ printf("KEY count %s = %llu\n", "MAP_FIXED", count);
+ if(count != NUM_KEYS)
+ ERROR;
+
+ i = 2;
+ ret = H5Mexists(map1, H5T_NATIVE_INT, &i, &exists);
+ if (ret != 0)
+ ERROR;
+ if(!exists) {
+ printf("Key %d should exist\n", i);
+ ERROR;
+ } /* end if */
+
+ i = 6;
+ ret = H5Mexists(map1, H5T_NATIVE_INT, &i, &exists);
+ if (ret != 0)
+ ERROR;
+ if(exists) {
+ printf("Key %d should NOT exist\n", i);
+ ERROR;
+ } /* end if */
+
+ printf("Reading VL DATA: \n");
+ for(i=0 ; i<5 ; i++) {
+ int increment=4, j=0;
+ int temp = i*increment + increment;
+
+ ret = H5Mget(map1, H5T_NATIVE_INT, &i, dtid1, &rdata[i],
+ H5P_DEFAULT);
+ if (ret != 0)
+ ERROR;
+ printf("Key %d size %zu: ", i, rdata[i].len);
+ for(j = 0; j < temp; j++)
+ printf("%d ",((unsigned int *)rdata[i].p)[j]);
+ printf("\n");
+ } /* end for */
+
+ printf("Reading VL Strings: \n");
+ for(i=0 ; i<5 ; i++) {
+ str_rdata[i] = NULL;
+ ret = H5Mget(map2, H5T_NATIVE_INT, &i, dtid2, &str_rdata[i],
+ H5P_DEFAULT);
+ if (ret != 0)
+ ERROR;
+ printf("Key %d: %s\n", i, str_rdata[i]);
+ free(str_rdata[i]);
+ }
+
+ printf("Checking Fixed length Data ... \n");
+ for(i=0 ; i<NUM_KEYS ; i++) {
+ value = -1;
+ ret = H5Mget(map3, H5T_NATIVE_INT, &i, H5T_NATIVE_INT, &value,
+ H5P_DEFAULT);
+
+ if(value != 1000+i) {
+ printf("Key %d: Value recieved = %d\n", i, value);
+ ERROR;
+ }
+ }
+ printf("All good\n");
+
+
+ /* Close */
+ if(H5Tclose(dtid2) < 0)
+ ERROR;
+ if(H5Mclose(map1) < 0)
+ ERROR;
+ if(H5Mclose(map2) < 0)
+ ERROR;
+ if(H5Mclose(map3) < 0)
+ ERROR;
+ if(H5Fclose(file) < 0)
+ ERROR;
+ if(H5Pclose(fapl) < 0)
+ ERROR;
+
+ printf("Success\n");
+
+ (void)MPI_Finalize();
+ return 0;
+
+error:
+ H5E_BEGIN_TRY {
+ H5Mclose(map1);
+ H5Mclose(map2);
+ H5Mclose(map3);
+ H5Fclose(file);
+ H5Tclose(dtid2);
+ H5Pclose(fapl);
+ } H5E_END_TRY;
+
+ (void)MPI_Finalize();
+ return 1;
+}
+
diff --git a/src/H5.c b/src/H5.c
index a4b55f6..2bd2a60 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -27,6 +27,7 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
#include "H5Lprivate.h" /* Links */
+#include "H5Mprivate.h" /* Maps */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5SLprivate.h" /* Skip lists */
@@ -305,6 +306,7 @@ H5_term_library(void)
pending += DOWN(A_top);
pending += DOWN(D_top);
pending += DOWN(G_top);
+ pending += DOWN(M_top);
pending += DOWN(R_top);
pending += DOWN(S_top);
pending += DOWN(T_top);
@@ -330,6 +332,7 @@ H5_term_library(void)
pending += DOWN(A);
pending += DOWN(D);
pending += DOWN(G);
+ pending += DOWN(M);
pending += DOWN(R);
pending += DOWN(S);
pending += DOWN(T);
diff --git a/src/H5FF.c b/src/H5FF.c
index 1378f9e..f92d7e7 100644
--- a/src/H5FF.c
+++ b/src/H5FF.c
@@ -99,10 +99,10 @@ H5FF__init_package(void)
HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init dataset interface")
/*if(H5A_init() < 0)
- HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init attribute interface")
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init attribute interface")*/
if(H5M_init() < 0)
- HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface") DSMINC*/
+ HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface")
if(H5TR_init() < 0)
HDONE_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to init map interface")
diff --git a/src/H5I.c b/src/H5I.c
index 0fbc58f..bfe608f 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -1990,7 +1990,7 @@ H5I__iterate_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata)
H5I_type_t type = udata->obj_type;
const void *obj_ptr = NULL;
- if(H5I_FILE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type) {
+ if(H5I_FILE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type || H5I_MAP == type) {
const H5VL_object_t *obj = (const H5VL_object_t *)item->obj_ptr;
obj_ptr = obj->vol_obj;
}
@@ -2190,7 +2190,7 @@ H5Iget_file_id(hid_t obj_id)
type = H5I_TYPE(obj_id);
if(H5I_FILE == type || H5I_DATATYPE == type || H5I_GROUP == type ||
- H5I_DATASET == type || H5I_ATTR == type) {
+ H5I_DATASET == type || H5I_ATTR == type || H5I_MAP == type) {
/* get the object pointer*/
if(NULL == (obj = H5VL_get_object(obj_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid identifier")
@@ -2257,7 +2257,7 @@ H5I_get_file_id(hid_t obj_id, hbool_t app_ref)
HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
ret_value = obj_id;
} /* end if */
- else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) {
+ else if(type == H5I_DATATYPE || type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR || type == H5I_MAP) {
H5G_loc_t loc; /* Location of object */
/* Get the object location information */
@@ -2303,7 +2303,7 @@ H5I__get_id_cb(void *_item, void H5_ATTR_UNUSED *_key, void *_udata)
HDassert(item);
HDassert(udata);
- if(H5I_FILE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type) {
+ if(H5I_FILE == type || H5I_GROUP == type || H5I_DATASET == type || H5I_ATTR == type || H5I_MAP == type) {
const H5VL_object_t *obj = (const H5VL_object_t *)item->obj_ptr;
obj_ptr = obj->vol_obj;
}
diff --git a/src/H5Ipublic.h b/src/H5Ipublic.h
index 6c823b7..5434516 100644
--- a/src/H5Ipublic.h
+++ b/src/H5Ipublic.h
@@ -38,6 +38,7 @@ typedef enum H5I_type_t {
H5I_BADID = (-1), /*invalid Type */
H5I_FILE = 1, /*type ID for File objects */
H5I_GROUP, /*type ID for Group objects */
+ H5I_MAP, /*type ID for Map objects */
H5I_DATATYPE, /*type ID for Datatype objects */
H5I_DATASPACE, /*type ID for Dataspace objects */
H5I_DATASET, /*type ID for Dataset objects */
diff --git a/src/H5M.c b/src/H5M.c
new file mode 100644
index 0000000..db55152
--- /dev/null
+++ b/src/H5M.c
@@ -0,0 +1,575 @@
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5Mmodule.h" /* This source code file is part of the H5M module */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Mpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Pprivate.h" /* Property lists */
+#include "H5VLprivate.h" /* VOL plugins */
+#include "H5VLdaosm.h"
+
+/****************/
+/* Local Macros */
+/****************/
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+
+/********************/
+/* Package Typedefs */
+/********************/
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Package initialization variable */
+hbool_t H5_PKG_INIT_VAR = FALSE;
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+/* Map ID class */
+static const H5I_class_t H5I_MAP_CLS[1] = {{
+ H5I_MAP, /* ID class value */
+ 0, /* Class flags */
+ 0, /* # of reserved IDs for class */
+ (H5I_free_t)H5M_close_map /* Callback routine for closing objects of this class */
+}};
+
+/* Flag indicating "top" of interface has been initialized */
+static hbool_t H5M_top_package_initialize_s = FALSE;
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5M_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5M_init(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+ /* FUNC_ENTER() does all the work */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5M__init_package
+ *
+ * Purpose: Initializes the H5M interface.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5M__init_package(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Initialize the atom map for the map IDs */
+ if(H5I_register_type(H5I_MAP_CLS) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface")
+
+ /* Mark "top" of interface as initialized, too */
+ H5M_top_package_initialize_s = TRUE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M__init_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5M_top_term_package
+ *
+ * Purpose: Close the "top" of the interface, releasing IDs, etc.
+ *
+ * Return: Success: Positive if anything is done that might
+ * affect other interfaces; zero otherwise.
+ * Failure: Negative.
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5M_top_term_package(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5M_top_package_initialize_s) {
+ if(H5I_nmembers(H5I_MAP) > 0) {
+ (void)H5I_clear_type(H5I_MAP, FALSE, FALSE);
+ n++; /*H5I*/
+ } /* end if */
+
+ /* Mark closed */
+ if(0 == n)
+ H5M_top_package_initialize_s = FALSE;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5M_top_term_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5M_term_package
+ *
+ * Purpose: Terminates the H5M interface
+ *
+ * Note: Finishes shutting down the interface, after
+ * H5M_top_term_package() is called
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5M_term_package(void)
+{
+ int n = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ if(H5_PKG_INIT_VAR) {
+ /* Sanity checks */
+ HDassert(0 == H5I_nmembers(H5I_MAP));
+ HDassert(FALSE == H5M_top_package_initialize_s);
+
+ /* Destroy the map object id map */
+ n += (H5I_dec_type_ref(H5I_MAP) > 0);
+
+ /* Mark closed */
+ if(0 == n)
+ H5_PKG_INIT_VAR = FALSE;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5M_term_package() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mopen
+ *
+ * Purpose: Creates a map object for storing key-value pairs.
+ *
+ * Return: Success: Object ID of the map.
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mcreate(hid_t loc_id, const char *name, hid_t keytype, hid_t valtype,
+ hid_t mcpl_id, hid_t mapl_id)
+{
+ void *map = NULL; /* pointer to map object created */
+ H5VL_object_t *obj = NULL; /* object token of loc_id */
+ H5VL_loc_params_t loc_params;
+ hid_t dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
+ hid_t ret_value;
+
+ FUNC_ENTER_API(FAIL);
+ H5TRACE6("i", "i*siiii", loc_id, name, keytype, valtype, mcpl_id, mapl_id);
+
+ /* Check arguments */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+
+ /* Check group creation property list */
+ if(H5P_DEFAULT == mcpl_id)
+ mcpl_id = H5P_MAP_CREATE_DEFAULT;
+ else if(TRUE != H5P_isa_class(mcpl_id, H5P_MAP_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map create property list");
+
+ /* Verify access property list and get correct dxpl */
+ if(H5P_verify_apl_and_dxpl(&mapl_id, H5P_CLS_GACC, &dxpl_id, loc_id, TRUE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists");
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the location object */
+ if(NULL == (obj = (H5VL_object_t *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier");
+
+ /* call the IOD specific private routine to create a map object */
+ if(NULL == (map = H5VL_daosm_map_create(obj->vol_obj, loc_params, name, keytype, valtype,
+ mcpl_id, mapl_id, dxpl_id, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create map");
+
+ /* Get an atom for the map */
+ if((ret_value = H5VL_register_id(H5I_MAP, map, obj->vol_info, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize map handle");
+
+done:
+ if(ret_value < 0 && map)
+ if(H5VL_daosm_map_close(map, dxpl_id, NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release map");
+
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Mcreate */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mopen
+ *
+ * Purpose: Opens an existing map for modification.
+ *
+ * Return: Success: Object ID of the map.
+ * Failure: FAIL
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id)
+{
+ void *map = NULL; /* map token from VOL plugin */
+ H5VL_object_t *obj = NULL; /* object token of loc_id */
+ H5VL_loc_params_t loc_params;
+ hid_t dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("i", "i*si", loc_id, name, mapl_id);
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Verify access property list and get correct dxpl */
+ if(H5P_verify_apl_and_dxpl(&mapl_id, H5P_CLS_GACC, &dxpl_id, loc_id, FALSE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists")
+
+ loc_params.type = H5VL_OBJECT_BY_SELF;
+ loc_params.obj_type = H5I_get_type(loc_id);
+
+ /* get the location object */
+ if(NULL == (obj = (H5VL_object_t *)H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid location identifier")
+
+ /* Create the map through the VOL */
+ if(NULL == (map = H5VL_daosm_map_open(obj->vol_obj, loc_params,
+ name, mapl_id, dxpl_id, NULL)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open map")
+
+ /* Get an atom for the map */
+ if((ret_value = H5VL_register_id(H5I_MAP, map, obj->vol_info, TRUE)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize map handle")
+
+done:
+ if(ret_value < 0 && map)
+ if(H5VL_daosm_map_close(map, dxpl_id, H5_REQUEST_NULL) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release map")
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mopen() */
+
+
+/*-------------------------------------------------------------------------
+ * Function:H5Mset
+ *
+ * Purpose:
+ * The H5Mset routine inserts or sets a key/value pair in a
+ * map object, given by map_id. The key (pointed to by key) is of
+ * type key_mem_type_id in memory and the value (pointed to by value)
+ * is of type value_mem_type_id in memory.
+ *
+ * Return: Success:non-negative
+ * Failure: negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mset(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ const void *value, hid_t dxpl_id)
+{
+ H5VL_object_t *map = NULL; /* pointer to map object created */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL);
+ H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value,
+ dxpl_id);
+
+ /* check arguments */
+ if(NULL == (map = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a Map");
+
+ /* Get the default map transfer property list if the user didn't provide one */
+ if(H5P_DEFAULT == dxpl_id)
+ dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+
+ /* Set the data through the IOD VOL */
+ if((ret_value = H5VL_daosm_map_set(map->vol_obj, key_mem_type_id, key, val_mem_type_id,
+ value, dxpl_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set map KV pair");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Mset_ff */
+
+
+/*-------------------------------------------------------------------------
+ * Function:H5Mget
+ *
+ * Purpose:
+ * The H5Mget routine retrieves a value from a map object,
+ * given by map_id. The key value used to retrieve the value (pointed
+ * to by key) is of type key_mem_type_id in memory and the value
+ * (pointed to by value) is of type value_mem_type_id in memory.
+ *
+ * Return:Success:non-negative
+ * Failure:negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ void *value, hid_t dxpl_id)
+{
+ H5VL_object_t *map = NULL; /* pointer to map object created */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL);
+ H5TRACE6("e", "ii*xi*xi", map_id, key_mem_type_id, key, val_mem_type_id, value,
+ dxpl_id);
+
+ /* check arguments */
+ if(NULL == (map = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a Map");
+
+ /* Get the default dataset transfer property list if the user didn't provide one */
+ if(H5P_DEFAULT == dxpl_id)
+ dxpl_id= H5P_DATASET_XFER_DEFAULT;
+ else
+ if(TRUE != H5P_isa_class(dxpl_id, H5P_DATASET_XFER))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms");
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_daosm_map_get(map->vol_obj, key_mem_type_id, key, val_mem_type_id, value,
+ dxpl_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Mget */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mget_types
+ *
+ * Purpose:
+ * The H5Mget_types routine retrieves the datatypes for the
+ * keys and values of a map, given by map_id. The key datatype is
+ * returned in key_type_id and the value datatype is returned in
+ * value_type_id.
+ *
+ * Return:Success:non-negative
+ * Failure:negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget_types(hid_t map_id, hid_t *key_type_id, hid_t *val_type_id)
+{
+ H5VL_object_t *map = NULL; /* pointer to map object created */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL);
+ H5TRACE3("e", "i*i*i", map_id, key_type_id, val_type_id);
+
+ /* check arguments */
+ if(NULL == (map = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a Map");
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_daosm_map_get_types(map->vol_obj, key_type_id, val_type_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Mget_types */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mget_count
+ *
+ * Purpose:
+ * The H5Mget_count routine retrieves the number of key/value
+ * pairs in a map, given by map_id.
+ *
+ * Return:Success:non-negative
+ * Failure:negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mget_count(hid_t map_id, hsize_t *count)
+{
+ H5VL_object_t *map = NULL; /* pointer to map object created */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL);
+ H5TRACE2("e", "i*h", map_id, count);
+
+ /* check arguments */
+ if(NULL == (map = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a Map");
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_daosm_map_get_count(map->vol_obj, count, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Mget_count */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mexists
+ *
+ * Purpose:
+ * The H5Mexists routine checks if a key exists in a map,
+ * given by map_id. The key value used (pointed to by key) is of type
+ * key_mem_type_id in memory and the status of the key in the map is
+ * returned in the exists pointerÕs value. The H5Mexists_ff routine is
+ * identical in functionality, but allows for asynchronous operation
+ * and inclusion in a transaction.
+ *
+ * Return:Success:non-negative
+ * Failure:negative
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists)
+{
+ H5VL_object_t *map = NULL; /* pointer to map object created */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL);
+ H5TRACE4("e", "ii*x*b", map_id, key_mem_type_id, key, exists);
+
+ /* check arguments */
+ if(NULL == (map = (H5VL_object_t *)H5I_object_verify(map_id, H5I_MAP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a Map");
+
+ /* Get the data through the IOD VOL */
+ if((ret_value = H5VL_daosm_map_exists(map->vol_obj, key_mem_type_id, key, exists, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get map value");
+
+done:
+ FUNC_LEAVE_API(ret_value);
+} /* end H5Mexists */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Mclose
+ *
+ * Purpose: Closes the specified map. The map ID will no longer be
+ * valid for accessing the map.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, December 31, 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Mclose(hid_t map_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", map_id);
+
+ /* Check args */
+ if(NULL == H5I_object_verify(map_id, H5I_MAP))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a map")
+
+ /*
+ * Decrement the counter on the map atom. It will be freed if the count
+ * reaches zero.
+ */
+ if(H5I_dec_app_ref(map_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close map")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Mclose() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5M_close_map
+ *
+ * Purpose: Called when the ref count reaches zero on the map_id
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * June 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5M_close_map(void *_map)
+{
+ H5VL_object_t *map = (H5VL_object_t *)_map;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Close the map through the VOL*/
+ if((ret_value = H5VL_daosm_map_close(map->vol_obj, H5AC_ind_read_dxpl_id, NULL)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to close map")
+
+ /* free map */
+ if(H5VL_free_object(map) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "unable to free VOL object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5M_close_map() */
+
diff --git a/src/H5Mmodule.h b/src/H5Mmodule.h
new file mode 100644
index 0000000..b8f0cd4
--- /dev/null
+++ b/src/H5Mmodule.h
@@ -0,0 +1,32 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: This file contains declarations which define macros for the
+ * H5M package. Including this header means that the source file
+ * is part of the H5M package.
+ */
+#ifndef _H5Mmodule_H
+#define _H5Mmodule_H
+
+/* Define the proper control macros for the generic FUNC_ENTER/LEAVE and error
+ * reporting macros.
+ */
+#define H5M_MODULE
+#define H5_MY_PKG H5M
+#define H5_MY_PKG_ERR H5E_MAP
+#define H5_MY_PKG_INIT YES
+
+#endif /* _H5Mmodule_H */
+
diff --git a/src/H5Mpkg.h b/src/H5Mpkg.h
new file mode 100644
index 0000000..46657b8
--- /dev/null
+++ b/src/H5Mpkg.h
@@ -0,0 +1,31 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * Purpose: This file contains declarations which are visible
+ * only within the H5M package. Source files outside the
+ * H5M package should include H5Mprivate.h instead.
+ */
+#if !(defined H5M_FRIEND || defined H5M_MODULE)
+#error "Do not include this file outside the H5M package!"
+#endif
+
+#ifndef _H5Mpkg_H
+#define _H5Mpkg_H
+
+/* Get package's private header */
+#include "H5Mprivate.h"
+
+#endif /* _H5Mpkg_H */
diff --git a/src/H5Mprivate.h b/src/H5Mprivate.h
new file mode 100644
index 0000000..9b04ef5
--- /dev/null
+++ b/src/H5Mprivate.h
@@ -0,0 +1,40 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Mprivate.h
+ *
+ * Purpose: Library-visible declarations.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef _H5Mprivate_H
+#define _H5Mprivate_H
+
+/* Include package's public header */
+#include "H5Mpublic.h"
+
+/* Private headers needed by this file */
+#include "H5private.h" /* Generic Functions */
+
+/*
+ * Library prototypes... These are the ones that other packages routinely
+ * call.
+ */
+H5_DLL herr_t H5M_init(void);
+
+#endif /* _H5Mprivate_H */
diff --git a/src/H5Mpublic.h b/src/H5Mpublic.h
new file mode 100644
index 0000000..0adc9e1
--- /dev/null
+++ b/src/H5Mpublic.h
@@ -0,0 +1,66 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*
+ * This file contains function prototypes for each exported function in the
+ * H5M module.
+ */
+#ifndef _H5Mpublic_H
+#define _H5Mpublic_H
+
+/* System headers needed by this file */
+
+/* Public headers needed by this file */
+#include "H5public.h"
+#include "H5Ipublic.h"
+
+/*****************/
+/* Public Macros */
+/*****************/
+
+/*******************/
+/* Public Typedefs */
+/*******************/
+
+/********************/
+/* Public Variables */
+/********************/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*********************/
+/* Public Prototypes */
+/*********************/
+
+/* API wrappers */
+H5_DLL hid_t H5Mcreate(hid_t loc_id, const char *name, hid_t keytype, hid_t valtype,
+ hid_t mcpl_id, hid_t mapl_id);
+H5_DLL hid_t H5Mopen(hid_t loc_id, const char *name, hid_t mapl_id);
+H5_DLL herr_t H5Mset(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ const void *value, hid_t dxpl_id);
+H5_DLL herr_t H5Mget(hid_t map_id, hid_t key_mem_type_id, const void *key, hid_t val_mem_type_id,
+ void *value, hid_t dxpl_id);
+H5_DLL herr_t H5Mget_types(hid_t map_id, hid_t *key_type_id, hid_t *val_type_id);
+H5_DLL herr_t H5Mget_count(hid_t map_id, hsize_t *count);
+H5_DLL herr_t H5Mexists(hid_t map_id, hid_t key_mem_type_id, const void *key, hbool_t *exists);
+H5_DLL herr_t H5Mclose(hid_t map_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _H5Mpublic_H */
diff --git a/src/H5Opublic.h b/src/H5Opublic.h
index a7d386a..fac3cb7 100644
--- a/src/H5Opublic.h
+++ b/src/H5Opublic.h
@@ -85,6 +85,7 @@ typedef enum H5O_type_t {
H5O_TYPE_GROUP, /* Object is a group */
H5O_TYPE_DATASET, /* Object is a dataset */
H5O_TYPE_NAMED_DATATYPE, /* Object is a named data type */
+ H5O_TYPE_MAP, /* Object is a map */
H5O_TYPE_NTYPES /* Number of different object types (must be last!) */
} H5O_type_t;
diff --git a/src/H5Pint.c b/src/H5Pint.c
index 4e26dcd..385d7ce 100644
--- a/src/H5Pint.c
+++ b/src/H5Pint.c
@@ -145,6 +145,10 @@ hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g = FAIL;
H5P_genclass_t *H5P_CLS_ATTRIBUTE_CREATE_g = NULL;
hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g = FAIL;
H5P_genclass_t *H5P_CLS_ATTRIBUTE_ACCESS_g = NULL;
+hid_t H5P_CLS_MAP_CREATE_ID_g = FAIL;
+H5P_genclass_t *H5P_CLS_MAP_CREATE_g = NULL;
+hid_t H5P_CLS_MAP_ACCESS_ID_g = FAIL;
+H5P_genclass_t *H5P_CLS_MAP_ACCESS_g = NULL;
hid_t H5P_CLS_OBJECT_COPY_ID_g = FAIL;
H5P_genclass_t *H5P_CLS_OBJECT_COPY_g = NULL;
hid_t H5P_CLS_LINK_CREATE_ID_g = FAIL;
@@ -170,6 +174,8 @@ hid_t H5P_LST_DATATYPE_CREATE_ID_g = FAIL;
hid_t H5P_LST_DATATYPE_ACCESS_ID_g = FAIL;
hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g = FAIL;
hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g = FAIL;
+hid_t H5P_LST_MAP_CREATE_ID_g = FAIL;
+hid_t H5P_LST_MAP_ACCESS_ID_g = FAIL;
hid_t H5P_LST_OBJECT_COPY_ID_g = FAIL;
hid_t H5P_LST_LINK_CREATE_ID_g = FAIL;
hid_t H5P_LST_LINK_ACCESS_ID_g = FAIL;
@@ -213,6 +219,47 @@ const H5P_libclass_t H5P_CLS_AACC[1] = {{
NULL /* Class close callback info */
}};
+/* Map access property list class library initialization object */
+/* (move to proper source code file when used for real) */
+const H5P_libclass_t H5P_CLS_MACC[1] = {{
+ "map access", /* Class name for debugging */
+ H5P_TYPE_MAP_ACCESS, /* Class type */
+
+ &H5P_CLS_LINK_ACCESS_g, /* Parent class */
+ &H5P_CLS_MAP_ACCESS_g, /* Pointer to class */
+ &H5P_CLS_MAP_ACCESS_ID_g, /* Pointer to class ID */
+ &H5P_LST_MAP_ACCESS_ID_g, /* Pointer to default property list ID */
+ NULL, /* Default property registration routine */
+
+ NULL, /* Class creation callback */
+ NULL, /* Class creation callback info */
+ NULL, /* Class copy callback */
+ NULL, /* Class copy callback info */
+ NULL, /* Class close callback */
+ NULL /* Class close callback info */
+}};
+
+/* Map create property list class library initialization object */
+/* (move to proper source code file when used for real) */
+const H5P_libclass_t H5P_CLS_MCRT[1] = {{
+ "map create", /* Class name for debugging */
+ H5P_TYPE_MAP_CREATE, /* Class type */
+
+ &H5P_CLS_LINK_CREATE_g, /* Parent class */
+ &H5P_CLS_MAP_CREATE_g, /* Pointer to class */
+ &H5P_CLS_MAP_CREATE_ID_g, /* Pointer to class ID */
+ &H5P_LST_MAP_CREATE_ID_g, /* Pointer to default property list ID */
+ NULL, /* Default property registration routine */
+
+ NULL, /* Class creation callback */
+ NULL, /* Class creation callback info */
+ NULL, /* Class copy callback */
+ NULL, /* Class copy callback info */
+ NULL, /* Class close callback */
+ NULL /* Class close callback info */
+}};
+
+
/* Group access property list class library initialization object */
/* (move to proper source code file when used for real) */
const H5P_libclass_t H5P_CLS_GACC[1] = {{
@@ -322,6 +369,8 @@ static H5P_libclass_t const * const init_class[] = {
H5P_CLS_TACC, /* Datatype access */
H5P_CLS_ACRT, /* Attribute creation */
H5P_CLS_AACC, /* Attribute access */
+ H5P_CLS_MCRT, /* Map creation */
+ H5P_CLS_MACC, /* Map access */
H5P_CLS_LCRT /* Link creation */
};
@@ -513,6 +562,8 @@ H5P_term_package(void)
H5P_LST_DATATYPE_ACCESS_ID_g =
H5P_LST_ATTRIBUTE_CREATE_ID_g =
H5P_LST_ATTRIBUTE_ACCESS_ID_g =
+ H5P_LST_MAP_CREATE_ID_g =
+ H5P_LST_MAP_ACCESS_ID_g =
H5P_LST_OBJECT_COPY_ID_g =
H5P_LST_LINK_CREATE_ID_g =
H5P_LST_LINK_ACCESS_ID_g =
@@ -540,6 +591,8 @@ H5P_term_package(void)
H5P_CLS_STRING_CREATE_g =
H5P_CLS_ATTRIBUTE_CREATE_g =
H5P_CLS_ATTRIBUTE_ACCESS_g =
+ H5P_CLS_MAP_CREATE_g =
+ H5P_CLS_MAP_ACCESS_g =
H5P_CLS_OBJECT_COPY_g =
H5P_CLS_LINK_CREATE_g =
H5P_CLS_LINK_ACCESS_g =
@@ -559,6 +612,8 @@ H5P_term_package(void)
H5P_CLS_STRING_CREATE_ID_g =
H5P_CLS_ATTRIBUTE_CREATE_ID_g =
H5P_CLS_ATTRIBUTE_ACCESS_ID_g =
+ H5P_CLS_MAP_CREATE_ID_g =
+ H5P_CLS_MAP_ACCESS_ID_g =
H5P_CLS_OBJECT_COPY_ID_g =
H5P_CLS_LINK_CREATE_ID_g =
H5P_CLS_LINK_ACCESS_ID_g =
@@ -5281,7 +5336,7 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
FUNC_ENTER_PACKAGE
/* Sanity checks */
- HDcompile_assert(H5P_TYPE_ATTRIBUTE_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
+ HDcompile_assert(H5P_TYPE_MAP_ACCESS == (H5P_TYPE_MAX_TYPE - 1));
HDassert(type >= H5P_TYPE_USER && type <= H5P_TYPE_LINK_ACCESS);
/* Check arguments */
@@ -5348,6 +5403,14 @@ H5P__new_plist_of_type(H5P_plist_type_t type)
class_id = H5P_CLS_ATTRIBUTE_ACCESS_ID_g;
break;
+ case H5P_TYPE_MAP_CREATE:
+ class_id = H5P_CLS_MAP_CREATE_ID_g;
+ break;
+
+ case H5P_TYPE_MAP_ACCESS:
+ class_id = H5P_CLS_MAP_ACCESS_ID_g;
+ break;
+
case H5P_TYPE_OBJECT_COPY:
class_id = H5P_CLS_OBJECT_COPY_ID_g;
break;
diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h
index 6cadc3b..581e126 100644
--- a/src/H5Pprivate.h
+++ b/src/H5Pprivate.h
@@ -83,6 +83,8 @@ typedef enum H5P_plist_type_t {
H5P_TYPE_LINK_CREATE = 16,
H5P_TYPE_LINK_ACCESS = 17,
H5P_TYPE_ATTRIBUTE_ACCESS = 18,
+ H5P_TYPE_MAP_CREATE = 19,
+ H5P_TYPE_MAP_ACCESS = 20,
H5P_TYPE_MAX_TYPE
} H5P_plist_type_t;
@@ -131,6 +133,8 @@ H5_DLLVAR H5P_genclass_t *H5P_CLS_DATATYPE_CREATE_g;
H5_DLLVAR H5P_genclass_t *H5P_CLS_DATATYPE_ACCESS_g;
H5_DLLVAR H5P_genclass_t *H5P_CLS_ATTRIBUTE_CREATE_g;
H5_DLLVAR H5P_genclass_t *H5P_CLS_ATTRIBUTE_ACCESS_g;
+H5_DLLVAR H5P_genclass_t *H5P_CLS_MAP_CREATE_g;
+H5_DLLVAR H5P_genclass_t *H5P_CLS_MAP_ACCESS_g;
H5_DLLVAR H5P_genclass_t *H5P_CLS_OBJECT_COPY_g;
H5_DLLVAR H5P_genclass_t *H5P_CLS_LINK_CREATE_g;
H5_DLLVAR H5P_genclass_t *H5P_CLS_LINK_ACCESS_g;
@@ -139,6 +143,8 @@ H5_DLLVAR H5P_genclass_t *H5P_CLS_STRING_CREATE_g;
/* Internal property list classes */
H5_DLLVAR const struct H5P_libclass_t H5P_CLS_LACC[1]; /* Link access */
H5_DLLVAR const struct H5P_libclass_t H5P_CLS_AACC[1]; /* Attribute access */
+H5_DLLVAR const struct H5P_libclass_t H5P_CLS_MACC[1]; /* Map access */
+H5_DLLVAR const struct H5P_libclass_t H5P_CLS_MCRT[1]; /* Map access */
H5_DLLVAR const struct H5P_libclass_t H5P_CLS_DACC[1]; /* Dataset access */
H5_DLLVAR const struct H5P_libclass_t H5P_CLS_GACC[1]; /* Group access */
H5_DLLVAR const struct H5P_libclass_t H5P_CLS_TACC[1]; /* Named datatype access */
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index bb116fc..c3f9bc4 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -67,6 +67,8 @@
#define H5P_STRING_CREATE (H5OPEN H5P_CLS_STRING_CREATE_ID_g)
#define H5P_ATTRIBUTE_CREATE (H5OPEN H5P_CLS_ATTRIBUTE_CREATE_ID_g)
#define H5P_ATTRIBUTE_ACCESS (H5OPEN H5P_CLS_ATTRIBUTE_ACCESS_ID_g)
+#define H5P_MAP_CREATE (H5OPEN H5P_CLS_MAP_CREATE_ID_g)
+#define H5P_MAP_ACCESS (H5OPEN H5P_CLS_MAP_ACCESS_ID_g)
#define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_ID_g)
#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_ID_g)
#define H5P_LINK_ACCESS (H5OPEN H5P_CLS_LINK_ACCESS_ID_g)
@@ -86,6 +88,8 @@
#define H5P_DATATYPE_ACCESS_DEFAULT (H5OPEN H5P_LST_DATATYPE_ACCESS_ID_g)
#define H5P_ATTRIBUTE_CREATE_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_CREATE_ID_g)
#define H5P_ATTRIBUTE_ACCESS_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_ACCESS_ID_g)
+#define H5P_MAP_CREATE_DEFAULT (H5OPEN H5P_LST_MAP_CREATE_ID_g)
+#define H5P_MAP_ACCESS_DEFAULT (H5OPEN H5P_LST_MAP_ACCESS_ID_g)
#define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_ID_g)
#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_ID_g)
#define H5P_LINK_ACCESS_DEFAULT (H5OPEN H5P_LST_LINK_ACCESS_ID_g)
@@ -192,6 +196,8 @@ H5_DLLVAR hid_t H5P_CLS_DATATYPE_ACCESS_ID_g;
H5_DLLVAR hid_t H5P_CLS_STRING_CREATE_ID_g;
H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_CREATE_ID_g;
H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_ACCESS_ID_g;
+H5_DLLVAR hid_t H5P_CLS_MAP_CREATE_ID_g;
+H5_DLLVAR hid_t H5P_CLS_MAP_ACCESS_ID_g;
H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_ID_g;
H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_ID_g;
H5_DLLVAR hid_t H5P_CLS_LINK_ACCESS_ID_g;
@@ -210,6 +216,8 @@ H5_DLLVAR hid_t H5P_LST_DATATYPE_CREATE_ID_g;
H5_DLLVAR hid_t H5P_LST_DATATYPE_ACCESS_ID_g;
H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_CREATE_ID_g;
H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_ACCESS_ID_g;
+H5_DLLVAR hid_t H5P_LST_MAP_CREATE_ID_g;
+H5_DLLVAR hid_t H5P_LST_MAP_ACCESS_ID_g;
H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_ID_g;
H5_DLLVAR hid_t H5P_LST_LINK_CREATE_ID_g;
H5_DLLVAR hid_t H5P_LST_LINK_ACCESS_ID_g;
diff --git a/src/H5VLdaosm.c b/src/H5VLdaosm.c
index d3e4589..0e883be 100644
--- a/src/H5VLdaosm.c
+++ b/src/H5VLdaosm.c
@@ -30,6 +30,7 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5FFprivate.h" /* Fast Forward */
#include "H5Iprivate.h" /* IDs */
+#include "H5Mprivate.h" /* Maps */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Objects */
#include "H5Pprivate.h" /* Property lists */
@@ -53,6 +54,10 @@ hid_t H5VL_DAOSM_g = -1;
#define H5VL_DAOSM_ATTR_KEY "/Attribute"
#define H5VL_DAOSM_CHUNK_KEY 0u
+#define H5VL_DAOSM_KTYPE_KEY "Key Datatype"
+#define H5VL_DAOSM_VTYPE_KEY "Value Datatype"
+#define H5VL_DAOSM_MAP_KEY "MAP_AKEY"
+
/* Stack allocation sizes */
#define H5VL_DAOSM_GH_BUF_SIZE 1024
#define H5VL_DAOSM_FOI_BUF_SIZE 1024
@@ -69,6 +74,7 @@ hid_t H5VL_DAOSM_g = -1;
#define H5VL_DAOSM_TYPE_GRP 0x0000000000000000ull
#define H5VL_DAOSM_TYPE_DSET 0x4000000000000000ull
#define H5VL_DAOSM_TYPE_DTYPE 0x8000000000000000ull
+#define H5VL_DAOSM_TYPE_MAP 0xc000000000000000ull
/* DAOSM-specific file access properties */
typedef struct H5VL_daosm_fapl_t {
@@ -212,6 +218,7 @@ static herr_t H5VL_daosm_object_close(void *_obj, hid_t dxpl_id, void **req);
H5FL_DEFINE(H5VL_daosm_file_t);
H5FL_DEFINE(H5VL_daosm_group_t);
H5FL_DEFINE(H5VL_daosm_dset_t);
+H5FL_DEFINE(H5VL_daosm_map_t);
H5FL_DEFINE(H5VL_daosm_attr_t);
/* The DAOS-M VOL plugin struct */
@@ -511,6 +518,8 @@ H5VL_daosm_init(void)
* initialize that type) */
if(H5G_init() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize group interface")
+ if(H5M_init() < 0)
+ HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize map interface")
if(H5D_init() < 0)
HGOTO_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize dataset interface")
if(H5T_init() < 0)
@@ -840,9 +849,11 @@ H5VL_daosm_oid_encode(daos_obj_id_t *oid, uint64_t idx, H5I_type_t obj_type)
type_bits = H5VL_DAOSM_TYPE_GRP;
else if(obj_type == H5I_DATASET)
type_bits = H5VL_DAOSM_TYPE_DSET;
- else {
- HDassert(obj_type == H5I_DATATYPE);
+ else if(obj_type == H5I_DATATYPE)
type_bits = H5VL_DAOSM_TYPE_DTYPE;
+ else {
+ HDassert(obj_type == H5I_MAP);
+ type_bits = H5VL_DAOSM_TYPE_MAP;
} /* end else */
/* Encode type and address and generate oid */
@@ -866,6 +877,8 @@ H5VL_daosm_addr_to_type(uint64_t addr)
return(H5I_DATASET);
else if(type_bits == H5VL_DAOSM_TYPE_DTYPE)
return(H5I_DATATYPE);
+ else if(type_bits == H5VL_DAOSM_TYPE_MAP)
+ return(H5I_MAP);
else
return(H5I_BADID);
} /* end H5VL_daosm_oid_to_type() */
@@ -3470,7 +3483,7 @@ H5VL_daosm_dataset_create(void *_item,
/* Check for collective access, if not already set by the file */
if(!collective)
if(H5Pget_all_coll_metadata_ops(dapl_id, &collective) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTGET, NULL, "can't get collective access property")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get collective access property")
/* Get the dcpl plist structure */
if(NULL == (plist = (H5P_genplist_t *)H5I_object(dcpl_id)))
@@ -3738,8 +3751,8 @@ H5VL_daosm_dataset_open(void *_item,
if(0 != (ret = daos_obj_open(item->file->coh, dset->obj.oid, item->file->epoch, item->file->flags & H5F_ACC_RDWR ? DAOS_COO_RW : DAOS_COO_RO, &dset->obj.obj_oh, NULL /*event*/)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "can't open dataset: %d", ret)
- /* Set up operation to read datatype, dataspace, and DCPL sizes from dataset
- */
+ /* Set up operation to read datatype, dataspace, and DCPL sizes from
+ * dataset */
/* Set up dkey */
daos_iov_set(&dkey, int_md_key, (daos_size_t)(sizeof(int_md_key) - 1));
@@ -4772,13 +4785,19 @@ H5VL_daosm_object_open(void *_item, H5VL_loc_params_t loc_params,
? loc_params.loc_data.loc_by_name.lapl_id : H5P_DATASET_ACCESS_DEFAULT, dxpl_id, req)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "can't open dataset")
} /* end if */
- else {
- HDassert(obj_type == H5I_DATATYPE);
+ else if(obj_type == H5I_DATATYPE) {
if(NULL == (obj = (H5VL_daosm_obj_t *)H5VL_daosm_datatype_open(item, sub_loc_params, NULL,
((H5VL_OBJECT_BY_NAME == loc_params.type) && (loc_params.loc_data.loc_by_name.lapl_id != H5P_DEFAULT))
? loc_params.loc_data.loc_by_name.lapl_id : H5P_DATATYPE_ACCESS_DEFAULT, dxpl_id, req)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "can't open datatype")
} /* end if */
+ else {
+ HDassert(obj_type == H5I_MAP);
+ if(NULL == (obj = (H5VL_daosm_obj_t *)H5VL_daosm_map_open(item, sub_loc_params, NULL,
+ ((H5VL_OBJECT_BY_NAME == loc_params.type) && (loc_params.loc_data.loc_by_name.lapl_id != H5P_DEFAULT))
+ ? loc_params.loc_data.loc_by_name.lapl_id : H5P_MAP_ACCESS_DEFAULT, dxpl_id, req)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, NULL, "can't open map")
+ } /* end if */
/* Set return value */
if(opened_type)
@@ -4880,9 +4899,11 @@ H5VL_daosm_object_optional(void *_item, hid_t dxpl_id, void **req,
obj_info->type = H5O_TYPE_GROUP;
else if(target_obj->item.type == H5I_DATASET)
obj_info->type = H5O_TYPE_DATASET;
- else {
- HDassert(target_obj->item.type == H5I_DATATYPE);
+ else if(target_obj->item.type == H5I_DATATYPE)
obj_info->type = H5O_TYPE_NAMED_DATATYPE;
+ else {
+ HDassert(target_obj->item.type == H5I_MAP);
+ obj_info->type = H5O_TYPE_MAP;
} /* end else */
/* Reference count is always 1 - change this when
@@ -4935,7 +4956,7 @@ H5VL_daosm_object_close(void *_obj, hid_t dxpl_id, void **req)
HDassert(obj);
HDassert(obj->item.type == H5I_GROUP || obj->item.type == H5I_DATASET
- || obj->item.type == H5I_DATATYPE);
+ || obj->item.type == H5I_DATATYPE || obj->item.type == H5I_MAP);
/* Call type's close function */
if(obj->item.type == H5I_GROUP) {
@@ -4950,6 +4971,10 @@ H5VL_daosm_object_close(void *_obj, hid_t dxpl_id, void **req)
if(H5VL_daosm_datatype_close(obj, dxpl_id, req))
HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "can't close datatype")
} /* end if */
+ else if(obj->item.type == H5I_MAP) {
+ if(H5VL_daosm_map_close(obj, dxpl_id, req))
+ HGOTO_ERROR(H5E_MAP, H5E_CLOSEERROR, FAIL, "can't close map")
+ } /* end if */
else
HDassert(0 && "Invalid object type");
@@ -5589,7 +5614,7 @@ H5VL_daosm_attribute_get(void *_item, H5VL_attr_get_t get_type,
H5VL_loc_params_t loc_params = va_arg(arguments, H5VL_loc_params_t);
size_t buf_size = va_arg(arguments, size_t);
char *buf = va_arg(arguments, char *);
- ssize_t *ret_val = va_arg(arguments, ssize_t *);
+ ssize_t *ret_val = va_arg(arguments, ssize_t *);
H5VL_daosm_attr_t *attr = (H5VL_daosm_attr_t *)_item;
if(H5VL_OBJECT_BY_SELF == loc_params.type) {
@@ -5897,3 +5922,867 @@ H5VL_daosm_attribute_close(void *_attr, hid_t dxpl_id, void **req)
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5VL_daosm_attribute_close() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_map_create
+ *
+ * Purpose: Sends a request to DAOS-M to create a map
+ *
+ * Return: Success: map object.
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5VL_daosm_map_create(void *_item, H5VL_loc_params_t H5_ATTR_UNUSED loc_params,
+ const char *name, hid_t ktype_id, hid_t vtype_id,
+ hid_t H5_ATTR_UNUSED mcpl_id, hid_t mapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_daosm_item_t *item = (H5VL_daosm_item_t *)_item;
+ H5VL_daosm_map_t *map = NULL;
+ H5VL_daosm_group_t *target_grp = NULL;
+ void *ktype_buf = NULL;
+ void *vtype_buf = NULL;
+ hbool_t collective = item->file->collective;
+ int ret;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check for write access */
+ if(!(item->file->flags & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, NULL, "no write intent on file")
+
+ /* Check for collective access, if not already set by the file */
+ if(!collective)
+ if(H5Pget_all_coll_metadata_ops(mapl_id, &collective) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, NULL, "can't get collective access property")
+
+ /* Allocate the map object that is returned to the user */
+ if(NULL == (map = H5FL_CALLOC(H5VL_daosm_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate DAOS-M map struct")
+ map->obj.item.type = H5I_MAP;
+ map->obj.item.file = item->file;
+ map->obj.item.rc = 1;
+ map->obj.obj_oh = DAOS_HDL_INVAL;
+ map->ktype_id = FAIL;
+ map->vtype_id = FAIL;
+
+ /* Generate map oid */
+ H5VL_daosm_oid_encode(&map->obj.oid, item->file->max_oid + (uint64_t)1, H5I_MAP);
+
+ /* Create map and write metadata if this process should */
+ if(!collective || (item->file->my_rank == 0)) {
+ const char *target_name = NULL;
+ H5VL_daosm_link_val_t link_val;
+ daos_key_t dkey;
+ daos_iod_t iod[2];
+ daos_sg_list_t sgl[2];
+ daos_iov_t sg_iov[2];
+ size_t ktype_size = 0;
+ size_t vtype_size = 0;
+ char int_md_key[] = H5VL_DAOSM_INT_MD_KEY;
+ char ktype_key[] = H5VL_DAOSM_KTYPE_KEY;
+ char vtype_key[] = H5VL_DAOSM_VTYPE_KEY;
+
+ /* Traverse the path */
+ if(NULL == (target_grp = H5VL_daosm_group_traverse(item, name, dxpl_id,
+ req, &target_name, NULL, NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_BADITER, NULL, "can't traverse path")
+
+ /* Create map */
+ /* Update max_oid */
+ item->file->max_oid = H5VL_daosm_oid_to_idx(map->obj.oid);
+
+ /* Write max OID */
+ if(H5VL_daosm_write_max_oid(item->file) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, NULL, "can't write max OID")
+
+ /* Open map */
+ if(0 != (ret = daos_obj_open(item->file->coh, map->obj.oid, item->file->epoch, DAOS_OO_RW, &map->obj.obj_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, NULL, "can't open map: %d", ret)
+
+ /* Encode datatypes */
+ if(H5Tencode(ktype_id, NULL, &ktype_size) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't determine serialized length of datatype")
+ if(NULL == (ktype_buf = H5MM_malloc(ktype_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate buffer for serialized datatype")
+ if(H5Tencode(ktype_id, ktype_buf, &ktype_size) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTENCODE, NULL, "can't serialize datatype")
+
+ if(H5Tencode(vtype_id, NULL, &vtype_size) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't determine serialized length of datatype")
+ if(NULL == (vtype_buf = H5MM_malloc(vtype_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate buffer for serialized datatype")
+ if(H5Tencode(vtype_id, vtype_buf, &vtype_size) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTENCODE, NULL, "can't serialize datatype")
+
+ /* Eventually we will want to store the MCPL in the file, and hold
+ * copies of the MCP and MAPL in memory. To do this look at the dataset
+ * and group code for examples. -NAF */
+
+ /* Set up operation to write datatypes to map */
+ /* Set up dkey */
+ daos_iov_set(&dkey, int_md_key, (daos_size_t)(sizeof(int_md_key) - 1));
+
+ /* Set up iod */
+ HDmemset(iod, 0, sizeof(iod));
+ daos_iov_set(&iod[0].iod_name, (void *)ktype_key, (daos_size_t)(sizeof(ktype_key) - 1));
+ daos_csum_set(&iod[0].iod_kcsum, NULL, 0);
+ iod[0].iod_nr = 1u;
+ iod[0].iod_size = (uint64_t)ktype_size;
+ iod[0].iod_type = DAOS_IOD_SINGLE;
+
+ daos_iov_set(&iod[1].iod_name, (void *)vtype_key, (daos_size_t)(sizeof(vtype_key) - 1));
+ daos_csum_set(&iod[1].iod_kcsum, NULL, 0);
+ iod[1].iod_nr = 1u;
+ iod[1].iod_size = (uint64_t)vtype_size;
+ iod[1].iod_type = DAOS_IOD_SINGLE;
+
+ /* Set up sgl */
+ daos_iov_set(&sg_iov[0], ktype_buf, (daos_size_t)ktype_size);
+ sgl[0].sg_nr.num = 1;
+ sgl[0].sg_iovs = &sg_iov[0];
+ daos_iov_set(&sg_iov[1], vtype_buf, (daos_size_t)vtype_size);
+ sgl[1].sg_nr.num = 1;
+ sgl[1].sg_iovs = &sg_iov[1];
+
+ /* Write internal metadata to map */
+ if(0 != (ret = daos_obj_update(map->obj.obj_oh, item->file->epoch, &dkey, 2, iod, sgl, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, NULL, "can't write metadata to map: %d", ret)
+
+ /* Create link to map */
+ link_val.type = H5L_TYPE_HARD;
+ link_val.target.hard = map->obj.oid;
+ if(H5VL_daosm_link_write(target_grp, target_name, HDstrlen(target_name), &link_val) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, NULL, "can't create link to map")
+ } /* end if */
+ else {
+ /* Update max_oid */
+ item->file->max_oid = map->obj.oid.lo;
+
+ /* Open map */
+ if(0 != (ret = daos_obj_open(item->file->coh, map->obj.oid, item->file->epoch, DAOS_OO_RW, &map->obj.obj_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, NULL, "can't open map: %d", ret)
+ } /* end else */
+
+ /* Finish setting up map struct */
+ if((map->ktype_id = H5Tcopy(ktype_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy datatype")
+ if((map->vtype_id = H5Tcopy(vtype_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "failed to copy datatype")
+
+ /* Set return value */
+ ret_value = (void *)map;
+
+done:
+ /* Close target group */
+ if(target_grp && H5VL_daosm_group_close(target_grp, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CLOSEERROR, NULL, "can't close group")
+
+ /* Cleanup on failure */
+ /* Destroy DAOS object if created before failure DSMINC */
+ if(NULL == ret_value)
+ /* Close map */
+ if(map && H5VL_daosm_map_close(map, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CLOSEERROR, NULL, "can't close map");
+
+ /* Free memory */
+ ktype_buf = H5MM_xfree(ktype_buf);
+ vtype_buf = H5MM_xfree(vtype_buf);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_map_open
+ *
+ * Purpose: Sends a request to DAOS-M to open a map
+ *
+ * Return: Success: map object.
+ * Failure: NULL
+ *
+ *-------------------------------------------------------------------------
+ */
+void *
+H5VL_daosm_map_open(void *_item, H5VL_loc_params_t loc_params, const char *name,
+ hid_t mapl_id, hid_t dxpl_id, void **req)
+{
+ H5VL_daosm_item_t *item = (H5VL_daosm_item_t *)_item;
+ H5VL_daosm_map_t *map = NULL;
+ H5VL_daosm_group_t *target_grp = NULL;
+ const char *target_name = NULL;
+ daos_key_t dkey;
+ daos_iod_t iod[2];
+ daos_sg_list_t sgl[2];
+ daos_iov_t sg_iov[2];
+ uint64_t ktype_len = 0;
+ uint64_t vtype_len = 0;
+ uint64_t tot_len;
+ uint8_t minfo_buf_static[H5VL_DAOSM_DINFO_BUF_SIZE];
+ uint8_t *minfo_buf_dyn = NULL;
+ uint8_t *minfo_buf = minfo_buf_static;
+ char int_md_key[] = H5VL_DAOSM_INT_MD_KEY;
+ char ktype_key[] = H5VL_DAOSM_KTYPE_KEY;
+ char vtype_key[] = H5VL_DAOSM_VTYPE_KEY;
+ uint8_t *p;
+ hbool_t collective = item->file->collective;
+ hbool_t must_bcast = FALSE;
+ int ret;
+ void *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* Check for collective access, if not already set by the file */
+ if(!collective)
+ if(H5Pget_all_coll_metadata_ops(mapl_id, &collective) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, NULL, "can't get collective access property")
+
+ /* Allocate the map object that is returned to the user */
+ if(NULL == (map = H5FL_CALLOC(H5VL_daosm_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate DAOS-M map struct")
+ map->obj.item.type = H5I_MAP;
+ map->obj.item.file = item->file;
+ map->obj.item.rc = 1;
+ map->obj.obj_oh = DAOS_HDL_INVAL;
+ map->ktype_id = FAIL;
+ map->vtype_id = FAIL;
+
+ /* Check if we're actually opening the group or just receiving the map
+ * info from the leader */
+ if(!collective || (item->file->my_rank == 0)) {
+ if(collective && (item->file->num_procs > 1))
+ must_bcast = TRUE;
+
+ /* Check for open by address */
+ if(H5VL_OBJECT_BY_ADDR == loc_params.type) {
+ /* Generate oid from address */
+ H5VL_daosm_oid_generate(&map->obj.oid, (uint64_t)loc_params.loc_data.loc_by_addr.addr, H5I_MAP);
+ } /* end if */
+ else {
+ /* Open using name parameter */
+ /* Traverse the path */
+ if(NULL == (target_grp = H5VL_daosm_group_traverse(item, name, dxpl_id, req, &target_name, NULL, NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_BADITER, NULL, "can't traverse path")
+
+ /* Follow link to map */
+ if(H5VL_daosm_link_follow(target_grp, target_name, HDstrlen(target_name), dxpl_id, req, &map->obj.oid) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, NULL, "can't follow link to map")
+ } /* end else */
+
+ /* Open map */
+ if(0 != (ret = daos_obj_open(item->file->coh, map->obj.oid, item->file->epoch, item->file->flags & H5F_ACC_RDWR ? DAOS_COO_RW : DAOS_COO_RO, &map->obj.obj_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, NULL, "can't open map: %d", ret)
+
+ /* Set up operation to read datatype sizes from map */
+ /* Set up dkey */
+ daos_iov_set(&dkey, int_md_key, (daos_size_t)(sizeof(int_md_key) - 1));
+
+ /* Set up iod */
+ HDmemset(iod, 0, sizeof(iod));
+ daos_iov_set(&iod[0].iod_name, (void *)ktype_key, (daos_size_t)(sizeof(ktype_key) - 1));
+ daos_csum_set(&iod[0].iod_kcsum, NULL, 0);
+ iod[0].iod_nr = 1u;
+ iod[0].iod_size = DAOS_REC_ANY;
+ iod[0].iod_type = DAOS_IOD_SINGLE;
+
+ daos_iov_set(&iod[1].iod_name, (void *)vtype_key, (daos_size_t)(sizeof(vtype_key) - 1));
+ daos_csum_set(&iod[1].iod_kcsum, NULL, 0);
+ iod[1].iod_nr = 1u;
+ iod[1].iod_size = DAOS_REC_ANY;
+ iod[1].iod_type = DAOS_IOD_SINGLE;
+
+ /* Read internal metadata sizes from map */
+ if(0 != (ret = daos_obj_fetch(map->obj.obj_oh, item->file->epoch, &dkey, 2, iod, NULL,
+ NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTDECODE, NULL, "can't read metadata sizes from map: %d", ret)
+
+ /* Check for metadata not found */
+ if((iod[0].iod_size == (uint64_t)0) || (iod[1].iod_size == (uint64_t)0))
+ HGOTO_ERROR(H5E_MAP, H5E_NOTFOUND, NULL, "internal metadata not found");
+
+ /* Compute map info buffer size */
+ ktype_len = iod[0].iod_size;
+ vtype_len = iod[1].iod_size;
+ tot_len = ktype_len + vtype_len;
+
+ /* Allocate map info buffer if necessary */
+ if(tot_len > sizeof(minfo_buf_static)) {
+ if(NULL == (minfo_buf_dyn = (uint8_t *)H5MM_malloc(tot_len + (5 * sizeof(uint64_t)))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate map info buffer")
+ minfo_buf = minfo_buf_dyn;
+ } /* end if */
+
+ /* Set up sgl */
+ p = minfo_buf + (5 * sizeof(uint64_t));
+ daos_iov_set(&sg_iov[0], p, (daos_size_t)ktype_len);
+ sgl[0].sg_nr.num = 1;
+ sgl[0].sg_iovs = &sg_iov[0];
+ p += ktype_len;
+ daos_iov_set(&sg_iov[1], p, (daos_size_t)vtype_len);
+ sgl[1].sg_nr.num = 1;
+ sgl[1].sg_iovs = &sg_iov[1];
+
+ /* Read internal metadata from map */
+ if(0 != (ret = daos_obj_fetch(map->obj.obj_oh, item->file->epoch, &dkey, 2, iod, sgl, NULL /*maps*/, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTDECODE, NULL, "can't read metadata from map: %d", ret)
+
+ /* Broadcast map info if there are other processes that need it */
+ if(collective && (item->file->num_procs > 1)) {
+ HDassert(minfo_buf);
+ HDassert(sizeof(minfo_buf_static) >= 5 * sizeof(uint64_t));
+
+ /* Encode oid */
+ p = minfo_buf;
+ UINT64ENCODE(p, map->obj.oid.lo)
+ UINT64ENCODE(p, map->obj.oid.mid)
+ UINT64ENCODE(p, map->obj.oid.hi)
+
+ /* Encode serialized info lengths */
+ UINT64ENCODE(p, ktype_len)
+ UINT64ENCODE(p, vtype_len)
+
+ /* MPI_Bcast minfo_buf */
+ if(MPI_SUCCESS != MPI_Bcast((char *)minfo_buf, sizeof(minfo_buf_static), MPI_BYTE, 0, item->file->comm))
+ HGOTO_ERROR(H5E_MAP, H5E_MPI, NULL, "can't bcast map info");
+
+ /* Need a second bcast if it did not fit in the receivers' static
+ * buffer */
+ if(tot_len + (5 * sizeof(uint64_t)) > sizeof(minfo_buf_static))
+ if(MPI_SUCCESS != MPI_Bcast((char *)p, (int)tot_len, MPI_BYTE, 0, item->file->comm))
+ HGOTO_ERROR(H5E_MAP, H5E_MPI, NULL, "can't bcast map info (second bcast)")
+ } /* end if */
+ else
+ p = minfo_buf + (5 * sizeof(uint64_t));
+ } /* end if */
+ else {
+ /* Receive map info */
+ if(MPI_SUCCESS != MPI_Bcast((char *)minfo_buf, sizeof(minfo_buf_static), MPI_BYTE, 0, item->file->comm))
+ HGOTO_ERROR(H5E_MAP, H5E_MPI, NULL, "can't bcast map info")
+
+ /* Decode oid */
+ p = minfo_buf_static;
+ UINT64DECODE(p, map->obj.oid.lo)
+ UINT64DECODE(p, map->obj.oid.mid)
+ UINT64DECODE(p, map->obj.oid.hi)
+
+ /* Decode serialized info lengths */
+ UINT64DECODE(p, ktype_len)
+ UINT64DECODE(p, vtype_len)
+ tot_len = ktype_len + vtype_len;
+
+ /* Check for type_len set to 0 - indicates failure */
+ if(ktype_len == 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTINIT, NULL, "lead process failed to open map")
+
+ /* Check if we need to perform another bcast */
+ if(tot_len + (5 * sizeof(uint64_t)) > sizeof(minfo_buf_static)) {
+ /* Allocate a dynamic buffer if necessary */
+ if(tot_len > sizeof(minfo_buf_static)) {
+ if(NULL == (minfo_buf_dyn = (uint8_t *)H5MM_malloc(tot_len)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTALLOC, NULL, "can't allocate space for map info")
+ minfo_buf = minfo_buf_dyn;
+ } /* end if */
+
+ /* Receive map info */
+ if(MPI_SUCCESS != MPI_Bcast((char *)minfo_buf, (int)tot_len, MPI_BYTE, 0, item->file->comm))
+ HGOTO_ERROR(H5E_MAP, H5E_MPI, NULL, "can't bcast map info (second bcast)")
+
+ p = minfo_buf;
+ } /* end if */
+
+ /* Open map */
+ if(0 != (ret = daos_obj_open(item->file->coh, map->obj.oid, item->file->epoch, item->file->flags & H5F_ACC_RDWR ? DAOS_COO_RW : DAOS_COO_RO, &map->obj.obj_oh, NULL /*event*/)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTOPENOBJ, NULL, "can't open map: %d", ret)
+ } /* end else */
+
+ /* Decode datatype, dataspace, and DCPL */
+ if((map->ktype_id = H5Tdecode(p)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTDECODE, NULL, "can't deserialize datatype")
+ p += ktype_len;
+ if((map->vtype_id = H5Tdecode(p)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTDECODE, NULL, "can't deserialize datatype")
+
+ /* Set return value */
+ ret_value = (void *)map;
+
+done:
+ /* Cleanup on failure */
+ if(NULL == ret_value) {
+ /* Bcast minfo_buf as '0' if necessary - this will trigger failures in
+ * in other processes so we do not need to do the second bcast. */
+ if(must_bcast) {
+ HDmemset(minfo_buf_static, 0, sizeof(minfo_buf_static));
+ if(MPI_SUCCESS != MPI_Bcast(minfo_buf_static, sizeof(minfo_buf_static), MPI_BYTE, 0, item->file->comm))
+ HDONE_ERROR(H5E_MAP, H5E_MPI, NULL, "can't bcast empty map info")
+ } /* end if */
+
+ /* Close map */
+ if(map && H5VL_daosm_map_close(map, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CLOSEERROR, NULL, "can't close map")
+ } /* end if */
+
+ /* Close target group */
+ if(target_grp && H5VL_daosm_group_close(target_grp, dxpl_id, req) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CLOSEERROR, NULL, "can't close group")
+
+ /* Free memory */
+ minfo_buf_dyn = (uint8_t *)H5MM_xfree(minfo_buf_dyn);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daos_map_get_size
+ *
+ * Purpose: Retrieves the size of a Key or Value binary
+ * buffer given its datatype and buffer contents.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_daos_map_get_size(hid_t type_id, const void *buf,
+ /*out*/uint64_t H5_ATTR_UNUSED *checksum, /*out*/size_t *size,
+ /*out*/H5T_class_t *ret_class)
+{
+ size_t buf_size = 0;
+ H5T_t *dt = NULL;
+ H5T_class_t dt_class;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
+
+ dt_class = H5T_get_class(dt, FALSE);
+
+ switch(dt_class) {
+ case H5T_STRING:
+ /* If this is a variable length string, get the size using strlen(). */
+ if(H5T_is_variable_str(dt)) {
+ buf_size = HDstrlen((const char*)buf) + 1;
+
+ break;
+ }
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_TIME:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_ENUM:
+ case H5T_ARRAY:
+ case H5T_NO_CLASS:
+ case H5T_REFERENCE:
+ case H5T_NCLASSES:
+ case H5T_COMPOUND:
+ /* Data is not variable length, so use H5Tget_size() */
+ /* MSC - This is not correct. Compound/Array can contian
+ VL datatypes, but for now we don't support that. Need
+ to check for that too */
+ buf_size = H5T_get_size(dt);
+
+ break;
+
+ /* If this is a variable length datatype, iterate over it */
+ case H5T_VLEN:
+ {
+ H5T_t *super = NULL;
+ const hvl_t *vl;
+
+ vl = (const hvl_t *)buf;
+
+ if(NULL == (super = H5T_get_super(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid super type of VL type");
+
+ buf_size = H5T_get_size(super) * vl->len;
+ H5T_close(super);
+ break;
+ } /* end block */
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "unsupported datatype");
+ } /* end switch */
+
+ *size = buf_size;
+ if(ret_class)
+ *ret_class = dt_class;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daos_map_get_size */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daos_map_dtype_info
+ *
+ * Purpose: Retrieves information about the datatype of Map Key or
+ * value datatype, whether it's VL or not. If it is not VL
+ * return the size.
+ *
+ * Return: Success: SUCCEED
+ * Failure: Negative
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5VL_daos_map_dtype_info(hid_t type_id, hbool_t *is_vl, size_t *size,
+ H5T_class_t *cls)
+{
+ size_t buf_size = 0;
+ H5T_t *dt = NULL;
+ H5T_class_t dt_class;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ if(NULL == (dt = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5T_NO_CLASS, "not a datatype")
+
+ dt_class = H5T_get_class(dt, FALSE);
+
+ switch(dt_class) {
+ case H5T_STRING:
+ /* If this is a variable length string, get the size using strlen(). */
+ if(H5T_is_variable_str(dt)) {
+ *is_vl = TRUE;
+ break;
+ }
+ case H5T_INTEGER:
+ case H5T_FLOAT:
+ case H5T_TIME:
+ case H5T_BITFIELD:
+ case H5T_OPAQUE:
+ case H5T_ENUM:
+ case H5T_ARRAY:
+ case H5T_NO_CLASS:
+ case H5T_REFERENCE:
+ case H5T_NCLASSES:
+ case H5T_COMPOUND:
+ /* Data is not variable length, so use H5Tget_size() */
+ /* MSC - This is not correct. Compound/Array can contian
+ VL datatypes, but for now we don't support that. Need
+ to check for that too */
+ buf_size = H5T_get_size(dt);
+ *is_vl = FALSE;
+ break;
+
+ /* If this is a variable length datatype, iterate over it */
+ case H5T_VLEN:
+ *is_vl = TRUE;
+ break;
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "unsupported datatype");
+ }
+
+ if(size)
+ *size = buf_size;
+ if(cls)
+ *cls = dt_class;
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daos_map_dtype_info */
+
+
+herr_t
+H5VL_daosm_map_set(void *_map, hid_t key_mem_type_id, const void *key,
+ hid_t val_mem_type_id, const void *value, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_map_t *map = (H5VL_daosm_map_t *)_map;
+ size_t key_size, val_size;
+ char const_akey[] = H5VL_DAOSM_MAP_KEY;
+ daos_key_t dkey;
+ daos_iod_t iod;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ H5T_class_t cls;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ /* get the key size and checksum from the provdied key datatype & buffer */
+ if(H5VL_daos_map_get_size(key_mem_type_id, key, NULL, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* get the val size and checksum from the provdied val datatype & buffer */
+ if(H5VL_daos_map_get_size(val_mem_type_id, value, NULL, &val_size, &cls) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get val size");
+
+ /* Set up dkey */
+ daos_iov_set(&dkey, (void *)key, (daos_size_t)key_size);
+
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.iod_name, (void *)const_akey, (daos_size_t)(sizeof(const_akey) - 1));
+ daos_csum_set(&iod.iod_kcsum, NULL, 0);
+ iod.iod_nr = 1u;
+ iod.iod_size = (daos_size_t)val_size;
+ iod.iod_type = DAOS_IOD_SINGLE;
+
+ /* Set up sgl */
+ if (H5T_VLEN == cls) {
+ hvl_t *vl_buf = (hvl_t *)value;
+
+ daos_iov_set(&sg_iov, (void *)vl_buf->p, (daos_size_t)val_size);
+ }
+ else {
+ daos_iov_set(&sg_iov, (void *)value, (daos_size_t)val_size);
+ }
+
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ if(0 != (ret_value = daos_obj_update(map->obj.obj_oh,
+ map->obj.item.file->epoch, &dkey,
+ 1, &iod, &sgl, NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTSET, FAIL, "Map set failed: %d", ret_value);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_set() */
+
+
+herr_t
+H5VL_daosm_map_get(void *_map, hid_t key_mem_type_id, const void *key,
+ hid_t val_mem_type_id, void *value, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_map_t *map = (H5VL_daosm_map_t *)_map;
+ size_t key_size, val_size;
+ hbool_t val_is_vl;
+ char const_akey[] = H5VL_DAOSM_MAP_KEY;
+ daos_key_t dkey;
+ daos_iod_t iod;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ H5T_class_t cls;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT;
+
+ /* get the key size and checksum from the provdied key datatype & buffer */
+ if(H5VL_daos_map_get_size(key_mem_type_id, key, NULL, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* get information about the datatype of the value. Get the values
+ size if it is not VL. val_size will be 0 if it is VL */
+ if(H5VL_daos_map_dtype_info(val_mem_type_id, &val_is_vl, &val_size, &cls) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* Set up dkey */
+ daos_iov_set(&dkey, (void *)key, (daos_size_t)key_size);
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.iod_name, const_akey, (daos_size_t)(sizeof(const_akey) - 1));
+ daos_csum_set(&iod.iod_kcsum, NULL, 0);
+ iod.iod_nr = 1u;
+ iod.iod_type = DAOS_IOD_SINGLE;
+
+ if (!val_is_vl) {
+ iod.iod_size = (daos_size_t)val_size;
+
+ /* Set up sgl */
+ daos_iov_set(&sg_iov, value, (daos_size_t)val_size);
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ if(0 != (ret_value = daos_obj_fetch(map->obj.obj_oh,
+ map->obj.item.file->epoch, &dkey,
+ 1, &iod, &sgl, NULL , NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "MAP get failed: %d", ret_value);
+ }
+ else {
+ iod.iod_size = DAOS_REC_ANY;
+ if(0 != (ret_value = daos_obj_fetch(map->obj.obj_oh,
+ map->obj.item.file->epoch, &dkey,
+ 1, &iod, NULL, NULL , NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "MAP get failed: %d", ret_value);
+
+ val_size = iod.iod_size;
+
+ if(cls == H5T_STRING) {
+ char *val;
+
+ val = (char *)malloc(val_size);
+ daos_iov_set(&sg_iov, val, (daos_size_t)val_size);
+ (*(void **) value) = val;
+ }
+ else {
+ hvl_t *vl_buf = (hvl_t *)value;
+
+ HDassert(H5T_VLEN == cls);
+
+ vl_buf->len = val_size;
+ vl_buf->p = malloc(val_size);
+ daos_iov_set(&sg_iov, vl_buf->p, (daos_size_t)val_size);
+ }
+
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ if(0 != (ret_value = daos_obj_fetch(map->obj.obj_oh,
+ map->obj.item.file->epoch, &dkey,
+ 1, &iod, &sgl, NULL , NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "MAP get failed: %d", ret_value);
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_get() */
+
+
+herr_t
+H5VL_daosm_map_get_types(void *_map, hid_t *key_type_id, hid_t *val_type_id,
+ void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_map_t *map = (H5VL_daosm_map_t *)_map;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT;
+
+ if((*key_type_id = H5Tcopy(map->ktype_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of map key");
+
+ if((*val_type_id = H5Tcopy(map->vtype_id)) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL, "can't get datatype ID of map val");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5VL_daosm_map_get_types() */
+
+
+#define ENUM_DESC_BUF 512
+#define ENUM_DESC_NR 5
+
+herr_t
+H5VL_daosm_map_get_count(void *_map, hsize_t *count, void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_map_t *map = (H5VL_daosm_map_t *)_map;
+ char *buf;
+ daos_key_desc_t kds[ENUM_DESC_NR];
+ daos_hash_out_t anchor;
+ uint32_t number;
+ hsize_t key_nr;
+ daos_sg_list_t sgl;
+ daos_iov_t sg_iov;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT;
+
+ memset(&anchor, 0, sizeof(anchor));
+ buf = (char *)malloc(ENUM_DESC_BUF);
+
+ daos_iov_set(&sg_iov, buf, ENUM_DESC_BUF);
+ sgl.sg_nr.num = 1;
+ sgl.sg_iovs = &sg_iov;
+
+ for (number = ENUM_DESC_NR, key_nr = 0; !daos_hash_is_eof(&anchor);
+ number = ENUM_DESC_NR) {
+ HDmemset(buf, 0, ENUM_DESC_BUF);
+
+ ret_value = daos_obj_list_dkey(map->obj.obj_oh,
+ map->obj.item.file->epoch,
+ &number, kds, &sgl, &anchor, NULL);
+ if(ret_value != 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "Map List failed: %d", ret_value);
+ if (number == 0)
+ continue; /* loop should break for EOF */
+
+ key_nr += (hsize_t)number;
+ }
+
+ /* -1 for MD dkey */
+ *count = (hsize_t)(key_nr - 1);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_get_count() */
+
+
+herr_t
+H5VL_daosm_map_exists(void *_map, hid_t key_mem_type_id, const void *key,
+ hbool_t *exists, void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_map_t *map = (H5VL_daosm_map_t *)_map;
+ size_t key_size;
+ char const_akey[] = H5VL_DAOSM_MAP_KEY;
+ daos_key_t dkey;
+ daos_iod_t iod;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT;
+
+ /* get the key size and checksum from the provdied key datatype & buffer */
+ if(H5VL_daos_map_get_size(key_mem_type_id, key, NULL, &key_size, NULL) < 0)
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "can't get key size");
+
+ /* Set up dkey */
+ daos_iov_set(&dkey, (void *)key, (daos_size_t)key_size);
+ /* Set up iod */
+ HDmemset(&iod, 0, sizeof(iod));
+ daos_iov_set(&iod.iod_name, (void *)const_akey, (daos_size_t)(sizeof(const_akey) - 1));
+ daos_csum_set(&iod.iod_kcsum, NULL, 0);
+ iod.iod_nr = 1u;
+ iod.iod_type = DAOS_IOD_SINGLE;
+ iod.iod_size = DAOS_REC_ANY;
+
+ if(0 != (ret_value = daos_obj_fetch(map->obj.obj_oh,
+ map->obj.item.file->epoch, &dkey,
+ 1, &iod, NULL, NULL , NULL)))
+ HGOTO_ERROR(H5E_MAP, H5E_CANTGET, FAIL, "MAP get failed: %d", ret_value);
+
+ if(iod.iod_size != 0)
+ *exists = TRUE;
+ else
+ *exists = FALSE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5VL_daosm_map_close
+ *
+ * Purpose: Closes a daos-m HDF5 map.
+ *
+ * Return: Success: 0
+ * Failure: -1
+ *
+ * Programmer: Neil Fortner
+ * November, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5VL_daosm_map_close(void *_map, hid_t H5_ATTR_UNUSED dxpl_id,
+ void H5_ATTR_UNUSED **req)
+{
+ H5VL_daosm_map_t *map = (H5VL_daosm_map_t *)_map;
+ int ret;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT
+
+ HDassert(map);
+
+ if(--map->obj.item.rc == 0) {
+ /* Free map data structures */
+ if(!daos_handle_is_inval(map->obj.obj_oh))
+ if(0 != (ret = daos_obj_close(map->obj.obj_oh, NULL /*event*/)))
+ HDONE_ERROR(H5E_MAP, H5E_CANTCLOSEOBJ, FAIL, "can't close map DAOS object: %d", ret)
+ if(map->ktype_id != FAIL && H5I_dec_app_ref(map->ktype_id) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "failed to close datatype")
+ if(map->vtype_id != FAIL && H5I_dec_app_ref(map->vtype_id) < 0)
+ HDONE_ERROR(H5E_MAP, H5E_CANTDEC, FAIL, "failed to close datatype")
+ map = H5FL_FREE(H5VL_daosm_map_t, map);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5VL_daosm_map_close() */
+
diff --git a/src/H5VLdaosm.h b/src/H5VLdaosm.h
index cf14924..ab9d754 100644
--- a/src/H5VLdaosm.h
+++ b/src/H5VLdaosm.h
@@ -97,6 +97,13 @@ typedef struct H5VL_daosm_dset_t {
hid_t dapl_id;
} H5VL_daosm_dset_t;
+/* The map struct */
+typedef struct H5VL_daosm_map_t {
+ H5VL_daosm_obj_t obj; /* Must be first */
+ hid_t ktype_id;
+ hid_t vtype_id;
+} H5VL_daosm_map_t;
+
/* The attribute struct */
typedef struct H5VL_daosm_attr_t {
H5VL_daosm_item_t item; /* Must be first */
@@ -119,6 +126,21 @@ extern hid_t H5VL_DAOSM_g;
H5_DLL herr_t H5VL_daosm_init(void);
+H5_DLL void * H5VL_daosm_map_create(void *_item, H5VL_loc_params_t loc_params, const char *name,
+ hid_t ktype_id, hid_t vtype_id, hid_t mcpl_id, hid_t mapl_id,
+ hid_t dxpl_id, void **req);
+H5_DLL void * H5VL_daosm_map_open(void *_item, H5VL_loc_params_t loc_params, const char *name,
+ hid_t mapl_id, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VL_daosm_map_set(void *_map, hid_t key_mem_type_id, const void *key,
+ hid_t val_mem_type_id, const void *value, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VL_daosm_map_get(void *_map, hid_t key_mem_type_id, const void *key,
+ hid_t val_mem_type_id, void *value, hid_t dxpl_id, void **req);
+H5_DLL herr_t H5VL_daosm_map_get_types(void *_map, hid_t *key_type_id, hid_t *val_type_id, void **req);
+H5_DLL herr_t H5VL_daosm_map_get_count(void *_map, hsize_t *count, void **req);
+H5_DLL herr_t H5VL_daosm_map_exists(void *_map, hid_t key_mem_type_id, const void *key,
+ hbool_t *exists, void **req);
+H5_DLL herr_t H5VL_daosm_map_close(void *_map, hid_t dxpl_id, void **req);
+
#endif /* H5_HAVE_EFF */
#ifdef __cplusplus
diff --git a/src/H5VLprivate.h b/src/H5VLprivate.h
index 9240a2d..152bf3b 100644
--- a/src/H5VLprivate.h
+++ b/src/H5VLprivate.h
@@ -142,6 +142,7 @@ H5_DLL herr_t H5F_close_file(void *file);
H5_DLL herr_t H5A_close_attr(void *attr);
H5_DLL herr_t H5D_close_dataset(void *dset);
H5_DLL herr_t H5G_close_group(void *grp);
+H5_DLL herr_t H5M_close_map(void *map);
H5_DLL herr_t H5T_close_datatype(void *dt);
H5_DLL hid_t H5VL_native_register(H5I_type_t type, void *obj, hbool_t app_ref);
diff --git a/src/H5err.txt b/src/H5err.txt
index 2251958..32e9819 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -61,6 +61,7 @@ MAJOR, H5E_OHDR, Object header
MAJOR, H5E_DATATYPE, Datatype
MAJOR, H5E_DATASPACE, Dataspace
MAJOR, H5E_DATASET, Dataset
+MAJOR, H5E_MAP, Map
MAJOR, H5E_STORAGE, Data storage
MAJOR, H5E_PLIST, Property lists
MAJOR, H5E_ATTR, Attribute
diff --git a/src/H5private.h b/src/H5private.h
index 848228e..2aaddc2 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -2551,6 +2551,8 @@ H5_DLL int H5FL_term_package(void);
H5_DLL int H5FS_term_package(void);
H5_DLL int H5G_term_package(void);
H5_DLL int H5G_top_term_package(void);
+H5_DLL int H5M_term_package(void);
+H5_DLL int H5M_top_term_package(void);
H5_DLL int H5I_term_package(void);
H5_DLL int H5L_term_package(void);
H5_DLL int H5P_term_package(void);
diff --git a/src/Makefile.am b/src/Makefile.am
index 79850ae..ed19d60 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -78,6 +78,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5HG.c H5HGcache.c H5HGdbg.c H5HGquery.c \
H5HL.c H5HLcache.c H5HLdbg.c H5HLint.c H5HLprfx.c H5HLdblk.c\
H5HP.c H5I.c H5Itest.c H5L.c H5Lexternal.c H5lib_settings.c \
+ H5M.c \
H5MF.c H5MFaggr.c H5MFdbg.c H5MFsection.c \
H5MM.c H5MP.c H5MPtest.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
@@ -136,8 +137,8 @@ include_HEADERS = hdf5.h H5api_adpt.h H5overflow.h H5pubconf.h H5public.h H5vers
H5FFpublic.h \
H5VLpublic.h H5VLnative.h \
H5VLdaosm_public.h \
- H5Gpublic.h H5Ipublic.h H5Lpublic.h \
- H5MMpublic.h H5Opublic.h H5Ppublic.h \
+ H5Gpublic.h H5Ipublic.h H5Lpublic.h \
+ H5Mpublic.h H5MMpublic.h H5Opublic.h H5Ppublic.h \
H5PLextern.h H5PLpublic.h \
H5Rpublic.h H5Spublic.h \
H5Tpublic.h H5TRpublic.h H5Zpublic.h
diff --git a/src/hdf5.h b/src/hdf5.h
index 7d3e74b..4ddc7ab 100644
--- a/src/hdf5.h
+++ b/src/hdf5.h
@@ -32,6 +32,7 @@
#include "H5Ipublic.h" /* ID management */
#include "H5Lpublic.h" /* Links */
#include "H5MMpublic.h" /* Memory management */
+#include "H5Mpublic.h" /* Maps */
#include "H5Opublic.h" /* Object headers */
#include "H5Ppublic.h" /* Property lists */
#include "H5PLpublic.h" /* Plugins */